#!perl -w
use strict;
use warnings;
use File::stat;
use File::Basename;
require 'fgutils.pl' or die "Unable to load fgutils.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";
open_log($outfile);

my @warnings = ();
my @tmp_hb = ();
my @tmp_pr = ();
my @tmp_tt = ();

# DEBUG
my $dbg_sd0 = 0;
my $dbg_sd1 = 0;
my $dbg_sd2 = 0;
my $dbg_sd3 = 0;
my $dbg_sd4 = 0;
my $dbg_sd5 = 0;    # show prt( "$lnnum: Defined [$itm1] = [$itm2] to v6defs hash ...
my $dbg_sd6 = 0;
my $dbg_sd7 = 0;
my $dbg_sd8 = 0;
my $dbg_sd9 = 0;
my $dbg_sd10 = 0;   # prt( "$lnnum: ELSIF [$itm1] == [$itm2]... (or $dbg_sd6)
my $dbg_sd11 = 0;   # show SPLIT if PROP - lots of stuff output!!!

my $max_show = 20;
my $show_hash = 0;

#my $dsp_in1 = 'tempscan.dsp';
my $dsp_in2 = 'test.dsp';

my (%h, %h2, %h3);

#show_file_stat($dsp_in1, 1);
###%h = scan_DSP($dsp_in1, $root);
#%h = scan_DSP($dsp_in1);
#%h2 = %h;
show_file_stat($dsp_in2, 1);
###%h = scan_DSP($dsp_in2, $root);
%h = scan_DSP($dsp_in2);
%h3 = %h;

if ($show_hash) {
    #prt( "\nContents of $dsp_in1 ...\n" );
    #show_hash(\%h2);
    prt( "\nContents of $dsp_in2 ...\n" );
    show_hash(\%h3);
}
prt("\n");

show_dsp_list();

show_warnings();

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

sub show_dsp_list {
    my $fil = 'tempdsp.txt';
    my ($line);
    if (open INF, "<$fil") {
        my @lines = <INF>;
        close INF;
        foreach $line (@lines) {
            chomp $line;
            scan_DSP($line);
        }
        my $cnt = scalar @tmp_tt;
        prt( "\nGot $cnt target types ...\n" );
        foreach $line (@tmp_tt) {
            prt( "$line\n" );
        }
    } else {
        prtw("WARNING: Can not open $fil ...\n" );
    }
}


sub show_hash {
    my ($hr) = shift;
    foreach my $sk (keys %{$hr}) {
        my $vl = $$hr{$sk};
        show_key_val($sk,$vl);
    }
}

sub show_key_val {
    my ($k,$v) = @_;
    my ($c,$j,$k2,@ks,$k3,$s,$mc);
    if ($k eq 'SOURCES') {
        $c = scalar @{$v};
        prt( "SOURCES has $c entries ...\n" );
        $mc = 0;
        for ($j = 0; $j < $c; $j++) {
            $k2 = $$v[$j][0];   # multidimensional array
            $mc++;
            prt( "$mc: [$k2]\n" );
            if ($max_show && ($mc > $max_show)) {
                prt( "$mc: Above $max_show count, aborting listing ...\n" );
                last;
            }
        }
    } else {
        @ks = sort keys(%{$v});   # keys are ...
        $c = scalar @ks;
        prt( "$k has $c entries ...\n" );
        $mc = 0;
        for ($j = 0; $j < $c; $j++) {
            $k3 = $ks[$j];
            $s = $$v{$k3};
            $mc++;
            prt( "$mc: [$k3] = [$s]\n" );
        }
    }
}

