am2dsp7.pl to HTML.

index -|- end

Generated: Tue Feb 2 17:54:20 2010 from am2dsp7.pl 2009/06/09 79.6 KB.

#!/Perl
# am2dsp7.pl
# AIM: Read Makefile.am set, and generate MSVC6 DSW/DSP files for the project.
# Variable $static_lib controls if app or lib = 1 for SimGear, 0 for FlightGear
# ALSO SEE amsrcs[nn].pl to show the sources, and write temp DSP/DSW file
#
# 21/11/2008 - This will run without a 'config' file, but the results???
# in other attempts at this have used the VCPROJ file to get such values.
# Has BIG problem, in that it COMBINES ALL sources, into ONE, including some
# of the standalone 'test' and 'utitlity' applications.
#
# NOTE: Because of changing/evolving spec for config file, am2dsp?.cfg,
# this version will not run without finding, at least a blank file am2dsp7.cfg
# Also, to simplify the script a little, the writing of the old style DSP,
# with 'folders' to match the source folders has been completely abandoned!
# also abandoned is the effort to read and modify the MSVC8 solutions files.
# geoff mclane - 7 Nov, 2006
# 19/05/2008 - Many changes to try to analyse ANY project, and write DSP/DSW file(s)
#
# FIX20061107 bug fix: like some JSBSim Makefile.am files, others have been found with
# source files listed under 'noinst_HEADERS', this function now only adds
# a file from this tag if it has a 'header' extension - h, hpp, or hxx
# 20070421 - totally remove all MSVC8 stuff
# 21/04/2007 - and do a general tidyup of code
# 04/04/2008 - add log file
# 2006 geoff mclane http://geoffair.net/mperl
# ######################################################################################
use strict;
use Cwd;
use File::Basename;
require 'logfile.pl' or die "Unable to load logfile.pl ...\n";
require 'relative.pl' or die "Unable to load relative.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);
my $vers = "7";
my $pack = "am2dsp".$vers;
# the all important ROOT PATH to process
my $root_dir = '';
my $build_dir = '';
my $static_lib = 0;     # 1 for SimGear, 0 for FlightGear
# debug defaults only
my $def_root = 'C:\Projects\ftgl-2.1.3';
#my $def_root = 'C:\Projects\giflib';
#my $def_root = 'C:\FG\PREOSG\FlightGear\source';
#my $def_root = 'C:\FG\PREOSG\Simgear\source';
my $def_build = $def_root;
##my $def_root = 'C:\Projects\tar\lib';
##my $def_build = 'C:\Projects\tar\build';
##my $def_root = 'C:\Projects\grep';
##my $def_build = 'C:\Projects\grep\build';
##my $def_root = 'C:\FG\19\FlightGear';
##my $def_root = 'C:\Projects\SWIG';
##my $def_root = 'C:\FG\FGCOMXML\libwww';
##my $def_root = 'C:\FG\FGCOMXML\curl';
#my $def_root = 'C:\Projects\fgms';
#my $def_root = "G:\\FG\\13-MSVC6\\FlightGear\\";
#my $def_root = "G:\\FG\\13-MSVC6\\SimGear\\source\\";
my $use_def = 1;   # should be OFF in release
my $def_cfg = "am2dsp".$vers.".cfg";
my $src_cfg = $def_cfg;
my $use_cwd_cfg = 0; # also search CWD for config ...
my $use_build_dir = 1;   # make SOURCE files relative to 'build' folder
# String 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]*([^)]+)";
# AC_INIT (package, version, [bug-report], [tarname]) 
# Set the name of the package and its version
my $AC_INIT = "AC_INIT\\((.+)\\)";
my $AC_DEF = "AC_DEFINE\\((.+)";
my $AC_DEFU = "AC_DEFINE_UNQUOTED\\((.+)";
my $AC_DEFINE = "AC_DEFINE\\((.+)\\)";
my $AC_DEFINE_UNQ = "AC_DEFINE_UNQUOTED\\((.+)\\)";
# Hash table of AM_CONDITIONAL variables seen in configure.
my %configure_cond = ();
# This holds the names which are targets.  These also appear in
# %contents.
my %targets = ();
# This holds the line numbers at which various elements of
# %contents are defined.
my %content_lines = ();
my %content_seen = ();
# This maps the source extension of a suffix rule to its
# corresponding output extension.
my %suffix_rules = ();
# Hash table of discovered configure substitutions.  Keys are names,
# values are `FILE:LINE' strings which are used by error message
# generation.
my %configure_vars = ();
# This holds the set of included files.
my @include_stack = ();
my $verbose = 0;
my $vcond;
my @conditional_stack = ();
my %contents = ();   # after scan of Makefile.am
my %conditional = ();
# This holds our (eventual) exit status.  We don't actually exit until
# we have processed all input files - except when 'critical' ...
my $exit_status = 0;
my @make_input_list = ();
my %make_list = ();
# Names used in AC_CONFIG_HEADER call.  @config_fullnames holds the
# name which appears in AC_CONFIG_HEADER, colon and all.
# @config_names holds the file names.  @config_headers holds the '.in'
# files.  Ordinarily these are similar, but they can be different if
# the weird "NAME:FILE" syntax is used.
my @config_fullnames = ();
my @config_names = ();
my @config_headers = ();
# Line number at which AC_CONFIG_HEADER appears in configure.ac.
my $config_header_line = 0;
# Relative location of top build directory.
my $top_builddir = '';
my $relat_dir = '.';
my $output_vars = '';
my $output_trailer = '';
# List of Makefile.am's to process, and their corresponding outputs.
my @input_files = ();
my %output_files = ();
# List of files in AC_OUTPUT without Makefile.am, and their outputs.
my @other_input_files = ();
my @var_list = ();
my %am_vars = ();
my %def_type = ();
my @excluded_dirs = ();
my @excluded_files = ();
my $msvc_cflags = "";
my $msvc_threads = "";
my $msvc_libs = "";
my @extra_sources = ();
my @extra_projects = ();
my %used_inc_paths = ();
my %used_lib_paths = ();
# new variables
my $verbose2 = 0;
my $verbose3 = 1;
my $msvc_dlibs = "";
my $msvc_rlibs = "";
my $in_debug = 0;
my $in_release = 0;
my $do_check = 0;
my @msvc_dlibs_list = ();
my @msvc_rlibs_list = ();
my @msvc_libs_list = ();
my @msvc_dlibs_paths = ();
my @msvc_rlibs_paths = ();
my @msvc_libs_paths = ();
my @msvc_inc_paths = ();
my @test_headers = ( 'zlib.h', 'AL/al.h', 'AL/alut.h',
  'simgear/compiler.h', 'simgear/debug/logstream.hxx', 'plib/pu.h', 'Main/main.hxx',
  'config.h', 'include/general.hxx', 'FGJSBBase.h');
