amsrcs01.pl to HTML.

index -|- end

Generated: Tue Feb 2 17:54:21 2010 from amsrcs01.pl 2009/06/24 76.2 KB.

# NAME: amsrcs01.pl
# AIM: Given a folder, trace the makefile.am files, collecting
# libraries, applications and sources
# Show 'projects' found, and SHOW the sources of each.
# AND write a DSP file for each!!!
# Also see am2dsp[n].pl as well ...
#
# Also scan the 'top' directory for ALL FILE,
# and show files NOT in a project
# Add projects NOT addressed by main configure.ac and makefile.am
# 17/11/2007 - geoff mclane - http://geoffair.net/mperl
# The process
#
# Read the configure.ac file, and build a set of contents
# and put inputs into @make_input_list, or @other_input_files
# which are then put in @input_files ... set $dgb20 to see list as processed
#
# Each @input_files, and later @other_inputs (makefile.am) is processed in process_am_file()
# Sources are added to @msvc_c_files in form 'Lib/Project | Source | Title'
# extract_am_project then separates these into $am_projects{$lib} .= ['|'.]$lsc;
#
# The %am_project's are shown by show_am_projects( $main_root_dir );
# Then the 'other' projects are shown - show_other_projects( $main_root_dir );
# and finally all source files found show_all_sources( "makefile.am set", $main_root_dir );
# 04/04/2008 - add read of sub-directory 'configure.ac' if present ...
use strict;
use warnings;
use File::Basename;   # to split path into ($name, $dir) = fileparse($ff); or ($nm,$dir,$ext) = fileparse( $fil, qr/\.[^.]*/ );
require 'logfile.pl' or die "Unable to load logfile.pl ...\n";
require 'relative.pl' or die "Unable to load relative.pl ...\n";
require 'chkmain.pl' or die "Unable to load chkmain.pl ...\n";
require 'utils.pl' or die "Unable to load utils.pl ...\n";
# log file stuff
my ($LF);
my $pgmname = $0;
if ($pgmname =~ /\w{1}:\\.*/) {
   my @tmpsp = split(/\\/,$pgmname);
   $pgmname = $tmpsp[-1];
}
my $outfile = "temp.$pgmname.txt";
my $pack = $pgmname;
open_log($outfile);
prt( "$0 ... Hello, World ...\n" );
my $main_root_dir = "C:\\Projects\\tar\\";
##my $main_root_dir = "C:\\Projects\\tar\\lib\\";
###my $main_root_dir = "C:\\FG\\FGCOMXML\\libwww\\";
###my $main_root_dir = "C:\\FG\\FGCOMXML\\curl\\";
###my $main_root_dir = "C:\\FGCVS\\FlightGear\\source\\";
###my $main_root_dir = "C:\\FG\\18\\SimGear\\";
###my $main_root_dir = "C:\\FG\\18\\FlightGear\\";
###my $out_folder = ".\\";
my $out_folder = $main_root_dir.'build'."\\";
my $recheck_am = 0;   # a debug RE-CHECK of makefile.am files for a reference
my $check_full = 1;   # check for the FULL file name
my $long_line = " C:\\FGCVS\\FlightGear\\source\\scripts\\example\\fgfsclient.cxx ";
my $min_line = length($long_line);
my $check4main = 1;   # check if the NOT FOUND modules have a main() service
my $check4main2 = 1;   # check if the source has a main() service
my $show_main = 0;      # actually SHOW the main
my $show_cond = 0;      # actually SHOW the condition for main
my $one_line = 0;      # output sources in ONE line
my $add_rel_src = 1;    # add the relative source to output
############################
####### ONLY DSP STUFF
my $out_dsp  = 1;   # output a MAIN DSP and DSW files
my $out_dsp2 = 1;   # output a secondary DSP files
my $msvc_cflags = '';   # see %am_includes and %am_cppflags # hash by project, the CPPFLAGS, if ANY
my $msvc_libs   = '';   # see %am_libadds  = ();   # hash by project, the LDADD, if ANY
my $msvc_dlibs  = '';
my $msvc_rlibs  = '';
my $last_project = '';
my $last_dsp_file = '';
my @dspinfo = ();
############################
######################
# constants
my $IGNORE_PATTERN = "^##([^#].*)?\$";
my $WHITE_PATTERN = "^[ \t]*\$";
my $COMMENT_PATTERN = "^#";
my $RULE_PATTERN = "^([\$a-zA-Z_.][-.a-zA-Z0-9_(){}/\$]*) *:([^=].*|)\$";
my $SUFFIX_RULE_PATTERN = "^\\.([a-zA-Z]+)\\.([a-zA-Z]+)\$";
my $MACRO_PATTERN = "^([A-Za-z][A-Za-z0-9_]*)[ \t]*([:+]?)=[ \t]*(.*)\$";
my $BOGUS_MACRO_PATTERN = "^([^ \t]*)[ \t]*([:+]?)=[ \t]*(.*)\$";
my $IF_PATTERN = "^if[ \t]+\([A-Za-z][A-Za-z0-9_]*\)[ \t]*\(#.*\)?\$";
my $ELSE_PATTERN = "^else[ \t]*\(#.*\)?\$";
my $ENDIF_PATTERN = "^endif[ \t]*\(#.*\)?\$";
my $PATH_PATTERN='(\\w|/|\\.)+';
# This will pass through anything not of the prescribed form.
my $INCLUDE_PATTERN = "^include[ \t]+((\\\$\\\(top_srcdir\\\)/${PATH_PATTERN})|(\\\$\\\(srcdir\\\)/${PATH_PATTERN})|([^/\\\$]${PATH_PATTERN}))[ \t]*(#.*)?\$";
my $AM_CONDITIONAL_PATTERN = "AM_CONDITIONAL\\((\\w+)";
my $AM_INIT_AUTOMAKE = "AM_INIT_AUTOMAKE\\(([^,]+),[ \t]*([^)]+)";
#### type constants
my $TYPE_NONE = 0;
my $TYPE_C    = 1;
my $TYPE_H    = 2;
my $TYPE_DSW  = 3;
my $TYPE_SLN  = 4;
my $TYPE_AM   = 5;
my $TYPE_MAK  = 6;
######################
# program variables
my $exit_status = 0;
my @input_files = ();
my @make_input_list = ();
my @other_input_files = ();
my %output_files = ();
my %make_list = ();
my %am_vars = ();
my %def_type = ();
my @excluded_dirs = ();
my @var_list = ();
my $dsp_package = '';
my $dsp_version = '';
my %configure_cond = ();
my %configure_vars = ();
my %cfg_defines = ();
my @config_fullnames = ();
my @config_names = ();
my @config_headers = ();
my $config_header_line = '';
####my $am_file = '';
my @msvc_c_extra = ();
my @msvc_h_extra = ();
my @msvc_o_extra = ();
my @done_am = ();   # list of AM files read
my @warnings = ();
my @ac_scanned = ();
my %config_ac_macros = ();
# These two variables are used when generating each Makefile.in.
# They hold the Makefile.in until it is ready to be printed.
my $output_vars = '';
my $output_trailer = '';
# This holds the contents of a Makefile.am, as parsed by
# read_am_file.
my %contents = ();
# This holds the names which are targets.  These also appear in
# %contents.
my %targets = ();
# For a variable or target which is defined conditionally, this
# holds an array of the conditional values.  The array is composed
# of pairs of condition strings (the variables which configure
# will substitute) and values (the value of a target is
# meaningless).  For an unconditional variable, this is empty.
my %conditional = ();
# This holds the line numbers at which various elements of
# %contents are defined.
my %content_lines = ();
# This holds a 1 if a particular variable was examined.
my %content_seen = ();
# This is the conditional stack.
my @conditional_stack = ();
# This holds the set of included files.
my @include_stack = ();
# This holds the "relative directory" of the current Makefile.in.
# Eg for src/Makefile.in, this is "src".
my $relative_dir = '';
# This maps the source extension of a suffix rule to its
# corresponding output extension.
my %suffix_rules = ();
# per AM file sources
my @am_c_files = ();
my @am_h_files = ();
my @am_o_files = ();
#################
### final source lists
my @msvc_c_files = ();
my @msvc_titles  = ();
my @msvc_h_files = ();
my @msvc_o_files = ();
my %other_projs = ();
my %am_projects = ();
my %am_includes = ();   # hash by project, the INCLUDES, if ANY
my %am_cppflags = ();   # hash by project, the CPPFLAGS, if ANY
my %am_libadds  = ();   # hash by project, the LDADD, if ANY
my @all_files = ();
my $active_am_file = '';
my $current_am_file = '';
my $next_am_file = '';
my ($fil_name, $fil_dir, $full_fil_path);
#######################
# debug
my $dbg1 = 0;   # show EACH configure.ac line
my $dbg2 = 0;   # show "Storing configure_cond key $1 ... value=? ..."
my $dbg2a = 0;   # show if (/$AM_CONDITIONAL_PATTERN/o) { prt( "$aclnnum: [$acline]\n" ) if ($dbg2a);
my $dbg3 = 0;   # show "Substute $key=$nval ... setting $var_hash{$key} = $nval;
my $dbg3a = 0;   # show "MACRO [$key]=[$nval]
my $dbg4 = 0;   # show "Got ac_output_line = [$ac_output_line] ...
my $dbg5 = 0;   # show "Adding $input [$ff] to make_input_list ...
my $dbg6 = 0;   # list Makefile list found
my $dbg7 = 0;   # show each 'makefile' processed ...
my $dbg8g = 1;   # show "Group set to [$group] ...
my $dbg8 = 0;   # show "Group set to [$group] ... *AND* "Expanding variable $varname ...
my $dbg9 = 0;   # show "Added [$file] to C EXTRA list...
my $dbg10 = 0;   # show each makefile.am line ...
my $dbg11 = 0;   # show "NO contents for [$last_var_name]! ...
my $dbg12 = 0;   # show "End $last_var_name = ["... if !$saw_bk
my $dbg13 = 0;   # show "Found if $1, and condition is TRUE (see cfg_defines) ...
my $dbg14 = 0;   # show "Found a macro definition. 1[$1] 2[$2] 3[$3] ... something=something in Makefile.am
my $dbg15 = 0;   # show macro "NB: [$last_var_name] = [$contents{$last_var_name}]" . ...
my $dbg16 = 1;   # show "$pack: reading $am_file ...
my $dbg17 = 0;   # show "Sources ending in .$source_suffix become .$object_suffix ...
my $dbg18 = 0;   # show "Add $src to C list
my $dbg19 = 0;   # show %contents after makefile.am parse
my $dbg20 = 1;   # show "\nProcessing [$am_file] from input_files array ...
my $dbg21 = 1;   # show "Project: [$proj] - sources [$srcs] ...
my $dbg22 = 1;   # show CHECK ME always ...
my $dbg23 = 0;   # show directory content count - "Found ".scalar @dir_cont." items in [$fil]
my $dbg24 = 0;   # show "Processing AM file [" . $makefile . ".am]
my $dbg25 = 0;   # show "Got INCLUDES [$incs] ...
my $dbg26 = 0;   # show "For $group, saved INCLUDES [$incs]
my $dbg27 = 0;   # show checking for substitution macros ...
my $dbg28 = 1;  # show ALL %contents ... see $dbg19 also above to show more ...
# Normally it was intended to read an am2cfg.def file, but set some anyway
$cfg_defines{"HAVE_GLUT"} = 1;
prt( "Moment, getting full file list of $main_root_dir ...\n" );
get_top_files( $main_root_dir );
prt( "Got ".scalar @all_files." files ...\n" );
scan_root_folder( $main_root_dir );
foreach my $afile (@input_files) {
   ($fil_name, $fil_dir) = fileparse($afile);
   #$full_fil_path = unix_2_dos($main_root_dir . $fil_dir);
   $full_fil_path = fix_rel($main_root_dir . $fil_dir);   # also returns DOS, minus trailing '\'
   $full_fil_path .= "\\" if ( !($full_fil_path =~ /\\$/) );      # add trailing '\' IF
   $next_am_file = $afile;
   $next_am_file .= ".am" if (has_no_extent($afile) && !is_am_file($afile));
   prt( "\nProcessing [$next_am_file] from input_files array ...\n" ) if ($dbg20);
    process_am_file($dsp_package, $afile, $main_root_dir) if !exclude_dir($afile);
   my $mk = mark_all_files(unix_2_dos($main_root_dir . $afile . '.am'));
   prt( "WARNING: NOT FOUND IN MARK [".unix_2_dos($main_root_dir.$afile.".am")."]!\n" ) if (!$mk);
}
my @other_inputs = get_missed_makes($main_root_dir);
if (@other_inputs) {
   prt( "Other AM files, not used = ".scalar @other_inputs." ...\n" );
   foreach my $afile (@other_inputs) {
      ($fil_name, $fil_dir) = fileparse($afile);
      ##$full_fil_path = unix_2_dos($main_root_dir . $fil_dir);
      $full_fil_path = fix_rel($main_root_dir . $fil_dir);   # also returns DOS, minus trailing '\'
      $full_fil_path .= "\\" if ( !($full_fil_path =~ /\\$/) );   # add trailing '\' IF
      $next_am_file = $afile;
      $next_am_file .= ".am" if (has_no_extent($afile) && !is_am_file($afile));
      prt( "\nProcessing other [$next_am_file] in ($full_fil_path) ...\n" );
       process_am_file('Others', $afile, $main_root_dir) if !exclude_dir($afile);
      my $mk = mark_all_files(unix_2_dos($main_root_dir . $afile ));
      prt( "WARNING: NOT FOUND IN MARK [".unix_2_dos($main_root_dir.$afile)."]!\n" ) if (!$mk);
   }
}
my $c_cnt = scalar @msvc_c_files;
my $t_cnt = scalar @msvc_titles;
my $h_cnt = scalar @msvc_h_files;
my $o_cnt = scalar keys(%other_projs);
prt( "c_cnt = $c_cnt, h_cnt = $h_cnt, t_cnt = $t_cnt, o_cnt = $o_cnt ...\n" );
extract_am_projects();
my $p_cnt = scalar keys(%am_projects);
show_am_projects( $main_root_dir );
show_other_projects( $main_root_dir );
show_all_sources( "makefile.am set", $main_root_dir );
if (@warnings) {
   foreach my $mg (@warnings) {
      prt("$mg\n");
   }
}
if (@dspinfo) {
    foreach my $di (@dspinfo) {
        prt("$di\n");
    }
}
close_log($outfile,1);
exit($exit_status);
#######################################################################
##### all subs below
sub extract_am_projects {
   foreach my $file (@msvc_c_files) {
      ##prt( "$file\n" );
      my @arr = split(/\|/ , $file);   # get Lib | Source | Title
      if (scalar @arr == 3) {
         my $lib = $arr[0];
         my $lsc = $arr[1];
         if (defined $am_projects{$lib}) {
            $am_projects{$lib} .= '|'.$lsc;
         } else {
            $am_projects{$lib} = $lsc;
         }
      } else {
         prt( "\nWARNING: Did NOT split as EXPECTED!!! [$file] ...\n\n" );
      }
   }
}
sub show_other_projects {
   my ($rd) = shift;
   my ($lsrcs, @arr, $s, $ind, $ff, $mk, $om);
   my ($in_file, $in_dir, $rel_src);
   my $outdir = $out_folder;
   my @projs = ();
   my $out_file = '';
   $last_dsp_file = '';
   prt( "\nFound $o_cnt OTHER projects ...root = $rd\n" );
   foreach my $key (keys %other_projs) {
      $lsrcs = $other_projs{$key};
        # ONLY GENERATE TEMPORARY DSP FILE
      #$out_file = $outdir.$key.'.dsp';
        $out_file = 'temp.'.$key.'.dsp';
      push(@projs, ".\\$key.dsp,$key");
      @arr = split(/\*/, $lsrcs);   # get sources
        if ($one_line) {
            $lsrcs =~ s/\*/, /g;
            prt( "Project: $key = $lsrcs\n" );
        } else {
            prt( "Project: $key\n" );
        }
        foreach $s (@arr) {
            $ind = index($s, '$(top_srcdir)');
            $s = substr($s, $ind + 14) if ($ind >= 0);
            $s = fix_rel($s);
            $ff = $rd . $s;
            $mk = mark_all_files($ff);
            ($in_file, $in_dir) = fileparse($ff);
            #                             source, target
            #$rel_src = get_relative_path( $in_dir, $outdir );
            $rel_src = get_relative_path_2( $in_dir, $outdir );
            $rel_src .= $in_file;
            $rel_src = unix_2_dos($rel_src);
            if (is_c_source($s)) {
                if ($check4main2) {
                    $om = get_main_msg($ff,$s,0,$rel_src); # check if a main()
                } else {
                    $om = "  $s ";
                    $om .= "(rs=$rel_src)" if ($add_rel_src);
                }
                $om .= "NOT FOUND IN MARK!" if (!$mk);
                prt("$om\n");
                if ($out_dsp2) {
                    # generate TEMP DSP file
                    out_dsp_file($key, $out_file, $rel_src, $rd, 0);
                }
            } else {
                $om = "H  $s ";
                $om .= "(rs=$rel_src)" if ($add_rel_src);
                $om .= "NOT FOUND IN MARK!" if (!$mk);
                prt("$om\n");
            }
      }
   }
   if ( length($last_dsp_file) ) {
      end_dsp_file($last_dsp_file);
   }
}
# need 'root' to do DSP/DSW
sub show_am_projects {
   my ($rd) = shift;
   prt( "\nFound $p_cnt LIBRARY projects ...root = $rd\n" );
   my $outdir = $out_folder;
   my @projs = ();
   my $out_file = '';
   my ($in_file, $in_dir, $rel_src);
   my ($s, $ff, $mk, $om);
   foreach my $key (keys %am_projects) {
      my $lsrcs = $am_projects{$key};
      # ONLY GENERATE A TEMPORARY DSP FILE
        #$out_file = $outdir.$key.'.dsp';
        $out_file = 'temp.'.$key.'.dsp';
      push(@projs, ".\\$key.dsp,$key");
      my @arr = split(/\|/ , $lsrcs);   # Sources
      if ($one_line) {
         foreach $s (@arr) {
            $ff = fix_rel($rd . $s);
            $mk = mark_all_files($ff);
            if ($out_dsp) {
               ($in_file, $in_dir) = fileparse($ff);
               #                             source, target
               #$rel_src = get_relative_path( $in_dir, $outdir );
               $rel_src = get_relative_path_2( $in_dir, $outdir );
               $rel_src .= $in_file;
               $rel_src = unix_2_dos($rel_src);
                    # generate TEMP DSP file
               out_dsp_file($key, $out_file, $rel_src, $rd, 1);
            }
         }
         $lsrcs =~ s/\|/, /g;
         prt( "Project: $key = $lsrcs\n" );
      } else {
         prt( "Project: $key\n" );
         foreach $s (@arr) {
            $s = fix_rel($s);
            $ff = $rd . $s;
                ($in_file, $in_dir) = fileparse($ff);
                #                             source, target
                #$rel_src = get_relative_path( $in_dir, $outdir );
                $rel_src = get_relative_path_2( $in_dir, $outdir );
                $rel_src .= $in_file;
                $rel_src = unix_2_dos($rel_src);
            $mk = mark_all_files($ff);
                if ($check4main2) {
                $om = get_main_msg($ff,$s,0,$rel_src); # check if a main()
                } else {
                $om = "  $s ";
                    $om .= "(rs=$rel_src)" if ($add_rel_src);
                }
            if (!$mk) {
               $om .= " NOT FOUND in MARK!";
            }
            prt("$om\n");
            if ($out_dsp) {
                    # genarate TEMP DSP file
               out_dsp_file($key, $out_file, $rel_src, $rd, 1);
            }
         }
      }
   }
   if ( length($last_dsp_file) ) {
      end_dsp_file($last_dsp_file);
      $rd =~ s/\\$//;
      ($in_file, $in_dir) = fileparse($rd);
        # ONLY generate a TEMP DSW
        ##########################
      ##$out_file = $outdir.$in_file.'.dsw';
        $out_file = 'temp.'.$in_file.'.dsw';
      # DSW file, @packs
      generate_dsw( $out_file, @projs );
      $last_dsp_file = '';
      $last_project = '';
   }
}
sub get_main_msg {
   my ($ffn,$sfn,$no,$rs) = @_;
   my $fom = " $sfn ";
    $fom .=  "(rs=$rs)" if ($add_rel_src);
   my @cm = ();
   if (chk_main($ffn,\@cm)) {
      while (length($fom) < $min_line) {
         $fom .= ' ';
      }
      $fom .= "HAS main()";
      my $cmc = scalar @cm;
      for (my $t = 0; $t < $cmc; $t++) {
         $fom .= "\n  ".$cm[$t][0].": ".$cm[$t][1] if ($show_main);
         if (length($cm[$t][2])) {
            if ($show_cond) {
               $fom .= " cond ".$cm[$t][2];
            } else {
               $fom .= " cond";
               last;
            }
         }
      }
   } elsif ($no) {
      while (length($fom) < $min_line) {
         $fom .= ' ';
      }
      $fom .= "NO main() FOUND";
   }
   return $fom;
}
sub scan_root_folder {
    my ($rd) = shift;
   $rd .= "\\" if !(substr($rd,-1,1) =~ /(\\|\/)/);
   my $ff = $rd;   
   $ff .= 'configure.ac';
   prt( "Scanning [$ff] file ...\n" );
    scan_one_configure_file($ff,$rd);
    $ff = $rd.'aclocal.m4';
    scan_one_configure_file($ff,$rd) if -f $ff;
    if (!@input_files) {
        prt( "Copying " . scalar @make_input_list . " make_input_list to input_files.\n" );
        @input_files = @make_input_list;
        %output_files = %make_list;
    } else {
        prt( "input_files has list of " . scalar @input_files . " ...\n" );
    }
   if ($dbg6) {
      my $cnt = scalar @input_files;
      prt( "\nOutput of $cnt input_files list ...\n" );
      $cnt = 0;
      foreach $ff (@input_files) {
         $cnt++;
         prt( "$cnt $ff\n" );
      }
      prt( "Done $cnt input_files list ...\n" );
   }
}
sub is_in_ac_done {
   my ($fil) = shift;
   foreach my $sd (@ac_scanned) {
      if( uc($fil) eq uc($sd) ) {
         return 1;
      }
   }
   return 0;
}
## my %config_ac_macros = ();
sub do_macro_sub2 {
   my ($item) = shift;
   prt( "Checking substitution for [$item] ...\n" ) if ($dbg27);
   if (defined $config_ac_macros{$item}) {   # if it is IN the MACROS
      my $ritem = $config_ac_macros{$item};   # extract the substitute value
      prt( "Found: returning [$ritem] ...\n" ) if ($dbg27);
      return $ritem;
   }
   return $item;
}
sub do_macro_sub {
   my ($item) = shift;
   if ($item =~ /^\$/) {
      my $msub = substr($item,1);   # remove leading '$'
      my $ritem = do_macro_sub2($msub);
      if ($ritem ne $msub) {
         return $ritem;
      }
   }
   return $item;
}
sub scan_one_configure_file {
    my ($filename, $rd) = @_;
   if( is_in_ac_done($filename) ) {
      return;
   }
    if (! open(CONFIGURE, $filename) ) {
        prt( "$pack: WARNING: can't open '$filename': $!\n" );
        return;
    }
   push(@ac_scanned, $filename);
    prt( "Processing configure file - $filename ...\n" );
    my $in_ac_output = 0;
    my $ac_output_line = '';
    my $ff = '';
   my $fline = '';
   my $cline = '';
   my $acline = '';
   my $aclnum = 0;
   my %var_hash = ();
   my $key  = '';
   my $nval = '';
    while (<CONFIGURE>) {
      $fline = $_;   # get current file line
      $cline = $fline;   # copy current file line
      chomp $cline;
      $acline = trim_all($cline);
      $aclnum++;
      ###prt( "$cline\n" );
      # Remove comments from current line.
      s/\bdnl\b.*$//;
      s/\#.*$//;
      $cline =~ s/\bdnl\b.*$//;
      $cline =~ s/\#.*$//;
      next if (length($cline) == 0);
      prt( "$cline\n" ) if ($dbg1);
      if ($cline =~ /^(\w+)="(\d+)"$/) {
         prt( "Num Variable $1=$2\n" ) if ($dbg3);
         $var_hash{$1} = $2;
      ##} elsif ($cline =~ /^(\w+)="(.+)"$/) {
      ##} elsif ($cline =~ /^(\w+)="{0,1}(.+)"{0,1}$/) {
      ##} elsif ($cline =~ /^(\w+)=(.+)$/) {
      } elsif ($cline =~ /^\s*(\w+)=(.+)$/) {
         $key  = $1;
         $nval = $2;
         if (substr($nval,0,1) eq '"') {
            $nval = substr($nval,1, length($nval)-2);
         }
         prt( "MACRO [$key]=[$nval]\n" ) if ($dbg3a);
         if (index($nval,'.') != -1) {
            my @varr = split(/\./,$nval);
            $nval = '';
            my $vlen = scalar @varr;
            prt( "Split to $vlen components ...\n" ) if ($dbg3);
            for (my $i = 0; $i < $vlen; $i++) {
               my $ky = trim_line($varr[$i]);
               prt( "Conponent $ky\n" ) if ($dbg3);
               if (substr($ky,0,1) eq '$') {
                  $ky = substr($ky,1);
                  if (defined $var_hash{$ky}) {
                     $nval .= '.' if (length($nval));
                     $nval .= $var_hash{$ky};
                  } else {
                     $nval .= '.' if (length($nval));
                     $nval .= $ky;
                  }
               } else {
                  $nval .= '.' if (length($nval));
                  $nval .= $ky;
               }
            }
         }
         prt( "Available substitute [$key]=[$nval]\n" ) if ($dbg3);
         $var_hash{$key} = $nval;
         $config_ac_macros{$key} = $nval;
      } elsif ($cline =~ /^(\w+)=(.+)$/) {
         $key  = $1;
         $nval = $2;
         prt( "\nWARNING: This should have already been processed!\nWARNING: Variable [$key]=[$nval] no quotes\n\n" );
      }
      # Skip macro definitions.  Otherwise we might be confused into
      # thinking that a macro that was only defined was actually
      # used.
      next if /AC_DEFUN/;
      # Follow includes.  This is a weirdness commonly in use at
      # Cygnus and hopefully nowhere else.
      if (/sinclude\((.*)\)/ && -f ($rd . $1)) {
         $ff = $rd . $1;
         scan_one_configure_file ($ff, $rd);
      }
      if (! $in_ac_output && ( s/AC_OUTPUT\s*\(\[?// || s/AC_CONFIG_FILES\s*\(\[?// ) ) {
         $in_ac_output = 1;
         $ac_output_line = $.;   # get LINE number
         prt( "Got ac_output_line = [$ac_output_line] ...\n" ) if ($dbg4);
      }
      if ($in_ac_output) {
         my $closing = 0;
         if (s/[\]\),].*$//) {
            $in_ac_output = 0;
            $closing = 1;
         }
         # Look at potential Makefile.am's
         foreach (split) {
            # Must skip empty string for Perl 4.
            next if $_ eq "\\" || $_ eq '';
            my ($local,$input,@rest) = split(/:/);
            if (! $input) {
               $input = $local;
            } else {
               $input =~ s/\.in$//;
            }
            $ff = $rd . $input . '.am';
            if (-f $ff) {
               prt( "Adding $input [$ff] to make_input_list ...\n" ) if ($dbg5);
               push(@make_input_list, $input);
               $make_list{$input} = join(':', ($local,@rest));
            } else {
               prt( "Adding $input [$ff] to other_input_files ...\n" ) if ($dbg5);
               # We have a file that automake should cause to be
               # rebuilt, but shouldn't generate itself.
               push (@other_input_files, $_);
            }
         }
      }
      # Handle configuration headers.  A config header of `[$1]'
      # means we are actually scanning AM_CONFIG_HEADER from
      # aclocal.m4.
      if (/A([CM])_CONFIG_HEADER\s*\((.*)\)/ && $2 ne '[$1]') {
         am_conf_line_error($filename, $., "automake requires AM_CONFIG_HEADER, not AC_CONFIG_HEADER")
               if $1 eq 'C';
         $config_header_line = $.;
         my ($one_hdr);
         foreach $one_hdr (split (' ', $2)) {
            push (@config_fullnames, $one_hdr);
            if ($one_hdr =~ /^([^:]+):(.+)$/) {
               push (@config_names, $1);
               push (@config_headers, $2);
            } else {
               push (@config_names, $one_hdr);
               push (@config_headers, $one_hdr . '.in');
            }
         }
      }
      if (/$AM_CONDITIONAL_PATTERN/o) {
         prt( "$aclnum: [$acline]\n" ) if ($dbg2a);
         if ( defined $cfg_defines{$1} ) {
            # has been DEFINED in am2dsp?.cfg file, or previously defined
            prt( "Storing configure_cond key $1 ... value=2\n" ) if ($dbg2);
            $configure_cond{$1} = 2;
         } else {
            prt( "Storing configure_cond key $1 ... value=1\n" ) if ($dbg2);
            $configure_cond{$1} = 1;
         }
      }
      if (/$AM_INIT_AUTOMAKE/o) {
         $dsp_package = $1;
         $dsp_version = $2;
         prt( "Got AM_INIT_AUTOMAKE($dsp_package, $dsp_version) ...\n" );
         $dsp_package = do_macro_sub($dsp_package);
         $dsp_version = do_macro_sub($dsp_version);
         prt( "Set DSP package = $dsp_package, DSP version = $dsp_version ...\n" );
      }
    }
    close(CONFIGURE);
}
sub am_error {
    my ($msg) = shift;
    prt( $msg."\n" );
   close_log($outfile,1);
   exit($exit_status);
}
sub am_conf_line_error {
   my (@args) = @_;
   am_error(join(' ',@args));
}
sub am_line_error {
    my ($symbol, @args) = @_;
    prt( "am_line_error: sym=[$symbol] arg0=[$args[0]] ...\n" );
    if ($symbol && "$symbol" ne '-1') {
      my ($file) = "$active_am_file";
      if ($symbol =~ /^\d+$/) {
         # SYMBOL is a line number, so just add the colon.
         $file .= ':' . $symbol;
      } elsif (defined $content_lines{$symbol}) {
         # SYMBOL is a variable defined in Makefile.am, so add the
         # line number we saved from there.
         $file .= ':' . $content_lines{$symbol};
      } elsif (defined $configure_vars{$symbol}) {
         # SYMBOL is a variable defined in configure.ac, so add the
         # appropriate line number.
         $file = $configure_vars{$symbol};
      } else {
         # Couldn't find the line number.
      }
      ###warn $file, ": ", join (' ', @args), "\n";
      prt( $file, ": ", join (' ', @args), "\n" );
      $exit_status = 1;
      close_log($outfile,1);
      exit($exit_status);
    } else {
      am_error (join(' ',@args));
   }
}
sub initialize_per_input {
    # These two variables are used when generating each Makefile.in.
    # They hold the Makefile.in until it is ready to be printed.
    $output_vars = '';
    $output_trailer = '';
    # This holds the contents of a Makefile.am, as parsed by
    # read_am_file.
    %contents = ();
    # This holds the names which are targets.  These also appear in
    # %contents.
    %targets = ();
    # For a variable or target which is defined conditionally, this
    # holds an array of the conditional values.  The array is composed
    # of pairs of condition strings (the variables which configure
    # will substitute) and values (the value of a target is
    # meaningless).  For an unconditional variable, this is empty.
    %conditional = ();
    # This holds the line numbers at which various elements of
    # %contents are defined.
    %content_lines = ();
    # This holds a 1 if a particular variable was examined.
    %content_seen = ();
    # This is the conditional stack.
    @conditional_stack = ();
    # This holds the set of included files.
    @include_stack = ();
    # This holds the "relative directory" of the current Makefile.in.
    # Eg for src/Makefile.in, this is "src".
    $relative_dir = '';
    # This maps the source extension of a suffix rule to its
    # corresponding output extension.
    %suffix_rules = ();
   # per AM file sources
   @am_c_files = ();
   @am_h_files = ();
   @am_o_files = ();
}
sub unique_proj {
   my ($prj) = shift;
   if (defined $other_projs{$prj}) {
      my $nprj = $prj;
      my $i = 0;
      while (defined $other_projs{$nprj}) {
         $i++;
         $nprj = "$prj$i";
      }
      return $nprj;
   }
   return $prj;
}
# process for OTHER THAN LIBRARIES
sub process_other_sources {
   my ($mf, $rd) = @_;
   my ($nam, $dir, $ext) = fileparse( $mf, qr/\.[^.]*/ );
    my $rel_dir = dirname($mf);
   # like 'noinst_PROGRAMS = calc_loc'
   # and then 'calc_loc_SOURCES = calc_loc.cxx'
   my ($key, $projs, $proj, $proj2, $ky, $fnd, $skey, $fil, $srcs, $fi, $dnmf, $dndir, $uproj);
    my $bas_dir = ".\\";
   my @dir_cont = ();
   my @proj_arr = ();
   my @proj_files = ();
   $fnd = 0;
   $dnmf = 0;
    foreach $key (keys %contents) {
      if (($key eq 'noinst_PROGRAMS')||($key eq 'bin_PROGRAMS')) {
         $projs = $contents{$key};   # get PROJECT name
         @proj_arr = split(' ', $projs);   # split in case multiple
         foreach $proj (@proj_arr) {   # process each project, getting the SOURCES
            $proj2 = $proj;
            $proj2 =~ s/-/_/g;
            foreach $ky (keys %contents) {
               if (($ky =~ /($proj)_SOURCES/) || ($ky =~ /($proj2)_SOURCES/)){
                  $skey = $ky;
                  $fnd = 1;
                  last;
               }
            }
            if ($fnd) {
               @proj_files = split(' ', $contents{$skey});
               #prt( "Project: [$proj] - sources [".$contents{$skey}."]\n" );
               $srcs = '';
               foreach $fil (@proj_files) {
                  if ($fil =~ /^\$\(([^\)]*)\)$/) {
                     # Found a variable.
                     my $varname = $1;
                     if (defined $contents{$varname}) {
                        my @f2 = split(' ', $contents{$varname});
                        foreach $fi (@f2) {
                           $srcs .= '*' if (length($srcs));
                           $srcs .= unix_2_dos($bas_dir . $rel_dir . "\\" . $fi);
                        }
                     } else {
                        $srcs .= '*' if (length($srcs));
                        $srcs .= unix_2_dos($bas_dir . $rel_dir . "\\" . $fil);
                     }
                  } else {
                     $srcs .= '*' if (length($srcs));
                     $srcs .= unix_2_dos($bas_dir . $rel_dir . "\\" . $fil);
                  }
               }
               prt( "Project: [$proj] - sources [$srcs]\n" ) if ($dbg21);
               $uproj = unique_proj($proj);
               $other_projs{$uproj} = $srcs;   # keep this PROJECT, and SOURCES (both c and h)
               find_am_includes( $proj, $uproj, $rd );
            } else {
               # if we can FIND a C source in the folder OF THE SAME NAME
               # as this project
               if ( !$dndir ) {
                  $fil = $rd . $rel_dir;
                  if (opendir( DIR, $fil)) {
                     @dir_cont = readdir(DIR);
                     close DIR;
                     prt( "Found ".scalar @dir_cont." items in [$fil]\n" ) if ($dbg23);
                  } else {
                     prt( "WARNING: FAILED to OPEN DIRECTORY [$fil] ...\n" );
                  }
                  $dndir = 1;
               }
               $srcs = '';
               $fnd = 0;
               if ( @dir_cont ) {
                  # check contents of local directory
                  foreach $fi (@dir_cont) {
                     next if (($fi eq '.')||($fi eq '..'));
                     $fil = $rd . $rel_dir . "\\" . $fi;
                     if ( is_c_source($fi) && (-f $fil)) {
                        if ($fi =~ /$proj\..+/) {
                           $srcs = unix_2_dos($rel_dir . "\\" . $fi);
                           $fnd = 1;
                           last;
                        }
                     }
                  }
               }
               if ($fnd) {
                  prt( "Project: [$proj] - sources [$srcs]\n" ) if ($dbg21 || $dbg23);
                  $uproj = unique_proj($proj);
                  $other_projs{$uproj} = $srcs;   # keep this PROJECT
                  $fnd = 0;
                  find_am_includes( $proj, $uproj, $rd );
               } else {
                  prt( "Processing file [$mf] ...\n" ) if (!$dnmf);
                  if ($proj =~ /^\@.+\@$/) {
                     $proj = substr($proj,1,length($proj)-2);
                     my $msub = do_macro_sub2($proj);
                     prt( "Project: @[$proj]@ = [$msub] - NO SOURCES FOUND???\n" );
                  } else {
                     prt( "Project: [$proj] - NO SOURCES FOUND???\n" );
                  }
                  $dnmf = 1;
               }
            }
         } # for each $proj in @proj_arr
      }
   }
}
sub replace_top_srcdir {
   my ($nam,$rd) = @_;
   if ($nam =~ /\$\(([^\)]*)\)/ ) {
      my $mac = $1;
      prt( "Checking [$mac] ...\n" ) if ($dbg25);
      if (($mac eq 'top_srcdir')  ||
         ($mac eq 'top_builddir') ) {
         $nam =~ s/\$\(${mac}\)/$rd/;
         $nam = unix_2_dos($nam);
         $nam =~ s/\\{2}/\\/g;
         prt( "Substituted [$nam] ...\n" ) if ($dbg25);
      }
   }
   return $nam;
}
sub find_am_includes {
   my ( $proj, $group, $rd ) = @_;
   ### FIND INCLUDES
   #################
   # like INCLUDES = -I$(top_srcdir)/include
   my $incs = '';
   my @files = ();
   my $cnt = 0;
   my $nam = '';
   my $mac = '';
   my $ii = 0;
   my $jj = 0;
   my $k2 = '';
   foreach $k2 (keys %contents) {
      if ($k2 eq 'INCLUDES') {
         $incs = $contents{$k2};
         last;
      }
   }
   $incs = trim_all($incs);
   if (length($incs)) {
      prt( "Got INCLUDES [$incs] ...\n" ) if ($dbg25);
      @files = split(' ',$incs);
      $cnt = scalar @files;
      for ($ii = 0; $ii < $cnt; $ii++) {
         $nam = $files[$ii];
         $nam =~ s/^-I//;
         $nam = replace_top_srcdir($nam,$rd);
         $files[$ii] = $nam;
      }
      # remove any DUPLICATES
      for ($ii = 0; $ii < $cnt; $ii++) {
         $nam = $files[$ii];
         if (length($nam)) {
            for ($jj = 0; $jj < $cnt; $jj++) {
               if ($ii != $jj) {
                  if ($nam eq $files[$jj]) {
                     $files[$jj] = '';
                  }
               }
            }
         }
      }
      $incs = join(' ', @files);
   }
   $am_includes{$group} = $incs;
   prt( "For $group, saved INCLUDES [$incs]\n" ) if ($dbg26);
   # STATICCPPFLAGS = -DCURL_STATICLIB
   # CPPFLAGS = -DCURL_NO_OLDIES $(STATICCPPFLAGS)
   $incs = '';
   foreach $k2 (keys %contents) {
      if ($k2 eq 'CPPFLAGS') {
         $incs = $contents{$k2};
         last;
      }
   }
   $incs = trim_all($incs);
   if (length($incs)) {
      prt( "Got CPPFLAGS [$incs] ...\n" ) if ($dbg25);
      @files = split(' ',$incs);
      $cnt = scalar @files;
      for ($ii = 0; $ii < $cnt; $ii++) {
         $nam = $files[$ii];
         $nam =~ s/^-D//;
            if ($nam =~ /\$\(([^\)]*)\)/ ) {
            $mac = $1;
            prt( "Checking [$mac] ...\n" ) if ($dbg25);
            if (defined $contents{$mac}) {
               my $mac2 = $contents{$mac};
               $nam =~ s/\$\(${mac}\)/$mac2/;
               $nam =~ s/^-D//;
               prt( "Substituted [$nam] ...\n" ) if ($dbg25);
            }
         }
         $files[$ii] = $nam;
      }
      $incs = join(' ', @files);
   }
   prt( "For $group, saved CPPFLAGS [$incs]\n" ) if ($dbg26);
   $am_cppflags{$group} = $incs;
   # LIBDIR = $(top_builddir)/lib
   # LDADD = $(LIBDIR)/libcurl.la
   $incs = '';
   foreach $k2 (keys %contents) {
      if ($k2 eq 'LDADD') {
         $incs = $contents{$k2};
         last;
      }
   }
   $incs = trim_all($incs);
   if (length($incs)) {
      prt( "Got LDADD [$incs] ...\n" ) if ($dbg25);
      @files = split(' ',$incs);
      $cnt = scalar @files;
      for ($ii = 0; $ii < $cnt; $ii++) {
         $nam = $files[$ii];
         $nam =~ s/^-I//;
            if ($nam =~ /\$\(([^\)]*)\)/ ) {
            $mac = $1;
            prt( "Checking [$mac] ...\n" ) if ($dbg25);
            if (defined $contents{$mac}) {
               my $mac2 = $contents{$mac};
               $mac2 = replace_top_srcdir($mac2,$rd);
               $nam =~ s/\$\(${mac}\)/$mac2/;
               $nam = unix_2_dos($nam);
               if ($nam =~ /lib(\w+)\.la/) {
                  $nam =~ s/lib(\w+)\.la/Lib_${1}\.lib/;
               }
               prt( "Substituted [$nam] ...\n" ) if ($dbg25);
            }
         }
         $files[$ii] = $nam;
      }
      $incs = join(' ', @files);
   }
   prt( "For $group, saved LDADD [$incs]\n" ) if ($dbg26);
   $am_libadds{$group} = $incs;
}
sub process_am_file {
    my ($dsp_name,$makefile,$rd) = @_;
    my $base_dir = './';
    my $dsp_file = $rd . $dsp_name . '.dsp';
    prt( "process_am_file: using dsp_name=$dsp_file, and makefile=$makefile ...\n" ) if $dbg7;
    initialize_per_input();
    ###my $relative_dir = dirname($makefile);
    $relative_dir = dirname($makefile);
    my $dupe = 0;
    my @files = ();
    my $key = '';
    my $group = 'Lib_Special';
    my $file = '';   # full path to file
   my $fi = '';   # filename only
   my $ext = '';   # and its extension
   my $dir = '';   # directory it is in
   my $nam = '';   # file title
   my $proj = '';
   my $cnt = 0;
    my $fnd = 0;
   # build AM file name
   my $file_am = $rd . $makefile;
   # 04/04/2008 READ 'configure.ac' if present in THIS DIRECTORY
   # ===========================================================
   my $file_ac = $full_fil_path . "configure.ac";
   if ( -f $file_ac ) {
      # we have an configure.ac file here
      scan_one_configure_file( $file_ac, $rd );
   }
   $file_am .= '.am' if !($file_am =~ /\.am$/i);
   $current_am_file = sub_common_folder($file_am,$rd);
   prt( "Processing AM file [$current_am_file]\n" ) if ($dbg24);
   push(@done_am,$file_am);
    read_main_am_file($file_am, $rd);
    # preview the 'contents' to find 'group'
    if ($dbg28 || $dbg19) {
        $cnt = scalar keys(%contents);
        prt( "CT: Got $cnt items in \%contents ... file $file_am ...\n" );
        $cnt = 0;
        foreach $key (keys %contents) {
            $file = trim_all($contents{$key});
            $cnt++;
            prt( "CT:$cnt: [$key] = [$file]\n" );
        }
    }
    ###############################################################
    ## process various contents of %contents
    ##############################################################
    # use 'noinst_LIBRARIES' macro
    foreach $key (keys %contents) {
        if ($key eq 'noinst_LIBRARIES') {
            @files = split(' ', $contents{$key});
            foreach $file (@files) {
                if ($file =~ /^lib([\w-]+)\.a/) {
                    $group = 'lib' . $1;
                    prt( "Group set to [$group] ... file $file_am ...\n" ) if ($dbg8 || $dbg8g);
                    $fnd = 1;
                    last;
                }
            }
        }
    }
    if (!$fnd) {
        # found NOT LIBRARY item
        # try for check_PROGRAMS or bin_PROGRAMS
        foreach $key (keys %contents) {
            if ($key =~ /\s*([\w-]+)_PROGRAMS\s*/) {
                $nam = $1;
                @files = split(' ', $contents{$key});
                foreach $file (@files) {
                    if ($file =~ /^([\w-]+)$/) {
                        ###$group = $nam.'_'. $1;
                        $group = $1;
                        prt( "Group set to [$group] ... file $file_am ...\n" ) if ($dbg8 || $dbg8g);
                        $fnd = 1;
                        last;
                    }
                }
            }
        }
    }
    if (!$fnd) {
        prt( "WARNING: NO 'GROUP' FOUND in $file_am ...\n" );
    } else {
    }
    # now extract LIBRARY SOURCES from 'contents' hash
    foreach $key (sort keys %contents) {
        #if ($key eq "include_HEADERS") {
        #} # not found in Makefile.am files?
        #if ($key =~ /^lib(.*)_a_SOURCES/) {
        #if (($key =~ /^lib(.*)_a_SOURCES/)  ||
      #   ($key =~ /^lib(.*)_la_SOURCES/) ||
      #   ($key =~ /^libc(.*)_la_SOURCES/) ) {
        if (($key =~ /lib(.*)_a_SOURCES/)  ||
         ($key =~ /lib(.*)_la_SOURCES/) ||
         ($key =~ /libc(.*)_la_SOURCES/) ) {
         $proj = $1;      # keep Project RAW name
            $group = 'lib' . $proj;   # generate a GROUP
            @files = split(' ', $contents{$key});
            foreach (@files) {
                my $src_dir = $base_dir . $relative_dir . '/';
                $src_dir =~ s/\//\\/g; # fixup DOS path separators
                if (/^\$\(([^\)]*)\)$/) {
                    # Found a variable.
                    my $varname = $1;
                    prt( "Expanding variable $varname ...\n" ) if ($dbg8);
                    foreach (split(' ', $contents{$varname})) {
                        $file = $src_dir . $_;
                        $dupe = add_2_source_list( $file, $group );
                    }
                    prt( "Done expanding variable $varname ...\n" ) if ($dbg8);
                } else {
                    $file = $src_dir . $_;
                    $dupe = add_2_source_list( $file, $group );
                }
            }
         find_am_includes( $proj, $group, $rd );
        }
        #elsif ($key =~ /(.*)_SOURCES/) {
        elsif ($key eq "fgfs_SOURCES") {
            $group = 'main';
            @files = split(' ', $contents{$key});
            foreach $fi (@files) {
                my $sdir = $base_dir . $relative_dir . '/';
                $sdir =~ s/\//\\/g; # fixup DOS path separators
                $file = $sdir . $fi;
                $dupe = add_2_source_list( $file, $group );
            }
        } else {
            # key is NOT ( Lib(.*)_a_SOURCES fgfs_SOURCES )
            if (($key eq 'EXTRA_DIST')||($key eq 'fgjs_SOURCES')) {
                @files = split(' ', $contents{$key});
                foreach $fi (@files) {
               ($nam, $dir, $ext) = fileparse( $fi, qr/\.[^.]*/ );
                    $file = $base_dir . $relative_dir . '/' . $fi;
                    $file =~ s/\//\\/g; # use DOS path sep
                    if (is_c_source_ext($ext)) {
                        push(@msvc_c_extra, $file);
                        prt( "Added [$file] to C EXTRA list\n" ) if $dbg9;
                    } elsif (is_h_source_ext($ext)) {
                        push(@msvc_h_extra, $file);
                        prt( "Added [$file] to H EXTRA list\n" ) if $dbg9;
                    } else {
                        push(@msvc_o_extra, $file);
                        prt( "Added [$file] to other EXTRA list\n" ) if $dbg9;
                    }
                }
            } elsif ($key eq 'noinst_HEADERS') {
                # JSBSim has put the HEADERS in HERE,
            # FIX20061107
            # more recently SimGear put some 'source' file in here
            # which are now discarded
                @files = split(' ', $contents{$key});
                foreach $fi (@files) {
               ($nam, $dir, $ext) = fileparse( $fi, qr/\.[^.]*/ );
               if (is_h_source_ext($ext)) { # FIX20061107 - only IFF a header
                  $file = $base_dir . $relative_dir . '/' . $fi;
                  $file =~ s/\//\\/g; # use DOS path sep
                  $dupe = add_2_source_list( $file, $group );
               }
                }
            }
        }
    }
   # process for OTHER THAN LIBRARIES
   process_other_sources( $makefile . '.am', $rd );
   # per AM file sources
   my $ac_cnt = scalar @am_c_files;
   my $ah_cnt = scalar @am_h_files;
    my $of_cnt = scalar @am_o_files;
    ###prt( "End am file: $dsp_file - ac_cnt=$ac_cnt, ah_cnt=$ah_cnt, from $makefile.am ...\n" ) if ($dbg20);
    prt( "End_am_file: ac_cnt=$ac_cnt, ah_cnt=$ah_cnt, of_cnt=$of_cnt, from $makefile ...\n" ) if ($dbg20);
}
sub read_main_am_file {
    my ($amfile, $rd) = @_;
    read_am_file($amfile, $rd);
    my @topdir = ();
    foreach (split(/\//, $relative_dir)) {
        next if $_ eq '.' || $_ eq '';
        if ($_ eq '..') {
            pop @topdir;
        } else {
            push(@topdir, '..');
        }
    }
    @topdir = ('.') if ! @topdir;
    my $top_builddir = join('/', @topdir);
}
sub read_am_file {
    my ($am_file, $rd) = @_;
   $active_am_file = $am_file;
    ###open( AM_FILE, $am_file ) or mydie( "ERROR: Can't open $am_file: $!\n" );
   ###if ($am_file =~ /^(\\|\/){1}/) {
   ###   $am_file = substr($am_file,1);
   ###}
    if (!open( AM_FILE, $am_file )) {
      prtw( "ERROR: Can't open $am_file: $! \n" );
      return;
   }
    prt( "\n$pack: reading $am_file (rel_dir=$relative_dir)\n" ) if ($dbg10 || $dbg16 || $dbg19);
   my @am_lines = <AM_FILE>;
   close AM_FILE;
   my $am_lncnt = scalar @am_lines;
   my ($am_name, $am_path) = fileparse($am_file);
    my $saw_bk = 0;
    my $was_rule = 0;
    my $spacing = '';
    my $comment = '';
    my $last_var_name = '';
    my $blank = 0;
    my $cond_true = 2; # undetermined ...
   my $msg = '';
   my $aml = '';
   my $aln = 0;
   my $ai = 0;
   my $cond_string = '';
   # process, line by line ... where $aln is current line
    for ($ai = 0; $ai < $am_lncnt; $ai++) {
      $_ = $am_lines[$ai];
      $aln = $ai + 1;
        if (/$IGNORE_PATTERN/o) {
            # Merely delete comments beginning with two hashes.
        } elsif (/$WHITE_PATTERN/o) {
            # Stick a single white line before the incoming macro or rule.
            $spacing = "\n";
            $blank = 1;
        } elsif (/$COMMENT_PATTERN/o) {
            # Stick comments before the incoming macro or rule.  Make
            # sure a blank line preceeds first block of comments.
            $spacing = "\n" unless $blank;
            $blank = 1;
            $comment .= $spacing . $_;
            $spacing = '';
        } else {
            last;
        }
    }
    $output_vars .= $comment . "\n";
    $comment = '';
    $spacing = "\n";
    my $source_suffix_pattern = '';
    my $is_ok_macro = 0;
   for ( ; $ai < $am_lncnt; $ai++) {
      $_ = $am_lines[$ai];
      $aln = $ai + 1;
      $aml = $am_lines[$ai];
        chomp $aml;
        $aml = trim_all($aml); # clean up line
        prt( "$aln [$aml]\n" ) if ($dbg10);
        $_ .= "\n" unless substr ($_, -1, 1) eq "\n";
        if (/$IGNORE_PATTERN/o) {
            # Merely delete comments beginning with two hashes.
        } elsif (/$WHITE_PATTERN/o) {
            # Stick a single white line before the incoming macro or rule.
            $spacing = "\n";
            ###am_line_error ($., "blank line following trailing backslash") if $saw_bk;
            am_line_error ($aln, "blank line following trailing backslash") if $saw_bk;
        } elsif (/$COMMENT_PATTERN/o) {
            # Stick comments before the incoming macro or rule.
            $comment .= $spacing . $_;
            $spacing = '';
            ###am_line_error ($., "comment following trailing backslash") if $saw_bk;
            am_line_error ($aln, "comment following trailing backslash") if $saw_bk;
        } elsif ($saw_bk) {
         # continuation of previous line(s) ...
            if ($was_rule) {
                $output_trailer .= join ('', @conditional_stack) . $_;
                $saw_bk = /\\$/;
            } else {
                $saw_bk = /\\$/;
                # Chop newline and backslash if this line is
                # continued.  ensure trailing whitespace exists.
                chop if $saw_bk;
                chop if $saw_bk;
            # decide if to be added to 'contents' ...
            my $add_it = 0; # assume NO
            my $disc_it = 0;   # also NO
                if ( defined $contents{$last_var_name} ) {
                    if ( @conditional_stack ) {
                        if ( $conditional_stack[$#conditional_stack] =~ /_TRUE\@$/ ) {
                            # we are in the if TRUE state
                            if ($cond_true == 1) {
                        $add_it = 1;
                     } else {
                        $disc_it = 1;
                     }
                  } else {
                     # we are in a FALSE state
                            if ($cond_true != 1) {
                        $add_it = 1;
                     } else {
                        $disc_it = 1;
                     }
                  }
               } else { 
                  ###prt( "No conditional stack for this macro! lv=[$last_var_name] ".
                  ###   "add_it\n" ) if ($dbg11);
                  $add_it = 1; # so add it
               }
            } else { # NO contents for this var
               prt( "NO contents for [$last_var_name]! ".
                  "Technical this is an ERROR, but for now add_it...\n" ) if ($dbg11);
               $add_it = 1;
            }
            if ($add_it) {
               $contents{$last_var_name} .= ' ' unless $contents{$last_var_name} =~ /\s$/;
               $contents{$last_var_name} .= $_;
               if (@conditional_stack) {
                  $conditional{$last_var_name} .= quote_cond_val ($_);
               }
               prt( "End $last_var_name = [".trim_line($contents{$last_var_name})."]...\n" ) if ( ! $saw_bk && $dbg12);
            } else {
               if ($dbg22 || !$disc_it) {
                  # that is, if NOT a deliberate discard
                  ###push(@warnings, "WARNING: File [$am_file], line $., last var [$last_var_name]");
                  push(@warnings, "WARNING: File [$am_file], line $aln, last var [$last_var_name]");
                  push(@warnings, " Discarding the [$_] ... CHECK ME");
                  if ( defined $contents{$last_var_name} ) {
                     if ( @conditional_stack ) {
                        push(@warnings, " stack = $conditional_stack[$#conditional_stack] cond_true=$cond_true");
                     }
                  }
                  prt( "Warning: Discarding this [$_] ... CHECK ME!\n" );
               }
            }
            }
        } elsif (/$IF_PATTERN/o) {
            if ( defined $configure_cond{$1} ) {
                ###if ( defined $cfg_defines{$1} )
                if ($configure_cond{$1} == 2) {
                    prt( "Found if $1, and condition is TRUE (see cfg_defines) ...\n" ) if ($dbg13);
                    $cond_true = 1;
                } else {
                    prt( "Found if $1, but NOT in cfg_defines ...\n" ) if ($dbg13);
                    $cond_true = 0;
                }
            } else {
                ###am_line_error ($., "$1 does not appear in AM_CONDITIONAL");
                am_line_error ($aln, "Line $aln: [$aml]\n[$1] does not appear in AM_CONDITIONAL!");
            }
            push (@conditional_stack, "\@" . $1 . "_TRUE\@");
        } elsif (/$ELSE_PATTERN/o) {
            if (! @conditional_stack) {
                ###am_line_error ($., "else without if");
                am_line_error ($aln, "else without if");
            } elsif ($conditional_stack[$#conditional_stack] =~ /_FALSE\@$/) {
                ###am_line_error ($., "else after else");
                am_line_error ($aln, "else after else");
            } else {
                $conditional_stack[$#conditional_stack] =~ s/_TRUE\@$/_FALSE\@/;
            }
        } elsif (/$ENDIF_PATTERN/o) {
            if (! @conditional_stack) {
                ###am_line_error ($., ": endif without if");
                am_line_error ($aln, ": endif without if");
            } else {
                pop @conditional_stack;
            }
            $cond_true = 2; # undetermined ...
        } elsif (/$RULE_PATTERN/o) {
            # Found a rule.
            $was_rule = 1;
            if (defined $contents{$1}
                && (@conditional_stack
                ? ! defined $conditional{$1}
                : defined $conditional{$1})) {
                am_line_error ($1, "$1 defined both conditionally and unconditionally");
            }
            # Value here doesn't matter; for targets we only note
            # existence.
            $contents{$1} = 1;
            $targets{$1} = 1;
            $cond_string = join ('', @conditional_stack);
            if (@conditional_stack) {
                if ($conditional{$1}) {
                    check_ambiguous_conditional ($1, $cond_string);
                    $conditional{$1} .= ' ';
                } else {
                    $conditional{$1} = '';
                }
                $conditional{$1} .= $cond_string . ' 1';
            }
            ###$content_lines{$1} = $.;
            $content_lines{$1} = $aln;
            $output_trailer .= $comment . $spacing . $cond_string . $_;
            $comment = $spacing = '';
            $saw_bk = /\\$/;
            # Check the rule for being a suffix rule. If so, store in
            # a hash.
            my $source_suffix;
            my $object_suffix;
            if (($source_suffix, $object_suffix) = ($1 =~ $SUFFIX_RULE_PATTERN)) {
              $suffix_rules{$source_suffix} = $object_suffix;
              prt( "Sources ending in .$source_suffix become .$object_suffix\n" ) if $dbg17;
              $source_suffix_pattern = "(" . join('|', keys %suffix_rules) . ")";
            }
            # FIXME: make sure both suffixes are in SUFFIXES? Or set
            # SUFFIXES from suffix_rules?
        } elsif (($is_ok_macro = /$MACRO_PATTERN/o) || /$BOGUS_MACRO_PATTERN/o) {
            prt( "Found a macro definition. 1[$1] 2[$2] 3[$3] ...\n" ) if ($dbg14);
            $was_rule = 0;
            $last_var_name = $1;
            if (defined $contents{$1} && (@conditional_stack ? ! defined $conditional{$1} : defined $conditional{$1})) {
                am_line_error ($1, "$1 defined both conditionally and unconditionally");
            }
            my $value;
            if ($3 ne '' && substr ($3, -1) eq "\\") {
                $value = substr ($3, 0, length ($3) - 1);
            } else {
                $value = $3;
            }
            my $type = $2;
            if ($type eq '+') {
                if (! defined $contents{$last_var_name}
                    && defined $configure_vars{$last_var_name}) {
                    $contents{$last_var_name} = '@' . $last_var_name . '@';
                }
                $contents{$last_var_name} .= ' ' . $value;
            } else {
                if ( defined $contents{$last_var_name} ) {
                    if ( @conditional_stack ) {
                        if ( $conditional_stack[$#conditional_stack] =~ /_TRUE\@$/ ) {
                            # we are in the if TRUE state
                            if ($cond_true == 1) {
                                if ($dbg15) {
                                    if ( $contents{$last_var_name} ne $value ) {
                                        ###    " replaced with [$value] (am_file=$am_file line=$.)".
                                        prt( "NB: [$last_var_name] = [$contents{$last_var_name}]" .
                                            " replaced with [$value] (am_file=$am_file line=$aln)".
                                 (/\\$/ ? "saw_bk" : "end") . "\n" );
                                    }
                                }
                                $contents{$last_var_name} = $value;
                                ###$content_lines{$last_var_name} = $.;
                                $content_lines{$last_var_name} = $aln;
                            }
                        } else {
                            # we are in the else FALSE state
                            if ($cond_true != 1) {
                                if ($dbg15) {
                                    if ( $contents{$last_var_name} ne $value ) {
                                        ###   " replaced with [$value] (am_file=$am_file line=$.)".
                                        prt( "NB: [$last_var_name] = [$contents{$last_var_name}]" .
                                            " replaced with [$value] (am_file=$am_file line=$aln)".
                                 (/\\$/ ? "saw_bk" : "end") . "\n" );
                                    }
                                }
                                $contents{$last_var_name} = $value;
                                ###$content_lines{$last_var_name} = $.;
                                $content_lines{$last_var_name} = $aln;
                            }
                        }
                    }
                } else {
                    ###    "(am_file=$am_file line=$.) ".
                    prt( "First setting [$last_var_name] = [$value] " .
                        "(am_file=$am_file line=$aln) ".
                  (/\\$/ ? "saw_bk" : "end") . "\n" ) if ($dbg15);
                    $contents{$last_var_name} = $value;
                    # The first assignment to a macro sets the line
                    # number.  Ideally I suppose we would associate line
                    # numbers with random bits of text.
                    ###$content_lines{$last_var_name} = $.;
                    $content_lines{$last_var_name} = $aln;
                }
            }
            $cond_string = join ('', @conditional_stack);
            if (@conditional_stack) {
                my $found = 0;
                my $val;
                if ($conditional{$last_var_name}) {
                    if ($type eq '+') {
                        # If we're adding to the conditional, and it
                        # exists, then we might want to simply replace
                        # the old value with the new one.
                        my (@new_vals, @cond_vals);
                        @cond_vals = split (' ', $conditional{$last_var_name});
                        while (@cond_vals) {
                            my $vcond = shift (@cond_vals);
                            push (@new_vals, $vcond);
                            if (conditional_same ($vcond, $cond_string)) {
                                $found = 1;
                                $val = (unquote_cond_val (shift (@cond_vals)) . ' ' . $value);
                                push (@new_vals, quote_cond_val ($val));
                            } else {
                                push (@new_vals, shift (@cond_vals));
                            }
                        }
                        if ($found) {
                            $conditional{$last_var_name} = join (' ', @new_vals);
                        }
                    }
                    if (! $found) {
                        check_ambiguous_conditional ($last_var_name, $cond_string);
                        $conditional{$last_var_name} .= ' ';
                        $val = $value;
                    }
                } else {
                    $conditional{$last_var_name} = '';
                    $val = $contents{$last_var_name};
                }
                if (! $found) {
                    $conditional{$last_var_name} .= ($cond_string . ' ' . quote_cond_val ($val));
                }
            }
            # FIXME: this doesn't always work correctly; it will group
            # all comments for a given variable, no matter where
            # defined.
            $am_vars{$last_var_name} = $comment . $spacing;
            $def_type{$last_var_name} = ($type eq ':') ? ':' : '';
            push (@var_list, $last_var_name);
            $comment = $spacing = '';
            $saw_bk = /\\$/;
            # Error if bogus.
            ###am_line_error ($., "bad macro name \`$last_var_name'") if ! $is_ok_macro;
            am_line_error ($aln, "bad macro name \`$last_var_name'") if ! $is_ok_macro;
        } elsif (/$INCLUDE_PATTERN/o) {
         my $orgpath = $1;
         my $path = $orgpath;
         if ($path =~ s/^\$\(top_srcdir\)\///) {
            push (@include_stack, "\$\(top_srcdir\)/$path");
         } else {
            $path =~ s/\$\(srcdir\)\///;
            push (@include_stack, "\$\(srcdir\)/$path");
            $path = $relative_dir . "/" . $path;
         }
         if ($path =~ /^\//) {
            $path = substr($path,1);
         }
         if (! -f $path) {
            my $ff = $relative_dir . "/" . $path;
            if (-f $ff) {
               $path = $ff;
            } else {
               $ff = $rd . $path;
               if (-f $ff) {
                  $path = $ff;
               } else {
                  prt( "WARNING: in [$am_file] - Include WILL FAIL! [$orgpath] ...\n" );
                  prt( "  Last try was $ff ...\n" );
               }
            }
         }
         read_am_file ($path, $rd);
         $active_am_file = $am_file;
        } else {
            # This isn't an error; it is probably a continued rule.
            # In fact, this is what we assume.
            $was_rule = 1;
            $output_trailer .= ($comment . $spacing
                    . join ('', @conditional_stack) . $_);
            $comment = $spacing = '';
            $saw_bk = /\\$/;
        }
        ###$_ = <AM_FILE>;
    }
    prt( "Done reading of $am_file\n" ) if ($dbg10 || $dbg16 || $dbg19);
    ###close(AM_FILE);
    $output_trailer .= $comment;
    am_error ("unterminated conditionals: " . join (' ', @conditional_stack)) if (@conditional_stack);
}
sub has_no_extent {
   my ($fil) = shift;
   my ($fnm, $fdir, $fe) = fileparse( $fil, qr/\.[^.]*/ );
   if (length($fe) == 0) {
      return 1;
   }
   return 0;
}
sub is_am_source_ext {
   my ($ext) = shift;
   $ext = lc($ext);
   if ($ext eq '.am') {
      return 1;
   }
   return 0;
}
sub is_am_file {
   my ($fil) = shift;
   my ($fnm, $fdir, $fe) = fileparse( $fil, qr/\.[^.]*/ );
   return is_am_source_ext($fe);
}
sub is_c_source_ext {
    my ($ext) = shift;
    my $fe = lc($ext);
    if (($fe eq '.c')||($fe eq '.cxx')||($fe eq '.cpp')) {
        return 1;
    }
    return 0;
}
sub is_h_source_ext {
    my ($ext) = shift;
    my $fe = lc($ext);
    if (($fe eq '.h')||($fe eq '.hxx')||($fe eq '.hpp')) {
        return 1;
    }
    return 0;
}
sub add_2_source_list {
    my ($fil, $grp) = @_;
   my ($ft, $dir, $fe) = fileparse( $fil, qr/\.[^.]*/ );
    my $src = ($grp . '|' . $fil . '|' . $ft);
    my $ret = 0;
    if ( is_c_source_ext($fe) ) {
        prt( "Add $src to C list\n" ) if $dbg18;
        push(@msvc_c_files, $src);
        foreach my $tt (@msvc_titles) {
            # just to deal with duplicate names
            if( $tt eq $ft ) {
                $ret = 1;
                last;
            }
        }
        push(@msvc_titles, $ft);
      push(@am_c_files, $src);
    } elsif ( is_h_source_ext($fe) ) {
        prt( "Add $src to H list\n" ) if $dbg18;
        push(@msvc_h_files, $src);
      push(@am_h_files, $src);
    } else {
        prt( "Add $src to OTHER list\n" ) if $dbg18;
        push(@msvc_o_files, $src);
      push(@am_o_files, $src);
    }
    return $ret;
}
sub exclude_dir {
    my ($dir) = shift;
    foreach my $d (@excluded_dirs) {
      if ($dir =~ "/$d/") {
         return 1;
      }
    }
    return 0;
}
# Quote a value in order to put it in $conditional.  We need to quote
# spaces, and we need to handle null strings, so that we can later
# retrieve values by splitting on space.
sub quote_cond_val
{
    my ($val) = @_;
    $val =~ s/ /\001/g;
    $val =~ s/\t/\003/g;
    $val = "\002" if $val eq '';
    return $val;
}
# this function seems MISSING - maybe never used!
sub unquote_cond_val {
    my ($val) = @_;
    $val =~ s/\001/ /g;
    $val =~ s/\003/\t/g;
    $val = '' if $val eq "\002";
    return $val;
}
# See if a conditional is true.  Both arguments are conditional
# strings.  This returns true if the first conditional is true when
# the second conditional is true.
sub conditional_true_when {
    my ($cond, $when) = @_;
    # Check the easy case first.
    if ($cond eq $when) {
      return 1;
    }
    # Check each component of $cond, which looks @COND1@@COND2@.
    foreach my $comp (split ('@', $cond)) {
      # The way we split will give null strings between each condition.
      next if ! $comp;
      if (index ($when, '@' . $comp . '@') == -1) {
         return 0;
      }
    }
    return 1;
}
# Check for an ambiguous conditional.  This is called when a variable
# or target is being defined conditionally.  If we already know about
# a definition that is true under the same conditions, then we have an
# ambiguity.
sub check_ambiguous_conditional {
    my ($var_name, $cond) = @_;
    my (@cond_vals) = split (' ', $conditional{$var_name});
    while (@cond_vals) {
      my ($vcond) = shift (@cond_vals);
      shift (@cond_vals);
      if (conditional_true_when ($vcond, $cond) || conditional_true_when ($cond, $vcond)) {
         prt( "$var_name multiply defined in condition\n" );
      }
    }
}
sub trim_line {
    my ($l) = shift;
    chomp $l;
    $l =~ s/\r$//; # and remove CR, if present
    $l =~ s/\t/ /g; # tab to space
    $l =~ s/\s\s/ /g while ($l =~ /\s\s/);   # double space to single
    for ($l) {   # trim leading and trailing spaces
        s/^\s+//;
        s/\s+$//;
    }
    return $l;
}
##sub unix_2_dos {   # now in utils.pl
##   my ($f) = shift;
##   $f =~ s/\//\\/g;
##   return $f;
##}
sub exclude_cvs_svn {
   my ($dir) = shift;
   $dir = lc($dir);
   if ($dir eq '.svn') {
      return 1;
   } elsif ($dir eq 'cvs') {
      return 1;
   }
   return 0;
}
sub get_top_files {
   my ($td) = shift;
   my @dirs = ();
   $td = unix_2_dos($td);   # ensure DOS form
   $td .= "\\" if (substr($td,length($td)-1) ne "\\"); # add trailing, if none
   if (opendir(DIR, $td)) {
      my @dfiles = readdir(DIR);
      close DIR;
      foreach my $df (@dfiles) {
         if (($df eq '.') || ($df eq '..')) {
            next;
         }
         my $ff = $td.$df;
         if (-f $ff) {
            my $typ = is_my_type($df);
            my ($nm,$dir) = fileparse($ff);
            #my $rd = get_relative_path( $dir, $td );
            my $rd = get_relative_path_2( $dir, $td );
            ##my $rd = unix_2_dos($rp);
            push(@all_files, [$df, $ff, 0, $typ, $rd]) if ($typ);
         } elsif (-d $ff) {
            push(@dirs,$ff) if (!exclude_cvs_svn($df));
         } else {
            prt( "WARNING: What is THIS [$ff] ???\n" );
         }
      }
   } else {
      prt( "WARNING: Unable to OPEN directory $td ...\n" );
   }
   foreach my $de (@dirs) {
      get_top_files($de, $td);
   }
}
sub is_c_source {
   my ($f) = shift;
   if ( ($f =~ /\.c$/i) || ($f =~ /\.cpp$/i) || ($f =~ /\.cxx$/i) ||
       ($f =~ /\.inl$/i) || ($f =~ /\.cc$/i) ) {
      return 1;
   }
   return 0;
}
sub is_h_special {
   my ($f) = shift;
   if (($f =~ /osg/i)||($f =~ /OpenThreads/i)||($f =~ /Producer/i)) {
      return 1;
   }
   return 0;
}
sub is_h_source {
   my ($f) = shift;
   if ( ($f =~ /\.h$/i) || ($f =~ /\.hpp$/i) || ($f =~ /\.hxx$/i) ) {
      return 1;
   }
   return 0;
}
sub is_dsw_file {
   my ($f) = shift;
   if ( ($f =~ /\.dsw$/i) || ($f =~ /\.dsp$/i) ) {
      return 1;
   }
   return 0;
}
sub is_sln_file {
   my ($f) = shift;
   if ( ($f =~ /\.sln$/i) || ($f =~ /\.vcproj$/i) ) {
      return 1;
   }
   return 0;
}
sub is_ch_source {
   my ($f) = shift;
   if (is_c_source($f) || is_h_source($f)) {
      return 1;
   }
   return 0;
}
sub is_my_type {
   my ($f) = shift;
   if (is_c_source($f)) {
      return $TYPE_C;
   } elsif (is_h_source($f)) {
      return $TYPE_H;
   } elsif (is_dsw_file($f)) {
      return $TYPE_DSW;
   } elsif (is_sln_file($f)) {
      return $TYPE_SLN;
   } elsif ($f =~ /^makefile\.am$/i) {
      return $TYPE_AM;
   } elsif ($f =~ /makefile/i) {
      return $TYPE_MAK;
   }
   return $TYPE_NONE;
}
# fix relative directory - fix relative path - path fix
# Remove any DOT or DOUBLE DOT from the PATH
sub fix_rel {
   my ($path) = shift;
   $path = unix_2_dos($path);   # ensure DOS separator
   my @a = split(/\\/, $path);   # split on DOS separator
   my $npath = '';
   my $wmsg = '';
   my $max = scalar @a;
   my @na = ();
   for (my $i = 0; $i < $max; $i++) {
      my $p = $a[$i];
      if ($p eq '.') {
         # ignore this
      } elsif ($p eq '..') {
         if (@na) {
            pop @na;   # discard previous
         } else {
            $wmsg = "WARNING: Got relative .. without previous!!! [$path]";
            prt( "$wmsg\n" );
            push(@warnings,$wmsg);
         }
      } else {
         push(@na,$p);
      }
   }
   foreach my $pt (@na) {
      $npath .= "\\" if length($npath);
      $npath .= $pt;
   }
   return $npath;
}
sub mark_all_files {
   my ($f) = shift;
   my $lcf = lc($f);
   #                   0    1    2  3     4
   # push(@all_files, [$df, $ff, 0, $typ, $rd]) if ($typ);
   my $ac = scalar @all_files;
   for (my $i = 0; $i < $ac; $i++) {
      my $tf = lc($all_files[$i][1]);
      if ($tf eq $lcf) {
         my $ct = $all_files[$i][2];
         $ct++;
         $all_files[$i][2] = $ct;
         return 1;
      }
   }
   return 0;
}
sub show_all_sources {
   my ($msg,$rd) = @_;
   my $ac = scalar @all_files;
   # push(@all_files, [$df, $ff, 0, $typ, $rd]) if ($typ);
   my ($mc, $i, $file, $line, $omsg);
   $mc = 0;
   my @files = ();
   my ($nam, $dir, $ext);
   # get count of MISSING items
   for ($i = 0; $i < $ac; $i++) {
      if ($all_files[$i][3] == $TYPE_C) {
         if ($all_files[$i][2] == 0) {
            $mc++;
         }
      }
   }
   if ($mc) {
      prt( "\nSources found, but MISSED - $mc ...root = $rd\n" );
      for ($i = 0; $i < $ac; $i++) {
         if ($all_files[$i][3] == $TYPE_C) {
            if ($all_files[$i][2] == 0) {
               $file = $all_files[$i][1];
               $omsg = " ".sub_common_folder($file, $rd)." ";
               $omsg = get_main_msg($file,sub_common_folder($file,$rd),1,"") if ($check4main2); # check if a main()
               prt( "$omsg\n" );
               push(@files, $file) if ($recheck_am);
            }
         }
      }
      prt( "Above $mc Sources NOT INCLUDED in $msg ...\n\n" );
      if ($recheck_am) {
         my @makes = get_all_makes();
         $mc = 0;
         foreach my $mk (@makes) {
            if (open MK, "<$mk") {
               my @lines = <MK>;
               close MK;
               foreach $file (@files) {
                  if ($check_full) {
                     ($nam, $dir) = fileparse($file);
                     foreach $line (@lines) {
                        chomp $line;
                        if ($line =~ /$nam/) {
                           prt( "Note: [$nam] is in [$mk] ... line[$line]\n" );
                           $mc++;
                           last;
                        }
                     }
                  } else {
                     ($nam, $dir, $ext) = fileparse( $file, qr/\.[^.]*/ );
                     foreach $line (@lines) {
                        chomp $line;
                        if ($line =~ /$nam/) {
                           prt( "Note: [$nam] is in [$mk] ... line[$line]\n" );
                           $mc++;
                           last;
                        }
                     }
                  }
               }
            }
         }
         if ($mc) {
            prt( "Above $mc references should be checked ...\n\n" );
         }
      }
   }
}
sub get_missed_makes {
   my ($rd) = shift;
   my $ac = scalar @all_files;
   my $i = 0;
   my @mam = ();
   for ($i = 0; $i < $ac; $i++) {
      if ($all_files[$i][3] == $TYPE_AM) {
         if ($all_files[$i][2] == 0) {
            my $file = $all_files[$i][1];   # get FULL (qualified) path name
            my ($nm, $path) = fileparse($file);   # split it to name,path
            #my $rp = unix_2_dos(get_relative_path( $path, $rd ).$nm);
            my $rp = unix_2_dos(get_relative_path_2( $path, $rd ).$nm);
            push( @mam, $rp );   # pass back the DOS relative makefile.am entry
         }
      }
   }
   return @mam;
}
sub get_all_makes {
   my $ac = scalar @all_files;
   my $i = 0;
   my @mam = ();
   for ($i = 0; $i < $ac; $i++) {
      if ($all_files[$i][3] == $TYPE_AM) {
         my $file = $all_files[$i][1];   # get FULL (qualified) path name
         ###my ($nm, $path) = fileparse($file);   # split it to name,path
         push( @mam, $file );   # pass back makefile.am full path
      }
   }
   return @mam;
}
########################################################################
####### ONLY DSP STUFF
sub expand_here {
    local $_ = shift;
    s/\%cflags\%/$msvc_cflags/g;
    s/\%libs\%/$msvc_libs/g;
    s/\%dlibs\%/$msvc_dlibs/g;
    s/\%rlibs\%/$msvc_rlibs/g;
    return $_;
}
sub console_app_dsp_init {
    my ($name, $dsp_name) = @_;
    prt( "Creating console app type $dsp_name ...\n" );
   my $ren = rename_2_old_bak( $dsp_name );
   if ($ren) {
      prt( "Renamed original to ".(($ren == 1) ? "OLD" : "BAK")." ...\n" );
   }
    open(DSP, ">$dsp_name") || mydie( "ERROR: Can't create $dsp_name: $!\n" );
    print DSP expand_here(<<"EOF");
# Microsoft Developer Studio Project File - Name="$name" - Package Owner=<4>\r
# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
# ** DO NOT EDIT **\r
\r
# TARGTYPE "Win32 (x86) Console Application" 0x0103\r
\r
CFG=$name - Win32 Debug\r
!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
!MESSAGE use the Export Makefile command and run\r
!MESSAGE \r
!MESSAGE NMAKE /f "$name.mak".\r
!MESSAGE \r
!MESSAGE You can specify a configuration when running NMAKE\r
!MESSAGE by defining the macro CFG on the command line. For example:\r
!MESSAGE \r
!MESSAGE NMAKE /f "$name.mak" CFG="$name - Win32 Debug"\r
!MESSAGE \r
!MESSAGE Possible choices for configuration are:\r
!MESSAGE \r
!MESSAGE "$name - Win32 Release" (based on "Win32 (x86) Console Application")\r
!MESSAGE "$name - Win32 Debug" (based on "Win32 (x86) Console Application")\r
!MESSAGE \r
\r
# Begin Project\r
# PROP AllowPerConfigDependencies 0\r
# PROP Scc_ProjName ""\r
# PROP Scc_LocalPath ""\r
CPP=cl.exe\r
RSC=rc.exe\r
\r
!IF  "\$(CFG)" == "$name - Win32 Release"\r
\r
# PROP Use_MFC 0\r
# PROP Use_Debug_Libraries 0\r
# PROP Output_Dir "Release"\r
# PROP Intermediate_Dir "Release"\r
# PROP Target_Dir ""\r
# ADD CPP /nologo /W3 /Gm /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /c %cflags%\r
# SUBTRACT CPP /YX\r
# ADD RSC /l 0xc09 /d "NDEBUG"\r
BSC32=bscmake.exe\r
# ADD BSC32 /nologo\r
LINK32=link.exe\r
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ws2_32.lib /nologo /subsystem:console /machine:I386 %libs% %rlibs%\r
\r
!ELSEIF  "\$(CFG)" == "$name - Win32 Debug"\r
\r
# PROP Use_MFC 0\r
# PROP Use_Debug_Libraries 1\r
# PROP Output_Dir "Debug"\r
# PROP Intermediate_Dir "Debug"\r
# PROP Ignore_Export_Lib 0\r
# PROP Target_Dir ""\r
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c %cflags%\r
# ADD RSC /l 0xc09 /d "_DEBUG"\r
BSC32=bscmake.exe\r
# ADD BSC32 /nologo\r
LINK32=link.exe\r
# ADD LINK32 kernel32.lib user32.lib winspool.lib comdlg32.lib gdi32.lib shell32.lib advapi32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept %libs% %dlibs%\r
\r
!ENDIF \r
\r
# Begin Target\r
\r
# Name "$name - Win32 Release"\r
# Name "$name - Win32 Debug"\r
EOF
    close(DSP);
}
sub static_lib_dsp_init {
    my ($name, $dsp_name) = @_;
    prt( "Creating static library type $dsp_name ... \n" );
   my $ren = rename_2_old_bak( $dsp_name );
   if ($ren) {
      prt( "Renamed original to ".(($ren == 1) ? "OLD" : "BAK")." ...\n" );
   }
    open(DSP, ">$dsp_name") || mydie( "ERROR: Can't create $dsp_name: $!\n" );
    print DSP expand_here(<<"EOF");
# Microsoft Developer Studio Project File - Name="$name" - Package Owner=<4>\r
# Microsoft Developer Studio Generated Build File, Format Version 6.00\r
# ** DO NOT EDIT **\r
\r
# TARGTYPE "Win32 (x86) Static Library" 0x0104\r
\r
CFG=$name - Win32 Debug\r
!MESSAGE This is not a valid makefile. To build this project using NMAKE,\r
!MESSAGE use the Export Makefile command and run\r
!MESSAGE \r
!MESSAGE NMAKE /f "$name.mak".\r
!MESSAGE \r
!MESSAGE You can specify a configuration when running NMAKE\r
!MESSAGE by defining the macro CFG on the command line. For example:\r
!MESSAGE \r
!MESSAGE NMAKE /f "$name.mak" CFG="$name - Win32 Debug"\r
!MESSAGE \r
!MESSAGE Possible choices for configuration are:\r
!MESSAGE \r
!MESSAGE "$name - Win32 Release" (based on "Win32 (x86) Static Library")\r
!MESSAGE "$name - Win32 Debug" (based on "Win32 (x86) Static Library")\r
!MESSAGE \r
\r
# Begin Project\r
# PROP AllowPerConfigDependencies 0\r
# PROP Scc_ProjName ""\r
# PROP Scc_LocalPath ""\r
CPP=cl.exe\r
RSC=rc.exe\r
\r
!IF  "\$(CFG)" == "$name - Win32 Release"\r
\r
# PROP Use_MFC 0\r
# PROP Use_Debug_Libraries 0\r
# PROP Output_Dir "Release"\r
# PROP Intermediate_Dir "Release"\r
# PROP Target_Dir ""\r
# ADD CPP /nologo /W3 /Gm /GX /O2 /D "NDEBUG" /D "WIN32" /D "_MBCS" /FD /c %cflags%\r
# ADD RSC /l 0x409 /d "NDEBUG"\r
BSC32=bscmake.exe\r
# ADD BASE BSC32 /nologo\r
# ADD BSC32 /nologo\r
LINK32=link.exe -lib\r
# ADD BASE LIB32 /nologo\r
# ADD LIB32 /nologo\r
\r
!ELSEIF  "\$(CFG)" == "$name - Win32 Debug"\r
\r
# PROP Use_MFC 0\r
# PROP Use_Debug_Libraries 1\r
# PROP Output_Dir "Debug"\r
# PROP Intermediate_Dir "Debug"\r
# PROP Target_Dir ""\r
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_MBCS" /FD /GZ /c %cflags%\r
# ADD RSC /l 0x409 /d "_DEBUG"\r
BSC32=bscmake.exe\r
# ADD BASE BSC32 /nologo\r
# ADD BSC32 /nologo\r
LINK32=link.exe -lib\r
# ADD BASE LIB32 /nologo\r
# ADD LIB32 /nologo\r
\r
!ENDIF \r
\r
# Begin Target\r
\r
# Name "$name - Win32 Release"\r
# Name "$name - Win32 Debug"\r
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;cc"
EOF
    close(DSP);
}
sub end_dsp_file {
   my ($fil) = shift;
   if (open DSP, ">>$fil") {
        print DSP "# End Group\r\n";
       # just the HEADER files
      print DSP "# Begin Group \"Header Files\"\n";
      print DSP "\n";
      print DSP "# PROP Default_Filter \"h;hpp;hxx;hm;inl\"\r\n";
      print DSP "\n";
       print DSP "# End Group\r\n";
       print DSP "# End Target\r\n";
      print DSP "# End Project\r\n";
      close(DSP);
        prtd( "Ending last DSP - [$fil] ...\n" );
   }
}
sub generate_dsw {
    my ($dsw_name, @packs) = @_;
    prtd( "Creating $dsw_name ...\nrenaming any original to OLD or BAK ...\n" );
   rename_2_old_bak( $dsw_name );
    open(DSW, ">$dsw_name") || mydie( "Can't create $dsw_name: $!\n" );
    print DSW <<"EOF";
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
EOF
    foreach my $p (@packs) {
      print DSW "###############################################################################\n\n";
      my ($dsp,$name) = split ',', $p;
      print DSW "Project: \"$name\"=\"$dsp\" - Package Owner=<4>\r\n\r\n";
      print DSW <<"EOF";
Package=<5>\r
{{{\r
}}}\r
\r
Package=<4>\r
{{{\r
}}}\r
\r
EOF
    }
    print DSW <<"EOF";
###############################################################################\r
\r
Global:\r
\r
Package=<5>\r
{{{\r
}}}\r
\r
Package=<3>\r
{{{\r
}}}\r
\r
###############################################################################\r
\r
EOF
    close(DSW);
}
sub get_am_incs {
   my ($prj) = shift;
   my $incs = '';
   my $ics = '';
   my @pths = ();
   my $ic = '';
   if (defined $am_includes{$prj}) {
      $ics = $am_includes{$prj};
      @pths = split(' ',$ics);
      foreach $ic (@pths) {
         $incs .= " " if (length($incs));
         $incs .= "/I \"$ic\"";   # could go for RELATIVE DIRECTORY
      }
   }
   if (defined $am_cppflags{$prj}) {
      $ics = $am_cppflags{$prj};
      @pths = split(' ',$ics);
      foreach $ic (@pths) {
         $incs .= " " if (length($incs));
         $incs .= "/D \"$ic\"";
      }
   }
   return $incs;
}
sub get_am_libs {
   my ($prj) = shift;
   my $incs = '';
   if (defined $am_libadds{$prj}) {
      $incs = $am_libadds{$prj};
   }
   return $incs;
}
sub out_dsp_file {
   my ($prj, $fil, $src, $rd, $typ) = @_;
    my ($dsptype);
   if ($prj ne $last_project) {
        end_dsp_file($last_dsp_file) if (length($last_dsp_file));
      $last_project = $prj;
      $last_dsp_file = $fil;
      $msvc_cflags = get_am_incs( $prj );
      $msvc_libs = get_am_libs( $prj );
      if ($typ) {
         static_lib_dsp_init( $prj, $fil );
            $dsptype = 'static lib';
      } else {
         console_app_dsp_init( $prj, $fil );
            $dsptype = 'console app';
      }
        prtd( "Started new DSP $fil, project $prj, type $dsptype ...\n" );
   }
   if (open OF, ">>$fil") {
      print OF "# Begin Source File\n";
      print OF "\n";
      print OF "SOURCE=$src\n";
      print OF "# End Source File\n";
      close OF;
   }
}
# RENAME A FILE TO .OLD, or .BAK
# 0 - do nothing if file does not exist.
# 1 - rename to .OLD if .OLD does NOT exist
# 2 - rename to .BAK, if .OLD already exists,
# 3 - deleting any previous .BAK ...
sub rename_2_old_bak {
   my ($fil) = shift;
   my $ret = 0;
   if ( -f $fil ) {
      my ($nm,$dir,$ext) = fileparse( $fil, qr/\.[^.]*/ );
      my $nmbo = $dir . $nm . '.old';
      $ret = 1;
      if ( -f $nmbo) {
         $ret = 2;
         $nmbo = $dir . $nm . '.bak';
         if ( -f $nmbo ) {
            $ret = 3;
            unlink $nmbo;
         }
      }
      rename $fil, $nmbo;
   }
   return $ret;
}
sub prtw {
    my ($wm) = shift;
    prt($wm);
    $wm =~ s/\n$//;
    push(@warnings,$wm);
}
sub prtd {
    my ($tx) = shift;
    prt($tx);
    $tx =~ s/\n$//;
    push(@dspinfo, $tx);
}
# eof - amsrcs01.pl

index -|- top

checked by tidy  Valid HTML 4.01 Transitional