# NAME: vcfix.pl
# AIM: VERY SPECIFIC - Given a VCPROJ file, and a configuration name
# fix that configuration... as specifically shown below
# 29/05/2010 geoff mclane http://geoffair.net/mperl
use strict;
use warnings;
use File::Basename;  # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[.]*/] )
use Cwd;
unshift(@INC, 'C:\GTools\perl');
require 'logfile.pl' or die "Unable to load logfile.pl ...\n";
# log file stuff
my ($LF);
my $pgmname = $0;
if ($pgmname =~ /\w{1}:\\.*/) {
    my @tmpsp = split(/\\/,$pgmname);
    $pgmname = $tmpsp[-1];
}
my $perl_dir = 'C:\GTools\perl';
my $outfile = $perl_dir."\\temp.$pgmname.txt";
open_log($outfile);

# user variables
my $debug_mode = 0;
#my $def_file = 'C:\Projects\fltk-1.3\ide\vc2005\arc.vcproj';
#my $def_file = 'C:\Projects\fltk-1.3\ide\vc2005\table.vcproj';
#my $def_file = 'C:\Projects\fltk-1.3\ide\vc2005\adjuster.vcproj';
#my $def_file = 'C:\Projects\fltk-1.3\ide\vc2005\ask.vcproj';
my $def_file = 'C:\Projects\fltk-1.3\ide\vc2005\cairo_test.vcproj';

my $config = 'Debug-mt|Win32';
my $config2 = 'Release-mt|Win32';
my $load_log = 0;
my $in_file = '';
my $show_source = 0;
my $use_blank_pch = 1;  # just BLANK the pch file
my $add_typelib_fix = 0;

my $key_nam = 'Name';
my $key_tag = '* TAG *';
my $key_clo = '* CLOSED *';
my $key_end = '* ENDTAG *';
my $key_hdr = '* HEADER *';
my $key_com = '* COMMENT *';

### special fixes
# 				Name="VCBscMakeTool" -> remove 'OutputFile'
#----------arc.vcproj
#	RootNamespace="arc"
#	>
#	<Platforms>
#----------tempa.vcproj
#	>
#	<Platforms>
#-----------------------------------------------
#----------arc.vcproj
##			OutputDirectory="$(ConfigurationName)\$(ProjectName)"
##			IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
#			ConfigurationType="1"
#----------tempa.vcproj
##			OutputDirectory="$(ConfigurationName)"
##			IntermediateDirectory="$(ConfigurationName)"
#			ConfigurationType="1"
#----------arc.vcproj
#				RuntimeLibrary="0"
#				UsePrecompiledHeader="0"
#				PrecompiledHeaderFile=""
#				AssemblerListingLocation=".\Release-mt\$(ProjectName)/"
#				ObjectFile=".\Release-mt\$(ProjectName)/"
#				ProgramDataBaseFileName=".\Release-mt\$(ProjectName)/"
#				SuppressStartupBanner="true"
#----------tempa.vcproj
#				RuntimeLibrary="2"
#				UsePrecompiledHeader="0"
#				PrecompiledHeaderFile=".\Release/arc.pch"
#				AssemblerListingLocation=".\Release/"
#				ObjectFile=".\Release/"
#				ProgramDataBaseFileName=".\Release/"
#				SuppressStartupBanner="true"
#-----------------------------------------------
#----------arc.vcproj
#				AdditionalDependencies="fltk-mt.lib comctl32.lib"
#				OutputFile="../../test/arc-mt.exe"
#				LinkIncremental="1"
#----------tempa.vcproj
#				AdditionalDependencies="fltk.lib comctl32.lib"
#				OutputFile="../../test/arc.exe"
#				LinkIncremental="1"
#-----------------------------------------------
#----------arc.vcproj
#				IgnoreDefaultLibraryNames=""
#				ProgramDatabaseFile=".\Release-mt\$(ProjectName)/arc.pdb"
#				SubSystem="2"
#----------tempa.vcproj
#				IgnoreDefaultLibraryNames="libcd"
#				ProgramDatabaseFile=".\Release/arc.pdb"
#				SubSystem="2"
#----------fltkgl.vcproj
#                                OutputFile="..\..\lib\fltkgl-mt.lib"
#                                SuppressStartupBanner="true"
#----------tempgl.vcproj
#                                OutputFile="..\..\lib\fltkgl.lib"
#                                SuppressStartupBanner="true"
# ============================================================================
# previous
# <Configuration Name="Debug-mt|Win32" OutputDirectory="$(ConfigurationName)" IntermediateDirectory="$(ConfigurationName)" ConfigurationType="1" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" >
# <Tool Name="VCLinkerTool" 
# AdditionalDependencies="fltkd.lib comctl32.lib" -> fltkd-mt.lib
# OutputFile="../../test/tabled.exe" -> tabled-mt.exe
# LinkIncremental="1" SuppressStartupBanner="true" AdditionalLibraryDirectories="..\..\lib" IgnoreDefaultLibraryNames="libcd" GenerateDebugInformation="true" 
# ProgramDatabaseFile=".\table_/tabled.pdb" -> table_mt/tabled-mt.pdb 
# SubSystem="2" TargetMachine="1" />

#C:\Projects\fltk-1.3\ide\vc2005>fc4 threads.vcproj old\threads.vcproj
#----------threads.vcproj
#                                RuntimeLibrary="1"
#                                UsePrecompiledHeader="0"
#                                PrecompiledHeaderFile=""
#                                AssemblerListingLocation=".\threads_mt/"
#                                ObjectFile=".\threads_mt/"
#                                ProgramDataBaseFileName=".\threads_mt/"
#                                SuppressStartupBanner="true"
#----------old\threads.vcproj
#                                RuntimeLibrary="3"
#                                UsePrecompiledHeader="0"
#                                PrecompiledHeaderFile=".\threads_/threads.pch"
#                                AssemblerListingLocation=".\threads_/"
#                                ObjectFile=".\threads_/"
#                                ProgramDataBaseFileName=".\threads_/"
#                                SuppressStartupBanner="true"
#-----------------------------------------------
#----------threads.vcproj
#                                AdditionalDependencies="fltkd-mt.lib comctl32.lib"
#                                OutputFile="../../test/threadsd-mt.exe"
#                                LinkIncremental="1"
#----------old\threads.vcproj
#                                AdditionalDependencies="fltkd.lib comctl32.lib"
#                                OutputFile="../../test/threadsd.exe"
#                                LinkIncremental="1"
#-----------------------------------------------
#----------threads.vcproj
#                                ProgramDatabaseFile=".\threads_mt/threadsd-mt.pdb"
#                                SubSystem="2"
#----------old\threads.vcproj
#                                ProgramDatabaseFile=".\threads_/threadsd.pdb"
#                                SubSystem="2"
#-----------------------------------------------
#----------threads.vcproj
#                                RuntimeLibrary="1"
#                                UsePrecompiledHeader="0"
#----------old\threads.vcproj
#                                RuntimeLibrary="3"
#                                UsePrecompiledHeader="0"
#-----------------------------------------------
#End - Files are different!

my $chk_tag1 = 'Configuration';
my $chk_itm1 = 'IntermediateDirectory';
my $chk_def1 = '"$(ConfigurationName)"';
my $chk_itm2 = 'OutputDirectory';
my $chk_def2 = $chk_def1;

my $chk_tag2 = 'VCCLCompilerTool';
my $chk_t2i1 = 'ProgramDataBaseFileName';   #      = [".\table_/"]
# PreprocessorDefinitions      = ["_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN"]
# AdditionalIncludeDirectories = [".;..\..\zlib;..\..\png;..\..\jpeg;../.."]
my $chk_t2i2 = 'ObjectFile';    #  = [".\table_/"]
my $chk_t2i3 = 'AssemblerListingLocation'; # = [".\table_/"]
my $chk_t2i4 = 'PrecompiledHeaderFile'; # = [".\table_/table.pch"]
# DebugInformationFormat       = ["3"]
# SuppressStartupBanner        = ["true"]
my $chk_t2i5 = 'RuntimeLibrary'; # = ["3"]
my $chk_t2i5d = '"1"';

