#!perl -w
# 05/10/2008 - Part of a series of Perl scripts to compare and show changes
# in the build files of FlightGear and SimGear
# MODULE: fgamscan.pl
# AIM: To scan makefile.am in FG/SG, and list builds and sources
# 02/10/2008 geoff mclane - http://geoffair.net/fg
use strict;
use warnings;
use File::Basename;
######################################################################################
require 'fgutils.pl' or die "Unable to load fgutils.pl ...\n";
require 'fgdsphdrs.pl' or die "Unable to load fgdsphdrs.pl ...\n";
# log file stuff
my ($LF);
my $pgname = $0;    # get perl module name
if ($pgname =~ /\w{1}:\\.*/) {
	my @tmpsp = split(/\\/,$pgname);
	$pgname= $tmpsp[-1];
}
my $outfile = "temp.$pgname.txt";
open_log($outfile);

# OPTIONS
my $root_dir = "C:\\FG\\20";
my $in_list = 'tempamdone.txt';
##my $in_list = 'tempam.txt';
my $show_fg_only = 1;
my $pgm_fg = "fgfs";
my $trace_from_1am = 1; # given ONLY 1 Makefile.am, use SUBDIRS to search for more
my $primary_am = 'FlightGear\Makefile.am';

my $fg_dir = $root_dir."\\FlightGear";
my $sg_dir = $root_dir."\\SimGear";
my $fg_dat = $root_dir."\\data";
my $bld_dir = $root_dir."\\fgfs";
# may need to adjust my $fg_dir2 = "C:\\\\FG\\\\20\\\\FlightGear"; below

# DEBUG OUTPUT OPTIONS
my $dbg_s01 = 0;    # show line not processed - prt( "$i2: $fline
my $dbg_s02 = 0;    # list keys in hash prt( "Listing $acnt keys in hash ...
my $dbg_s03 = 0;    # report when there are NO KEYS ... like prt( "No LIBRARY keys ... and PROGRAM
my $dbg_s04 = 0;    # show PROGRAM and LIBRARY found ... like prt( "PROGRAM [$ky] has SOURCES [$val]
my $dbg_s05 = 0;    # show AM file name before processing ... like prt( "$am ". ((-f $am) ? "ok" : "no find!")
my $dbg_s06 = 0;    # show cond_stack actions ... like prt( "Opened cond_stack with [".$cond_stack[$#cond_stack]."] $fil
my $dbg_s07 = 0;    # grab NEW LINE, when showing Processing ... if $dbg_s08 also on ...
my $dbg_s08 = 0;    # show prt( "Processing $cnt lines from $fil ...\n" )
my $dbg_s09 = 0;    # show sub-directories, like prt( "Got $cnt subdirectories [$slist] ...
my $dbg_s10 = 0;    # show EACH SOURCE, as moved to array, like ... prt( "$fil

# CONSTANTS
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 %def_condits = (
    "USE_GLUT" => "TRUE",
    "ENABLE_JPEG_SERVER" => "FALSE",
    "ENABLE_SP_FDM" => "TRUE"
);

my %global_hash = (
    'top_srcdir' => $fg_dir,
    'base_LIBS'  => "",
    'opengl_LIBS' => "",
    'network_LIBS' => "",
    'joystick_LIBS' => "",
    'top_builddir' => $bld_dir,
    'thread_LIBS' => "",
    'pkgdatadir' => $fg_dat,
    'openal_LIBS' => ""
);

my %dsp_dummy_sub = (
    "-NEW_PROJECT_NAME-" => $pgm_fg,
    "-NEW_RT_REL-"       => "/MD",
    "-NEW_RT_DBG-"       => "/MDd",
    "-NEW_DEFS_REL-"     => "/D \"FGFS\" /D \"_CRT_SECURE_NO_WARNINGS\"",
    "-NEW_DEFS_DBG-"     => "/D \"FGFS\" /D \"_CRT_SECURE_NO_WARNINGS\"",
    "-NEW_LIBS_DBG-"     => "Winmm.lib ws2_32.lib",
    "-NEW_LIBS_REL-"     => "Winmm.lib ws2_32.lib",
    "-NEW_POST_DBG-"     => "",
    "-NEW_POST_REL-"     => "",
    "-NEW_INCS_DBG-"     => "",
    "-NEW_INCS_REL-"     => "",
    "-NEW_OUTD_DBG-"     => "\"Debug\"",
    "-NEW_OUTD_REL-"     => "\"Release\"",
    "-NEW_INTER_DBG-"    => "\"Debug\"",
    "-NEW_INTER_REL-"    => "\"Release\"",
    "-NEW_OUT_DBG-"      => "",
    "-NEW_OUT_REL-"      => ""
);

