#!/bin/perl -w
#< getvcdirs.pl - LIBRARY
#####################################################################
######### getting the INCLUDE folders, either from the ENVIRONMENT
######### or from where MSVC8 stroes its stuff
# 2010/04/25  - geoff mclane - http://geoffair.net/mperl/
use strict;
use warnings;


my $dbg_gvc_10 = 0; # prt( "[dbg_gvc_10] $cln\n" ) if ($dbg_gvc_10);
my $dbg_gvc_11 = 0;
my $dbg_gvc_13 = 0;
my $dbg_gvc_14 = 0;
my $dbg_gvc_15 = 0;
my $dbg_gvc_16 = 0;
my $dbg_gvc_17 = 0;
my $dbg_gvc_18 = 0;
my $dbg_gvc_19 = 0; # prt("[dbg_i19] NOTE: Can NOT locate folder [$d2] $var\n") if ($dbg_gvc_19);

# ===================================================================
my @vc8_found3 = ( 'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include', #  907 File(s)     51,017,044 bytes
'C:\Program Files\Debugging Tools for Windows\sdk\inc', #  4 File(s)        780,272 bytes
'C:\Program Files\Debugging Tools for Windows\winext\manifest', #  32 File(s)      1,264,957 bytes
'C:\Program Files\Microsoft DirectX SDK (October 2006)\Include', #   82 File(s)      3,511,805 bytes
'C:\Program Files\Microsoft DirectX SDK (October 2006)\Samples\C++\Common', #  9 File(s)        135,789 bytes
'C:\Program Files\Microsoft DirectX SDK (October 2006)\Samples\C++\DXUT\Core', #  3 File(s)         56,644 bytes
'C:\Program Files\Microsoft DirectX SDK (October 2006)\Samples\C++\DXUT\Optional', #  8 File(s)        111,530 bytes
'C:\Program Files\Microsoft DirectX SDK (October 2006)\Samples\C++\Misc\DxDiagReport',  # 10 File(s)         23,610 bytes
'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include\atl', #  13 File(s)      1,512,619 bytes
'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include\crt', #  65 File(s)        608,821 bytes
'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include\crt\sys', #   5 File(s)         12,467 bytes
'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include\gl', #  3 File(s)         99,389 bytes
'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include\mfc', #   44 File(s)        962,431 bytes
#'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\misc\Include Updates', #  1 File(s)        138,296 bytes
'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\src\crt', #   79 File(s)        474,787 bytes
'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\src\crt\sys', # 5 File(s)         15,741 bytes
'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\src\mfc', #  21 File(s)        644,692 bytes
'C:\Program Files\Microsoft SQL Server\90\SDK\Include', #    4 File(s)        169,617 bytes
'C:\Program Files\Microsoft Visual Studio 8\VC\include', #   72 File(s)      1,284,522 bytes
'C:\Program Files\Microsoft Visual Studio 8\VC\include\msclr', #   8 File(s)        151,706 bytes
'C:\Program Files\Microsoft Visual Studio 8\VC\include\sys', # 5 File(s)         17,462 bytes
);

sub load_vc8_cfg {
	my ($vc8c) = shift;
	my @v8_incs = ();
	if (open INF, "<$vc8c") {
		my @clns = <INF>;
		close INF;
		foreach my $cln (@clns) {
			chomp $cln;
			$cln = trim_all($cln);
			prt( "[dbg_gvc_10] $cln\n" ) if ($dbg_gvc_10);
			if ($cln =~ /include=\"(.+)\"/i) {
				my $iln = $1;
				my @vc8i = split(';',$iln);
				prt( "INCLUDE=[$iln]\n" );
				foreach my $itm (@vc8i) {
					push(@v8_incs, $itm);
				}
			}
		}
	} else {
		prt( "WARNING: can not open [$vc8c] ... $! ...\n" );
	}
	return @v8_incs;
}