my $chk_tag3 = 'VCMIDLTool';  #  * TAG *                 = [Tool]  * CLOSED *              = [1]
# Name                    = ["VCMIDLTool"]
# TargetEnvironment       = ["1"]
my $chk_t3i1 = 'TypeLibraryName';   # = [".\table_/table.tlb"]
# MkTypLibCompatible      = ["true"]
# PreprocessorDefinitions = ["_DEBUG"]
# HeaderFileName          = [""]
# SuppressStartupBanner   = ["true"]

#59: NEEDS FIX? [<Tool Name="VCLinkerTool" AdditionalDependencies="fltkd.lib comctl32.lib" OutputFile="../../test/tabled.exe" LinkIncremental="1" SuppressStartupBanner="true" AdditionalLibraryDirectories="..\..\lib" IgnoreDefaultLibraryNames="libcd" GenerateDebugInformation="true" ProgramDatabaseFile=".\table_/tabled.pdb" SubSystem="2" TargetMachine="1" />]
# * TAG *                      = [Tool]
# * CLOSED *                   = [1]
my $chk_tag4 = 'VCLinkerTool'; # Name = ["VCLinkerTool"]
# LinkIncremental              = ["1"]
# IgnoreDefaultLibraryNames    = ["libcd"]
my $chk_t4i1 = 'ProgramDatabaseFile'; # = [".\table_/tabled.pdb"]
# GenerateDebugInformation     = ["true"]
my $chk_t4i2 = 'AdditionalDependencies'; # = ["fltkd.lib comctl32.lib"]
# TargetMachine                = ["1"]
# SubSystem                    = ["2"]
# SuppressStartupBanner        = ["true"]
my $chk_t4i3 = 'OutputFile'; # = ["../../test/tabled.exe"]
# AdditionalLibraryDirectories = ["..\..\lib"]

my $chk_tag5 = 'VCResourceCompilerTool';
# no changes seen
my $chk_tag6 = 'VCCustomBuildTool';
# no changes seen

# $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
# SECOND SET OF CHANGES
# ===================================================================================
#			OutputDirectory="$(ConfigurationName)\$(ProjectName)"
#			IntermediateDirectory="$(ConfigurationName)\$(ProjectName)"
my $ch2_tag1 = $chk_tag1;   # 'Configuration';
my $ch2_itm1 = $chk_itm1;   # = 'IntermediateDirectory';
my $ch2_def1 = '"$(ConfigurationName)\$(ProjectName)"';
my $ch2_itm2 = $chk_itm2;   # = 'OutputDirectory';
my $ch2_def2 = $ch2_def1;

my $ch2_tag2 = 'VCCLCompilerTool';
#				RuntimeLibrary="0"
#				UsePrecompiledHeader="0"
#				PrecompiledHeaderFile=""
#				AssemblerListingLocation=".\Release-mt\$(ProjectName)/"
#				ObjectFile=".\Release-mt\$(ProjectName)/"
#				ProgramDataBaseFileName=".\Release-mt\$(ProjectName)/"
#				SuppressStartupBanner="true"
my $ch2_t2i1 = 'ProgramDataBaseFileName';   #      = [".\table_/"]
my $ch2_t2i1d = '".\Release-mt\$(ProjectName)/"';
# PreprocessorDefinitions      = ["_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN"]
# AdditionalIncludeDirectories = [".;..\..\zlib;..\..\png;..\..\jpeg;../.."]
my $ch2_t2i2 = 'ObjectFile'; #  = [".\table_/"]
my $ch2_t2i3 = 'AssemblerListingLocation'; # = [".\table_/"]
my $ch2_t2i4 = 'PrecompiledHeaderFile'; # = [".\table_/table.pch"]
# DebugInformationFormat       = ["3"]
# SuppressStartupBanner        = ["true"]
my $ch2_t2i5 = 'RuntimeLibrary'; # = ["3"]
my $ch2_t2i5d = '"0"';

my $ch2_tag3 = 'VCMIDLTool';
my $ch2_t3i1 = 'TypeLibraryName';   # = [".\table_/table.tlb"]
# see $add_typelib_fix - off at present

my $ch2_tag4 = $chk_tag4;   # 'VCLinkerTool'; # Name = ["VCLinkerTool"]
# IgnoreDefaultLibraryNames    = ["libcd"]
my $ch2_t4i1 = $chk_t4i1; # 'ProgramDatabaseFile'; # = [".\table_/tabled.pdb"]
# GenerateDebugInformation     = ["true"]
my $ch2_t4i2 = $chk_t4i2; # 'AdditionalDependencies'; # = ["fltkd.lib comctl32.lib"]
# TargetMachine                = ["1"]
# SubSystem                    = ["2"]
# SuppressStartupBanner        = ["true"]
my $ch2_t4i3 = $chk_t4i3; # 'OutputFile'; # = ["../../test/tabled.exe"]

my $ch2_tag5 = $chk_tag5; # 'VCResourceCompilerTool';
# no changes seen
my $ch2_tag6 = $chk_tag6; # 'VCCustomBuildTool';
# no changes seen

# ===================================================================================
# $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

my %nofixtoolnames = (
    'VCPreBuildEventTool' => 1,
    'VCCustomBuildTool' => 2,
    'VCXMLDataGeneratorTool' => 3,
    'VCWebServiceProxyGeneratorTool' => 4,
    'VCManagedResourceCompilerTool' => 5,
    'VCPreLinkEventTool' => 6,
    'VCALinkTool' => 7,
    'VCManifestTool' => 8,
    'VCXDCMakeTool' => 9,
    'VCBscMakeTool' => 10,
    'VCFxCopTool' => 11,
    'VCAppVerifierTool' => 12,
    'VCWebDeploymentTool' => 13,
    'VCPostBuildEventTool' => 14
    );

### DEBUG
my $debug_xml = 0;
my $dbg_01 = 0; # Configurations
my $dbg_02 = 0; # Configuration
my $dbg_03 = 0; # Files
my $dbg_04 = 0; # File
my $dbg_05 = 0; # FileConfiguration
my $dbg_06 = 0; # show fixed line
my $dbg_07 = 0; # show "NEED FIX?'
my $dbg_08 = 0; # prt("[dbg_08] $i2: tag = [$tag] Name = [$name]\n") if ($dbg_08);
my $dbg_09 = 0; # show CHANGED
my $dbg_10 = 0; # prt("[dbg_10] $i2:$xlnn: tag [$tag] name [$name]\n") if ($dbg_10);

### program variables
my @warnings = ();
my $cwd = cwd();
my $os = $^O;

### forward
sub get_xml_hash($);

sub show_warnings($) {
    my ($val) = shift;
   if (@warnings) {
      prt( "\nGot ".scalar @warnings." WARNINGS...\n" );
      foreach my $itm (@warnings) {
         prt("$itm\n");
      }
      prt("\n");
   } elsif ($val) {
      prt( "\nNo warnings issued.\n\n" );
   }
}

sub pgm_exit($$) {
    my ($val,$msg) = @_;
    if (length($msg)) {
        $msg .= "\n" if (!($msg =~ /\n$/));
        prt($msg)
    }
    show_warnings($val);
    close_log($outfile,$load_log);
    exit($val);
}


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

sub show_xml_hash($) {
    my ($rth) = @_;
    my ($key,$val,$min,$len);
    $min = 0;
    foreach $key (keys %{$rth}) {
        $val = ${$rth}{$key};
        $len = length($key);
        $min = $len if ($len > $min);
    }
    foreach $key (keys %{$rth}) {
        next if ( !($key =~ /^\*\s/) );
        $val = ${$rth}{$key};
        $key .= ' ' while (length($key) < $min);
        prt(" $key = [$val]\n");
    }
    foreach $key (keys %{$rth}) {
        next if ($key =~ /^\*\s/);
        next if ($key ne $key_nam);    # 'Name'
        $val = ${$rth}{$key};
        $key .= ' ' while (length($key) < $min);
        prt(" $key = [$val]\n");
    }
    foreach $key (keys %{$rth}) {
        next if ($key =~ /^\*\s/);
        next if ($key eq $key_nam); # 'Name'
        $val = ${$rth}{$key};
        $key .= ' ' while (length($key) < $min);
        prt(" $key = [$val]\n");
    }
}