my %programs = ();
my %libraries = ();

my @msvc_c_files = ();
my @msvc_h_files = ();
my @warnings = ();

my $def_src_g = "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90";
my $def_hdr_g = "h;hpp;hxx;hm;inl;fi;fd";
my $def_rcs_g = "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe";
my $def_spl_g = "txt;vc5;h-msvc8;asm";

my $def_src_nm = "Source Files";    # Begin Group "Source Files"
my $def_hdr_nm = "Header Files";	# Begin Group "Header Files"
my $def_rcs_nm = "Resource Files";	# Begin Group "Resource Files"
my $def_spl_nm = "Special Files";
my $def_unknown = "Unknown";

if ($trace_from_1am) {
    if (-f $primary_am) {
        process_primary($primary_am);
    } else {
        prt( "ERROR: Unable to find $primary_am ...\n" );
    }
} else {
    if (open INL, "<$in_list") {
        my @files = <INL>;
        close INL;
        prt( "Processing ".scalar @files." files from $in_list ...\n" );
        foreach my $file (@files) {
            chomp $file;
            ###if ($file =~ /^C:\\FG\\20\\FlightGear/) {
              process_AM_file($file);
            ###}
        }
        list_to_arrays();
        write_temp_dsp("tempscan.dsp");
    } else {
        prt( "ERROR: Unable to open $in_list ...\n" );
    }
}

show_warnings();
close_log($outfile,1);
exit(0);

# ################################################
# SUBS ONLY #

sub process_one_am_file {
    my ($fil) = shift;
    my %h = process_AM_file($fil);
    if (defined $h{'SUBDIRS'}) {
        my $slist = $h{'SUBDIRS'};
        my @ar = split(/\s/,$slist);
        my $cnt = scalar @ar;
        my ($p_tit,$p_dir,$p_ext) = fileparse( $fil, qr/\.[^.]*/ );
        prt( "Got $cnt subdirectories [$slist] ...\n" ) if ($dbg_s09);
        foreach my $dir (@ar) {
            my $am = $p_dir.$dir.'\Makefile.am';
            prt( "$am ". ((-f $am) ? "ok" : "no find!") . "\n" ) if ($dbg_s05);
            process_one_am_file($am);
        }
    }
}

sub process_primary {
    my ($fil) = shift;
    process_one_am_file($fil);  # iteratively process the Makefile.am files
    list_to_arrays();
    write_temp_dsp("tempscan.dsp");
}

sub write_temp_dsp {
    my ($of) = shift;
    my $ccnt = scalar @msvc_c_files;
    return if ($ccnt == 0);
    my $msg = get_dsp_head_console();
    my ($ky, $val, $i, @av, $fil, $src, $hcnt);
    # perform SUBSTITUTIONS
    my $fnm = $def_src_nm;
    my $ftyp = $def_src_g;
    foreach $ky (keys %dsp_dummy_sub) {
        $val = $dsp_dummy_sub{$ky};
        $msg =~ s/$ky/$val/gm;
    }

    $msg .= '# Begin Group "'.$fnm."\"\n";
    $msg .= "\n";
    $msg .= '# PROP Default_Filter "'.$ftyp."\"\n";
    for ($i = 0; $i < $ccnt; $i++) {
        $src = $msvc_c_files[$i];
        @av = split( /\|/, $src ); # get file title, name and group
        $fil = $av[1];
        $msg .= "# Begin Source File\n";
        $msg .= "\n";
        $msg .= "SOURCE=$fil\n";
        # $msg .= "# PROP Exclude_From_Build 1\n" if ($ex eq $excl_mark);
        $msg .= "# End Source File\n";
    }
    $msg .= "# End Group\n";

    $hcnt = scalar @msvc_h_files;
    $fnm = $def_hdr_nm;
    $ftyp = $def_hdr_g;
    $msg .= '# Begin Group "'.$fnm."\"\n";
    $msg .= "\n";
    $msg .= '# PROP Default_Filter "'.$ftyp."\"\n";
    for ($i = 0; $i < $hcnt; $i++) {
        $src = $msvc_h_files[$i];
        @av = split( /\|/, $src ); # get file title, name and group
        $fil = $av[1];
        $msg .= "# Begin Source File\n";
        $msg .= "\n";
        $msg .= "SOURCE=$fil\n";
        # $msg .= "# PROP Exclude_From_Build 1\n" if ($ex eq $excl_mark);
        $msg .= "# End Source File\n";
    }
    $msg .= "# End Group\n";

	$msg .= get_dsp_tail();

    # got DSP file information, now write it
    write2file($msg, $of);
    prt( "\nWritten $of, with $ccnt C sources, and $hcnt others ...\n" );
}