sub load_vc8_bat {
	my ($vc8b) = shift;
	my @v8_folders = ();
	my @v8_incs = ();
	my %v8_hash = ();
	if (open INB, "<$vc8b") {
		my @lns = <INB>;
		close INB;
		foreach my $ln (@lns) {
			chomp $ln;
			$ln = trim_all($ln);
			if ($ln =~ /\@*SET\s+(.*)/) {
				my @arr = split(/=/,$1);
				my $sz = scalar @arr;
				if ($sz == 2) {
					my $ky = uc($arr[0]);
					my $val = $arr[1];
					$v8_hash{$ky} = $val;
					prt( "[$ky]=[$val]\n" ) if ($$dbg_gvc_11);
					if ($ky =~ /^VCINSTALLDIR$/i) {
						# got the INSTALL DIECTORY
						my $vc8_cfg = $val. "\\vcpackages\\vcprojectengine.dll.config";
						if (-f $vc8_cfg) {
							@v8_incs = load_vc8_cfg($vc8_cfg);
						} else {
							prt( "WARNING: [$vc8_cfg] does not exist ...\n" );
						}
					}

				} else {
					prt( "SET $1\n" );
				}
			}
		}
		foreach my $item (@v8_incs) {
			# expand
			if ($item =~ /.*\$\((.+)\).+/) {
				my $eit = uc($1);
				prt( "Item [$eit] in [$item] needs expansion ...\n" ) if ($$dbg_gvc_13);
				foreach my $key (keys %v8_hash) {
					if ($key eq $eit) {
						$item =~ s/\$\($key\)/$v8_hash{$key}\\/i;
						prt( "New item = [$item] ...\n" ) if ($$dbg_gvc_13);
						last;
					}
				}
			}
			push(@v8_folders, $item) if (length($item));
		}
	} else {
		prt( "WARNING: No open of [$vc8b] ... $! ...\n" );
	}
	return @v8_folders;
}

sub add_to_files_nc3($$) {
    my ($fil,$rarr) = @_;
    my $lcfil = lc($fil);
    return 1 if (defined ${$rarr}{$lcfil});
    ${$rarr}{$lcfil} = $fil;
    return 0;
}