sub show_xml_hash_diff($$) {
    my ($rth,$orth) = @_;
    my ($key,$val,$min,$len);
    my ($v2);
    $min = 0;
    foreach $key (keys %{$rth}) {
        $val = ${$rth}{$key};
        $len = length($key);
        $min = $len if ($len > $min);
    }
    foreach $key (keys %{$rth}) {
        next if ( !($key =~ /^\*\s/) );
        $val = ${$rth}{$key};
        if (! defined ${$orth}{$key}) {
            $key .= ' ' while (length($key) < $min);
            prt(" $key = [$val] NEW\n");
        }
    }
    foreach $key (keys %{$rth}) {
        next if ($key =~ /^\*\s/);
        next if ($key ne $key_nam);    # 'Name'
        $val = ${$rth}{$key};
        if (defined ${$orth}{$key}) {
            $v2 = ${$orth}{$key};
            if ($val ne $v2) {
                $key .= ' ' while (length($key) < $min);
                prt(" $key = [$val] vs [$v2] CHANGED\n");
            }
        } else {
            $key .= ' ' while (length($key) < $min);
            prt(" $key = [$val] NEW\n");
        }
    }
    foreach $key (keys %{$rth}) {
        next if ($key =~ /^\*\s/);
        next if ($key eq $key_nam); # 'Name'
        $val = ${$rth}{$key};
        if (defined ${$orth}{$key}) {
            $v2 = ${$orth}{$key};
            if ($val ne $v2) {
                $key .= ' ' while (length($key) < $min);
                prt(" $key = [$val] vs [$v2] CHANGED\n");
            }
        } else {
            $key .= ' ' while (length($key) < $min);
            prt(" $key = [$val] NEW\n");
        }
    }
}

sub get_xml_hash($) {
    my ($x) = shift;
    my $len = length($x);
    my ($ch,$pc,$i,$tag,$val,$tmp,$rh);
    $pc = '';
    my %hash = ();
    $tag = '';
    for ($i = 0; $i < $len; $i++) {
        $ch = substr($x,$i,1);
        last if ($ch eq '<');
    }
    if ($ch eq '<') {
        $i++;
        for (; $i < $len; $i++) {
            $ch = substr($x,$i,1);
            last if (!($ch =~ /\w/));
            $tag .= $ch;
        }
        if (length($tag)) {
            $hash{$key_tag} = $tag; # '* TAG *'
            return \%hash if ($ch eq '>');
            while ($i < $len) {
                $tag = '';
                $val = '';
                # eat any spaces
                for (; $i < $len; $i++) {
                    $ch = substr($x,$i,1);
                    last if (!($ch =~ /\s/));
                }
                # collect tag
                for (; $i < $len; $i++) {
                    $ch = substr($x,$i,1);
                    last if (($ch eq '/') || ($ch =~ /\s/) || ($ch eq '=') || ($ch eq '>'));
                    $tag .= $ch;
                }
                if (($ch eq '/')||($ch eq '>')) {
                    $hash{$tag} = $val if (length($tag));
                    if ($ch eq '/') {
                        $hash{$key_clo} = 1;    # '* CLOSED *'
                    }
                    return \%hash;
                }
                if ($ch eq '=') {
                    # collect the value
                    $i++;
                    $pc = substr($x,$i,1);
                    if ($pc eq '"') {
                        $val = $pc;
                        $i++;
                        for (; $i < $len; $i++) {
                            $ch = substr($x,$i,1);
                            $val .= $ch;
                            last if ($ch eq $pc);
                        }
                        $i++;   # increment past final '"' char, already included
                    } else {
                        for (; $i < $len; $i++) {
                            $ch = substr($x,$i,1);
                            last if (($ch eq '/') || ($ch =~ /\s/) || ($ch eq '>'));
                            $val .= $ch;
                        }
                    }
                    $hash{$tag} = $val;
                } else {
                    $hash{$tag} = $val if (length($tag));
                }
            }
        } else {
            if ($ch eq '/') {
                # tag has no length
                # deal with a CLOSE
                $i++;
                for (; $i < $len; $i++) {
                    $ch = substr($x,$i,1);
                    last if (!($ch =~ /\w/));
                    $tag .= $ch;
                }
                if (length($tag)) {
                    $hash{$key_tag} = $tag; # '* TAG *'
                    $hash{$key_end} = 1;    # '* ENDTAG *'
                }
            } elsif (($ch eq '?') && ($x =~ /\?>$/) && ($len > 6)) {
                $i++;   # header line <? blah blah ?>
                # [<?xml version="1.0" encoding="Windows-1252"?>]
                $tmp = "<".substr($x,$i,($len - 4)).">";
                $rh = get_xml_hash($tmp);
                ${$rh}{$key_hdr} = 1;   # '* HEADER *'
                return $rh;
            } elsif (($ch eq '!') && ($x =~ /^<!--(.*)-->$/)) {
                $tmp = "<".$1.">";
                $rh = get_xml_hash($tmp);
                ${$rh}{$key_com} = 1;   # '* COMMENT *'
                return $rh;
            }
        }
    }
    return \%hash;
}

sub get_xml_line_from_hash($) {
    my ($rh) = @_;
    my $xml = '';
    my $key = $key_tag; # '* TAG *';
    my $hdr = '';
    if ( ! defined ${$rh}{$key}) {
        prtw("WARNING: Reference hash does NOT have [$key] KEY!\nIt only contains -\n");
        show_xml_hash($rh);
        return $xml;
    }

    $xml = '<'; # begin XML
    my $val = ${$rh}{$key}; # get the tag

    $key = '* ENDTAG *';
    if (defined ${$rh}{$key}) {
        $xml .= "/$val";
        my $cnt = 0;
        foreach $key (keys %{$rh}) {
            next if ($key =~ /^\*\s/);  # skip these
            $cnt++;
        }
        $xml .= ">";
        if ($cnt != 0) {
            prtw("WARNING: Somethings BAD about this ref hash...\n");
            show_xml_hash($rh);
        }
        return $xml;
    }

    $key = $key_hdr;    # '* HEADER *'
    if (defined ${$rh}{$key}) {
        $hdr = '?';
        $xml .= $hdr;
    } elsif (defined ${$rh}{$key_com}) { # '* COMMENT *'
        $hdr = '--';
        $xml .= '!--';
    }

    $xml .= "$val";    # add tag to XML
    foreach $key (keys %{$rh}) {
        next if ($key =~ /^\*\s/);  # skip these
        $val = ${$rh}{$key};    # get value (already has quotes
        $xml .= " $key=$val";   # add to XML
    }

    $key = $key_clo;    # '* CLOSED *  # check if a open/close tag
    if (defined ${$rh}{$key}) {
        $xml .= " /";
    }

    $xml .= $hdr if (length($hdr));
    $xml .= ">";
    return $xml;
}

sub is_my_config($) {
    my ($cfg) = shift;
    return 1 if ($cfg eq $config);
    return 0;
}

sub is_my_config2($) {
    my ($cfg) = shift;
    return 1 if ($cfg eq $config2);
    return 0;
}


sub debug_xml_lines($) {
    my ($xml) = shift;
    my $rh = get_xml_hash($xml);
    my $x2 = get_xml_line_from_hash($rh);
    if ($debug_xml > 1) {
        prt("[$xml]\n");
        prt("[$x2]\n");
    } elsif ($xml ne $x2) {
        if ($debug_xml > 2) {
            prt("[$xml]\n");
            prt("[$x2]\n");
        } else {
            my $rh2 = get_xml_hash($x2);
            foreach my $key (keys %{$rh}) {
                my $v1 = ${$rh}{$key};
                if (defined ${$rh2}{$key}) {
                    my $v2 = ${$rh2}{$key};
                    if ($v1 ne $v2) {
                        prt("Diff [$key] = [$v1] vs [$v2]\n");
                    }
                } else {
                    prt("Key [$key] NOT in reconstitution..\n");
                }
            }
        }
    }
}