sub list_to_arrays {
    prt("\n");
    prt( "AM files yielded programs ... " );
    prt( "just for FlightGear, separated into groups ..." ) if ($show_fg_only);
    prt("\n");

    my ($key, $val, @av, $fil);
    my ($src, $tit, $dir, $ext, $cnt);
    my @done = ();
    my $grp = "fgfs";
    foreach $key (sort keys %programs) {
        next if ($show_fg_only && !($key eq $pgm_fg));
        $val = $programs{$key};
        @av = split(/\s/,$val);
        $cnt = scalar @av;
        prt( "PROGRAM [$key] $cnt SOURCES\n" );
        foreach $fil (@av) {
            prt( "$fil\n" ) if ($dbg_s10);
            ($tit,$dir,$ext) = 	fileparse( $fil, qr/\.[^.]*/ );
            $src = ($grp.'|'.$fil.'|'.$tit);
            if (is_c_source($fil)) {
                if (is_in_array($tit,@done)) {
                    prtw("Duplicate of FILE TITLE $tit ($fil)!!!\n" );
                } else {
                    push(@done,$tit);
                }
                push(@msvc_c_files, $src);
            } else {
                push(@msvc_h_files, $src);
            }
        }
    }
    prt("\n") if ($dbg_s10);
    prt( "And following library SOURCES ...\n" );
    foreach $key (sort keys %libraries) {
        $val = $libraries{$key};
        @av = split(/\s/,$val);
        $cnt = scalar @av;
        prt( "LIBRARY [$key] $cnt SOURCES" ) if (!$show_fg_only);
        foreach $fil (@av) {
            prt( "$fil\n" ) if ($dbg_s10);
            ($tit,$dir,$ext) = 	fileparse( $fil, qr/\.[^.]*/ );
            $src = ($grp.'|'.$fil.'|'.$tit);
            if (is_c_source($fil)) {
                if (is_in_array($tit,@done)) {
                    prtw("Duplicate of FILE TITLE $tit ($fil)!!!\n" );
                } else {
                    push(@done,$tit);
                }
                push(@msvc_c_files, $src);
            } else {
                push(@msvc_h_files, $src);
            }
        }
    }

    $key = scalar @msvc_c_files;
    $val = scalar @msvc_h_files;
    prt( "Set of $key C SOURCE files, and $val headers (and others) ...\n" );
}

# VARIOUS FIXES FOR THE FILE NAME
# 1. ensure ALL DOS format
# 2. remove any simple dot relative, like '.\' from beginning
# 3. if given a FULL PATH name, remove C:\FG\20\FlightGear
# 4. if a relative name, remove FligthGear
# 5. if any removal, ensure any beginning '\' is removed
sub sub_fg_dir {
    my ($pth) = shift;
    my $fg_dir2 = "C:\\\\FG\\\\20\\\\FlightGear";
    $pth = strip_dotrel(path_u2d($pth));  # ensure in DOS format, without any '.\' start
    if ($pth =~ /$fg_dir2/i) {
        $pth =~ s/$fg_dir2//i;
    } elsif ($pth =~ /^FlightGear/i) {
        $pth =~ s/^FlightGear//i;
    }
    $pth =~ s/^\\//;    # strip leading '\', if any
    return $pth;
}