sub scan_DSP_array {
	my ($fil, @dsp_lines) = @_;
    my %dsphash = (
        "Intermediate_Dir" => "-NEW_INTER_"
    );
	my ($line, $prjname, $grpname, $filter, $ff, $src, $chr, $tmp, $conf, $ffnr);
	my ($itm1, $itm2, $key, $targtype, @av, $cnt, $item);
	my $scnt = 0;
    my %v6_hash = ();
    my %v6conf = ();
    my %v6defs = ();
    my @v6srcs = ();
    my @names = ();
    my $lncnt = 0;
    my $lncm = 2;
    my $lnnum = '';
    my @ss = ();
    my @sg = ();
    my @sg2 = ();
    my @sg3 = ();
	my ($d_name,$d_dir) = fileparse($fil);
	$d_dir = trim_all($d_dir);
    $lncnt = scalar @dsp_lines;
    prt( "Got $lncnt lines to process from $fil ...\n" );
    $lnnum = "$lncnt";
    $lncm = length($lnnum);
    my $ins = 0;
    my $inspl = 0;
    my $intrg = 0;
    my $ingrp = 0;
    my $platform = '';
    my $apptype = '';
    $lncnt = 0;
    foreach $line (@dsp_lines) {
        $lncnt++;
        $line = trim_all($line);
        next if (length($line) == 0);
        $lnnum = "$lncnt";
        $lnnum = ' '.$lnnum while (length($lnnum) < $lncm);
        $chr = substr($line, 0, 1);	# get FIRST char of LINE
        @av = space_split($line);
        $cnt = scalar @av;
        $item = $av[0];
        push(@sg, $item) if !is_in_array($item,@sg);
        if ( ($cnt > 1) && ($item ne '!MESSAGE') ) {
            $item = $av[1];
            push(@sg2, $item) if !is_in_array($item,@sg2);
            if ($cnt > 2) {
                $item = $av[2];
                push(@sg3, $item) if !is_in_array($item,@sg3);
            }
        }
        if ($dbg_sd11) {
            prt( "$lnnum: [$line] split to $cnt pieces ...\n" );
            foreach $tmp (@av) {
                prt( "$tmp\n" );
            }
        }
        scan_DSP_line($fil,$line);
        if( $chr eq '#' ) {
            # line begins with SHARP
            if ($line =~ /\s+Microsoft Developer Studio Project File - Name=\"([\.\w\s-]+)+/) {
                $prjname = $1;
                prt( "Project NAME = $prjname ...\n" ) if ($dbg_sd0);
            } elsif ($line =~ /\s+Microsoft Developer Studio Generated Build File, Format Version ([\d\.]+)/) {
                prt( "MSVC Version $1 ...\n" ) if ($dbg_sd0);
            } elsif ($line =~ /\s*TARGTYPE\s+\"(.+)\"\s+/) { # Win32 (x86) Console Application" 0x0103
                $targtype = $1;
                push(@tmp_tt,$targtype) if !is_in_array($targtype,@tmp_tt);
                #($platform,$apptype) = parse_targtype($line);
                prt( "TARGTYPE: [$targtype], name=[$prjname]\n" );
            } elsif ($line =~ /Begin Group \"([\s\w]+)+/ ) {
                $grpname = $1;
                $ingrp = 1;
                prt( "Begin group ... $grpname\n" ) if ($dbg_sd0);
            } elsif ($line =~ /\s+Name\s+"(.+)"/) {
                push(@names, $1);
            } elsif ($line =~ /Begin Source File/) {
                $ins = 1;
                prt( "Begin source ... $ins ...\n" ) if ($dbg_sd0);
            } elsif ($line =~ /End Source File/) {
                $ins = 0;
                prt( "End source ... $ins ...\n" ) if ($dbg_sd0);
            } elsif ( $line =~ /\*\*\s+(.+)\s+\*\*/ ) {
            # } elsif ( $line =~ /DO\s+NOT\s+EDIT\s+/ ) { # but this does NOT include say the GERMAN 'NICHT BEARBEITEN'
                # skip this line
            } elsif ( $line =~ /Begin\s+Project/ ) {
                # skip this line
            } elsif ( $line =~ /End\s+Project/ ) {
                # skip this line
            } elsif ( $line =~ /\s+PROP\s+/ ) {
                if ($line =~ /PROP\s+Default_Filter\s+\"([\w;]+)+\"/ ) {
                    $filter = $1;
                    prt( "Begin Filter group $grpname, filter $filter\n" ) if ($dbg_sd8);
                } elsif ($line =~ /\s+PROP\s+BASE\s+(.+)$/) {
                    # PROP BASE Use_MFC 0]
                    # PROP BASE Use_Debug_Libraries 0]
                    # PROP BASE Output_Dir "Release"]
                    # PROP BASE Intermediate_Dir "Release"]
                    # PROP BASE Target_Dir ""]
                } else {
                    # PROP AllowPerConfigDependencies 0]
                    # PROP Scc_ProjName ""]
                    # PROP Scc_LocalPath ""]
                    # PROP Use_MFC 0]
                    # PROP Use_Debug_Libraries 0]
                    # PROP Output_Dir "Release"]
                    # PROP Intermediate_Dir "Release"]
                    # PROP Ignore_Export_Lib 0]
                    # PROP Target_Dir ""]
                }
            } elsif ( $line =~ /\s+SUBTRACT\s+/ ) {
                # SUBTRACT CPP /YX]
                # SUBTRACT LINK32 /nodefaultlib]
            } elsif ( $line =~ /\s+ADD\s+/ ) {
                # ADD BASE RSC /l 0x40c /d "NDEBUG"]
                # ADD RSC /l 0x40c /d "NDEBUG"]
                # ADD BASE BSC32 /nologo]
                # ADD BSC32 /nologo]
                if ( $line =~ /ADD CPP (.+)$/ )  {
                    $item = $1;
                    # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
                    $key = 'CPP '.$conf;
                    prt( "ADD $key [$1]\n" ) if ($dbg_sd4);
                    $v6conf{$key} = $item;
                } elsif ( $line =~ /ADD BASE LINK32 (.+)$/ )  {
                    $item = $1;
                    # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
                    $key = 'LINK '.$conf;
                    prt( "ADD BASE $key [$item]\n" ) if ($dbg_sd4);
                    $v6conf{$key} = $item;
                } elsif ( $line =~ /ADD LINK32 (.+)$/ )  {
                    $item = $1;
                    $key = 'LINK '.$conf;
                    # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
                    prt( "ADD $key [$item]\n" ) if ($dbg_sd4);
                    $v6conf{$key} = $item;
                } elsif ( $line =~ /ADD BASE CPP (.+)$/ )  {
                    $item = $1;
                    # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
                    $key = 'CPP '.$conf;
                    prt( "ADD BASE $key [$item]\n" ) if ($dbg_sd4);
                    $v6conf{$key} = $item;
                }
            } elsif ( $line =~ /\s+Begin\s+Special\s+Build\s+Tool/ ) {
                $inspl = 1;
            } elsif ( $line =~ /\s+End\s+Special\s+Build\s+Tool/ ) {
                $inspl = 0;
            } elsif ( $line =~ /\s+Begin\s+Target/ ) {
                $intrg = 1;
            } elsif ( $line =~ /\s+End\s+Target/ ) {
                $intrg = 0;
            } elsif ( $line =~ /\s+End\s+Group/ ) {
                $ingrp = 0;
            } else {
                prtw( "$lnnum:$fil: *** NOT PARSED *** [$line]\n" );
            }
        } elsif ( $chr eq '!' ) {
            # !IF "CFG" == "something"
            if ($line =~ /^!IF\s+(.+)/i ) {
                prt( "Entering IF $1 ...\n" ) if ($dbg_sd6);
                if ($line =~ /!IF\s+(.+) == (.+)/i) {
                    $itm1 = $1;
                    $itm2 = $2;
                    $itm1 =~ s/\"//g;
                    $itm2 =~ s/\"//g;
                    prt( "$lnnum: !IF     [$itm1] == [$itm2]...\n" ) if ($dbg_sd6 || $dbg_sd10);
                    if ($itm1 =~ /^\$\((.+)\)/ ) {
                        $item = $1;
                        if (defined $v6defs{$item}) {
                            if ($v6defs{$item} eq $itm2) {
                                $tmp = "TRUE";
                            } else {
                                $tmp = "FALSE";
                            }
                            if( $1 eq 'CFG' ) {
                                $conf = $itm2;
                            }
                            prt( "and [$item] defined as [".$v6defs{$item}."] ... now $tmp, CFG now [$conf]\n" ) if ($dbg_sd6 || $dbg_sd10);
                        } else {
                            prtw( "$lnnum: WARNING: NOT DEFINED [$item] ...[$line]!\n" );
                        }
                    }
                } else {
                    prtw( "$lnnum: FAILED IF == [$line]\n" );
                }
            } elsif ( $line =~ /^!ELSE\s+/i ) {
                prt( "Entering ELSE ...\n" ) if ($dbg_sd6);
            } elsif ( $line =~ /^!ELSEIF\s+(.+)/i ) {
                prt( "Entering ELSEIF $1 ...\n" ) if ($dbg_sd6);
                if ($line =~ /!ELSEIF\s+(.+) == (.+)/i) {
                    $itm1 = $1;
                    $itm2 = $2;
                    $itm1 =~ s/\"//g;
                    $itm2 =~ s/\"//g;
                    prt( "$lnnum: !ELSIF  [$itm1] == [$itm2]...\n" ) if ($dbg_sd6 || $dbg_sd10);
                    if ($itm1 =~ /^\$\((.+)\)/ ) {
                        $item = $1;
                        if (defined $v6defs{$item}) {
                            if ($v6defs{$item} eq $itm2) {
                                $tmp = "TRUE";
                            } else {
                                $tmp = "FALSE";
                            }
                            if( $item eq 'CFG' ) {
                                $conf = $itm2;
                            }
                            prt( "and [$item] defined as [".$v6defs{$item}."] ... to $tmp NOW [$conf]\n" ) if ($dbg_sd6 || $dbg_sd10);
                        } else {
                            prtw( "$lnnum: WARNING: NOT DEFINED [$item] ...[$line]\n" );
                        }
                    }
                } else {
                    prtw( "$lnnum: FAILED ELSEIF == [$line]\n" );
                }
            } elsif ( $line =~ /^!ENDIF\s*/i ) {
                prt( "$lnnum: !ENDIF ...\n" ) if ($dbg_sd6 || $dbg_sd10);
            } elsif ( $line =~ /^!MESSAGE\s*/ ) {
                # skip these MESSAGES ONLY
            } else {
                prtw( "$lnnum: !ITEM NOT USED [$line]\n" );
            }
        } else {
            # SOURCE=.\test.c, or
            # SOURCE=src\FDM\YASim\YASim.hxx OR
            # SOURCE=".\common with space\file with space.c"
            ### if ($line =~ /SOURCE=([\.\\\w-:]+)+/ ) {
            ###	$src = $1;
            if ($line =~ /^SOURCE=/ ) {
                $src = strip_quotes(substr($line,7));
                $ff = $d_dir.$src;
                $ffnr = fix_rel_path($ff);
                ###prt( "fixed=$ffnr, src=[$src], dir=[$dir]\n" );
                if ($ins) {
                    prt( "SOURCE = $src ($ff)... $ins \n" ) if ($dbg_sd0);
                    if (is_c_source($src)) {
                        prt("SOURCE=[$src]\n") if ($dbg_sd1);
                    } elsif (is_h_source($src)) {
                        prt("HEADER=[$src]\n") if ($dbg_sd2);
                    } elsif (is_h_special($src)) {
                        prt("HEADER=[$src]\n") if ($dbg_sd2);
                    } else {
                        prt("OTHER=[$src]\n") if ($dbg_sd3);
                    }
                    #                0     1      2          3          4  5  6
                    #push(@v6srcs, [$src, $ffnr, $filtname, $filttype, 0, 0, $projname] );
                    push(@v6srcs, [$src, $ffnr, $grpname, $filter, 0, 0, $prjname] );
                    $scnt++;
                    prt( "$scnt v6srcs: $src, $ffnr, $grpname, $filter, 0, 0, $prjname\n" ) if ($dbg_sd9);
                } else {
                    if ($inspl) {
                        # ignore SOURCE line in SPECIAL
                    } else {
                        prtw( "$lnnum: WARNING: SOURCE = $src OUTSIDE 'in source' or 'special' ... CHECK ME\n" );
                    }
                }
            } elsif ( $line =~ /(.*)=(.*)/ ) {
                $itm1 = $1;
                $itm2 = $2;
                $v6defs{$itm1} = $itm2;
                prt( "$lnnum: Defined [$itm1] = [$itm2] to v6defs hash ...\n" ) if ($dbg_sd5);
            } else {
                prtw( "$lnnum: WARNING: SKIPPED [$line]\n" );
            }
        }
    }
    prt( "End DSP - got $scnt source files ...\n" );
    if ($dbg_sd11) {
        $cnt = scalar @sg;
        prt( "Got $cnt first level items ...\n" );
        foreach $item (@sg) {
            prt("$item\n");
        }
        $cnt = scalar @sg2;
        prt( "Got $cnt second level items (sans !MESSAGE)...\n" );
        foreach $item (@sg2) {
            prt("$item\n");
        }
        $cnt = scalar @sg3;
        prt( "Got $cnt third level items ...(sans !MESSAGE)\n" );
        foreach $item (@sg3) {
            prt("$item\n");
        }
        $cnt = scalar @tmp_hb;
        prt( "Got $cnt 2nd level items after HASH begin\n" );
        foreach $item (@tmp_hb) {
            prt("$item\n");
        }
        $cnt = scalar @tmp_pr;
        prt( "Got $cnt 3rd level items after HASH begin and PROP\n" );
        foreach $item (@tmp_pr) {
            prt("$item\n");
        }
    }
    if ($dbg_sd7) {
        foreach $key (keys %v6conf) {
            prt( "Config $key = [$v6conf{$key}]\n" );
        }
    }
    $v6_hash{'CONFIG'}  = \%v6conf;
    $v6_hash{"DEFINES"} = \%v6defs;
    $v6_hash{'SOURCES'} = [@v6srcs];    # copy the ARRAY (reference)
    return %v6_hash;
}