sub get_bat_text($$$$) {
    my ($inf,$tmp,$nm,$dir) = @_;
    my $on = $nm.".old";
    my $bn = $nm.".bak";
    my $fon = $inf.".old";
    my $fbn = $inf.".bak";
    my $txt = <<EOF;
\@echo Update?
\@echo [$tmp] to
\@echo [$inf]
\@echo *** CONTINUE? ***
\@pause
\@if NOT EXIST $inf goto ERR1
\@if EXIST $fon goto DOBAK
ren $inf $on
copy $tmp $inf
\@goto END
:DOBAK
\@if NOT EXIST $fbn goto DOBAK2
del $fbn
:DOBAK2
ren $inf $bn
copy $tmp $inf
\@goto END
:ERR1
\@echo Error: Can NOT locate [$inf]!
\@goto END
:END
EOF
    return $txt;
}

sub tag_has_attributes($) {
    my ($rh) = @_;
    my $cnt = 0;
    foreach my $key (keys %{$rh}) {
        next if ($key =~ /^\*\s/);
        next if ($key eq $key_nam); # 'Name'
        $cnt++;
    }
    return $cnt;
}


sub process_file($) {
    my ($inf) = shift;
    if (!open INF, "<$inf") {
        pgm_exit(1,"ERROR: Unable to open [$inf]!\n");
    }
    my @lines = <INF>;
    close INF;
    my $lncnt = scalar @lines;
    prt("Processing $lncnt lines from [$inf]...\n");
    my ($i,$line,$xml,$ch,$pc,$j,$len,$tline,$inele,$i2);
    my ($incfgs,$incfg,$rth,$key,$name);
    my ($infiles,$infile,$infcfg,$confcnt,$fconfcnt);
    my ($srccnt, $bgncfg, $endcfg, $actcfg,$msg,$infixes,$chgtot,$delcnt);
    my ($xlnn,$cntfixes,$bgnxln,$endxln,$delxcnt,$chgxtot);
    my ($tag,$changed,$k2,$v2,$nv,$orth,$tmp);
    my ($proj,$infixes2,$chgthis,$list);

    $proj = '';
    $ch = '';
    $inele = 0;
    $incfgs = 0;
    $incfg = 0;
    $infiles = 0;
    $infile = 0;
    $infcfg = 0;
    $confcnt = 0;
    $fconfcnt = 0;
    $srccnt = 0;
    $actcfg = '';
    $infixes = 0;   # Debug-mt fixes
    $infixes2 = 0;  # Release-mt fixes
    $chgthis = 0;
    $chgtot = 0;
    $cntfixes = 0;
    $xlnn = 0;
    $chgxtot = 0;

    my @sources = ();
    my @xmllines = ();
    my @configsfound = ();
    for ($i = 0; $i < $lncnt; $i++) {
        $i2 = $i + 1;
        $line = $lines[$i];
        chomp $line;
        $tline = trim_all($line);
        $len = length($tline);
        for ($j = 0; $j < $len; $j++) {
            $pc = $ch;
            $ch = substr($tline,$j,1);
            $xml .= $ch;
            if ($inele) {
                if ($ch eq '>') {
                    $inele = 0;     # ended an ELEMENT
                    debug_xml_lines($xml) if ($debug_xml);
                    $rth = get_xml_hash($xml);
                    $orth = get_xml_hash($xml); # keep and unchanged ORIGINAL
                    $key = $key_tag;    # '* TAG *'
                    $tag = '';
                    if (defined ${$rth}{$key}) {
                        $tag = ${$rth}{$key};
                    }
                    $key = $key_nam;    # 'Name'
                    $name = '';
                    if ( defined ${$rth}{$key} ) {
                        $name = strip_quotes(${$rth}{$key});
                    }
                    if ($tag eq 'VisualStudioProject') {
                        $proj = $name;
                        prt("$i2:$xlnn: Project Name [$proj]\n");
                    } else {
                        prt("[dbg_10] $i2:$xlnn: tag [$tag] name [$name]\n") if ($dbg_10);
                    }
                    if ($incfgs) {
                        # 486: </Configurations>
                        if ($xml eq '</Configurations>') {
                            $incfgs = 0;
                            prt("$i2: End   configs [$xml]\n") if ($dbg_01);
                        } else {
                            # 24: <Configuration Name="Debug|Win32" OutputDirectory=".\ask_" IntermediateDirectory=".\ask_" ConfigurationType="1" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" >
                            if ($incfg) {
                                # done in POST
                            } else {
                                if ($xml =~ /^<Configuration\s+/) {
                                    prt("$i2: Begin config [$xml]\n") if ($dbg_02);
                                    $bgncfg = $i2;
                                    $bgnxln = $xlnn;
                                    $incfg = 1;
                                    $key = $key_nam;    # 'Name'
                                    if (defined ${$rth}{$key}) {
                                        $confcnt++;
                                        $actcfg = $name;
                                        $infixes = is_my_config($actcfg);
                                        $infixes2 = is_my_config2($actcfg);
                                        $msg = '';
                                        if ($infixes) {
                                            push(@configsfound,$name);
                                            $msg = "FOR FIX"
                                        } elsif ($infixes2) {
                                            push(@configsfound,$name);
                                            $msg = "FOR FIX2"
                                        }
                                        prt( "$i2:Config:$confcnt: [$name] $msg\n" );
                                    } else {
                                        prtw("WARNING: 'Name' not defined in [$xml]!\n");
                                        show_xml_hash($rth);
                                    }
                                }
                            }
                        }
                    } elsif ($infiles) {
                        if ($xml eq '</Files>') {
                            $infiles = 0;
                            prt("$i2: End   Files   [$xml]\n") if ($dbg_03);
                        } else {
                            if ($infile) {
                                if ($xml eq '</File>') {
                                    prt("$i2: End   File    [$xml]\n") if ($dbg_04);
                                    $infile = 0;
                                } else {
                                    if ($infcfg) {
                                        # done in POST
                                    } else {
                                        if ($xml =~ /^<FileConfiguration\s/) {
                                            prt("$i2: Begin FileCFG [$xml]\n") if ($dbg_05);
                                            $infcfg = 1;
                                            $bgncfg = $i2;
                                            $bgnxln = $xlnn;
                                            $key = $key_nam;    # 'Name'
                                            if (defined ${$rth}{$key}) {
                                                $fconfcnt++;
                                                $actcfg = $name;
                                                $infixes = is_my_config($actcfg);
                                                $infixes2 = is_my_config2($actcfg);
                                                $msg = '';
                                                if ($infixes) {
                                                    push(@configsfound,$name);
                                                    $msg = "FOR FIX";
                                                } elsif ($infixes2) {
                                                    push(@configsfound,$name);
                                                    $msg = "FOR FIX2";
                                                }
                                                prt( "$i2:FileCFG:$fconfcnt: [$name] $msg\n" );
                                            } else {
                                                prtw("WARNING:$i2: 'Name' not defined in [$xml]!\n");
                                                show_xml_hash($rth);
                                            }
                                        }
                                    }
                                }
                            } else {
                                if ($xml =~ /^<File\s/) {
                                    prt("$i2: Begin File    [$xml]\n") if ($dbg_04);
                                    $infile = 1;
                                    $key = 'RelativePath';
                                    if (defined ${$rth}{$key}) {
                                        $srccnt++;
                                        push(@sources,$name);
                                        prt( "$i2: Source $srccnt: [$name] ($infixes|$infixes2)\n" ) if ($show_source);
                                    } else {
                                        prtw("WARNING:$i2: 'RelativePath' not defined in [$xml]!\n");
                                        show_xml_hash($rth);
                                    }
                                }
                            }
                        }
                    } else {
                        # 15: <Configurations>
                        if ($xml eq '<Configurations>') {
                            $incfgs = 1;
                            prt("$i2: Begin configs [$xml]\n") if ($dbg_01);
                        } elsif ($xml eq '<Files>') {
                            $infiles = 1;
                            prt("$i2: Begin Files   [$xml]\n") if ($dbg_03);
                        }
                    }
                    #prt("$i2: $xml\n");
                    if ($infixes) {
                        if (tag_has_attributes($rth)) {
                            prt("\n$i2: NEEDS FIX? [$xml]\n") if ($dbg_07);
                            show_xml_hash($rth) if ($dbg_07);
                            $key = $key_tag;    # '* TAG *'
                            $changed = 0;
                            if (defined ${$rth}{$key}) {
                                $tag = ${$rth}{$key};
                                $key = $key_nam;    # 'Name'
                                if ( defined ${$rth}{$key} ) {
                                    # 49: tag = [Configuration] Name = ["Debug-mt|Win32"]
                                    prt("[dbg_08] $i2: tag = [$tag] Name = [$name]\n") if ($dbg_08);
                                    if ($tag eq $chk_tag1) { # 'Configuration') {  # && ($name eq $config)
                                         # IntermediateDirectory            = ["$(ConfigurationName)"]
                                         $k2 = $chk_itm1;   # 'IntermediateDirectory'
                                         if (defined ${$rth}{$k2}) {
                                             $v2 = ${$rth}{$k2};
                                             if ($v2 ne $chk_def1) { # '"$(ConfigurationName)"'
                                                ${$rth}{$k2} = $chk_def1; # '"$(ConfigurationName)"'
                                                $changed++;
                                             }
                                         }
                                         # OutputDirectory                  = ["$(ConfigurationName)"]
                                         $k2 = $chk_itm2;   # 'OutputDirectory'
                                         if (defined ${$rth}{$k2}) {
                                             $v2 = ${$rth}{$k2};
                                             if ($v2 ne $chk_def2) { # '"$(ConfigurationName)"'
                                                ${$rth}{$k2} = $chk_def2;   # '"$(ConfigurationName)"'
                                                $changed++;
                                             }
                                         }
                                    } elsif ($name eq $chk_tag2) {   # "VCCLCompilerTool"
                                        ## PreprocessorDefinitions      = ["_CRT_SECURE_NO_DEPRECATE;WIN32;_DEBUG;_WINDOWS;WIN32_LEAN_AND_MEAN;VC_EXTRA_LEAN;WIN32_EXTRA_LEAN"]
                                        ## AdditionalIncludeDirectories = [".;..\..\zlib;..\..\png;..\..\jpeg;../.."]
                                        ## DebugInformationFormat       = ["3"]
                                        ## SuppressStartupBanner        = ["true"]
                                        $k2 = $chk_t2i1;
                                        if (defined ${$rth}{$k2}) {
                                            #my $chk_t2i1 = 'ProgramDataBaseFileName';   #      = [".\table_/"]
                                            $v2 = ${$rth}{$k2};
                                            if ($v2 =~ /^"\.[\\\/](\w+)[\/\\]"$/) {
                                                $tmp = $1;
                                                if ($tmp =~ /^\w+mt$/) {
                                                    # looks good already
                                                } else {
                                                    $nv = "\".\\".$tmp."mt/\"";
                                                    ${$rth}{$k2} = $nv;
                                                    $changed++;
                                                    prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                                }
                                            }
                                            else {
                                                pgm_exit(1,"Regex FAILED on [$v2]\n");
                                            }
                                        } else {
                                            prtw("WARNING:$i2:1: Key [$k2] NOT PRESENT in [$chk_tag2] tag [$tag] name [$name]\n") if (!$infcfg);
                                        }
                                        $k2 = $chk_t2i2;
                                        if (defined ${$rth}{$k2}) {
                                            #my $chk_t2i2 = 'ObjectFile'; #  = [".\table_/"]
                                            $v2 = ${$rth}{$k2};
                                            if ($v2 =~ /^"\.[\\\/](\w+)[\/\\]"$/) {
                                                $tmp = $1;
                                                if ($tmp =~ /^\w+mt$/) {
                                                    # looks good already
                                                } else {
                                                    $nv = "\".\\".$tmp."mt/\"";
                                                    ${$rth}{$k2} = $nv;
                                                    $changed++;
                                                    prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                                }
                                            }
                                            else {
                                                pgm_exit(1,"Regex FAILED on [$v2]\n");
                                            }
                                        } else {
                                            prtw("WARNING:$i2:2: Key [$k2] NOT PRESENT in [$chk_tag2] tag [$tag] name [$name]\n") if (!$infcfg);
                                        }
                                        $k2 = $chk_t2i3;
                                        if (defined ${$rth}{$k2}) {
                                            #my $chk_t2i3 = 'AssemblerListingLocation'; # = [".\table_/"]
                                            $v2 = ${$rth}{$k2};
                                            if ($v2 =~ /^"\.[\\\/](\w+)[\/\\]"$/) {
                                                $tmp = $1;
                                                if ($tmp =~ /^\w+mt$/) {
                                                    # looks good already
                                                } else {
                                                    $nv = "\".\\".$tmp."mt/\"";
                                                    ${$rth}{$k2} = $nv;
                                                    $changed++;
                                                    prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                                }
                                            }
                                            else {
                                                pgm_exit(1,"Regex FAILED on [$v2]\n");
                                            }
                                        } else {
                                            prtw("WARNING:$i2:3: Key [$k2] NOT PRESENT in [$chk_tag2] tag [$tag] name [$name]\n") if (!$infcfg);
                                        }
                                        $k2 = $chk_t2i4;
                                        if (defined ${$rth}{$k2}) {
                                            #my $chk_t2i4 = 'PrecompiledHeaderFile'; # = [".\table_/table.pch"]
                                            if ($use_blank_pch) {
                                                $v2 = strip_quotes(${$rth}{$k2});
                                                if (length($v2)) {
                                                    $nv = '""';
                                                    ${$rth}{$k2} = $nv;
                                                    $changed++;
                                                    prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                                }
                                            } else {
                                                $v2 = ${$rth}{$k2};
                                                if ($v2 =~ /^"\.[\\\/](\w+)[\/\\](\w+)\.pch"$/) {
                                                    $nv = "\".\\$1mt/$2-mt.pch\"";
                                                    ${$rth}{$k2} = $nv;
                                                    $changed++;
                                                    prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                                }
                                                else {
                                                    pgm_exit(1,"Regex FAILED on [$v2]\n");
                                                }
                                            }
                                        } else {
                                            prtw("WARNING:$i2:4: Key [$k2] NOT PRESENT in [$chk_tag2] tag [$tag] name [$name]\n") if (!$infcfg);
                                        }
                                        $k2 = $chk_t2i5;
                                        if (defined ${$rth}{$k2}) {
                                            #my $chk_t2i5 = 'RuntimeLibrary'; # = ["3"]
                                            #my $chk_t2i5d = '"1"';
                                            $v2 = ${$rth}{$k2};
                                            $nv = $chk_t2i5d;
                                            if ($v2 ne $nv) {
                                                ${$rth}{$k2} = $nv;
                                                $changed++;
                                                prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                            }
                                        } else {
                                            prtw("WARNING:$i2:5: Key [$k2] NOT PRESENT in [$chk_tag2] tag [$tag] name [$name]\n") if (!$infcfg);
                                        }
                                    } elsif ($name eq $chk_tag3) { #'"VCMIDLTool"';  #  * TAG * = [Tool]  * CLOSED * = [1]
                                        # Name                    = ["VCMIDLTool"]
                                        # TargetEnvironment       = ["1"]
                                        if ($add_typelib_fix) {
                                            $k2 = $chk_t3i1;
                                            if (defined ${$rth}{$k2}) {
                                                # 'TypeLibraryName';   # = [".\table_/table.tlb"]
                                                $v2 = ${$rth}{$k2};
                                                $nv = strip_quotes($v2);
                                                if (length($nv)) {
                                                    if ($v2 =~ /^"\.[\\\/](\w+)[\/\\](\w+)-mt\.tlb"$/) {
                                                        # looks GOOD
                                                    } elsif ($v2 =~ /^"\.[\\\/](\w+)[\/\\](\w+)\.tlb"$/) {
                                                        $nv = "\".\\$1mt/$2-mt.tlb\"";
                                                        ${$rth}{$k2} = $nv;
                                                        $changed++;
                                                        prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                                    }
                                                    else {
                                                        pgm_exit(1,"Regex FAILED on [$v2]\n");
                                                    }
                                                }
                                            }
                                            # MkTypLibCompatible      = ["true"]
                                            # PreprocessorDefinitions = ["_DEBUG"]
                                            # HeaderFileName          = [""]
                                            # SuppressStartupBanner   = ["true"]
                                        }
                                    } elsif ($name eq $chk_tag4) {
                                        #59: NEEDS FIX? [<Tool Name="VCLinkerTool" AdditionalDependencies="fltkd.lib comctl32.lib" OutputFile="../../test/tabled.exe" LinkIncremental="1" SuppressStartupBanner="true" AdditionalLibraryDirectories="..\..\lib" IgnoreDefaultLibraryNames="libcd" GenerateDebugInformation="true" ProgramDatabaseFile=".\table_/tabled.pdb" SubSystem="2" TargetMachine="1" />]
                                        # * TAG *                      = [Tool]
                                        # * CLOSED *                   = [1]
                                        #my $chk_tag4 = '"VCLinkerTool"'; # Name = ["VCLinkerTool"]
                                        # LinkIncremental              = ["1"]
                                        # IgnoreDefaultLibraryNames    = ["libcd"]
                                        #my $chk_t4i1 = 'ProgramDatabaseFile'; # = [".\table_/tabled.pdb"]
                                        $k2 = $chk_t4i1;
                                        if (defined ${$rth}{$k2}) {
                                            $v2 = ${$rth}{$k2};
                                            $nv = strip_quotes($v2);
                                            if (length($nv)) {
                                                if ($v2 =~ /^"\.[\\\/](\w+)[\/\\](\w+)-mt\.pdb"$/) {
                                                    # looks good to go
                                                } elsif ($v2 =~ /^"\.[\\\/](\w+)[\/\\](\w+)\.pdb"$/) {
                                                    $nv = "\".\\$1mt/$2-mt.pdb\"";
                                                    ${$rth}{$k2} = $nv;
                                                    $changed++;
                                                    prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                                }
                                                else {
                                                    pgm_exit(1,"Regex FAILED on [$v2]\n");
                                                }
                                            }
                                        }

                                        # GenerateDebugInformation     = ["true"]
                                        #my $chk_t4i2 = 'AdditionalDependencies'; # = ["fltkd.lib comctl32.lib"]
                                        $k2 = $chk_t4i2;
                                        if (defined ${$rth}{$k2}) {
                                            $v2 = ${$rth}{$k2};
                                            if ($v2 =~ /fltkd-mt\.lib/) {
                                                # already using fltk-mt.lib
                                            } else {
                                                $nv = $v2;
                                                $nv =~ s/fltkd\.lib/fltkd-mt\.lib/;
                                                if ($v2 ne $nv) {
                                                    ${$rth}{$k2} = $nv;
                                                    $changed++;
                                                    prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                                }
                                                else {
                                                    prtw("WARNING: fltkd.lib NOT in [$v2]\n");
                                                }
                                            }
                                        }

                                        # TargetMachine                = ["1"]
                                        # SubSystem                    = ["2"]
                                        # SuppressStartupBanner        = ["true"]
                                        #my $chk_t4i3 = 'OutputFile'; # = ["../../test/tabled.exe"]
                                        $k2 = $chk_t4i3;
                                        if (defined ${$rth}{$k2}) {
                                            $v2 = ${$rth}{$k2};
                                            $nv = strip_quotes($v2);
                                            if (length($nv)) {
                                                if ($v2 =~ /^"\.\.\/\.\.\/test\/(\w+)-mt\.exe"$/) {
                                                    # looks good to go
                                                } elsif ($v2 =~ /^"\.\.\/\.\.\/test\/(\w+)\.exe"$/) {
                                                    $nv = "\"../../test/$1-mt.exe\"";
                                                    ${$rth}{$k2} = $nv;
                                                    $changed++;
                                                    prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                                }
                                                else {
                                                    pgm_exit(1,"Regex FAILED on [$v2]\n");
                                                }
                                            }
                                        }
                                        # AdditionalLibraryDirectories = ["..\..\lib"]
                                    } elsif ($name eq $chk_tag5) {
                                        # no changes noted
                                    } elsif ($name eq $chk_tag6) {
                                        # no changes noted
                                    } else {
                                        prtw("WARNING: tag [$tag] name [$name] NOT CODED1\n");
                                    }
                                }
                            }
                            if ($changed) {
                                $cntfixes++;
                                $chgtot += $changed;
                                $xml = get_xml_line_from_hash($rth);
                                if ($dbg_08) {
                                    prt("$i2: CHANGE [$xml]\n");
                                    show_xml_hash_diff($rth,$orth);
                                }
                                $chgxtot++;
                            } else {
                                prt("$i2: NO CHANGE1\n") if ($dbg_08);
                            }
                        } else {
                            # items WITHOUT attributes, besides 'Name' perhaps
                            $k2 = $key_end;
                            if (defined ${$rth}{$k2}) {
                                # would NOT expect a FIX for these - just end items like
                                # </Configuration[s]>
                            } else {
                                if (defined $nofixtoolnames{$name}) {
                                    # for present forget these
                                } else {
                                    if (($name eq $config)&&($tag eq 'FileConfiguration')) {
                                        # forget this for now
                                    } else {
                                        prtw("WARNING:$i2: NO FIX [$xml] tag [$tag] name [$name]\n"); # if ($dbg_06);
                                        show_xml_hash($rth);
                                    }
                                }
                            }
                        }
                    } elsif ($infixes2) {
                        # second set of FIXES
                        if ( tag_has_attributes($rth) && length($tag) && length($name) ) {
                            if ($dbg_07) {
                                prt("\n$i2:$xlnn: NEEDS FIX2? [$xml]\n"); # if ($dbg_07);
                                show_xml_hash($rth); # if ($dbg_07);
                            }
                            # ===============================================
                            if ($tag eq $ch2_tag1) { # 'Configuration') {  # && ($name eq $config)
                                $chgthis = 0;
                                # ----------------------------------
                                # IntermediateDirectory            = ["$(ConfigurationName)"]
                                $k2 = $ch2_itm1;   # 'IntermediateDirectory'
                                $list = $k2;
                                if (defined ${$rth}{$k2}) {
                                     $v2 = ${$rth}{$k2};
                                     if ($v2 ne $ch2_def1) { # '"$(ConfigurationName)/$(ProjectName)"'
                                        ${$rth}{$k2} = $ch2_def1;
                                        $changed++;
                                        $chgthis++;
                                     }
                                 }
                                # ----------------------------------
                                 # OutputDirectory                  = ["$(ConfigurationName)"]
                                 $k2 = $ch2_itm2;   # 'OutputDirectory'
                                 $list .= " $k2";
                                 if (defined ${$rth}{$k2}) {
                                     $v2 = ${$rth}{$k2};
                                     if ($v2 ne $ch2_def2) { # '"$(ConfigurationName)/$(ProjectName)"'
                                        ${$rth}{$k2} = $ch2_def2;
                                        $changed++;
                                        $chgthis++;
                                     }
                                 }
                                 if ($chgthis) {
                                    prt("$i2:$xlnn: $chgthis changes\n"); # if ($dbg_07);
                                 } else {
                                    prt("$i2:$xlnn: NO CHANGE2 [$list]\n") if ($dbg_07);
                                 }
                            # ===============================================
                            } elsif ($name eq $ch2_tag2) {   # "VCCLCompilerTool"
                                # ----------------------------------
                                $k2 = $ch2_t2i1;
                                $list = $k2;
                                if (defined ${$rth}{$k2}) {
                                    $v2 = ${$rth}{$k2};
                                    $nv = $ch2_t2i1d;
                                    $chgthis = 0;
                                    if ($v2 ne $nv) {
                                        ${$rth}{$k2} = $nv;
                                        $changed++;
                                        $chgthis++;
                                        prt("$i2:$xlnn:$k2: changed [$v2] to [$nv]\n");
                                    }
                                     if ($chgthis) {
                                        prt("$i2:$xlnn: $chgthis changes\n"); # if ($dbg_07);
                                     } else {
                                        prt("$i2:$xlnn: NO CHANGE_2 [$k2]\n") if ($dbg_07);
                                     }
                                } else {
                                    prtw("WARNING:$i2:1: Key [$k2] NOT PRESENT in [$chk_tag2] tag [$tag] name [$name]\n") if (!$infcfg);
                                }
                                # ----------------------------------
                                $k2 = $ch2_t2i2;
                                $list .= " $k2";
                                if (defined ${$rth}{$k2}) {
                                    $v2 = ${$rth}{$k2};
                                    $nv = $ch2_t2i1d;
                                    $chgthis = 0;
                                    if ($v2 ne $nv) {
                                        ${$rth}{$k2} = $nv;
                                        $changed++;
                                        $chgthis++;
                                        prt("$i2:$xlnn:$k2: changed [$v2] to [$nv]\n");
                                    }
                                     if ($chgthis) {
                                        prt("$i2:$xlnn: $chgthis changes\n"); # if ($dbg_07);
                                     } else {
                                        prt("$i2:$xlnn: NO CHANGE_2 [$k2]\n") if ($dbg_07);
                                     }
                                } else {
                                    prtw("WARNING:$i2:1: Key [$k2] NOT PRESENT in [$chk_tag2] tag [$tag] name [$name]\n") if (!$infcfg);
                                }
                                # ----------------------------------
                                $k2 = $ch2_t2i3;
                                $list .= " $k2";
                                if (defined ${$rth}{$k2}) {
                                    $v2 = ${$rth}{$k2};
                                    $nv = $ch2_t2i1d;
                                    $chgthis = 0;
                                    if ($v2 ne $nv) {
                                        ${$rth}{$k2} = $nv;
                                        $changed++;
                                        $chgthis++;
                                        prt("$i2:$xlnn:$k2: changed [$v2] to [$nv]\n");
                                    }
                                     if ($chgthis) {
                                        prt("$i2:$xlnn: $chgthis changes\n"); # if ($dbg_07);
                                     } else {
                                        prt("$i2:$xlnn: NO CHANGE_2 [$k2]\n") if ($dbg_07);
                                     }
                                } else {
                                    prtw("WARNING:$i2:1: Key [$k2] NOT PRESENT in [$chk_tag2] tag [$tag] name [$name]\n") if (!$infcfg);
                                }
                                # ----------------------------------
                                $k2 = $ch2_t2i4;
                                $list .= " $k2";
                                if (defined ${$rth}{$k2}) {
                                    #my $ch2_t2i4 = 'PrecompiledHeaderFile'; # = [".\table_/table.pch"]
                                    if ($use_blank_pch) {
                                        $v2 = strip_quotes(${$rth}{$k2});
                                        if (length($v2)) {
                                            $nv = '""';
                                            ${$rth}{$k2} = $nv;
                                            $changed++;
                                            prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                        } else {
                                            prt("$i2:$xlnn: NO CHANGE_2 [$k2]\n") if ($dbg_07);
                                        }
                                    } else {
                                        $v2 = ${$rth}{$k2};
                                        if ($v2 =~ /^"\.[\\\/](\w+)[\/\\](\w+)\.pch"$/) {
                                            $nv = "\".\\$1mt/$2-mt.pch\"";
                                            ${$rth}{$k2} = $nv;
                                            $changed++;
                                            prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                        }
                                        else {
                                            pgm_exit(1,"Regex FAILED on [$v2]\n");
                                        }
                                    }
                                } else {
                                    prtw("WARNING:$i2:4: Key [$k2] NOT PRESENT in [$chk_tag2] tag [$tag] name [$name]\n") if (!$infcfg);
                                }
                                # ----------------------------------
                                $k2 = $ch2_t2i5;
                                $list .= " $k2";
                                if (defined ${$rth}{$k2}) {
                                    #my $chk_t2i5 = 'RuntimeLibrary'; # = ["3"]
                                    #my $chk_t2i5d = '"1"';
                                    $v2 = ${$rth}{$k2};
                                    $nv = $ch2_t2i5d;
                                    if ($v2 ne $nv) {
                                        ${$rth}{$k2} = $nv;
                                        $changed++;
                                        prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                    } else {
                                        prt("$i2:$xlnn: NO CHANGE_2 [$k2]\n") if ($dbg_07);
                                    }
                                } else {
                                    prtw("WARNING:$i2:5: Key [$k2] NOT PRESENT in [$chk_tag2] tag [$tag] name [$name]\n") if (!$infcfg);
                                }
                                prt("Done list [$list]\n") if ($dbg_07);
                            # ===============================================
                            } elsif ( $name eq $ch2_tag3 ) { # 'VCMIDLTool'
                                if ($add_typelib_fix) {
                                    $k2 = $ch2_t3i1;    # 'TypeLibraryName';   # = [".\table_/table.tlb"]
                                    if (defined ${$rth}{$k2}) {
                                        $v2 = ${$rth}{$k2};
                                        $nv = "\".\\".strip_quotes($ch2_def1)."/".$proj.".tlb\""; # '"$(ConfigurationName)\$(ProjectName)"';
                                        if ($v2 ne $nv) {
                                            ${$rth}{$k2} = $nv;
                                            $changed++;
                                            prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                        } else {
                                            prt("$i2:$xlnn: NO CHANGE_2 [$k2]\n") if ($dbg_07);
                                        }
                                    }
                                }
                            # ===============================================
                            } elsif ($name eq $ch2_tag4) {
                                #59: NEEDS FIX? [<Tool Name="VCLinkerTool" AdditionalDependencies="fltkd.lib comctl32.lib" OutputFile="../../test/tabled.exe" LinkIncremental="1" SuppressStartupBanner="true" AdditionalLibraryDirectories="..\..\lib" IgnoreDefaultLibraryNames="libcd" GenerateDebugInformation="true" ProgramDatabaseFile=".\table_/tabled.pdb" SubSystem="2" TargetMachine="1" />]
                                # * TAG *                      = [Tool]
                                # * CLOSED *                   = [1]
                                #my $chk_tag4 = '"VCLinkerTool"'; # Name = ["VCLinkerTool"]
                                # LinkIncremental              = ["1"]
                                # IgnoreDefaultLibraryNames    = ["libcd"]
                                #my $chk_t4i1 = 'ProgramDatabaseFile'; # = [".\table_/tabled.pdb"]
                                $k2 = $ch2_t4i1;
                                $list = $k2;
                                $chgthis = 0;
                                if (defined ${$rth}{$k2}) {
                                    $v2 = ${$rth}{$k2};
                                    $nv = "\".\\".strip_quotes($ch2_def1)."/".$proj.".pdb\""; # '"$(ConfigurationName)\$(ProjectName)"';
                                    $tmp = '".\Release-mt\$(ProjectName)/arc.pdb"';
                                    if (($v2 ne $nv)&&($v2 ne $tmp)) {
                                        #${$rth}{$k2} = $nv;
                                        ${$rth}{$k2} = $tmp; # not sure why I like this form better
                                        $changed++;
                                        $chgthis++;
                                        #prt("$i2:$k2: changed [$v2] to [$nv] (or [$tmp])\n");
                                        prt("$i2:$k2: changed [$v2] to [$tmp]\n");
                                    } else {
                                        prt("$i2:$xlnn: NO CHANGE_2 [$k2]\n") if ($dbg_07);
                                    }
                                }

                                # GenerateDebugInformation     = ["true"]
                                #my $chk_t4i2 = 'AdditionalDependencies'; # = ["fltkd.lib comctl32.lib"]
                                $k2 = $ch2_t4i2;
                                $list .= " $k2";
                                if (defined ${$rth}{$k2}) {
                                    $v2 = ${$rth}{$k2};
                                    if ($v2 =~ /fltk-mt\.lib/) {
                                        # already using fltk-mt.lib
                                    } else {
                                        $nv = $v2;
                                        $nv =~ s/fltk\.lib/fltk-mt\.lib/;
                                        if ($v2 ne $nv) {
                                            ${$rth}{$k2} = $nv;
                                            $changed++;
                                            $chgthis++;
                                            prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                        } else {
                                            prtw("WARNING: fltkd.lib NOT in [$v2]\n");
                                        }
                                    }
                                }

                                # TargetMachine                = ["1"]
                                # SubSystem                    = ["2"]
                                # SuppressStartupBanner        = ["true"]
                                #my $chk_t4i3 = 'OutputFile'; # = ["../../test/tabled.exe"]
                                $k2 = $ch2_t4i3;
                                $list .= " $k2";
                                if (defined ${$rth}{$k2}) {
                                    $v2 = ${$rth}{$k2};
                                    $nv = strip_quotes($v2);
                                    if (length($nv)) {
                                        if ($v2 =~ /^"\.\.\/\.\.\/test\/(\w+)-mt\.exe"$/) {
                                            # looks good to go
                                        } elsif ($v2 =~ /^"\.\.\/\.\.\/test\/(\w+)\.exe"$/) {
                                            $nv = "\"../../test/$1-mt.exe\"";
                                            ${$rth}{$k2} = $nv;
                                            $changed++;
                                            prt("$i2:$k2: changed [$v2] to [$nv]\n");
                                        }
                                        else {
                                            pgm_exit(1,"Regex FAILED on [$v2]\n");
                                        }
                                    }
                                }
                                # AdditionalLibraryDirectories = ["..\..\lib"]
                                prt( "Done list [$list]\n") if ($dbg_07);
                            # ===============================================
                            } elsif ($name eq $ch2_tag5) {
                                # nothing
                            } elsif ($name eq $ch2_tag6) {
                                # nothing
                            } else {
                                prtw("WARNING: tag [$tag] name [$name] NOT CODED2\n");
                            }
                            if ($changed) {
                                $cntfixes++;
                                $chgtot += $changed;
                                $xml = get_xml_line_from_hash($rth);
                                if ($dbg_08) {
                                    prt("$i2: CHANGE [$xml]\n");
                                    show_xml_hash_diff($rth,$orth);
                                }
                                $chgxtot++;
                            } else {
                                prt("$i2: NO CHANGE1\n") if ($dbg_08);
                            }
                        } else {
                            # should be IGNORING all these
                            if (defined ${$rth}{$key_end}) {
                                # ignore
                            } elsif (defined ${$rth}{$key_com}) {
                                #ignore
                            } elsif (defined $nofixtoolnames{$name}) {
                                #ignore
                            } elsif ($tag eq 'FileConfiguration') {
                                # ignore
                            } else {
                                prtw("WARNING:$i2: NO FIX [$xml] tag [$tag] val [$name]\n"); # if ($dbg_06);
                                show_xml_hash($rth);
                            }
                        }
                    }
                    push(@xmllines,$xml);

                    # POST processing
                    if ($incfgs) {
                            if ($incfg) {
                                if ($xml eq '</Configuration>') {
                                    prt("$i2: End   config [$xml]\n") if ($dbg_02);
                                    $incfg = 0;
                                    $endcfg = $i2;
                                    $endxln = $xlnn;
                                    if ($infixes) {
                                        $delcnt = $endcfg - $bgncfg;
                                        $delxcnt = $endxln - $bgnxln;
                                        prt( "$i2: Will FIX file lines $bgncfg to $endcfg, $delcnt lines, x-line $bgnxln - $endxln = $delxcnt\n" );
                                        $infixes = 0;
                                    } elsif ($infixes2) {
                                        $delcnt = $endcfg - $bgncfg;
                                        $delxcnt = $endxln - $bgnxln;
                                        prt( "$i2: Will FIX2 file lines $bgncfg to $endcfg, $delcnt lines, x-line $bgnxln - $endxln = $delxcnt\n" );
                                        $infixes2 = 0;
                                    }
                                }
                            }
                    } elsif ($infiles) {
                            if ($infile) {
                                    if ($infcfg) {
                                        # </FileConfiguration>
                                        if ($xml eq '</FileConfiguration>') {
                                            $infcfg = 0;
                                            prt("$i2: End   FileCFG [$xml]\n") if ($dbg_05);
                                            $endcfg = $i2;
                                            $endxln = $xlnn;
                                            if ($infixes) {
                                                $delcnt = $endcfg - $bgncfg;
                                                $delxcnt = $endxln - $bgnxln;
                                                prt( "$i2: Will FIX file lines $bgncfg to $endcfg, $delcnt lines x-line $bgnxln - $endxln = $delxcnt\n" );
                                                $infixes = 0;
                                            } elsif ($infixes2) {
                                                $delcnt = $endcfg - $bgncfg;
                                                $delxcnt = $endxln - $bgnxln;
                                                prt( "$i2: Will FIX2 file lines $bgncfg to $endcfg, $delcnt lines x-line $bgnxln - $endxln = $delxcnt\n" );
                                                $infixes2 = 0;
                                            }
                                        }
                                    }
                            }
                    }
                }
            } elsif ($ch eq '<') {
                $inele = 1;
                $xml = $ch;
                $xlnn++;
            }
        }
        $xml .= ' ' if (!($xml =~ /\s$/));
    }
    $inele = scalar @xmllines;
    prt( "Done file $lncnt lines, total changes $chgtot, or\n");
    $msg = "Check TOTALS!";
    if ($chgxtot == $cntfixes) {
        $msg = "ok";
    }
    prt( "Of $xlnn xml lines, changed $chgxtot ($cntfixes) $msg\n");
    if ($chgtot == 0) {
        prt("Appears NOTHING changed, so no update...\n");
    } else {
        my ($fname,$fdir) = fileparse($inf);
        $tmp = $perl_dir."\\temp.$fname.xml";
        $xml = join("\n",@xmllines);
        $xml .= "\n";
        write2file($xml,$tmp);
        prt("Written to [$tmp] file...\n");
        my $tmp2 = $perl_dir."\\temp.$fname.bat";
        $xml = get_bat_text($inf,$tmp,$fname,$fdir);
        write2file($xml,$tmp2);
        prt("Written to [$tmp2] file to do update...\n");
        my $tmp3 = 'C:\MDOS';
        if (-d $tmp3) {
            $tmp3 .= "\\tempupd.bat";
            $xml = "call $tmp2\n";
            write2file($xml,$tmp3);
            prt("Or run tempupd...\n");
        }
    }
}