sub get_value_from_hash {
    my ( $rval2, $ms, $rhash ) = @_;
    my ($ky2, @vals, $fnd, $val, @keys, $i);
    my ($itm, $cond);
    $fnd = 0;
    foreach $ky2 (keys %{$rhash}) {
        if ($ky2 =~ /^$ms\s+/) {
            $val = $$rhash{$ky2};
            if (!is_in_array($val, @vals)) {
                push(@vals,$val);
                push(@keys,$ky2);
                $fnd++;
            }
        }
    }
    if ($fnd == 1) {
        $$rval2 = $vals[0]; # just ONE to RETURN
    } elsif ($fnd > 1) {
        my $msg = "WARNING: For sub of [$ms], have [$fnd] to CHOOSE FROM!\n";
        for ($i = 0; $i < $fnd; $i++) {
            $val = $vals[$i];
            $ky2 = $keys[$i];
            $msg .= " or \n" if ($i > 0);
            $msg .= "[$ky2={".$val.'}]';
            if ($ky2 =~ /^$ms\s+if\s+(\w+)\@_(TRUE|FALSE)\@/) {
                $itm = $1;
                $cond = $2;
                $msg .= " [$itm]=[$cond]";
                if (defined $def_condits{$itm}) {
                    if ($def_condits{$itm} eq $cond) {
                        $$rval2 = $val; # RETURN selected
                        ### prtw("CHECK: Returning [$val] for [$ms], due [$itm]=[$cond] in def_condits!\n" );
                        return $fnd;
                    }
                }
            }
        }
        $msg .= " Defaulting to FIRST! CHECK ME!!\n";
        prtw("$msg\n");
        $$rval2 = $vals[0]; # just RETURN first
    }
    return $fnd;
}