sub scan_DSP {
	my ($fil) = @_;
	my @dsp_lines = ();
    my %v6_hash = ();
	prt( "Process DSP file $fil ...\n" );
	if ( -f $fil ) {
		if ( open IF, "<$fil" ) {
			@dsp_lines = <IF>;
			close IF;
            %v6_hash = scan_DSP_array($fil, @dsp_lines);
		} else {
			prtw( "WARNING: FAILED TO OPEN $fil FILE!\n" );
		}
	} else {
		prtw( "WARNING: $fil *** DOES NOT EXIST ***\n" );
	}
    return %v6_hash;
}

sub scan_DSP_OLD_good {
	my ($fil) = @_;
    my %dsphash = (
        "Intermediate_Dir" => "-NEW_INTER_"
    );
	my ($line, $prjname, $grpname, $filter, $ff, $src, $chr, $tmp, $conf, $ffnr);
	my ($itm1, $itm2, $key, $targtype, @av, $cnt, $item);
	my $scnt = 0;
	my @dsp_lines = ();
    my %v6_hash = ();
    my %v6conf = ();
    my %v6defs = ();
    my @v6srcs = ();
    my @names = ();
    my $lncnt = 0;
    my $lncm = 2;
    my $lnnum = '';
	prt( "Process DSP file $fil ...\n" );
	if ( -f $fil ) {
		###prt( "already exists ...\n" );
		my ($d_name,$d_dir) = fileparse($fil);
		$d_dir = trim_all($d_dir);
		###$d_dir = $rd if ((length($d_dir) == 0)||($d_dir eq ".\\"));
		if ( open IF, "<$fil" ) {
			@dsp_lines = <IF>;
			close IF;
            $lncnt = scalar @dsp_lines;
			prt( "Got $lncnt lines to process ...\n" );
            $lnnum = "$lncnt";
            $lncm = length($lnnum);
			my $ins = 0;
            my $inspl = 0;
            my $intrg = 0;
            my $ingrp = 0;
            $lncnt = 0;
			foreach $line (@dsp_lines) {
                $lncnt++;
				$line = trim_all($line);
				next if (length($line) == 0);
                $lnnum = "$lncnt";
                $lnnum = ' '.$lnnum while (length($lnnum) < $lncm);
				$chr = substr($line, 0, 1);	# get FIRST char of LINE
				if( $chr eq '#' ) {
					# line begins with SHARP
					if ($line =~ /\s+Microsoft Developer Studio Project File - Name=\"([\.\w\s-]+)+/) {
						$prjname = $1;
						prt( "Project NAME = $prjname ...\n" ) if ($dbg_sd0);
					} elsif ($line =~ /\s+Microsoft Developer Studio Generated Build File, Format Version ([\d\.]+)/) {
						prt( "MSVC Version $1 ...\n" ) if ($dbg_sd0);
					} elsif ($line =~ /\s*TARGTYPE\s+\"(.+)\"\s+/) { # Win32 (x86) Console Application" 0x0103
						$targtype = $1;
						prt( "TARGTYPE: [$targtype], name=[$prjname]\n" );
					} elsif ($line =~ /Begin Group \"([\s\w]+)+/ ) {
						$grpname = $1;
                        $ingrp = 1;
						prt( "Begin group ... $grpname\n" ) if ($dbg_sd0);
                    } elsif ($line =~ /\s+Name\s+"(.+)"/) {
                        push(@names, $1);
					} elsif ($line =~ /Begin Source File/) {
						$ins = 1;
						prt( "Begin source ... $ins ...\n" ) if ($dbg_sd0);
					} elsif ($line =~ /End Source File/) {
						$ins = 0;
						prt( "End source ... $ins ...\n" ) if ($dbg_sd0);
                    } elsif ( $line =~ /DO\s+NOT\s+EDIT\s+/ ) {
                        # skip this line
                    } elsif ( $line =~ /Begin\s+Project/ ) {
                        # skip this line
                    } elsif ( $line =~ /End\s+Project/ ) {
                        # skip this line
                    } elsif ( $line =~ /\s+PROP\s+/ ) {
                        @av = space_split($line);
                        $cnt = scalar @av;
                        if ($dbg_sd11) {
                            prt( "$lnnum: [$line] split to $cnt pieces ...\n" );
                            foreach $tmp (@av) {
                                prt( "$tmp\n" );
                            }
                        }
                        if ($line =~ /PROP\s+Default_Filter\s+\"([\w;]+)+\"/ ) {
						    $filter = $1;
						    prt( "Begin Filter group $grpname, filter $filter\n" ) if ($dbg_sd8);
                        } elsif ($line =~ /\s+PROP\s+BASE\s+(.+)$/) {
                            # PROP BASE Use_MFC 0]
                            # PROP BASE Use_Debug_Libraries 0]
                            # PROP BASE Output_Dir "Release"]
                            # PROP BASE Intermediate_Dir "Release"]
                            # PROP BASE Target_Dir ""]
                        } else {
                            # PROP AllowPerConfigDependencies 0]
                            # PROP Scc_ProjName ""]
                            # PROP Scc_LocalPath ""]
                            # PROP Use_MFC 0]
                            # PROP Use_Debug_Libraries 0]
                            # PROP Output_Dir "Release"]
                            # PROP Intermediate_Dir "Release"]
                            # PROP Ignore_Export_Lib 0]
                            # PROP Target_Dir ""]
                        }
                    } elsif ( $line =~ /\s+SUBTRACT\s+/ ) {
                        # SUBTRACT CPP /YX]
                        # SUBTRACT LINK32 /nodefaultlib]
                    } elsif ( $line =~ /\s+ADD\s+/ ) {
                        # ADD BASE RSC /l 0x40c /d "NDEBUG"]
                        # ADD RSC /l 0x40c /d "NDEBUG"]
                        # ADD BASE BSC32 /nologo]
                        # ADD BSC32 /nologo]
                        if ( $line =~ /ADD CPP (.+)$/ )  {
                            $item = $1;
                            # ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
                            $key = 'CPP '.$conf;
                            prt( "ADD $key [$1]\n" ) if ($dbg_sd4);
                            $v6conf{$key} = $item;
                        } elsif ( $line =~ /ADD BASE LINK32 (.+)$/ )  {
                            $item = $1;
                            # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
                            $key = 'LINK '.$conf;
                            prt( "ADD BASE $key [$item]\n" ) if ($dbg_sd4);
                            $v6conf{$key} = $item;
                        } elsif ( $line =~ /ADD LINK32 (.+)$/ )  {
                            $item = $1;
                            $key = 'LINK '.$conf;
                            # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
                            prt( "ADD $key [$item]\n" ) if ($dbg_sd4);
                            $v6conf{$key} = $item;
                        } elsif ( $line =~ /ADD BASE CPP (.+)$/ )  {
                            $item = $1;
                            # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Yu"stdafx.h" /FD /c
                            $key = 'CPP '.$conf;
                            prt( "ADD BASE $key [$item]\n" ) if ($dbg_sd4);
                            $v6conf{$key} = $item;
                        }
                    } elsif ( $line =~ /\s+Begin\s+Special\s+Build\s+Tool/ ) {
                        $inspl = 1;
                    } elsif ( $line =~ /\s+End\s+Special\s+Build\s+Tool/ ) {
                        $inspl = 0;
                    } elsif ( $line =~ /\s+Begin\s+Target/ ) {
                        $intrg = 1;
                    } elsif ( $line =~ /\s+End\s+Target/ ) {
                        $intrg = 0;
                    } elsif ( $line =~ /\s+End\s+Group/ ) {
                        $ingrp = 0;
					} else {
                        prt( "$lnnum: NOT PARSED: [$line]\n" );
                    }
				} elsif ( $chr eq '!' ) {
                    # !IF "CFG" == "something"
					if ($line =~ /^!IF\s+(.+)/i ) {
						prt( "Entering IF $1 ...\n" ) if ($dbg_sd6);
						if ($line =~ /!IF\s+(.+) == (.+)/i) {
							$itm1 = $1;
							$itm2 = $2;
							$itm1 =~ s/\"//g;
							$itm2 =~ s/\"//g;
							prt( "$lnnum: !IF     [$itm1] == [$itm2]...\n" ) if ($dbg_sd6 || $dbg_sd10);
							if ($itm1 =~ /^\$\((.+)\)/ ) {
                                $item = $1;
								if (defined $v6defs{$item}) {
									if ($v6defs{$item} eq $itm2) {
										$tmp = "TRUE";
									} else {
										$tmp = "FALSE";
									}
									if( $1 eq 'CFG' ) {
										$conf = $itm2;
									}
									prt( "and [$item] defined as [".$v6defs{$item}."] ... now $tmp, CFG now [$conf]\n" ) if ($dbg_sd6 || $dbg_sd10);
								} else {
									prtw( "$lnnum: WARNING: NOT DEFINED [$item] ...[$line]!\n" );
								}
							}
						} else {
							prtw( "$lnnum: FAILED IF == [$line]\n" );
						}
					} elsif ( $line =~ /^!ELSE\s+/i ) {
						prt( "Entering ELSE ...\n" ) if ($dbg_sd6);
					} elsif ( $line =~ /^!ELSEIF\s+(.+)/i ) {
						prt( "Entering ELSEIF $1 ...\n" ) if ($dbg_sd6);
						if ($line =~ /!ELSEIF\s+(.+) == (.+)/i) {
							$itm1 = $1;
							$itm2 = $2;
							$itm1 =~ s/\"//g;
							$itm2 =~ s/\"//g;
							prt( "$lnnum: !ELSIF  [$itm1] == [$itm2]...\n" ) if ($dbg_sd6 || $dbg_sd10);
							if ($itm1 =~ /^\$\((.+)\)/ ) {
                                $item = $1;
								if (defined $v6defs{$item}) {
									if ($v6defs{$item} eq $itm2) {
										$tmp = "TRUE";
									} else {
										$tmp = "FALSE";
									}
									if( $item eq 'CFG' ) {
										$conf = $itm2;
									}
									prt( "and [$item] defined as [".$v6defs{$item}."] ... to $tmp NOW [$conf]\n" ) if ($dbg_sd6 || $dbg_sd10);
								} else {
									prtw( "$lnnum: WARNING: NOT DEFINED [$item] ...[$line]\n" );
								}
							}
						} else {
							prtw( "$lnnum: FAILED ELSEIF == [$line]\n" );
						}
					} elsif ( $line =~ /^!ENDIF\s*/i ) {
						prt( "$lnnum: !ENDIF ...\n" ) if ($dbg_sd6 || $dbg_sd10);
                    } elsif ( $line =~ /^!MESSAGE\s*/ ) {
                        # skip these MESSAGES ONLY
					} else {
                        prtw( "$lnnum: !ITEM NOT USED [$line]\n" );
                    }
				} else {
                    # SOURCE=.\test.c, or
                    # SOURCE=src\FDM\YASim\YASim.hxx OR
                    # SOURCE=".\common with space\file with space.c"
					### if ($line =~ /SOURCE=([\.\\\w-:]+)+/ ) {
					###	$src = $1;
					if ($line =~ /^SOURCE=/ ) {
						$src = strip_quotes(substr($line,7));
						$ff = $d_dir.$src;
						$ffnr = fix_rel_path($ff);
						###prt( "fixed=$ffnr, src=[$src], dir=[$dir]\n" );
						if ($ins) {
							prt( "SOURCE = $src ($ff)... $ins \n" ) if ($dbg_sd0);
                            if (is_c_source($src)) {
                                prt("SOURCE=[$src]\n") if ($dbg_sd1);
                            } elsif (is_h_source($src)) {
                                prt("HEADER=[$src]\n") if ($dbg_sd2);
                            } elsif (is_h_special($src)) {
                                prt("HEADER=[$src]\n") if ($dbg_sd2);
                            } else {
                                prt("OTHER=[$src]\n") if ($dbg_sd3);
                            }
                            #                0     1      2          3          4  5  6
                            #push(@v6srcs, [$src, $ffnr, $filtname, $filttype, 0, 0, $projname] );
                            push(@v6srcs, [$src, $ffnr, $grpname, $filter, 0, 0, $prjname] );
                            $scnt++;
                            prt( "$scnt v6srcs: $src, $ffnr, $grpname, $filter, 0, 0, $prjname\n" ) if ($dbg_sd9);
						} else {
                            if ($inspl) {
                                # ignore SOURCE line in SPECIAL
                            } else {
                                prtw( "$lnnum: WARNING: SOURCE = $src OUTSIDE 'in source' or 'special' ... CHECK ME\n" );
                            }
						}
					} elsif ( $line =~ /(.*)=(.*)/ ) {
						$itm1 = $1;
						$itm2 = $2;
						$v6defs{$itm1} = $itm2;
						prt( "$lnnum: Defined [$itm1] = [$itm2] to v6defs hash ...\n" ) if ($dbg_sd5);
					} else {
						prtw( "$lnnum: WARNING: SKIPPED [$line]\n" );
					}
				}
			}

			prt( "End DSP - got $scnt source files ...\n" );
			if ($dbg_sd7) {
				foreach $key (keys %v6conf) {
					prt( "Config $key = [$v6conf{$key}]\n" );
				}
			}
		} else {
			prtw( "WARNING: FAILED TO OPEN $fil FILE!\n" );
		}
	} else {
		prtw( "WARNING: $fil *** DOES NOT EXIST ***\n" );
	}
    $v6_hash{'CONFIG'}  = \%v6conf;
    $v6_hash{"DEFINES"} = \%v6defs;
    $v6_hash{'SOURCES'} = [@v6srcs];    # copy the ARRAY (reference)
    return %v6_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");
    }
}