#########################################
### MAIN ###
parse_args(@ARGV);
prt( "$pgmname: in [$cwd]: Hello, World...\n" );
process_file($in_file);
pgm_exit(0,"Normal exit(0)");
########################################
sub give_help {
    prt("$pgmname: version 0.0.1 2010-05-29\n");
    prt("Usage: $pgmname in_vcproj_file [-l[load_log] [-h[elp] [-?]\n");

}
sub need_arg {
    my ($arg,@av) = @_;
    pgm_exit(1,"ERROR: [$arg] must have follwoing argument!\n")
        if (!@av);
}
sub parse_args {
    my (@av) = @_;
    my $cnt = 0;
    while (@av) {
        my $arg = $av[0];
        if ($arg =~ /-/) {
            my $sarg = substr($arg,1);
            $sarg = substr($sarg,1) while ($sarg =~ /-/);
            if (($sarg =~ /^h/i)||($sarg eq '?')) {
                give_help();
                pgm_exit(0,"Help exit(0)");
            } elsif ($sarg =~ /^l/i) {
                $load_log = 1;
                prt( "Set to load log at end.\n" );
            } else {
                pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n");
            }
        } else {
            if ($cnt == 0) {
                $in_file = $arg;
                prt("Set input to [$in_file]\n");
            } else {
                pgm_exit(1,"ERROR: Unknown [$arg]!\n");
            }
            $cnt++;
        }
        shift @av;
    }
    if (length($in_file) == 0) {
        if ($debug_mode) {
            if (-f $def_file) {
                $in_file = $def_file;
                prt("Set input to DEFAULT [$in_file]\n");
            }
        }
    }
    if (length($in_file) == 0) {
        pgm_exit(1,"ERROR: No input file found!\n");
    }
}

# eof - vcfix.pl