sub extract_from_hash {
    my ($fil, $rhash) = @_;
    my ($a_nm, $a_dir) = fileparse($fil);
    my ($key, $val, @av);
    my (@skeys, @progs, @progkeys, @libs, @libkeys, @srcs, @srckeys);
    my ($ky, $vky, $ms, $val2, $ky2, $orgval, $fnd, $acnt);
    my ($src, $ff, $scnt, $i);
    # really interested in 
    # noinst_LIBRARIES = libAirports.a
    # noinst_PROGRAMS = calc_loc
    # bin_PROGRAMS = fgfs something
    # libAirports_a_SOURCES = apt_loader.cxx apt_loader.hxx ...
    @skeys = sort keys(%{$rhash});
    $acnt = scalar @skeys;
    prt( "Listing $acnt keys in hash ...\n" ) if ($dbg_s02);
    # collect PROGRAM keys
    @progs = ();
    @progkeys = ();
    @libs = ();
    @libkeys = ();
    @srcs = ();
    @srckeys = ();
    # try to do substitutions
    foreach $key (@skeys) {
        $val = $$rhash{$key};
        $orgval = $val;
        if ($val =~ /\$\((\w+)\)/) {
            $ms = $1;
            $val2 = ''; # no sub yet
            $fnd = 0;   # none found
            if (defined $global_hash{$ms}) {
                $val2 = $global_hash{$ms};  # found in global
                $fnd = 1;
            } elsif (defined $$rhash{$ms}) {
                $val2 = $$rhash{$ms}; # found in local
                $fnd = 2;
            } else {
                # hmmm, maybe like 'GFX_CODE if @USE_GLUT_FALSE@ = fg_os_osgviewer.cxx $(GFX_COMMON)'
                $fnd = get_value_from_hash(\$val2, $ms, $rhash ); 
            }
            if ($fnd > 0) {
                $val =~ s/\$\($ms\)/$val2/g;
            } else {
                prtw("WARNING:1: No substitution for [$ms] found in hash ...\n" );
            }
        }

        if ($val ne $orgval) {
            $$rhash{$key} = $val;
        }
    }

    # try to do substitutions, twice
    foreach $key (@skeys) {
        $val = $$rhash{$key};
        $orgval = $val;
        if ($val =~ /\$\((\w+)\)/) {
            $ms = $1;
            $val2 = '';
            $fnd = 0;
            if (defined $global_hash{$ms}) {
                $val2 = $global_hash{$ms};
                $fnd = 1;
            } elsif (defined $$rhash{$ms}) {
                $val2 = $$rhash{$ms};
                $fnd = 2;
            } else {
                # hmmm, maybe like 'GFX_CODE if @USE_GLUT_FALSE@ = fg_os_osgviewer.cxx $(GFX_COMMON)'
                foreach $ky2 (keys %{$rhash}) {
                    if ($ky2 =~ /^$ms/) {
                        $val2 = $$rhash{$ky2};
                        $fnd = 3;
                        last;
                    }
                }
            }
            if ($fnd > 0) {
                $val =~ s/\$\($ms\)/$val2/g;
            } else {
                prtw("WARNING:2: No substitution for [$ms] found in hash ...\n" );
            }
        }
        if ($val ne $orgval) {
            $$rhash{$key} = $val;
        }
    }

    foreach $key (@skeys) {
        $val = $$rhash{$key};
        if ($key =~ /_PROGRAMS/) {
            push(@progkeys,$key);
            push(@progs,$val);
        } elsif ($key =~ /_LIBRARIES/) {
            push(@libkeys,$key);
            push(@libs,$val);
        } elsif ($key =~ /_SOURCES/) {
            push(@srckeys,$key);
            ###push(@srcs,$val);
        }
    }

    foreach $key (@skeys) {
        $val = $$rhash{$key};
        prt( "$key = $val\n" ) if ($dbg_s02);
    }
    if (@libkeys) {
        foreach $key (@libkeys) {
            $val = $$rhash{$key};
            @av = split(/\s/,$val);
            foreach $ky (@av) {
                $ky =~ s/-/_/g;
                $ky =~ s/\./_/g;
                $vky = $ky.'_SOURCES';
                if (defined $$rhash{$vky}) {
                    $val = $$rhash{$vky};
                    @srcs = split(/\s/, $val);
                    $scnt = scalar @srcs;
                    for ($i = 0; $i < $scnt; $i++) {
                        $src = $srcs[$i];
                        $ff = sub_fg_dir($a_dir.$src);
                        $srcs[$i] = $ff;
                    }
                    $val = join(' ',@srcs);
                    if (defined $libraries{$ky}) {
                        prtw( "WARNING: libraries[$ky] has value [".$libraries{$ky}."] ADDING $val!\n" );
                        $libraries{$ky} .= ' @AND@ '.$val;
                    } else {
                        $libraries{$ky} = $val;
                    }
                    prt( "LIBRARY [$ky] has SOURCES [$val]\n" ) if ($dbg_s04);
                } else {
                    prtw( "WARNING: No sources for LIBRARY [$ky]\n" );
                }
            }
        }
    } else {
        prt( "No LIBRARY keys ...\n" ) if ($dbg_s03);
    }

    if (@progkeys) {
        foreach $key (@progkeys) {
            $val = $$rhash{$key};
            @av = split(/\s/,$val);
            foreach $ky (@av) {
                $ky =~ s/-/_/g;
                $ky =~ s/\./_/g;
                $vky = $ky.'_SOURCES';
                if (defined $$rhash{$vky}) {
                    $val = $$rhash{$vky};
                    @srcs = split(/\s/, $val);
                    $scnt = scalar @srcs;
                    for ($i = 0; $i < $scnt; $i++) {
                        $src = $srcs[$i];
                        $ff = sub_fg_dir($a_dir.$src);
                        $srcs[$i] = $ff;
                    }
                    $val = join(' ',@srcs);
                    if (defined $programs{$ky}) {
                        prtw( "WARNING: programs[$ky] has value [".$programs{$ky}."] ADDING $val!\n" );
                        $programs{$ky} .= ' @AND@ '.$val;
                    } else {
                        $programs{$ky} = $val;
                    }
                    prt( "PROGRAM [$ky] has SOURCES [$val]\n" ) if ($dbg_s04);
                } else {
                    prtw( "WARNING: No sources for PROGRAM [$ky]\n" );
                }
            }
        }
    } else {
        prt( "No PROGRAM keys ...\n" ) if ($dbg_s03);
    }
}


# ***TBD*** TO BE DONE - must process better on CONDITIONS, like
# tempscan.dsp contains this, NOT in FlightGear\FlightGear.dsp
# src\Main\fg_os_osgviewer.cxx            (FlightGear\src\Main\fg_os_osgviewer.cxx)      ok
# AND
# FlightGear\FlightGear.dsp contains this, NOT in tempscan.dsp ...
# src\Main\fg_os.cxx                      (FlightGear\src\Main\fg_os.cxx)                ok
# ok, this is a problem deciding, SDL, GLUT, or OSG-viewer - from src/Main/Makefile.am
#if USE_SDL
#GFX_CODE = fg_os_sdl.cxx $(GFX_COMMON)
#else
#if USE_GLUT
#GFX_CODE = fg_os.cxx $(GFX_COMMON)
#else
#GFX_CODE = fg_os_osgviewer.cxx $(GFX_COMMON)
#endif
#endif