sub get_include_dirs3($) {
    my ($rs) = @_;
    #if ( length($vs_install_directory) ) {
    #    ${$rs} = $vs_install_directory;
    #    return 1;
    #}
    my $bfil = get_vs_vars_bat();   ## like 'C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat';
    my $fil = 'tempvc.txt';
    my $bat = 'tempvc.bat';
    my $iret = 0;
    unlink $fil if (-f $fil);
    unlink $bat if (-f $bat);
    my %d_added = ();
    my $rda = \%d_added;
    if (-f $bfil) {
        my $msg = '@call "'.$bfil.'" x86 >nul'."\n";
        $msg .= "\@echo VSINSTALLDIR=\%VSINSTALLDIR\% >$fil\n";
        # $(WindowsSdkDir)\include
        $msg .= "\@echo WindowsSdkDir=\%WindowsSdkDir\% >>$fil\n";
        # $(FrameworkSDKDir)include
        $msg .= "\@echo FrameworkSDKDir=\%FrameworkSDKDir\% >>$fil\n";
        # C:\Program Files\Microsoft DirectX SDK (March 2008)\Include
        # maybe HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment
        # DXSDK_DIR=C:\Program Files\Microsoft DirectX SDK (March 2008)\ so...
        $msg .= "\@echo DXSDK_DIR=\%DXSDK_DIR\% >>$fil\n";
        # ALL INCLUDE items
        $msg .= "\@echo INCLUDE=\%INCLUDE\% >>$fil\n";
        write2file($msg,$bat);
        system($bat);   # run it
        my ($ln,@arr,@dirs,$tmp,$var,$val,@arr2,$d2,$lnn);
        if (open INF, "<$fil") {
            @arr = <INF>;
            close INF;
            @dirs = ();
            $tmp = scalar @arr;
            prt( "[dbg_f14] Got $tmp lines, from $fil...\n" ) if ($dbg_gvc_14);
            $lnn = 0;
            foreach $ln (@arr) {
                chomp $ln;
                $ln = substr($ln,0,length($ln)-1) while ($ln =~ /\s$/);
                $lnn++;
                prt( "[dbg_f15] $lnn: $ln\n" ) if ($dbg_gvc_15);
                if ($ln =~ /(\w+)=(.+)/) {
                    $var = $1;
                    $val = $2;
                    prt( "$lnn: $var=$val\n" ) if ($dbg_gvc_15);
                    if ($var eq 'INCLUDE') {
                        @arr2 = split(";",$val);
                        $tmp = scalar @arr2;
                        # prt( "Got $tmp INCLUDE items...\n" );
                        foreach $d2 (@arr2) {
                            if (-d $d2) {
                                if (add_to_files_nc3($d2,$rda)) {
                                    prt("[dbg_f17] Folder [$d2] already in list.\n") if ($dbg_gvc_17);
                                } else {
                                    push(@dirs,$d2);
                                    prt("[dbg_f16] Added folder [$d2] $var\n") if ($dbg_gvc_16);
                                }
                            } else {
                                prt("[dbg_i19] NOTE: Can NOT locate folder [$d2] $var\n") if ($dbg_gvc_19);
                            }
                        }
                    } elsif ($var eq 'VSINSTALLDIR') {
                        $d2 = "$val";
                        $d2 .= "\\" if (!($d2 =~ /(\\|\/)$/));
                        $d2 .= "VC\\include";
                        if (-d $d2) {
                            if (add_to_files_nc3($d2,$rda)) {
                                prt("[dbg_f17] Folder [$d2] already in list.\n") if ($dbg_gvc_17);
                            } else {
                                push(@dirs,$d2);
                                prt("[dbg_f16] Added folder [$d2] $var=$val\n") if ($dbg_gvc_16);
                            }
                        } else {
                            prt("NOTE: Can NOT locate folder [$d2] $var=$val\n");
                        }
                    } elsif ($var eq 'WindowsSdkDir') {
                        $d2 = "$val";
                        $d2 .= "\\" if (!($d2 =~ /(\\|\/)$/));
                        $d2 .= "include";
                        if (-d $d2) {
                            if (add_to_files_nc3($d2,$rda)) {
                                prt("[dbg_f17] Folder [$d2] already in list.\n") if ($dbg_gvc_17);
                            } else {
                                push(@dirs,$d2);
                                prt("[dbg_f16] Added folder [$d2] $var=$val\n") if ($dbg_gvc_16);
                            }
                        } else {
                            prt("NOTE: Can NOT locate folder [$d2] $var=$val\n");
                        }
                    } elsif ($var eq 'FrameworkSDKDir') {
                        $d2 = "$val";
                        $d2 .= "\\" if (!($d2 =~ /(\\|\/)$/));
                        $d2 .= "include";
                        if (-d $d2) {
                            if (add_to_files_nc3($d2,$rda)) {
                                prt("[dbg_f17] Folder [$d2] already in list.\n") if ($dbg_gvc_17);
                            } else {
                                push(@dirs,$d2);
                                prt("[dbg_f16] Added folder [$d2] $var=$val\n") if ($dbg_gvc_16);
                            }
                        } else {
                            prt("NOTE: Can NOT locate folder [$d2] $var=$val\n");
                        }
                    } elsif ($var eq 'DXSDK_DIR') {
                        $d2 = "$val";
                        $d2 .= "\\" if (!($d2 =~ /(\\|\/)$/));
                        $d2 .= "include";
                        if (-d $d2) {
                            if (add_to_files_nc3($d2,$rda)) {
                                prt("[dbg_f17] Folder [$d2] already in list.\n") if ($dbg_gvc_17);
                            } else {
                                push(@dirs,$d2);
                                prt("[dbg_f16] Added folder [$d2] $var=$val\n") if ($dbg_gvc_16);
                            }
                        } else {
                            prt("NOTE: Can NOT locate folder [$d2] $var=$val\n");
                        }
                    }
                } else {
                    prt("[dbg_f18] NOTE: Line [$ln] skipped\n") if ($dbg_gvc_18);
                }
            }
            $tmp = scalar @dirs;
            prt( "[dbg_i18] get_include_dirs: return $tmp dirs...\n" ) if ($dbg_gvc_18);
            ${$rs} = [ @dirs ];
            $iret = 1;
        } else {
            prtw("ERROR: Failed to open [$fil]!!!\n");
        }
    } else {
        prtw( "ERROR: Failed to find [$bfil]!\n" );
    }
    #unlink $fil if (-f $fil);
    #unlink $bat if (-f $bat);
    return $iret;
}

sub get_vc8_dirs3 {
    my @vc8 = ();
    my %dirs = ();
    my $rd = \%dirs;
    my ($dir,$cnt,$insdir);
    foreach $dir (@vc8_found3) {
        if (-d $dir) {
            if ( add_to_files_nc3($dir,$rd) ) {
                # already in LIST
            } else {
                push(@vc8,$dir) if (-d $dir);
            }
        }
    }
    if (get_include_dirs3(\$insdir) ) {
        $cnt = scalar @{$insdir};
        # prt("OK got $cnt\n");
        foreach $dir (@{$insdir}) {
            if (-d $dir) {
                if ( add_to_files_nc3($dir,$rd) ) {
                    # already in LIST
                } else {
                    push(@vc8,$dir);
                }
            }
        }
    } else {
        prt("Failed to get include directories!\n");
    }
	#return @vc8_found;
	return \@vc8;
}

# ===================================================================
1;