sub scan_DSP_line {
    my ($fil, $line) = @_;
    my ($item,$ind,$max,$itm1,$itm2,@av);
    @av = space_split($line);
    $max = scalar @av;
    $ind = 0;
    if (@av) {
        if ($max) {
            $item = $av[$ind];
            #Got 23 first level items ...
            if ($item eq '#') {
                if ($max > 1) {
                    $itm1 = $av[1];
                    push(@tmp_hb,$itm1) if !is_in_array($itm1,@tmp_hb);
                    # Got 9 2nd level items after HASH begin
                    if ($itm1 eq 'Microsoft') {
                    } elsif ($itm1 eq '**') {
                    } elsif ($itm1 eq 'TARGTYPE') {
                    } elsif ($itm1 eq 'Begin') {
                    } elsif ($itm1 eq 'PROP') {
                        if ($max > 2) {
                            $itm2 = $av[2];
                            push(@tmp_pr,$itm2) if !is_in_array($itm2,@tmp_pr);
                            # Got 12 3rd level items after HASH begin and PROP
                            if ($itm2 eq 'AllowPerConfigDependencies') {
                            } elsif ($itm2 eq 'Scc_ProjName') {
                            } elsif ($itm2 eq 'Scc_LocalPath') {
                            } elsif ($itm2 eq 'BASE') {
                            } elsif ($itm2 eq 'Use_MFC') {
                            } elsif ($itm2 eq 'Use_Debug_Libraries') {
                            } elsif ($itm2 eq 'Output_Dir') {
                            } elsif ($itm2 eq 'Intermediate_Dir') {
                            } elsif ($itm2 eq 'Ignore_Export_Lib') {
                            } elsif ($itm2 eq 'Target_Dir') {
                            } elsif ($itm2 eq 'Default_Filter') {
                            } elsif ($itm2 eq 'Exclude_From_Build') {
                            } else {
                                prtw( "WARNING: UNUSED 3rd after '# PROP'??? [$line]\n" );
                            }
                        } else {
                            prtw( "WARNING: WHAT IS THIS??? [$line]\n" );
                        }
                    } elsif ($itm1 eq 'ADD') {
                    } elsif ($itm1 eq 'SUBTRACT') {
                    } elsif ($itm1 eq 'End') {
                    } elsif ($itm1 eq 'Name') {
                    } else {
                        prtw( "WARNING: UNPROCESS 2ND LEVEL??? [$line]\n" );
                    }
                } else {
                    prtw( "WARNING: WHAT IS THIS??? [$line]\n" );
                }
            } elsif ($item eq '!MESSAGE') {
                # skip all these
            } elsif ($item eq '!IF') {
            } elsif ($item eq '!ELSE') {
            } elsif ($item eq '!ELSEIF') {
            } elsif ($item eq '!ENDIF') {
            } elsif ($item =~ /(.+)=(.+)$/) {
                $itm1 = $1;
                $itm2 = $2;
            } else {
                prtw( "WARNING: UNCASED LINE [$line]\n" );
            }
        }
    }
}

# eof - fgdspscan.pl