sub process_AM_file {
    my ($fil) = shift;
    my ($a_nm, $a_dir) = fileparse($fil);
    my %hash = ();
    my $dooldext = 0;
    if (open INF, "<$fil") {
        my @lns = <INF>;
        close INF;
        my $cnt = scalar @lns;
        prt("\n") if ($dbg_s07 && $dbg_s08);
        prt( "Processing $cnt lines from $fil ...\n" ) if ($dbg_s08);
        my ($i, $line, $fline, $i2, @av, $key, $val, $j, $acnt, $ifcond);
        my @cond_stack = ();
        $fline = '';
        for ($i = 0; $i < $cnt; $i++) {
            $line = $lns[$i];
            $i2 = $i + 1;
            chomp $line;
            next if ($line =~ /^#/);
            $fline .= trim_all($line);
            next if (length($fline) == 0);
            if ($fline =~ /\\$/) {
                $fline =~ s/\\$/ /;
            } else {
                # deal with the line
                $fline = trim_all($fline);
                if ($fline =~ /$IF_PATTERN/o) {
                    # open an IF
                    $ifcond = $1;
                    push(@cond_stack, $ifcond . "\@_TRUE\@");
                    prt( "Opened cond_stack with [".$cond_stack[$#cond_stack]."] $fil\n" ) if ($dbg_s06);
                } elsif ($fline =~ /$ELSE_PATTERN/o) {
                    # switch to else
                    if (! @cond_stack) {
                        mydie( "ERROR: else without if!\n" );
                    } elsif ($cond_stack[$#cond_stack] =~ /\@_FALSE\@$/) {
                        mydie( "ERROR: else after an else!\n" );
                    } else {
                        $cond_stack[$#cond_stack] =~ s/\@_TRUE\@$/\@_FALSE\@/;
                        prt( "Else switched cond_stack to [".$cond_stack[$#cond_stack]."] $fil\n" ) if ($dbg_s06);
                    }
                } elsif ($fline =~ /$ENDIF_PATTERN/o) {
                    # reached endif
                    if (! @cond_stack) {
                        mydie( "ERROR: endif without if!\n" );
                    }
                    $ifcond = pop (@cond_stack);
                    prt( "Closed cond_stack with [$ifcond] $fil\n" ) if ($dbg_s06);
                } elsif ($fline =~ /$INCLUDE_PATTERN/o) {
                    $key = $1;
                    mydie( "ERROR: Unhandled INCLUDE [$key], in $fil ...\n" );
                } elsif ($fline =~ /^(\w+)\s*=\s*(.*)$/) {
                    @av = split('=',$fline);
                    $key = trim_all($av[0]);
                    $acnt = scalar @av;
                    $val = '';  # start with NO VALUE
                    # if can be 'JPEG_SERVER ='
                    for ($j = 1; $j < $acnt; $j++) {
                        if ($j == 1) {
                            $val = trim_all($av[$j]);
                        } else {
                            $val .= '='.trim_all($av[$j]);
                        }
                    }
                    if (@cond_stack) {
                        $ifcond = $cond_stack[$#cond_stack];
                        $key .= ' if '.$ifcond;
                    }
                    if (defined $hash{$key}) {
                        prtw( "WARNING: hash[$key] exists with [".$hash{$key}."]! Adding [$val]!! file=$fil\n" );
                        $hash{$key} .= '|'.$val;
                    } else {
                        $hash{$key} = $val;
                    }
                } else {
                    prt( "$i2: $fline\n" ) if ($dbg_s01);
                }
                $fline = '';
            }
        }
        $acnt = scalar keys(%hash);
        if ($acnt) {
            extract_from_hash( $fil, \%hash );
        } else {
            prtw( "WARNING: NO KEYS IN HASH!\n" );
        }
        if (@cond_stack) {
            prtw( "WARNING: Items still in cond_stack! [".join(' ',@cond_stack)."]\n" );
        }
    } else {
        prtw( "WARNING: Unable to open $fil ... $! ...\n" );
    }
    return %hash;
}


sub prtw {
    my ($tx) = shift;
    if ($tx =~ /\n$/) {
        prt($tx);
        $tx =~ s/\n$//;
    } else {
        prt("$tx\n");
    }
    push(@warnings,$tx);
}

sub show_warnings {
    if (@warnings) {
        prt( "\nGot ".scalar @warnings." WARNINGS ...\n" );
        foreach my $line (@warnings) {
            prt("$line\n" );
        }
        prt("\n");
    } else {
        prt("\nNo warnings issued.\n\n");
    }
}

# items of interest
# SUBDIRS, ?_LIBRARIES, bin_PROGRAMS, noinst_PROGRAMS, ?_SOURCES, ?_LDADD
# INCLUDES
# if <...> ... else ... endif macros
# specifically bin_PROGRAMS = fgfs in FlightGear
#
# SAMPLE OF SOME makefile.am files
#SUBDIRS = \
#        Include \
#        Aircraft
#noinst_LIBRARIES = libAIModel.a
#libAIModel_a_SOURCES = submodel.cxx submodel.hxx 	\
#			AIManager.hxx AIManager.cxx
#INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
#noinst_LIBRARIES = libAircraft.a
#libAircraft_a_SOURCES = \
#noinst_LIBRARIES = libAirports.a
# from C:\FG\20\FlightGear\src\Airports\Makefile.am 
#noinst_PROGRAMS = calc_loc
#libAirports_a_SOURCES = \
#	apt_loader.cxx apt_loader.hxx \
#calc_loc_SOURCES = calc_loc.cxx
#calc_loc_LDADD = -lsgmath -lsgdebug -lsgmisc -lz $(base_LIBS)
# from C:\FG\20\FlightGear\src\FDM\Makefile.am
#if ENABLE_SP_FDM
#SP_DIR = SP
#else
#SP_DIR =
#endif
#SUBDIRS	= JSBSim LaRCsim UIUCModel YASim \
#          $(SP_DIR) ExternalNet ExternalPipe
#noinst_LIBRARIES = libFlight.a
# from C:\FG\20\FlightGear\src\FDM\JSBSim\Makefile.am 
#SUBDIRS = initialization models input_output math
#noinst_LIBRARIES = libJSBSim.a
#libJSBSim_a_SOURCES =  FGFDMExec.cpp FGJSBBase.cpp FGState.cpp JSBSim.cxx
#noinst_HEADERS = FGFDMExec.h FGJSBBase.h FGState.h JSBSim.hxx
#INCLUDES = -I$(top_srcdir)/src -I$(top_srcdir)/src/FDM/JSBSim
# from C:\FG\20\FlightGear\src\FDM\LaRCsim\Makefile.am 
#AIRCRAFT_MODEL =  c172_aero.c c172_engine.c c172_gear.c c172_init.c \
#noinst_LIBRARIES = libLaRCsim.a
#libLaRCsim_a_SOURCES = \
#	LaRCsim.cxx LaRCsim.hxx \
#	$(AIRCRAFT_MODEL) \
#	ls_interface.c ls_interface.h
# from C:\FG\20\FlightGear\src\FDM\YASim\Makefile.am 
#SHARED_SOURCE_FILES = \
#        Airplane.cpp Airplane.hpp \
#noinst_LIBRARIES = libYASim.a
#libYASim_a_SOURCES = YASim.cxx YASim.hxx FGGround.cpp FGGround.hpp $(SHARED_SOURCE_FILES)
#bin_PROGRAMS = yasim
#noinst_PROGRAMS = proptest
#yasim_SOURCES = yasim-test.cpp $(SHARED_SOURCE_FILES)
#yasim_LDADD = -lsgxml -lsgprops -lsgdebug -lsgmisc -lsgstructure $(base_LIBS)
#proptest_SOURCES = proptest.cpp $(SHARED_SOURCE_FILES)
#proptest_LDADD = -lsgxml -lsgprops -lsgdebug -lsgmisc -lsgstructure $(base_LIBS)
# from C:\FG\20\FlightGear\src\GUI\Makefile.am 
#noinst_LIBRARIES = libGUI.a
#noinst_PROGRAMS = layout-test
#libGUI_a_SOURCES = \
#       new_gui.cxx new_gui.hxx \
#INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
#layout_test_SOURCES = layout-test.cxx
#layout_test_LDADD = libGUI.a \
#                    -lsgprops -lsgdebug -lsgstructure -lsgmisc -lsgxml \
#                    -lplibpw -lplibpu -lplibfnt -lplibul $(opengl_LIBS)
# from C:\FG\20\FlightGear\src\Input\Makefile.am 
#AM_CXXFLAGS = -DPKGLIBDIR=\"$(pkgdatadir)\"
#noinst_LIBRARIES = libInput.a
#libInput_a_SOURCES = input.cxx input.hxx
#bin_PROGRAMS = js_demo fgjs
#js_demo_SOURCES = js_demo.cxx
#js_demo_LDADD = -lplibjs $(base_LIBS) $(joystick_LIBS) -lplibul
#fgjs_SOURCES = fgjs.cxx jsinput.cxx jsinput.h jssuper.cxx jssuper.h
#fgjs_LDADD = -lplibjs -lplibul $(base_LIBS) $(joystick_LIBS) \
#	-lsgprops -lsgmisc -lsgio -lsgdebug -lsgstructure -lsgxml -lz
#INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/src/Main
# C:\FG\20\FlightGear\src\Main\Makefile.am 
# ************************************************************* 
#EXTRA_DIST = 3dfx.sh runfgfs.in runfgfs.bat.in \
#             fg_os_sdl.cxx fg_os.cxx fg_os_osgviewer.cxx fg_os.hxx
#MPLAYER_LIBS = $(top_builddir)/src/MultiPlayer/libMultiPlayer.a
#if ENABLE_SP_FDM
#SP_FDM_LIBS = $(top_builddir)/src/FDM/SP/libSPFDM.a
#else
#SP_FDM_LIBS = 
#endif
#if WITH_THREADS
#THREAD_LIBS = -lsgthreads $(thread_LIBS)
#else
#THREAD_LIBS =
#endif
#GFX_COMMON = fg_os_common.cxx fg_os.hxx
#if USE_SDL
#GFX_CODE = fg_os_sdl.cxx $(GFX_COMMON)
#else
#if USE_GLUT
#GFX_CODE = fg_os.cxx $(GFX_COMMON)
#else
#GFX_CODE = fg_os_osgviewer.cxx $(GFX_COMMON)
#endif
#endif
#JSBSIM_LIBS = \
#	$(top_builddir)/src/FDM/JSBSim/libJSBSim.a \
#        $(top_builddir)/src/FDM/JSBSim/initialization/libInit.a \
#AM_CXXFLAGS = -DPKGLIBDIR=\"$(pkgdatadir)\"
#bin_PROGRAMS = fgfs metar
#noinst_SCRIPTS = runfgfs.bat runfgfs
#noinst_LIBRARIES = libMain.a
## bin_SCRIPTS = runfgfs
#libMain_a_SOURCES = \
#	main.cxx main.hxx \
#	$(GFX_CODE)
#fgfs_SOURCES = bootstrap.cxx
#fgfs_LDADD = \
#	$(top_builddir)/src/Main/libMain.a \
#	$(JSBSIM_LIBS) \
#	$(SP_FDM_LIBS) \
#	$(MPLAYER_LIBS) \
#	-lsgroute -lsgsky -lsgsound -lsgephem -lsgmaterial -lsgtgdb -lsgmodel \
#	-lplibpuaux -lplibpu -lplibfnt -lplibjs -lplibnet \
#	$(OSG_LIBS) \
#	$(THREAD_LIBS) \
#	$(network_LIBS) \
#	-lz \
#	$(openal_LIBS)
#metar_SOURCES = metar_main.cxx
#metar_LDADD = \
#        -lsgenvironment -lsgio -lsgbucket -lsgmisc -lsgstructure -lsgdebug \
#        -lplibnet -lplibul $(network_LIBS) \
#        -lz $(base_LIBS)
#INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/src/FDM/JSBSim
# C:\FG\20\FlightGear\src\Network\Makefile.am 
# ************************************************************* 
#EXTRA_DIST = jpg-httpd.cxx jpg-httpd.hxx \
#             multiplay.cxx multiplay.hxx
#noinst_LIBRARIES = libNetwork.a
#if ENABLE_JPEG_SERVER
#JPEG_SERVER = jpg-httpd.cxx jpg-httpd.hxx
#else
#JPEG_SERVER =
#endif
#MPLAYER_AS = multiplay.cxx multiplay.hxx
#libNetwork_a_SOURCES = \
#	protocol.cxx protocol.hxx \
#       $(JPEG_SERVER) \
#	$(MPLAYER_AS) \
#	generic.hxx generic.cxx
# ====================================================================

# eof - fgamscan.pl