my $add_groups = 0; # default to single, put duplicates 'Dupes' folder ... 
my @msvc_c_files = ();
my @msvc_h_files = ();
my @msvc_titles = (); # just to deal with duplicate names
# EXTRA_DIST file lists from Makefile.am list
my @msvc_c_extra = ();
my @msvc_h_extra = ();
my @msvc_o_extra = ();
my @am_source_list = ();
my $err_msg = '';
# am2dsp?.cfg define = AAA
my %cfg_defines = ();
# configure.ac equivalent
my %def_defines = ( 'FG_JPEG_SERVER', 'ENABLE_JPEG_SERVER' );
my %config_ac_macros = ();
my @ignore_folders = qw( utils\\fgadmin );
# Extracted from AC_INIT, or
# AM_INIT_AUTOMAKE(package,version)
my $dsp_package = 'FGFS';
my $dsp_version = '0.2';
# debug items
my $debug_on = 0;
my $debug_on3 = 0;
my $sw_dbg = 0;
my $dbg10 = 0;   # show EACH line in configure.ac parse
my $dbg11 = 0;   # show "Split to $vlen components ...
my $dbg12a = 1;   # show prt( "Adding $input [$ff] to make_input_list ... - items added to @make_input_list
my $dbg12b = 0;   # show items added to @other_input_list
my $dbg13 = 0;   # show ac_output_line information ...
my $dbg14 = 0;   # prt( "Variable $key=$nval\n"
my $dbg15 = 0;   # prt( "Copying " . scalar @make_input_list . " make_input_list to input_files.\n" ) if ($verbose2 || $dbg15);
my $dbg16 = 0;   # prt( "Substitute $key=$nval\n" ) if ((($orgkey ne $key)||($orgnval ne $nval)) && $dbg16);
my $dbg17 = 0;   # prt( "\nProcessing [$am_file] from input_files array ...\n" ) if ($verbose2 || $dbg17);
my $dbg18 = 0;   # prt( "process_am_file: using dsp_name=$dsp_file, and makefile=$makefile ...\n" ) if ($verbose2 || $dbg18);
my $dbg19 = 1;   # prt( "$pack: reading $am_file\n" ) if ($verbose || $dbg19);
my $dbg20 = 0;   # prt( "$. [$aml]\n" ) if ($debug_on3 || /$dbgnn/);
my $dbg21 = 0;   # prt( "Found a macro definition. 1[$1] 2[$2] 3[$3] ...\n" ) if ($debug_on3 || /$dbgnn/);
my $dbg22 = 0;   # show_contents() if (/$dbgnn/);
my $dbg23 = 0;   # show contents of %config_ac_macros
my $dbg24 = 0;   # prt( "$. Should JOIN lines? - [$cline]\n" ) if (/$dbgnn/);
my $dbg25 = 0;   # prt( "ADDING SOURCE: $file ($dsp_name, $group, $dup)\n" ) if (/$dbgnn/);
my $dbg26 = 0;   # prt( "$. Got AC_INIT = [$1]\n" ) if (/$dbgnn/);
my @warnings = ();   # re-show any WARNINGS at end ...
my $cwdir = getcwd();
###set_all_debug();  # turn ON ALL noise
parse_arguments(@ARGV);
# THIS IS ESSENTIALLY ONLY FOR DEBUG - so no command input works for a trial
#######################################################################################
if ($use_def) {
    my $ff = $root_dir;
   $ff .= "\\" if (length($ff) && !( substr($ff,-1,1) =~ /(\\|\/)/));
   $ff .= 'configure.ac';
   if (! -f $ff) {
      prt( "Under DEBUG, switch root from [$root_dir] to [$def_root] ...\n" );
      $root_dir = $def_root;
      ###$src_cfg = $root_dir . $def_cfg;
   }
   if ( !( -f $src_cfg) ) {
      $err_msg = "WARNING: Unable to locate file [$src_cfg] ... ";
      if ( $use_cwd_cfg && ( -f $def_cfg)) {
         $err_msg .= "Using file [$def_cfg], in [".getcwd()."], in its place ...\n";
         $src_cfg = $def_cfg;
      } else {
         $err_msg .= "Check input, and/or folder ... \n";
      }
      prtw($err_msg);
   }
    # TRY TO DETERMINE TYPE FROM ROOT FOLDER
    if ($root_dir =~ /FlightGear/) {
        if ($static_lib) {
            prtw("WARNING: Setting variable \$static_lib to OFF- root=$root_dir\n");
            $static_lib = 0;
        }
    } elsif ($root_dir =~ /SimGear/) {
        if (!$static_lib) {
            prtw("WARNING: Setting variable \$static_lib to ON - root=$root_dir\n");
            $static_lib = 1;
        }
    }
}
#######################################################################################
$root_dir .= "\\" if !( substr($root_dir,-1,1) =~ /(\\|\/)/);
if (length($build_dir) == 0) {
   $build_dir = $root_dir;   # initially make them the SAME
   if ($use_def && length($def_build)) {
      $build_dir = $def_build;
   }
}
# Read project configuration file, IF ANY, else warning ...
read_am2dsp_rc($src_cfg);
scan_configure();   # check for configure.ac, configure.in, even configure.ac.in
if ( ! @input_files ) {
   prt( "$pack: no input_files, so no 'Makefile.am' found or specified\n" );
   $exit_status = 1;
}
my $am_file;
foreach $am_file (@input_files) {
   if (exclude_dir($am_file)) {
       prt( "NO Process of [$am_file] - in excluded directory!" );
   } else {
       prt( "Processing [$am_file] from input_files array ...\n" ); # if ($verbose2 || $dbg17);
      process_am_file($dsp_package, $am_file);
   }
}
if ($do_check) {
    check_includes();
}
write_new_dsp(); # NEW DSP separating source and headers
show_warnings();
close_log($outfile,1);
exit $exit_status;
# end of process
sub add_group_start {
    my $dsp_name = shift;
    ##my $dsp_file = $root_dir . $dsp_name . '.dsp';
    my $dsp_file = get_dsp_name($dsp_name);
    open(DSP, ">>$dsp_file") || mydie( "ERROR: Can't append to $dsp_file: $!\n" );
    print DSP "# Begin Group \"Source Files\"\n";
    print DSP "\n";
    print DSP "# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;h;hpp;hxx;hm;inl\"\n";
    close(DSP);
}
sub add_group_end {
    my $dsp_name = shift;
    ##my $dsp_file = $root_dir . $dsp_name . '.dsp';
    my $dsp_file = get_dsp_name($dsp_name);
    open(DSP, ">>$dsp_file") || mydie( "ERROR: Can't append to $dsp_file: $!\n" );
    print DSP "# End Group\n";
    close(DSP);
}
sub exclude_dir {
    my $dir = shift;
    foreach my $d (@excluded_dirs) {
      if ($dir =~ "/$d/") {
         return 1;
      }
    }
    return 0;
}
sub exclude_file {
    my $file = shift;
    foreach my $f (@excluded_files) {
      if ($file =~ /$f/) {
         return 1;
      }
    }
    return 0;
}
#
# TODO: option to specify static library or console app.
#
sub give_little_help {
    prt( "am2dsp".$vers.": Just a little help ...\n" );
    prt( "--help (or -h, -?) - This brief help!\n" );
    prt( "--verbose (or -v)  - Sets verbose mode. (v2,v3 for MORE, -dbg for ALL)\n" );
    prt( "--package name     - Set the DSP package name (default = $dsp_package)\n" );
    prt( "--lib (or -l)      - To create static library (Default is console app.)\n" );
#    prt( "--groups (-g)      - Output source into 'group' folders, as original!\n" );
    prt( "--dir path (-d)    - Establish input path for source, and the $def_cfg.\n" );
    prt( "--check (or -c)    - Check libraries, and some known include files, and exit.\n" );
    prt( "--cfg path\\file   - Use a specific configuration file, if not with source.\n" );
    prt( "Note, this --cfg path\\file MUST be after the --dir path, if used.\n" );
    prt( "Any other option beginning with '-' will abort, with a complaint ...\n" );
    mydie( "Any other input    - is ignored ...\n" );
}
sub set_input_dir {
    my $cfg = shift;
    if ( !(($cfg =~ /\/$/) || ($cfg =~ /\\$/)) ) {
        $cfg .= '\\';
    }
    my $fil = $cfg . $def_cfg;
    $src_cfg = $fil;
    $root_dir = $cfg;
    prt( "Using root path [$root_dir] ...\n" );
}
sub parse_arguments {
    my @av = @_;
    my $arg = '';
    while (@av) {
        $arg = $av[0];
        if ($arg eq '--help' || $arg eq '-h' || $arg eq '-?') {
            give_little_help(); # show help and exit
        } elsif ($arg eq '--verbose' || $arg eq '-v') {
            $verbose = 1;
        } elsif ($arg eq '--package' || $arg eq '-p') {
            require_argument(@av);
            shift @av;
            $dsp_package = $av[0];
        } elsif ($arg eq '--lib' || $arg eq '-l') {
            # Create a static library
            $static_lib = 1;
        } elsif (($arg eq '--dir')||($arg eq '-d')) {
            require_argument(@av);
            shift @av;
            set_input_dir($av[0]);
        } elsif ($arg eq '--check' || $arg eq '-c') {
            $do_check = 1; # perform check and exit
        } elsif ($arg eq '--cfg') {
            require_argument(@av);
            shift @av;
            $src_cfg = $av[0];
        } elsif ($arg eq '-v2' ) {
            $verbose2 = 1;
        } elsif ($arg eq '-v3' ) {
            $verbose3 = 1;
        } elsif ($arg eq '-dbg' ) {
         $sw_dbg = 1;
            $verbose = 1;
            $verbose2 = 1;
            $verbose3 = 1;
        } elsif ($arg =~ /^-/) {
            mydie( "$pack: unrecognised option, namely '$arg'\nTry --help or -? for some information.\n" );
        } else {
            # quietly IGNORE other inputs???
        }
        shift @av;
    }
}
sub add_2_msvc {
    my $flg = shift;
    if ($in_debug) {
        $msvc_dlibs .= $flg;
    } elsif ($in_release) {
        $msvc_rlibs .= $flg;
    } else {
        $msvc_libs .= $flg;
    }
}
sub add_2_libs {
    my $flg = shift;
    if ($in_debug) {
        push(@msvc_dlibs_list, $flg);
    } elsif ($in_release) {
        push(@msvc_rlibs_list, $flg);
    } else {
        push(@msvc_libs_list, $flg);
    }
}
sub add_2_libpaths {
    my $flg = shift;
    if ($in_debug) {
        push(@msvc_dlibs_paths, $flg);
    } elsif ($in_release) {
        push(@msvc_rlibs_paths, $flg);
    } else {
        push(@msvc_libs_paths, $flg);
    }
}
sub read_am2dsp_rc {
    my $rc_file = shift;
   prt( "Processing RC FILE [$rc_file] ...\n" );
    if ( !open( RC_FILE, $rc_file ) ) {
      $err_msg = "WARNING: Can't open $rc_file: $!\n";
      prtw($err_msg);
      return;
   }
    my $line;
   my $lncnt = 0;
    my @cond_stack = ();
    while (defined($line = <RC_FILE>)) {
        chomp $line;
      $lncnt++;
        if ($line =~ s/\\$//) {
            # continuation line
            $line .= "%";
            $line .= <RC_FILE>;
            redo unless eof(RC_FILE);
        }
        prt( "Processing line [$line] ...\n" ) if ($debug_on3);
        next if $line =~ /^$/; # ignore blank lines
        next if $line =~ /^#/; # ignore comments
        if ($line =~ /exclude_dir\s*=\s*(\S+)/) {
            push( @excluded_dirs, $1 );
        }
        elsif ($line =~ /exclude_file\s*=\s*(\S+)/) {
            my $f;
            ($f = $1) =~ s/\\/\\\\/g; # escape path separators, "\" -> "\\"
            push( @excluded_files, $f );
            prt( "Excluding file: $f\n" ) if $verbose;
        }
        elsif ($line =~ /include_path\s*=\s*(\S+)/) {
            $msvc_cflags .= " /I \"$1\"";
            push(@msvc_inc_paths, $1);
        }
        elsif ($line =~ /add_vc8_path\s*=\s*(\S+)/) {
         prt( "ERROR: Line $lncnt: Invalid CONFIG line [$line]! ...\n" );
            mydie( "ERROR: Got from VC8 to root path: [$1] ... this has been abandoned!\n" );
        }
        elsif ($line =~ /define\s*=\s*(\S+)/) {
            if ($debug_on) {
                if (defined $def_defines{$1} ) {
                    prt( "Got define of $1 ... which is $def_defines{$1} ...\n" );
                    $cfg_defines{$def_defines{$1}} = 1; # add configure.ac 
                } else {
                    prt( "Got define of $1 ...\n" );
                }
                if ( defined $cfg_defines{$1} ) {
                    prt( "Warning: cfg_defines of $1 already defined ...\n" );
                }
            }
            $cfg_defines{$1} = 1;
            $msvc_cflags .= " /D \"$1\"";
        }
        elsif ($line =~ /lib_path\s*=\s*(\S+)/) {
            add_2_msvc( " /libpath:\"$1\"" );
            add_2_libpaths( "$1" );
        }
        elsif ($line =~ /add_lib\s*=\s*(\S+)/) {
            add_2_msvc( " $1.lib" );
            add_2_libs( "$1.lib" );
        }
        elsif ($line =~ /type\s*=\s*(\S+)/) {
            my ($type,$threads,$debug) = split /,/, $1;
            prt( "type=$type, threading=$threads, debug=$debug\n" ); # if $verbose;
            if ($type =~ "ConsoleApplication") {
            $static_lib = 0
            } elsif ($type =~ "StaticLibrary") {
            $static_lib = 1
            } else {
            # Invalid type
            mydie( "ERROR: INVALID TYPE IN $rc_file FILE!\n" );
            }
            my $flags = " /ML"; # single threaded.
            if ($threads =~ /Multithreaded/) {
            $flags = " /MT";
            } elsif ($threads =~ /Singlethreaded/) {
            $flags = " /ML";
            } else {
            # Invalid threading option.
            mydie( "ERROR: INVALID THREADING IN $rc_file FILE!\n" );
            }
            if ($debug =~ /Debug/) {
            $flags .= "d";
            }
            $msvc_cflags .= $flags;
        }
        elsif ($line =~ /add_source_file\s*=\s*(.*)/) {
            my $rule;
            ($rule = $1) =~ s/%/\n/g;
            push( @extra_sources, $rule );
        }
        elsif ($line =~ /add_project\s*=\s*(.*)/) {
            push( @extra_projects, $1 );
        }
        elsif ($line =~ /$IF_PATTERN/o) {
            my $ifcond = $1;
            if ($ifcond =~ /Debug/io) {
                prt( "Entering DEBUG ...\n" ) if $verbose2;
                $in_debug = 1;
                $in_release = 0;
            } elsif ($ifcond =~ /Release/io) {
                prt( "Entering RELEASE ...\n" ) if $verbose2;
                $in_release = 1;
                $in_debug = 0;
            } else {
                prt( "EEK! Got $ifcond ...\n" );
                mydie( "ERROR: Presently ONLY if switch is 'Debug' or 'Release'!\n" );
            }
            push (@cond_stack, "\@" . $ifcond . "_TRUE\@");
        }
        elsif ($line =~ /$ELSE_PATTERN/o) {
            if (! @cond_stack) {
                mydie( "ERROR: else without if!\n" );
            }
            elsif ($cond_stack[$#cond_stack] =~ /_FALSE\@$/) {
                mydie( "ERROR: else after an else!\n" );
            } else {
                if ($in_debug) {
                    prt( "Switch to RELEASE ...\n" ) if $verbose2;
                    $in_debug = 0;
                    $in_release = 1;
                } else {
                    prt( "Switch to DEBUG ...\n" ) if $verbose2;
                    $in_debug = 1;
                    $in_release = 0;
                }
                $cond_stack[$#cond_stack] =~ s/_TRUE\@$/_FALSE\@/;
            }
        }
        elsif ($line =~ /$ENDIF_PATTERN/o) {
            if (! @cond_stack) {
                mydie( "ERROR: endif without if!\n" );
            }
            prt( "Exit $cond_stack[$#cond_stack] ...\n" ) if $verbose2;
            pop (@cond_stack);
            $in_debug = 0;
            $in_release = 0;
        }
    } # end while
    close(RC_FILE);
   prt( "Done RC FILE [$rc_file] ...\n" );
}
# Ensure argument exists, or die.
sub require_argument
{
    my ($arg, @arglist) = @_;
    mydie( "$pack: no argument given for option '$arg'\n" ) if ! @arglist;
}
sub scan_configure {
   ################################
   ### SCANNING configure files ###
   my $conf_file = '';
   my ($key, $val, $cnt);
    my $ff = $root_dir;
   $ff .= 'configure.ac';
   if ( -f $ff) {
      $conf_file = $ff;
      prt( "Scanning [$ff] file ...\n" );
      scan_one_configure_file($ff);
   } else {   # if (! -f $ff) {
      $ff .= '.in';
      if (-f $ff) {
         $conf_file = $ff;
         prt( "Scanning [$ff] file ...\n" );
          scan_one_configure_file($ff);
      } else {
         $ff = $root_dir;
          $ff .= 'configure.in';
         if (-f $ff) {
            $conf_file = $ff;
            prt( "Scanning [$ff] file ...\n" );
            scan_one_configure_file($ff);
         }
      }
   }
   prt( "End scan of [$conf_file] ...\n" );
   #################################
    $ff = $root_dir;
   $ff .= 'aclocal.m4';
   if ( -f $ff) {
      prt( "Scanning [$ff] file ...\n" );
      scan_one_configure_file($ff);
   }
    if ( ! @input_files ) {
        prt( "Copying " . scalar @make_input_list . " make_input_list to input_files.\n" ) if ($verbose2 || $dbg15);
        @input_files = @make_input_list;
        %output_files = %make_list;
    }
    if ( ! @input_files ) {
        $ff = $root_dir;
        $ff .= "\\" if ( !($ff =~ /[\\\/]$/) );
        $ff .= 'Makefile.am';
        if (-f $ff) {
            $ff = $root_dir;
            $ff .= "\\" if ( !($ff =~ /[\\\/]$/) );
            $ff .= 'Makefile';
            prt( "Adding Makefile found ...\n" );
            ##push(@input_files, 'Makefile');
            push(@input_files, $ff);
        }
    }
    prt( "\@input_files has list of " . scalar @input_files . " makefiles ...\n" );   ## if $verbose2;
    if ($verbose2) {
      $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" );
    }
   prt("\n");
   # $config_ac_macros{$key} = $nval;
   if ($dbg23) {
      $cnt = scalar keys(%config_ac_macros);
      prt( "Showing $cnt MACROS from $conf_file ...\n" );
      foreach $key (keys %config_ac_macros) {
         $val = trim_all($config_ac_macros{$key});
         prt("$key=$val\n");
      }
      prt("\n");
   }
}
sub add_2_ac_macros {
   my ( $key, $val ) = @_;
   $config_ac_macros{$key} = $val;
}
sub trim_all2 {
   my ($txt) = shift;
   $txt = trim_all($txt);
   if ($txt =~ /^\[.+\]$/) {
      $txt = substr($txt,1,length($txt)-2);
   }
   $txt = trim_all($txt);
   return $txt;
}
# scanning a configureation file
sub scan_one_configure_file {
    my $filename = shift;
   if (!open(CONFIGURE, $filename)) {
      $err_msg = "WARNING: can't open '$filename': $!\n";
      prtw($err_msg);
      return;
   }
    prt( "$pack: reading $filename\n" ) if $verbose;
    my $in_ac_output = 0;
    my $ac_output_line = '';
    my $ff = '';
   my $cline = '';
   my $rawline = '';
   my %var_hash = ();
   my ($key, $nval, $orgkey, $orgnval, @varr, $vlen, $i, $ky);
    while (<CONFIGURE>) {
      $cline = $_;   # get current line
      chomp $cline;
      $rawline = trim_all($cline);
      ###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 ($dbg10);
      prt( "$rawline\n" ) if ($dbg10 && length($rawline));
      if ($cline =~ /^(\w+)="(\d+)"$/) {
         prt( "Num Variable $1=$2\n" );
         $var_hash{$1} = $2;
      ###} elsif ($cline =~ /^(\w+)="(.+)"$/) {
      } elsif ($cline =~ /^(\w+)=(.+)$/) {
         $key  = $1;
         $nval = $2;
         $orgkey = $key;
         $orgnval = $nval;
         $nval = substr($nval,1,length($nval)-2) if ($nval =~ /^".*"$/);
         prt( "Variable $key=$nval\n" ) if ($dbg14);
         if (index($nval,'.') != -1) {
            @varr = split(/\./,$nval);
            $nval = '';
            $vlen = scalar @varr;
            prt( "Split to $vlen components ...\n" ) if ($dbg11);
            for ($i = 0; $i < $vlen; $i++) {
               $ky = trim_line($varr[$i]);
               prt( "Conponent $ky\n" ) if ($dbg11);
               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( "Substitute $key=$nval\n" ) if ((($orgkey ne $key)||($orgnval ne $nval)) && $dbg16);
         $var_hash{$key} = $nval;
         $config_ac_macros{$key} = $nval;
      } elsif ($cline =~ /^\s+(\w+)=(.+)$/) {
         ### prt( "Line [$cline] NOT USED ...\n" ); # there are lots of them ...
      }
      # Skip macro definitions.  Otherwise we might be confused into
      # thinking that a macro that was only defined was actually
      # used.
      next if /AC_DEFUN/;
      if ((/$AC_DEF/) && !(/$AC_DEFINE/)) {
         # indicates should add next line, until complete
         $cline = $_;   # get current line
         chomp $cline;
         prt( "$. Should JOIN lines? - [$cline]\n" ) if ($dbg24);
         $_ = <CONFIGURE>;
          if ($_) {
            $ky = $cline . ' ' . $_;
            $_ = $ky;
            chomp $ky;
            prt( "$. JOINED - [$ky]\n" ) if ($dbg24);
         }
      } elsif ((/$AC_DEFU/) && !(/$AC_DEFINE_UNQ/)) {
         # indicates should add next line, until complete
         $cline = $_;   # get current line
         chomp $cline;
         prt( "$. Should JOIN lines? - [$cline]\n" ) if ($dbg24);
         $_ = <CONFIGURE>;
          if ($_) {
            $ky = $cline . ' ' . $_;
            $_ = $ky;
            chomp $ky;
            prt( "$. JOINED - [$ky]\n" ) if ($dbg24);
         }
      }
      if (/$AC_INIT/) {
         prt( "$. Got AC_INIT = [$1]\n" ) if ($dbg26);
         @varr = split(',', $1);
         $vlen = scalar @varr;
         for ($i = 0; $i < $vlen; $i++) {
            $nval = trim_all($varr[$i]);
            if ($i == 0) {
               $nval =~ s/\s/_/g;
               add_2_ac_macros('PACKAGE_NAME', $nval);
               $dsp_package = $nval;
            } elsif ($i == 1) {
               add_2_ac_macros('PACKAGE_VERSION', $nval);
               add_2_ac_macros('PACKAGE_STRING', $config_ac_macros{'PACKAGE_NAME'} .' ' .$nval );
               $dsp_version = $nval;
            } elsif ($i == 2) {
               add_2_ac_macros('PACKAGE_BUGREPORT', $nval);
            } elsif ($i == 3) {
               add_2_ac_macros('PACKAGE_TARNAME', $nval);
            } else {
               $err_msg = "WARNING: $i Split of AC_INIT = $nval\n";
               prtw($err_msg);
            }
         }
         next;
      } elsif (/$AC_DEFINE/) {
         prt( "$. Got AC_DEFINE = [$1]\n" ) if ($dbg26);
         @varr = split(',', $1);
         $vlen = scalar @varr;
         if ($vlen >= 2) {
            $ky = trim_all2($varr[0]);
            $nval = trim_all2($varr[1]);
            add_2_ac_macros( $ky, $nval );
         }
         next;
      } elsif (/$AC_DEFINE_UNQ/) {
         prt( "$. Got AC_DEFINE_UNQUOTED = [$1]\n" ) if ($dbg26);
         @varr = split(',', $1);
         $vlen = scalar @varr;
         if ($vlen >= 2) {
            $ky = trim_all2($varr[0]);
            $nval = trim_all2($varr[1]);
            add_2_ac_macros( $ky, $nval );
         }
         next;
      }
      # Follow includes.  This is a weirdness commonly in use at
      # Cygnus and hopefully nowhere else.
      if (/sinclude\((.*)\)/ && -f ($root_dir . $1))
      {
         $ff = $root_dir . $1;
         scan_one_configure_file ($ff);
      }
      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 = line $ac_output_line ... [$rawline]\n" ) if ($dbg13);
      }
      if ($in_ac_output)
      {
         my $closing = 0;
         if (s/[\]\),].*$//)
         {
            $in_ac_output = 0;
            $closing = 1;
            prt( "ac_out: $rawline- CLOSING\n" ) if ($dbg13);
         } else {
            prt( "ac_out: $rawline\n" ) if ($dbg13);
         }
         # 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 = $root_dir . $input . '.am';
            if (-f $ff) {
               prt( "Adding $input [$ff] to make_input_list ...\n" ) if ($verbose2 || $dbg12a);
               push(@make_input_list, $input);
               $make_list{$input} = join(':', ($local,@rest));
            } else {
               prt( "Adding $input [$ff] to other_input_files ...\n" ) if ($verbose2 || $dbg12b);
               # 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)
      {
         if ( defined $cfg_defines{$1} ) {
            # has been DEFINED in am2dsp?.cfg file
            prt( "Storing configure_cond key $1 ... value=2\n" ) if ($debug_on3);
            $configure_cond{$1} = 2;
         } else {
            prt( "Storing configure_cond key $1 ... value=1\n" ) if ($debug_on3);
            $configure_cond{$1} = 1;
         }
      }
      if (/$AM_INIT_AUTOMAKE/o)
      {
         $dsp_package = $1;
         $dsp_version = $2;
         $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 show_contents {
   prt( "Showing contents of \%content ...\n" );
    # This holds the contents of a Makefile.am, as parsed by
    # read_am_file.
    #%contents = ();
   foreach my $key (keys %contents) {
      my $val = trim_all($contents{$key});
      prt( "$key = $val\n" );
   }
}
sub read_main_am_file {
    $am_file = shift;
    read_am_file($am_file);
    my @topdir = ();
    foreach (split(/\//, $relat_dir)) {
        next if $_ eq '.' || $_ eq '';
        if ($_ eq '..') {
            pop @topdir;
        } else {
            push(@topdir, '..');
        }
    }
    @topdir = ('.') if ! @topdir;
    my $top_builddir = join('/', @topdir);
    show_contents() if ($dbg22);
}
sub read_am_file {
    $am_file = shift;
    if( ! open( AM_FILE, $am_file ) ) {
        prtw( "WARNING: Can't open $am_file: $!\n" );
        return;
    }
    prt( "$pack: reading $am_file\n" ) if ($verbose || $dbg19);
    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 ($incfile, $path);
    while (<AM_FILE>) {
        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;
    while ($_) {
        my $aml = $_;
        chomp $aml;
        $aml =~ s/\r$//; # and remove CR, if present
        prt( "$. [$aml]\n" ) if ($debug_on3 || $dbg20);
        $_ .= "\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;
        } 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;
        } 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
                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 {
                     # we are in a FALSE state
                            if ($cond_true != 1) {
                        $add_it = 1;
                     }
                  }
               } else { 
                  ###prt( "No conditional stack for this macro! lv=[$last_var_name] ".
                  ###   "add_it\n" ) if ($debug_on3);
                  $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 ($debug_on3);
               $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 && $debug_on3);
            } else {
               prt( "Warning: Discarding this [$_] ... CHECK ME!\n" ) if ($debug_on3);
            }
            }
        } 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 ($debug_on3);
                    $cond_true = 1;
                } else {
                    prt( "Found if $1, but NOT in cfg_defines ...\n" ) if ($debug_on3);
                    $cond_true = 0;
                }
            } else {
                am_line_error ($., "$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");
            } elsif ($conditional_stack[$#conditional_stack] =~ /_FALSE\@$/) {
                am_line_error ($., "else after else");
            } else {
                $conditional_stack[$#conditional_stack] =~ s/_TRUE\@$/_FALSE\@/;
            }
        } elsif (/$ENDIF_PATTERN/o) {
            if (! @conditional_stack) {
                am_line_error ($., ": 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;
            my $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} = $.;
            $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 $verbose;
              $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 ($debug_on3 || $dbg21);
            $was_rule = 0;
            $last_var_name = $1;   # like say eswig_SOURCES
            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 ($debug_on3) {
                                    if ( $contents{$last_var_name} ne $value ) {
                                        prt( "NB: [$last_var_name] = [$contents{$last_var_name}]" .
                                            " replaced with [$value] (am_file=$am_file line=$.)".
                                 (/\\$/ ? "saw_bk" : "end") . "\n" );
                                    }
                                }
                                $contents{$last_var_name} = $value;
                                $content_lines{$last_var_name} = $.;
                            }
                        } else {
                            # we are in the else FALSE state
                            if ($cond_true != 1) {
                                if ($debug_on3) {
                                    if ( $contents{$last_var_name} ne $value ) {
                                        prt( "NB: [$last_var_name] = [$contents{$last_var_name}]" .
                                            " replaced with [$value] (am_file=$am_file line=$.)".
                                 (/\\$/ ? "saw_bk" : "end") . "\n" );
                                    }
                                }
                                $contents{$last_var_name} = $value;
                                $content_lines{$last_var_name} = $.;
                            }
                        }
                    }
                } else {
                    prt( "First setting [$last_var_name] = [$value] " .
                        "(am_file=$am_file line=$.) ".
                  (/\\$/ ? "saw_bk" : "end") . "\n" ) if ($debug_on3);
                    $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} = $.;
                }
            }
            my $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) {
                            $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;
        } elsif (/$INCLUDE_PATTERN/o) {
            $incfile = $1;
            $path = $incfile;
            if ($path =~ s/^\$\(top_srcdir\)\///) {
                push (@include_stack, "\$\(top_srcdir\)/$path");
            } else {
                $path =~ s/\$\(srcdir\)\///;
                push (@include_stack, "\$\(srcdir\)/$path");
                $path = $relat_dir . "/" . $path;
            }
            if (! -f $path) {
                $path = $root_dir . $incfile;
            }
            read_am_file ($path);
        } 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>;
    }
    close(AM_FILE);
    $output_trailer .= $comment;
    am_error ("unterminated conditionals: " . join (' ', @conditional_stack))
    if (@conditional_stack);
}
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".
    $relat_dir = '';
    # This maps the source extension of a suffix rule to its
    # corresponding output extension.
    %suffix_rules = ();
   @am_source_list = ();   # list of sources from ONE Makefile.am
}
# 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 am_error {
    my $msg = shift;
    mydie( $msg."\n" );
}
sub am_line_error {
    my ($symbol, @args) = @_;
    prt( "am_line_error: am_file=[$am_file] sym=[$symbol] arg0=[$args[0]] ...\n" ) if ($debug_on3);
    if ($symbol && "$symbol" ne '-1')
    {
      my ($file) = "${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";
      $exit_status = 1;
    } else {
       am_error (@args);
    }
}
sub generate_dsw {
    my $name = shift;
    ###my $dsw_name = $root_dir . $name . '.dsw';
    my $dsw_name = get_dsw_name($name);
    prt( "Creating $dsw_name ... " );
   show_rename( $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
    print DSW 'Project: ', "\"$name\"=\".\\", $name, ".dsp\" - Package Owner=<4>\n";
    print DSW <<EOF;
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
EOF
    foreach my $p (@extra_projects) {
    print DSW "###############################################################################\n\n";
    my ($dsp,$name) = split ',', $p;
    prt( "Project $name=$dsp\n" ) if $verbose;
    print DSW "Project: \"$name\"=\"$dsp\" - Package Owner=<4>\n\n";
    print DSW <<EOF;
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
EOF
    }
    print DSW <<EOF;
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
EOF
    close(DSW);
}
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 show_rename {
   my ($fil) = shift;
   my $res = rename_2_old_bak( $fil );
   if ($res == 0) {
      prt( "NEW FILE" );
   } elsif ($res == 1 ) {
      prt( "RENAMED current to OLD" );
   } elsif ($res == 2 ) {
      prt( "RENAMED current to BAK" );
   } else {
      prt( "RENAMED current to BAK, deleting previous" );
   }
   prt("\n");
}
sub console_app_dsp_init {
    my $name = shift;
    ###my $dsp_name = $root_dir . $name . '.dsp';
    my $dsp_name = get_dsp_name($name);
    prt( "Creating console app type $dsp_name ... " );
   show_rename( $dsp_name );
    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>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=$name - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE 
!MESSAGE NMAKE /f "$name.mak".
!MESSAGE 
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE 
!MESSAGE NMAKE /f "$name.mak" CFG="$name - Win32 Debug"
!MESSAGE 
!MESSAGE Possible choices for configuration are:
!MESSAGE 
!MESSAGE "$name - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "$name - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE 
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF  "\$(CFG)" == "$name - Win32 Release"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD CPP /nologo /W3 /GR /GX /O2 /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /c %cflags%
# SUBTRACT CPP /YX
# ADD RSC /l 0xc09 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# 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%
!ELSEIF  "\$(CFG)" == "$name - Win32 Debug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD CPP /nologo /W3 /GR /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c %cflags%
# ADD RSC /l 0xc09 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BSC32 /nologo
LINK32=link.exe
# 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%
!ENDIF 
# Begin Target
# Name "$name - Win32 Release"
# Name "$name - Win32 Debug"
EOF
    close(DSP);
}
sub static_lib_dsp_init {
    my $name = shift;
    ###my $dsp_name = $root_dir . $name . '.dsp';
    my $dsp_name = get_dsp_name($name);
    prt( "Creating static library type $dsp_name ... " );
   show_rename( $dsp_name );
    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>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=$name - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE 
!MESSAGE NMAKE /f "$name.mak".
!MESSAGE 
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE 
!MESSAGE NMAKE /f "$name.mak" CFG="$name - Win32 Debug"
!MESSAGE 
!MESSAGE Possible choices for configuration are:
!MESSAGE 
!MESSAGE "$name - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "$name - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE 
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF  "\$(CFG)" == "$name - Win32 Release"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD CPP /nologo /W3 /GR /GX /O2 /D "NDEBUG" /D "WIN32" /D "_MBCS" /FD /c %cflags%
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF  "\$(CFG)" == "$name - Win32 Debug"
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD CPP /nologo /W3 /GR /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_MBCS" /FD /GZ /c %cflags%
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF 
# Begin Target
# Name "$name - Win32 Release"
# Name "$name - Win32 Debug"
EOF
    close(DSP);
}
sub dsp_add_source_rule {
    my ($fh,$dsp_name,$group,$file,$dup) = @_;
   my ($ff, $nm, $target, $ext, $fromdir, $rp);
    print $fh "# Begin Source File\n";
    print $fh "\n";
   $ff = $root_dir . $file;
   $ff = fix_rel_path($ff);
   ($nm, $target, $ext) = fileparse( $ff, qr/\.[^.]*/ );
   $fromdir = $build_dir;
   ###$rp = get_relative_path($target, $fromdir);
   $rp = get_rel_dos_path($target, $fromdir);
   $rp .= $nm . $ext;
   prt( "ADDING SOURCE: $rp ($dsp_name, $group, $dup) $ff\n" ) if ($dbg25);
   if ($use_build_dir) {
       print $fh "SOURCE=$rp\n";
   } else {
       print $fh "SOURCE=$file\n";
   }
    if ($add_groups) {
        print $fh "\n";
        print $fh "!IF  \"\$(CFG)\" == \"$dsp_name - Win32 Release\"\n";
        print $fh "\n";
        print $fh "# PROP Intermediate_Dir \"Release\\$group\"\n";
        print $fh "# PROP Exclude_From_Build 1\n" if exclude_file($file);
        print $fh "\n";
        print $fh "!ELSEIF  \"\$(CFG)\" == \"$dsp_name - Win32 Debug\"\n";
        print $fh "\n";
        print $fh "# PROP Intermediate_Dir \"Debug\\$group\"\n";
        print $fh "# PROP Exclude_From_Build 1\n" if exclude_file($file);
        print $fh "\n";
        print $fh "!ENDIF \n";
        print $fh "\n";
    } elsif ($dup) {
        add_dupes_dir( \*$fh, $dsp_name );
    }
    print $fh "# End Source File\n";
}
sub is_in_list {
   my ($itm, @lst) = @_;
   foreach my $fnd (@lst) {
      if ($fnd eq $itm) {
         return 1;
      }
   }
   return 0;
}
# have decoded a Makefile.am file, and extracted a set of sources
# This is like in a SLN file when there is a 'project name', and a 'vcproj file' for it
# =====================================================================================
sub show_am_sources {
   my $scnt = scalar @am_source_list;
   prt( "Got $scnt sources from Makefile.am ... " );
   my @groups = ();
   my ($src, @bits, $group, $file, $gcnt, $type, $csrccnt, $grpname);
   my ($nm, $dir, $ext);
   foreach $src (@am_source_list) {
      @bits = split( /\|/, $src ); # get file title, name and group
      $group = $bits[0];
      $file  = $bits[1];
      push(@groups, $group) if (!is_in_list( $group, @groups ));
      ###prt( "$src\n" );
   }
   $gcnt = scalar @groups;
   prt( "in $gcnt group". (($gcnt > 1) ? "s" : "") ." ...\n" );
   if ($gcnt) {
      foreach $group (@groups) {
         if ($group =~ /^lib_(.+)/i) {
            $grpname = $1;   # get the PROJECT NAME
            $type = 'Library';
         } else {
            $type = 'Application';
            $grpname = $group;
         }
         $csrccnt = 0;
         foreach $src (@am_source_list) {
            @bits = split( /\|/, $src ); # get file group, pathname, title
            if ($group eq $bits[0]) {
               $file  = $bits[1];
               ($nm, $dir, $ext) = fileparse( $file, qr/\.[^.]*/ );
               if (is_c_source_ext(substr($ext,1))) {
                  $csrccnt++;
               }
            }
         }
         prt( "Group = $group ($type $grpname) C src count $csrccnt ...\n" );
         foreach $src (@am_source_list) {
            @bits = split( /\|/, $src ); # get file group, pathname, title
            if ($group eq $bits[0]) {
               $file  = $bits[1];
               ($nm, $dir, $ext) = fileparse( $file, qr/\.[^.]*/ );
               if (is_c_source_ext(substr($ext,1))) {
                  prt( "C/C++ $dir - $nm - $ext\n" );
               }
            }
         }
         foreach $src (@am_source_list) {
            @bits = split( /\|/, $src ); # get file group, pathname, title
            if ($group eq $bits[0]) {
               $file  = $bits[1];
               ($nm, $dir, $ext) = fileparse( $file, qr/\.[^.]*/ );
               if (!is_c_source_ext(substr($ext,1))) {
                  prt( "H/++ $dir - $nm - $ext\n" );
               }
            }
         }
      }
   }
}
# was sub dsp_add_group
sub process_am_file {
    my ($dsp_name,$makefile) = @_;
    my $base_dir = './';
    ###my $dsp_file = $root_dir . $dsp_name .'.dsp';
    my $dsp_file = get_dsp_name($dsp_name);
    my ($mfam);
    $mfam = $makefile . '.am';
    if ( -f $mfam ) {
        prt( "Processing 1 [$mfam] ...\n" ) if ($verbose2 || $dbg18);
    } else {
       $mfam = $root_dir . $makefile . '.am';
        prt( "Processing 2 [$mfam] ...\n" ) if ($verbose2 || $dbg18);
    }
   #########################################################################################
    initialize_per_input();      # reset MAKEFILE parameters
    my $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
    read_main_am_file($mfam);
    # preview the 'contents' to find 'group'
    # 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] ...\n" ) if ($debug_on3);
                    last;
                }
            }
        }
    }
    # now extract 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/) {
            $group = 'Lib_' . $1;
            @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 ($debug_on3);
                    foreach (split(' ', $contents{$varname})) {
                        $file = $src_dir . $_;
                        $dupe = add_2_source_list( $file, $group );
                    }
                    prt( "Done expanding variable $varname ...\n" ) if ($debug_on3);
                } else {
                    $file = $src_dir . $_;
                    $dupe = add_2_source_list( $file, $group );
                }
            }
        }
        #elsif ($key =~ /(.*)_SOURCES/) {
        elsif ($key eq "fgfs_SOURCES") {
            $group = 'main';
            @files = split(' ', $contents{$key});
            foreach $fi (@files) {
                my $src_dir = $base_dir . $relative_dir . '/';
                $src_dir =~ s/\//\\/g; # fixup DOS path separators
                $file = $src_dir . $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) {
                    $ext = file_extension($fi);
                    $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 $verbose2;
                    } elsif (is_h_source_ext($ext)) {
                        push(@msvc_h_extra, $file);
                        prt( "Added [$file] to H EXTRA list\n" ) if $verbose2;
                    } else {
                        push(@msvc_o_extra, $file);
                        prt( "Added [$file] to other EXTRA list\n" ) if $verbose2;
                    }
                }
            } 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) {
                    $ext = file_extension($fi);
               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 );
               }
                }
            } else {
               # key is NOT ( Lib(.*)_a_SOURCES fgfs_SOURCES )
              # and NOT (($key eq 'EXTRA_DIST')||($key eq 'fgjs_SOURCES')) {
            # and NOT ($key eq 'noinst_HEADERS')
            if ($key =~ /(\w+)_SOURCES/) {
               my $prog = $1;   # get the PROGRAM name
               $file = trim_all($contents{$key});
                   @files = split(/\s/, $file);
                   foreach $fi (@files) {
                      $ext = file_extension($fi);
                  if (is_c_source_ext($ext)) { # if a C/C++ source
                     $file = $base_dir . $relative_dir . '/' . $fi;
                     $file =~ s/\//\\/g; # use DOS path sep
                     $dupe = add_2_source_list( $file, $prog );
                  }
               }
            }
         }
        }
    }
   show_am_sources();
    prt( "Done $mfam ...\n" ) if ($verbose2 || $dbg18);
}
sub dsp_finish {
    my $dsp_name = shift;
    ###my $dsp_file = $root_dir . $dsp_name . '.dsp';
    my $dsp_file = get_dsp_name($dsp_name);
    open(DSP, ">>$dsp_file")
    || mydie( "ERROR: Can't append to $dsp_file: $!\n" );
    foreach my $r (@extra_sources) {
        print DSP "# Begin Source File\n\n";
        print DSP "$r\n";
        print DSP "# End Source File\n";
    }
    print DSP "# End Target\n";
    print DSP "# End Project\n";
    close(DSP);
}
# Return directory name of file.
sub dirname
{
    my ($file) = @_;
    my ($sub);
    ($sub = $file) =~ s,/+[^/]+$,,g;
    $sub = '.' if $sub eq $file;
    return $sub;
}
sub add_2_used_libs {
    my ($fil,$in) = @_;
    if (exists( $used_lib_paths{$in} ) ) {
        my @incs = split(/\|/ , $used_lib_paths{$in});
        my $got = 0;
        foreach my $i (@incs) {
            if ($i eq $fil) {
                $got = 1;
                last;
            }
        }
        if ( ! $got ) {
            $used_lib_paths{$in} .= '|'.$fil; # add new
        }
    } else {
        $used_lib_paths{$in} = $fil; # set first
    }
}
sub check_lib_paths {
    my $fil = shift;
    my $inc = '';
    my $ff = '';
    my $finc = '';
    my $fincr = '';
    my $fincd = '';
    my $found1 = 0;
    my $found2 = 0;
    my $found3 = 0;
    foreach $inc (@msvc_libs_paths) {
        $ff = $root_dir . $inc;
        if ( !(($ff =~ /\/$/) || ($ff =~ /\\$/)) ) {
            $ff .= '\\';
        }
        $ff .= $fil;
        if( -f $ff ) {
            $finc = $inc;
            $found1 = 1;
            last;
        }
    }
    foreach $inc (@msvc_rlibs_paths) {
        $ff = $root_dir . $inc;
        if ( !(($ff =~ /\/$/) || ($ff =~ /\\$/)) ) {
            $ff .= '\\';
        }
        $ff .= $fil;
        if( -f $ff ) {
            $fincr = $inc;
            $found2 = 1;
            last;
        }
    }
    foreach $inc (@msvc_dlibs_paths) {
        $ff = $root_dir . $inc;
        if ( !(($ff =~ /\/$/) || ($ff =~ /\\$/)) ) {
            $ff .= '\\';
        }
        $ff .= $fil;
        if( -f $ff ) {
            $fincd = $inc;
            $found3 = 1;
            last;
        }
    }
    if( $found1 || $found2 || $found3 ) {
        prt( "Found [$fil] in [$finc] [$ff] ...\n" ) if ($verbose2 && $found1);
        prt( "Found [$fil] in [$fincr] [$ff] ...\n" ) if ($verbose2 && $found2);
        prt( "Found [$fil] in [$fincd] [$ff] ...\n" ) if ($verbose2 && $found3);
        add_2_used_libs( $fil, $finc ) if $found1;
        add_2_used_libs( $fil, $fincr ) if $found2;
        add_2_used_libs( $fil, $fincd ) if $found3;
    } else {
        prt( "WARNING: Unable to locate $fil ...\n" ) if $verbose2;
    }
    return ($found1 + $found2 + $found3);
}
sub check_inc_paths {
    my $fil = shift;
    my $inc = '';
    my $ff = '';
    my $found = 0;
    if( ! $found ) {
        foreach $inc (@msvc_inc_paths) {
            $ff = $root_dir . $inc;
            if ( !(($ff =~ /\/$/) || ($ff =~ /\\$/)) ) {
                $ff .= '\\';
            }
            $ff .= $fil;
            ### print "Checking for $fil in $ff ...\n" if $verbose9;
            if( -f $ff ) {
                if (exists( $used_inc_paths{$inc} ) ) {
                    my @incs = split(/\|/ , $used_inc_paths{$inc});
                    my $got = 0;
                    foreach my $i (@incs) {
                        if ($i eq $fil) {
                            $got = 1;
                            last;
                        }
                    }
                    if ( ! $got ) {
                        $used_inc_paths{$inc} .= '|'.$fil; # add new
                    }
                } else {
                    $used_inc_paths{$inc} = $fil; # set first
                }
                $found = 1;
                last;
            }
        }
    }
    if( $found ) {
        prt( "Found $fil in $inc [$ff] ...\n" ) if $verbose2;
    } else {
        prt( "WARNING: Unable to locate $fil ...\n" ) if $verbose2;
    }
    return $found;
}
sub show_lib_found {
    my (@arr) = @_;
    foreach my $in (@arr) {
        if (exists( $used_lib_paths{$in} ) ) {
            my @ip = split(/\|/, $used_lib_paths{$in});
            prt( "On path [$root_dir][$in] found ".scalar @ip." items ...\n" );
            my $cntr = 0;
            $in .= '\\' if !($in =~ /(\\|\/)$/);
            foreach my $f (@ip) {
                $cntr++;
                prt( "$cntr ".$root_dir.$in.$f."\n" );
            }
        } else {
            prt( "Warning: Found nothing on [$root_dir][$in] ...\n" );
        }
    }
}
sub check_includes {
    my $fil = '';
    my $ff = '';
    my $cnt1 = 0;
    my $cnt2 = 0;
    my @missed = ();
    my @missed2 = ();
    my $inc = '';
    my @incpath = ();
    $cnt1 = scalar @msvc_dlibs_list + scalar @msvc_rlibs_list + scalar @msvc_libs_list;
    prt( "\nCheck 1: each $cnt1 additional library, in each library include path ...\n" );
    foreach $fil (@msvc_dlibs_list) {
        if( check_lib_paths( $fil ) == 0 ) {
            push(@missed, $fil);
        }
    }
    foreach $fil (@msvc_rlibs_list) {
        if( check_lib_paths( $fil ) == 0 ) {
            push(@missed, $fil);
        }
    }
    foreach $fil (@msvc_libs_list) {
        if( check_lib_paths( $fil ) == 0 ) {
            push(@missed, $fil);
        }
    }
    show_lib_found(@msvc_libs_paths);
    show_lib_found(@msvc_rlibs_paths);
    show_lib_found(@msvc_dlibs_paths);
    if( @missed ) {
        prt( "WARNING: Missed ". join(' ',@missed) . ".\n" );
        prt( "Check 'add_lib' and 'lib_path' in $src_cfg ...\n" );
    } else {
        prt( "Appears no libraries are is missing ...\n" );
    }
    prt( "Done 1: each $cnt1 additional library, in each library include path ...\n" );
    # check for a known set of INCLUDE (or source) files
    $cnt2 = scalar @test_headers;
    prt( "\nCheck 2: each of $cnt2 test headers, in each include path ...\n" );
    foreach $fil (@test_headers) {
        if( check_inc_paths( $fil ) == 0 ) {
            push(@missed2, $fil);
        }
    }
    foreach $inc (@msvc_inc_paths) {
        if (exists( $used_inc_paths{$inc} ) ) {
            @incpath = split(/\|/, $used_inc_paths{$inc});
            prt( "On path [$root_dir][$inc] found ".scalar @incpath." items ...\n" );
            my $cntr = 0;
            foreach $fil (@incpath) {
                $cntr++;
                if ( ! ($inc =~ /(\\|\/)$/) ) {
                    $inc .= '\\';
                }
                prt( "$cntr ".$root_dir.$inc.$fil."\n" );
            }
        } else {
            prt( "Warning: Found nothing on [$root_dir][$inc] ...\n" );
        }
    }
    if( @missed2 ) {
        prt( "WARNING: Missed ". join(' ',@missed2) . ".\n" );
        prt( "Check 'include_path' in $src_cfg ...\n" );
    } else {
        prt( "Appears no test sources, headers are missing ...\n" );
    }
    prt( "Done checking $cnt1 libraries, and $cnt2 test includes ...\n" );
## #V8  check_vc8_proj();
    # NO RETURN FROM HERE
    mydie( "End check of libraries and include files ... aborting ...\n" );
}
# some simple utility functions
# =============================
sub is_c_source_ext {
    my $fil = shift;
    my $fe = lc($fil);
    if (($fe eq 'c')||($fe eq 'cxx')||($fe eq 'cpp')) {
        return 1;
    }
    return 0;
}
sub is_h_source_ext {
    my $fil = shift;
    my $fe = lc($fil);
    if (($fe eq 'h')||($fe eq 'hxx')||($fe eq 'hpp')) {
        return 1;
    }
    return 0;
}
sub add_2_source_list {
    my ($fil, $grp) = @_;
    my $fe = file_extension($fil);
    my $ft = lc(file_title($fil));
    my $src = ($grp . '|' . $fil . '|' . $ft);
    my $ret = 0;
   push(@am_source_list, $src);
    ###if (($fe eq 'c')||($fe eq 'cxx')||($fe eq 'cpp')) {
    if ( is_c_source_ext($fe) ) {
        prt( "Add $src to C list\n" ) if $verbose2;
        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);
    } else {
        prt( "Add $src to H list\n" ) if $verbose2;
        push(@msvc_h_files, $src);
    }
    return $ret;
}
sub add_dupes_dir {
    my ($fh, $pack) = @_;
    print $fh "\n";
    print $fh "!IF  \"\$(CFG)\" == \"$pack - Win32 Release\"\n";
    print $fh "\n";
    print $fh "# PROP Intermediate_Dir \"Release\\Dupes\"\n";
    print $fh "\n";
    print $fh "!ELSEIF  \"\$(CFG)\" == \"$pack - Win32 Debug\"\n";
    print $fh "\n";
    print $fh "# PROP Intermediate_Dir \"Debug\\Dupes\"\n";
    print $fh "\n";
    print $fh "!ENDIF\n"; 
    print $fh "\n";
}
######################################
sub write_new_dsp {
   my $src_cnt = scalar @msvc_c_files;
    my $new_pack = $dsp_package;
    my $src;
    ###my $dsp_file = $root_dir . $new_pack .'.dsp';
    my $dsp_file = get_dsp_name($new_pack);
    my @bits = ();
    my @done = ();
    my $group = '';
    my $pgrp = '';
    my $tit = '';
    my $isdupe = 0;
   if ($src_cnt == 0) {
      $err_msg = "WARNING: There are NO SOURCES, so no DSP/DSW generated!\n";
      prtw($err_msg);
      return;
   }
    if ($static_lib) {
        static_lib_dsp_init($new_pack);
    } else {
        console_app_dsp_init($new_pack);
    }
    open(DSP, ">>$dsp_file") || mydie( "ERROR: Can't append to $dsp_file: $!\n" );
    if ( ! $add_groups) {
        print DSP "# Begin Group \"Source Files\"\n";
        print DSP "\n";
        print DSP "# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;idl;hpj;bat\"\n";
    }
    foreach $src (@msvc_c_files) {
        prt( "Processing $src from array ...\n" ) if $verbose2;
        @bits = split( /\|/, $src ); # get file title, name and group
        $group = 'Lib_' . $bits[0];
        $tit = $bits[2];
        $isdupe = 0;
        if ($add_groups && ($group ne $pgrp)) {
            print DSP "# Begin Group \"$group\"\n";
            print DSP "\n";
            print DSP "# PROP Default_Filter \"\"\n";
        } else {
            # not adding groups, check duplicate names
            foreach my $tt (@done) {
                if( $tt eq $tit ) {
                    $isdupe = 1;
                    last;
                }
            }
        }
        dsp_add_source_rule(\*DSP, $new_pack, $group, $bits[1], $isdupe);
        if ( !$add_groups && $isdupe) {
            prt( "Processed a DUPLICATE $tit from array ...\n" ) if $verbose2;
            prt( "Bits = ".$bits[0]."|".$bits[1].'|'.$bits[2]. " ...\n" ) if $verbose2;
        }
        push(@done, $tit);
        if ($add_groups && ($group ne $pgrp)) {
            print DSP "# End Group\n";
        }
        $pgrp = $group;
    }
    if ( !$add_groups) {
        print DSP "# End Group\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\"\n";
    my $savgrp = $add_groups;
    $add_groups = 0;
    foreach $src (@msvc_h_files) {
        @bits = split( /\|/, $src ); # get file title, name and group
        $group = 'Lib_' . $bits[2];
        dsp_add_source_rule(\*DSP, $new_pack, $group, $bits[1], 0);
    }
    print DSP "# End Group\n";
    close(DSP);
    $add_groups = $savgrp;
    dsp_finish($new_pack);
    generate_dsw($new_pack);
    prt( "Done temp.".$new_pack." DSP and DSW files ...\n" );
}
sub trim_line {
    my ($l) = shift;
    chomp $l;
    $l =~ s/\r$//; # and remove CR, if present
    $l =~ s/\t/ /g;
    $l =~ s/\s\s/ /g while ($l =~ /\s\s/);
    #$l = substr($l,1) while ($l =~ /^\s/);
    #$l = substr($l,0,length($l)-1) while (($l =~ /\s$/)&&(length($l)));
    for ($l) {
        s/^\s+//;
        s/\s+$//;
    }
    return $l;
}
# 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;   # assume NO SUCH FILE
   if ( -f $fil ) {   # is there?
      my ($nm,$dir,$ext) = fileparse( $fil, qr/\.[^.]*/ );
      my $nmbo = $dir . $nm . '.old';
      $ret = 1;   # assume renaming to OLD
      if ( -f $nmbo) {   # does OLD exist
         $ret = 2;      # yes - rename to BAK
         $nmbo = $dir . $nm . '.bak';
         if ( -f $nmbo ) {
            $ret = 3;
            unlink $nmbo;
         }
      }
      rename $fil, $nmbo;
   }
   return $ret;
}
######################################################################
## MAINLY DEBUG ONLY THINGS
######################################################################
#####################################################
## prt_list
## Debug output of line list, with some rough
## indenting ...
#####################################################
sub prt_list {
    my (@list) = @_;
    my $ind = '';
    foreach my $line (@list) {
        if ($line =~ /^</) {
            if ($line =~ /\/>/) {
                # end xml same line
            } elsif ($line =~ /^<\//) {
                $ind = substr($ind, 1) if (length($ind));
            } else {
                # $ind .= ' ';
            }
        }
        prt( $ind.$line."\n" );
        if ($line =~ /^</) {
            if ($line =~ /\/>/) {
                # end xml same line
            } elsif ($line =~ /^<\//) {
                # $ind = substr($ind, 1) if (length($ind));
            } else {
                $ind .= ' ';
            }
        }
    }
}
## 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 prtw {
   my ($txt) = shift;
    $txt =~ s/\n$//;
   push(@warnings,$txt);
   prt("$txt\n");
}
sub show_warnings {
   my $wcnt = scalar @warnings;
   if ($wcnt) {
      prt( "\nThere are $wcnt lines of WARNINGS ...\n" );
      foreach my $wn (@warnings) {
         prt("$wn\n");
      }
   } else {
      prt( "There are NO warnings ...\n" );
   }
    prt("\n");
}
sub get_root_name {
   my ($pn) = shift;
   my $rn = 'temp.'.$pn;
   return $rn;
}
sub get_dsp_name {
   my ($pn) = shift;
   my $dsp = get_root_name($pn).'.dsp';
   return $dsp;
}
sub get_dsw_name {
   my ($pn) = shift;
   my $dsp = get_root_name($pn).'.dsw';
   return $dsp;
}
sub fix_rel_path {
   my ($path) = shift;
   $path = path_u2d($path);   # ENSURE DOS PATH SEPARATOR (in relative.pl)
   my @a = split(/\\/, $path);
   my $npath = '';
   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 {
            prtw( "WARNING: Got relative .. without previous!!! path=$path\n" );
         }
      } else {
         push(@na,$p);
      }
   }
   foreach my $pt (@na) {
      $npath .= "\\" if length($npath);
      $npath .= $pt;
   }
   return $npath;
}
# redone using File::Basename;
sub file_extension {
    my $fil = shift;
   my ($nm, $dir, $ext) = fileparse( $fil, qr/\.[^.]*/ );
   $ext = substr($ext,1) if ($ext =~ /^\./);
   return $ext;
}
sub file_title {
    my $fil = shift;
   my ($nm, $dir, $ext) = fileparse( $fil, qr/\.[^.]*/ );
   return $nm;
}
# debug items
sub set_all_debug {
   $debug_on = 1;
   $debug_on3 = 1;
   $sw_dbg = 1;
   $dbg10 = 1;   # show EACH line in configure.ac parse
   $dbg11 = 1;   # show "Split to $vlen components ...
   $dbg12a = 1;   # show prt( "Adding $input [$ff] to make_input_list ... - items added to @make_input_list
   $dbg12b = 1;   # show items added to @other_input_list
   $dbg13 = 1;   # show ac_output_line information ...
   $dbg14 = 1;   # prt( "Variable $key=$nval\n"
   $dbg15 = 1;   # prt( "Copying " . scalar @make_input_list . " make_input_list to input_files.\n" ) if ($verbose2 || $dbg15);
   $dbg16 = 1;   # prt( "Substitute $key=$nval\n" ) if ((($orgkey ne $key)||($orgnval ne $nval)) && $dbg16);
   $dbg17 = 1;   # prt( "\nProcessing [$am_file] from input_files array ...\n" ) if ($verbose2 || $dbg17);
   $dbg18 = 1;   # prt( "process_am_file: using dsp_name=$dsp_file, and makefile=$makefile ...\n" ) if ($verbose2 || $dbg18);
   $dbg19 = 1;   # prt( "$pack: reading $am_file\n" ) if ($verbose || $dbg19);
   $dbg20 = 1;   # prt( "$. [$aml]\n" ) if ($debug_on3 || /$dbgnn/);
   $dbg21 = 1;   # prt( "Found a macro definition. 1[$1] 2[$2] 3[$3] ...\n" ) if ($debug_on3 || /$dbgnn/);
   $dbg22 = 1;   # show_contents() if (/$dbgnn/);
   $dbg23 = 1;   # show contents of %config_ac_macros
   $dbg24 = 1;   # prt( "$. Should JOIN lines? - [$cline]\n" ) if (/$dbgnn/);
   $dbg25 = 1;   # prt( "ADDING SOURCE: $file ($dsp_name, $group, $dup)\n" ) if (/$dbgnn/);
   $dbg26 = 1;   # prt( "$. Got AC_INIT = [$1]\n" ) if (/$dbgnn/);
}
# eof - am2dsp7.pl

index -|- top

checked by tidy  Valid HTML 4.01 Transitional