#!/usr/bin/perl -w # ####################################################################################### # module: fgdsphdrs03.pl - Version 3 - see fgdsphdrs.pl and 01 for versions 1 and 2 # header information, when building DSP files # 31/05/2010 - do not add a GROUP if the group string is null # 2010/05/05 - assume RELEASE when a DLL type # 2010/05/01 - added 'strict' and 'warnings', and did some fixes # 25/04/2010 - fix write_proj_DSW3, when outputing the 'copydsp' bat file, but still NOT correct is # -dsp= is given, and -fix_rel, since the dsw will have the old location, and likewise 'copydsp' ***TBD*** # 2010/04/23 - get_proj_begin() - remove '.\' in front of file, and added cwd() if output dsw is '.\' # 2010/03/08 - No warning when say ReadMe.txt is added 'outside' source groups. # 2010/03/01 - if vcproj contains IgnoreDefaultLibraryNames="MSVCRT", add /nodefaultlib:"MSVCRT" to DSP # Add this to the -NEW_OUT- substitution parameter - that is to the # ADD LINK32 line. # Can be DIFFERENT per configuration. # ALSO removed odbc32.lib and odbccp32.lib from the default dsp LINK32 # 2009/10/18 - incompatible with PREVIOUS versions. Begin separation of CONFIGURATION # so MULTIPLE configuration can be supported # # 20090819 - start to split header generation so additional options can be done # # 20090816 - Added ($dbg & 2) output of 'C_SOURCES' during check for duplicates # NOTE: The $hash{'C_SOURCES'} = [ @c_sources ] is of the form push(@c_sources, [ $file, $group, $filter ]); Similar for 'H_SOURCES'... # The 'default' group and filter are available through - # my $sgrp = get_def_src_grp(); # "Source Files"; my $sflt = get_def_src_filt(); # my $hgrp = get_def_hdr_grp(); # "Header Files"; my $hflt = get_def_hdr_filt(); # The DEFAULT hash, sub get_default_sub { } returns a HASH with all the '-NEW_*' items set. # To this MUST be added - # $hash{'APP_TYPE'} = $app_statlib_stg, or one of the other strings setting APPLICATION TYPE # and of course the above $hash{'C_SOURCES'} and 'H_SOURCES' before using sub write_hash_to_DSP2 {...} # # 10/11/2008 - Added /GR to compiler for each. Without this MSVC7 defaults to /GR-, which # disables Runt-Time Type Info, which causes a BIG problem with OSG # # APP_TYPE # $app_console_stg = 'Console Application' # $app_windows_stg = 'Application' # $app_dynalib_stg = 'Dynamic-Link Library' # $app_statlib_stg = 'Static Library' # $app_utility_stg = 'Utility' = *TBD* # # substitution variables # -NEW_PROJECT_NAME- = name of the project = MUST EXIST # -NEW_OUTD- = PROP Output_Dir ???? # -NEW_INTER- = PROP Intermediate_Dir ???? # ADD CPP with # -NEW_RT- = RUNTIME, like /MT /MD, /MTd, etc # -NEW_INCS- = INCLUDE DIRECTORIES, like /I ".." # -NEW_DEFS- = DEFINES, like /D "FGFS" # ADD LINK32 (for console, app, DLL) with # -NEW_LIBS- = Additional libraries for the link # -NEW_OUT- = link output, like /out:"StaticRelease\libpng.lib # -NEW_POST- = POST build - description and commands, TAB separated # ADD LIB32 (for static library) with # -NEW_OUT- = OUTPUT static library # 10/08/2010 - Note config can be divided into Debug, Release, thus # it is possible to have say R=foo.lib D=food_d.lib ... # ####################################################################################### use strict; use warnings; use Cwd; # DEBUG ONLY - should be OFF my $dbg_props = 0; my $g_write_dbg = 0; # given through write_hash_to_DSP3 or write_proj_DSW3 my $only_win32_conf = 1; # limitation to ONLY handle WIN32 configs sub set_dbg_props { $dbg_props = 1; } sub get_fetch_function($$$$); my $act_proj_dsphdrs = ''; # set on get # like zlib = ConfigurationType="4", alut = ConfigurationType="2", fg = ConfigurationType="1" # // This is an internal type to Visual Studio, it seems that: # // 4 == static library # // 2 == dll # // 1 == executable # // 10 == utility my $app_console_stg = 'Console Application'; my $app_windows_stg = 'Application'; my $app_dynalib_stg = 'Dynamic-Link Library'; my $app_statlib_stg = 'Static Library'; my $app_utility_stg = 'Utility'; # 2009/10/18 - return a REFERENCE to the NEW default sub get_default_sub3($) { my ($conf) = @_; my %def_sub = ( "-NEW_RT-" => "/MT", "-NEW_DEFS-" => "/D \"_CRT_SECURE_NO_WARNINGS\"", "-NEW_LIBS-" => "Winmm.lib ws2_32.lib", "-NEW_POST-" => "", "-NEW_INCS-" => "", "-NEW_OUTD-" => "", "-NEW_OUT-" => "", "-NEW_INTER-" => "\"Release\"" ); my $rds = \%def_sub; if ($conf == 1) { ${$rds}{"-NEW_RT-"} = '/MTd'; ${$rds}{"-NEW_INTER-"} = '"Debug"'; } return $rds; } sub get_default_sub_ref($) { my ($add) = @_; my %def_sub = ( "APP_TYPE" => "Static Library", "-NEW_PROJECT_NAME-" => "fgfs", "PROJECT_FLAGS" => [ 0, 0 ] ); if ($add) { $def_sub{'config-001-Debug'} = get_default_sub3(1); $def_sub{'config-002-Release'} = get_default_sub3(0); } return \%def_sub; } sub get_app_type_hash_ref_short() { my %short_2_app_type = ( 'CA' => $app_console_stg, 'WA' => $app_windows_stg, 'DLL' => $app_dynalib_stg, 'SL' => $app_statlib_stg ); return \%short_2_app_type; } sub get_app_type_4_short($$) { my ($st, $rs) = @_; my $ras = get_app_type_hash_ref_short(); if (defined ${$ras}{$st}) { ${$rs} = ${$ras}{$st}; return 1; } return 0; } # "Win32 (x86) Dynamic-Link Library" 0x0102 sub get_app_type_stg($) { my ($stg) = shift; if ($stg =~ /Static\s+Library/) { return $app_statlib_stg; } elsif ($stg =~ /Console\s+Application/) { return $app_console_stg; } elsif ($stg =~ /Dynamic-Link\s+Library/) { return $app_dynalib_stg; } return "Unresolved [$stg] FIXME in fgdsphdrs03.pl!!!"; } sub strip_quotes_02($) { my ($ln) = shift; if ($ln =~ /^".*"$/) { $ln = substr($ln,1,length($ln)-2); } return $ln; } sub dos_2_unix_02($) { my ($du) = shift; $du =~ s/\\/\//g; return $du; } sub scan_DSP_lines { my ($df,$mhr,$rdlns) = @_; my $lncnt = scalar @{$rdlns}; my @dspsrcs = (); my $projname = ''; my $projtype = ''; my $group = ''; my $filter = ''; my ($tmp, $key); my ($line); # 2010/05/01 my %dsp_hash = (); my $hr = \%dsp_hash; my @c_sources = (); my @h_sources = (); prt( "Scanning $lncnt lines, from [$df]...\n" ); ###prt( "File contains $lncnt lines ...\n" ); # push(@c_sources,[$src, $group, $filter, 0]); foreach $line (@{$rdlns}) { chomp $line; if ($line =~ /^#\s+Microsoft\s+Developer\s+Studio\s+.+Name="(\w+)".+$/) { $projname = $1; prt( "Project Name [$projname]\n" ); # -NEW_PROJECT_NAME-" = name of the project $key = '-NEW_PROJECT_NAME-'; ${$hr}{$key} = $projname; } elsif ($line =~ /^#\s+TARGTYPE\s+(.*)/) { $tmp = $1; #prt( "# TARGTYPE $1\n" ); $projtype = get_app_type_stg($tmp); prt( "Project Type [$projtype]\n" ); $key = 'APP_TYPE'; ${$hr}{$key} = $projtype; } elsif ( $line =~ /^#\s+Begin\s+Group\s+(.*)/ ) { $group = strip_quotes_02($1); prt( "Begin Group [$group]\n" ); } elsif ( $line =~ /^#\s+PROP\s+Default_Filter\s+"(.*)".*$/ ) { $filter = $1; prt( "Filter [$filter]\n" ); } elsif ( $line =~ /^SOURCE=/ ) { $line =~ s/^SOURCE=//o; while ($line =~ /\W$/) { # ending in NON-alphanumic ####prt( "Discarding [".substr($line,-1,1)."]!\n" ); $line = substr($line,0,length($line)-1); } ##while (( substr($line,-1,1) eq ' ' )||( substr($line,-1,1) eq "\t")|| ## ( substr($line,-1,1) eq "\r")||( substr($line,-1,1) eq "\n")) { ## $line = substr($line,0,length($line)-1); ##} $line =~ s/^\"//; # remove leading inverted commas $line =~ s/\"$//; # remove trailing inverted commas $line = dos_to_unix_02($line); $line =~ s/^\.\///; if (($line =~ /\.cxx$/i) || ($line =~ /\.c$/i) || ($line =~ /\.cpp$/i) || ($line =~ /\.cc$/i)) { push(@dspsrcs, $line); push(@c_sources, [$line, $group, $filter]); } elsif ( ($line =~ /\.hxx$/i) || ($line =~ /\.h$/i) || ($line =~ /\.hpp$/i) ) { push(@dspsrcs, $line); push(@h_sources, [$line, $group, $filter]); } else { if ( !($line =~ /^\$\(/) ) { prt( "CHECK Discarded [$line]\n" ); } } } } $key = 'C_SOURCES'; ${$hr}{$key} = [@c_sources]; $key = 'H_SOURCES'; ${$hr}{$key} = [@h_sources]; $key = $projname; ${$mhr}{$key} = $hr; $lncnt = scalar @dspsrcs; prt( "File [$df] contains $lncnt SOURCES ...\n" ); return \@dspsrcs; } sub process_DSP_file($$) { my ($df,$rmh) = @_; if (open(INF, "<$df")) { my @lns = ; close INF; my $lncnt = scalar @lns; my $rdsrcs = scan_DSP_lines($df,$rmh,\@lns); } else { prtw("WARNING:scan_DSP_file: Unable to OPEN [$df]!\n"); } } # building a DSP configuration block #!IF ..(a).. #!ELSEIF ..(b).. #!ELSE ..(c).. #!ENDIF sub get_list_of_subs($) { my ($txt) = @_; my $len = length($txt); my ($i,$tag,$cc); my @arr = (); my %h = (); $tag = ''; # start NO TAG for ($i = 0; $i < $len; $i++) { $cc = substr($txt,$i,1); if ($cc =~ /(\w|-)/) { $tag .= $cc; # accumulate TAG - add all '-' or \w (which INCLUDES the '_' char) } else { # NOT '-' or \w (which INCLUDES the '_' char) if (length($tag) && ($tag =~ /^-NEW_/)) { # if the TAG begins properly #push(@arr,$tag); $h{$tag} = 1; # store the substitution tag, like -NEW_LIBS-, } $tag = ''; # clear tag and seek more } } @arr = sort keys(%h); # but just want an ARRAY list $len = scalar @arr; # we MUST collect tags if ($len == 0) { prt( "ERROR: Collected NO tags! From string of $len chars -\n" ); prt( "$txt\n" ); pgm_exit(1,"NO TAGS FOUND in above! Seeking '-NEW_...'!"); } else { #prt(" $len sub-tags " ); } return \@arr; # return array reference } ################################################################################ # ============================================================================ # sub get_project_name($$) { my ($rh,$rn) = @_; my $key = '-NEW_PROJECT_NAME-'; my ($nm); $key = 'PROJECT_NAME' if (!defined ${$rh}{$key}); if (defined ${$rh}{$key}) { $nm = ${$rh}{$key}; if (length($nm)) { ${$rn} = $nm; return 1; } else { prtw("WARNING: Project name string BLANK!\n"); } } return 0; } sub get_common_dsp_head($$) { my ($rh,$name) = @_; my $key = '-NEW_PROJECT_NAME-'; my $dsp_head = < # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** EOF $dsp_head =~ s/$key/$name/g; return $dsp_head; } sub get_targ_type_ref() { my %type_2_target_type_hash = ( $app_console_stg => '# TARGTYPE "Win32 (x86) Console Application" 0x0103', $app_windows_stg => '# TARGTYPE "Win32 (x86) Application" 0x0101', $app_dynalib_stg => '# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102', $app_statlib_stg => '# TARGTYPE "Win32 (x86) Static Library" 0x0104' ); return \%type_2_target_type_hash; } # based on list sub get_based_on_ref() { my %type_2_based_on_hash = ( $app_console_stg => '(based on "Win32 (x86) Console Application")', $app_windows_stg => '(based on "Win32 (x86) Application")', $app_dynalib_stg => '(based on "Win32 (x86) Dynamic-Link Library")', $app_statlib_stg => '(based on "Win32 (x86) Static Library")' ); return \%type_2_based_on_hash; } sub get_APP_TYPE_string($) { my ($rh) = @_; my $key = 'APP_TYPE'; $key = 'PROJECT_APTP' if (!defined ${$rh}{$key}); return $key; } sub get_project_type($$) { my ($rh,$rs) = @_; my $key = get_APP_TYPE_string($rh); # 'APP_TYPE' or 'PROJECT_APTP' if (defined ${$rh}{$key}) { ${$rs} = ${$rh}{$key}; return 1; } return 0; } sub is_dll_project($) { my ($rh) = @_; my ($type); if (get_project_type($rh,\$type) ) { if ($type eq $app_dynalib_stg) { return 1; } } return 0; } sub is_app_project($) { my ($rh) = @_; my ($type); if (get_project_type($rh,\$type) ) { if ($type eq $app_windows_stg) { return 1; } } return 0; } sub get_based_on_stg($$) { my ($rh,$rs) = @_; my $typ = ''; if (get_project_type($rh,\$typ)) { my $rtth = get_based_on_ref(); if (defined ${$rtth}{$typ}) { ${$rs} = ${$rtth}{$typ}; return 1; } } return 0; } sub add_targ_type($$) { my ($rh,$rs) = @_; my $key = get_APP_TYPE_string($rh); # 'APP_TYPE' or 'PROJECT_APTP' my $rtth = get_targ_type_ref(); if (defined ${$rh}{$key}) { my $typ = ${$rh}{$key}; if (defined ${$rtth}{$typ}) { ${$rs} .= ${$rtth}{$typ}."\n\n"; return 1; } } return 0; } sub add_def_config3($$) { my ($rh,$rs) = @_; my $name = ''; return 0 if ( !get_project_name($rh,\$name) && length($name) ); my ($key,$rcfgs,$cnt,$conf,$confname); my ($i); # 2010/05/01 # my $rcfgs = ${$rh}{'PROJECT_CFGS'}; $key = 'PROJECT_CFGS'; if (defined ${$rh}{$key}) { $rcfgs = ${$rh}{$key}; $cnt = scalar @{$rcfgs}; if ($cnt) { # 0 1 2 3 # Debug -NEW_OUTD- Debug|WIN32 # push(@{$rcfgs}, [ $confname, $var1, $conf, $dsp_sub_sub ]); # search for 'Debug', and make it the Default for ($i = 0; $i < $cnt; $i++) { $confname = ${$rcfgs}[$i][0]; if ($confname eq 'Debug') { $conf = "$name - Win32 $confname"; ${$rh}{'CURR_CONF'} = $confname; ${$rh}{'CURR_CON1'} = ${$rcfgs}[$i][2]; ${$rs} .= "CFG=$conf\n"; return 1; } } # could not find pure 'Debug', so use FIRST in array $confname = ${$rcfgs}[0][0]; $conf = "$name - Win32 $confname"; ${$rh}{'CURR_CONF'} = $confname; ${$rh}{'CURR_CON1'} = ${$rcfgs}[$i][2]; ${$rs} .= "CFG=$conf\n"; return 1; } } return 0; } sub add_def_config($$) { my ($rh,$rs) = @_; my ($key); my $name = ''; return 0 if ( !get_project_name($rh,\$name) && length($name) ); # first search for 'Debug', and make it the DEFAULT foreach $key (keys %{$rh}) { if ($key =~ /^config-\d+/) { # this is the FIRST config item - make it the DEFAULT # like $def_sub{'config-001-Debug'} = get_default_sub3(); my @arr = split('-',$key); my $cnt = scalar @arr; if ( $cnt >= 3) { my $conf = $arr[2]; my $i = 3; for (; $i < $cnt; $i++) { $conf .= '-'; $conf .= $arr[$i]; } if ($conf eq 'Debug') { ${$rs} .= "CFG=$name - Win32 $conf\n"; return 1; } } } } # No pure 'Debug' found, so take the FIRST foreach $key (sort keys %{$rh}) { if ($key =~ /^config-\d+/) { # this is the FIRST config item - make it the DEFAULT # like $def_sub{'config-001-Debug'} = get_default_sub3(); my @arr = split('-',$key); my $cnt = scalar @arr; if ( $cnt >= 3) { my $conf = $arr[2]; my $i = 3; for (; $i < $cnt; $i++) { $conf .= '-'; $conf .= $arr[$i]; } ${$rs} .= "CFG=$name - Win32 $conf\n"; return 1; } } } return 0; } # Get the configs into a tidy array my $prev_proj_name = ''; sub get_configs_array3($$$) { my ($rh,$rs,$name) = @_; my @confarr = (); my ($key,$rcfgs,$cnt,$confname,$hr2,$conf,$test,@offs,$vcconf,@arr); my ($i,$ncnt); # 2010/05/01 my $prt_out = ($prev_proj_name eq $act_proj_dsphdrs) ? 0 : 1; # my $rcfgs = ${$rh}{'PROJECT_CFGS'}; my $dbg = $g_write_dbg; $key = 'CURR_DBGF'; $dbg = ${$rh}{$key} if (defined ${$rh}{$key}); if ($dbg & 128) { $prt_out = 1; } else { $prt_out = 0; } $key = 'PROJECT_CFGS'; @offs = (); if (defined ${$rh}{$key}) { $rcfgs = ${$rh}{$key}; $cnt = scalar @{$rcfgs}; prt("fgdsphdrs03.pl:get_configs_array3: Got $cnt CONFIGS...\n") if ($prt_out); $test = 0; push(@offs,-99); # setup min of 2 offsets push(@offs,-99); # to be fixed when found, IF found for ($i = 0; $i < $cnt; $i++) { $confname = ${$rcfgs}[$i][0]; $vcconf = ${$rcfgs}[$i][2]; # SPECIAL FIX = ONLY INCLUDE WIN32 # next if ($only_win32_conf && !($vcconf =~ /WIN32/i)); @arr = split(/\|/, $vcconf); if (($confname eq 'Release') && !($test & 1) && ($vcconf =~ /Win32/i)) { $offs[0] = $i; $test |= 1; } elsif (($confname eq 'Debug') && !($test & 2) && ($vcconf =~ /Win32/i)) { $offs[1] = $i; $test |= 2; } else { push(@offs,$i); } } if ($test == 3) { $ncnt = scalar @offs; if ($ncnt != $cnt) { prt("fgdsphdrs03.pl:get_configs_array3: Reduced to $ncnt of $cnt CONFIGS\n") if ($prt_out); } # process in ORDER 'Release, Debug, Others' # 0 1 2 3 # Debug -NEW_OUTD- Debug|WIN32 # push(@{$rcfgs}, [ $confname, $var1, $conf, $dsp_sub_sub ]); foreach $i (@offs) { $confname = ${$rcfgs}[$i][0]; $vcconf = ${$rcfgs}[$i][2]; $hr2 = ${$rcfgs}[$i][3]; @arr = split(/\|/, $vcconf); # build the NAME string $arr[1] = "Win64" if ($arr[1] =~ /64/); $conf = "\"$name - $arr[1] $confname\""; # 0 1 2 push(@confarr,[ $conf, '', $hr2 ] ); prt("fgdsphdrs03.pl:get_configs_array3:1: Stored [$conf]\n") if ($prt_out); if (length(${$rs}) == 0) { ${$rs} = $conf; # set the FIRST, as DEFAULT ${$rh}{'CURR_CONF'} = $confname; ${$rh}{'CURR_CON1'} = ${$rcfgs}[$i][2]; } } } else { # process in array ORDER # 0 1 2 3 # Debug -NEW_OUTD- Debug|WIN32 # push(@{$rcfgs}, [ $confname, $var1, $conf, $dsp_sub_sub ]); for ($i = 0; $i < $cnt; $i++) { $confname = ${$rcfgs}[$i][0]; $vcconf = ${$rcfgs}[$i][2]; $hr2 = ${$rcfgs}[$i][3]; next if ($only_win32_conf && !($vcconf =~ /WIN32/i)); # build the NAME string $conf = "\"$name - Win32 $confname\""; # 0 1 2 push(@confarr,[ $conf, '', $hr2 ] ); prt("fgdsphdrs03.pl:get_configs_array3:2: Stored [$conf]\n") if ($prt_out); if (length(${$rs}) == 0) { ${$rs} = $conf; # set the FIRST, as DEFAULT ${$rh}{'CURR_CONF'} = $confname; ${$rh}{'CURR_CON1'} = ${$rcfgs}[$i][2]; } } } } # ======================== $key = 'CURR_CARR'; ${$rh}{$key} = [@confarr]; # ======================== $prev_proj_name = $act_proj_dsphdrs; return \@confarr; } sub get_configs_array($$$) { my ($rh,$rs,$name) = @_; my @confarr = (); my %hash = (); my ($key,@arr,$conf,$cnt,$test,@ckeys,$keylist); my ($i); # 2010/05/01 ${$rs} = ''; # "-NEW_PROJECT_NAME- - Win32 Release" # Try to enforce order @ckeys = (); $test = 0; push(@ckeys,''); push(@ckeys,''); foreach $key (keys %{$rh}) { if ($key =~ /^config-\d+/) { @arr = split('-',$key); $conf = ''; $cnt = scalar @arr; if ( $cnt >= 3) { $conf .= $arr[2]; $i = 3; for (; $i < $cnt; $i++) { $conf .= '-'; $conf .= $arr[$i]; } } if ($conf eq 'Release') { $ckeys[0] = $key; $test |= 1; } elsif ($conf eq 'Debug') { $ckeys[1] = $key; $test |= 2; } else { push(@ckeys,$key); } } } if ($test == 3) { #prt( "We can ORDER the KEYS\n" ); foreach $key (@ckeys) { my $rh2 = ${$rh}{$key}; # like $def_sub{'config-001-Debug'} = get_default_sub3(); @arr = split('-',$key); $conf = "\"$name - Win32 "; $cnt = scalar @arr; if ( $cnt >= 3) { $conf .= $arr[2]; $i = 3; for (; $i < $cnt; $i++) { $conf .= '-'; $conf .= $arr[$i]; } $conf .= '"'; ${$rs} = $conf if (length(${$rs}) == 0); if (defined $hash{$conf}) { prtw("WARNING: DUPLICATED config [$conf]!\n"); @arr = (); return @arr; } $hash{$conf} = 1; ### prt("CONFIG: [$conf], key=[$key]\n"); push(@confarr,[ $conf, $key, $rh2 ] ); } else { prtw("WARNING: split of [$key] did not give 3 or more items!\n"); @arr = (); return @arr; } } } else { prtw( "Order of keys FAILED! Using pure key sort order - 'config-???-Debug', etc\n" ); foreach $key (sort keys %{$rh}) { if ($key =~ /^config-\d+/) { my $rh2 = ${$rh}{$key}; # like $def_sub{'config-001-Debug'} = get_default_sub3(); @arr = split('-',$key); $conf = "\"$name - Win32 "; $cnt = scalar @arr; if ( $cnt >= 3) { $conf .= $arr[2]; $i = 3; for (; $i < $cnt; $i++) { $conf .= '-'; $conf .= $arr[$i]; } $conf .= '"'; ${$rs} = $conf if (length(${$rs}) == 0); if (defined $hash{$conf}) { prtw("WARNING: DUPLICATED config [$conf]!\n"); @arr = (); return @arr; } $hash{$conf} = 1; ### prt("CONFIG: [$conf], key=[$key]\n"); push(@confarr,[ $conf, $key, $rh2 ] ); } else { prtw("WARNING: split of [$key] did not give 3 or more items!\n"); @arr = (); return @arr; } } } } ### prt( "Return ref to array of ".scalar @confarr." configs...\n" ); $key = 'CURR_CARR'; ${$rh}{$key} = [@confarr]; return \@confarr; } sub get_hash_version($) { my ($rh) = @_; my $key = 'PROJECT_VERS'; if (defined ${$rh}{$key}) { return ${$rh}{$key}; } return 0; } sub add_message_section($$) { my ($rh,$rs) = @_; my ($name, $conf, $i, $cnt, @arr, $basedon, $msg, $key); my ($hvers, $conf1, $rconfarr, $func); $hvers = get_hash_version($rh); if ($hvers) { $func = \&get_configs_array3; # ($$$); } else { $func = \&get_configs_array; # ($$$); } if ( !get_project_name($rh,\$name) ) { return 0; } if ( !get_based_on_stg($rh, \$basedon) ) { return 0; } $conf1 = ''; $rconfarr = $func->($rh, \$conf1, $name); $cnt = scalar @{$rconfarr}; if ($cnt < 2) { prtw("WARNING: get_configs_array returned [$cnt] configs!\n" ); return 0; } $msg = "!MESSAGE This is not a valid makefile. To build this project using NMAKE,\n"; $msg .= "!MESSAGE use the Export Makefile command and run\n"; $msg .= "!MESSAGE \n"; $msg .= "!MESSAGE NMAKE /f \"".$name.".mak\".\n"; $msg .= "!MESSAGE \n"; $msg .= "!MESSAGE You can specify a configuration when running NMAKE\n"; $msg .= "!MESSAGE by defining the macro CFG on the command line. For example:\n"; $msg .= "!MESSAGE \n"; $msg .= "!MESSAGE NMAKE /f \"".$name.".mak\" CFG=".$conf1."\n"; $msg .= "!MESSAGE \n"; $msg .= "!MESSAGE Possible choices for configuration are:\n"; $msg .= "!MESSAGE \n"; for ($i = 0; $i < $cnt; $i++) { $conf = ${$rconfarr}[$i][0]; $msg .= "!MESSAGE $conf $basedon\n"; } $msg .= "!MESSAGE \n"; $msg .= "\n"; ${$rs} .= $msg; return 1; } sub get_compile_block($$) { my ($rh,$rs) = @_; return 0; } sub get_project_flag($) { my ($rh) = @_; my $key = "PROJECT_FLAGS"; my $flag = 0; if (defined ${$rh}{$key}) { $flag = ${$rh}{$key}[0]; } return $flag; } sub get_dsp_head_stg($$$) { my ($rh,$rs,$dbg) = @_; my $name = ''; my $type = ''; my ($i,$conf,$key,$rh2,$hvers,$func,$func2); my $modstg = 'fgdpshdrs03:get_dsp_head_stg;'; my ($nt,@tmparr); $hvers = get_hash_version($rh); if ($hvers) { $func = \&get_configs_array3; # ($$$); $func2 = \&add_def_config3; } else { $func = \&get_configs_array; # ($$$); $func2 = \&add_def_config; } my $pflag = get_project_flag($rh); $name = ''; if ( !get_project_name($rh, \$name) || (length(trim_all($name)) == 0)) { prtw("ERROR:$modstg Unable to get project name!\n"); return 0; } if ( !get_project_type($rh, \$type) ) { prtw("ERROR:$modstg Unable to get project type!\n"); return 0; } my $isdllapp = (is_dll_project($rh) | is_app_project($rh)); my $conf1 = ''; #my $rconfarr = get_configs_array($rh, \$conf1, $name); my $rconfarr = $func->($rh, \$conf1, $name); my $cnt = scalar @{$rconfarr}; if ($cnt < 2) { prtw("WARNING:$modstg get_configs_array returned [$cnt] configs!\n" ); return 0; } my $flag = 0; for ($i = 0; $i < $cnt; $i++) { $conf = ${$rconfarr}[$i][0]; if ($hvers == 0) { # first version hash $key = ${$rconfarr}[$i][1]; if ( !defined ${$rh}{$key}) { prtw("WARNING:$modstg Unable to get ref HASH for key [$key] [$conf]!\n"); return 0; } } if ($conf =~ /Release/i) { $flag |= 1; } elsif ($conf =~ /Debug/i) { $flag |= 2; } elsif ($conf =~ /DLL/) { $flag |= 1; # 2010/05/05 - assume RELEASE when a DLL type } else { prtw("WARNING:$modstg Can NOT put [$conf] in Debug or Release category [$key]!\n"); return 0; } } if ($flag != 3) { prtw("WARNING:$modstg Do NOT have at least 1 Debug and 1 Release category!\n"); return 0; } # =========================================================== # commence string my $dsp_stg = get_common_dsp_head($rh,$name); if ( !add_targ_type($rh, \$dsp_stg) ) { prtw("WARNING:$modstg Unable to get target type string!\n"); return 0; } # if ( !add_def_config($rh, \$dsp_stg) ) { if ( ! $func2->($rh, \$dsp_stg) ) { prtw("WARNING:$modstg Unable to get default config string!\n"); return 0; } if ( !add_message_section($rh, \$dsp_stg) ) { prtw("WARNING:$modstg Unable to get MESSAGE section!\n"); return 0; } $dsp_stg .= "# Begin Project\n"; $dsp_stg .= "# PROP AllowPerConfigDependencies 0\n"; $dsp_stg .= "# PROP Scc_ProjName \"\"\n"; $dsp_stg .= "# PROP Scc_LocalPath \"\"\n"; $dsp_stg .= "CPP=cl.exe\n"; $dsp_stg .= "MTL=midl.exe\n" if ($isdllapp); $dsp_stg .= "RSC=rc.exe\n"; $dsp_stg .= "\n"; $func = 0; # begin the CONFIGS... process substitution of things like say -NEW_LIBS-, on a PER config basis $flag = 0; for ($i = 0; $i < $cnt; $i++) { $conf = ${$rconfarr}[$i][0]; # This is the FULL string 'name - Win32 Debug' $rh2 = ${$rconfarr}[$i][2]; if ($conf =~ /Release/i) { $flag = 1; } elsif ($conf =~ /Debug/i) { $flag = 2; } elsif ($conf =~ /DLL/) { $flag = 1; # 2010/05/05 - assume RELEASE when a DLL type } #if ($hvers) { # $rh2 = ${$rconfarr}[$i][2]; #} else { # $key = ${$rconfarr}[$i][1]; # if (defined ${$rh}{$key}) { # $rh2 = ${$rh}{$key}; # } else { # prtw("WARNING:$modstg Unable to get ref HASH for key [$key]!\n"); # return 0; # } #} if ($i == 0) { # !IF "\$(CFG)" == "-NEW_PROJECT_NAME- - Win32 Release" $dsp_stg .= "!IF \"\$(CFG)\" == $conf\n\n"; } else { #!ELSEIF "\$(CFG)" == "-NEW_PROJECT_NAME- - Win32 Debug" $dsp_stg .= "!ELSEIF \"\$(CFG)\" == $conf\n\n"; } if ( get_fetch_function($type,$conf,\$func,$dbg) ) { my $stg = $func->(); my $rsa = get_list_of_subs($stg); # collect list of '-NEW_...' tags # DO THE SUSTITUTIONS, per configuration # ====================================== prt( "Doing substitutions for [$conf] [$type] [dbg & 8])\n" ) if ($dbg & 8); foreach my $ky (@{$rsa}) { if (defined ${$rh2}{$ky}) { $nt = ${$rh2}{$ky}; # extract the substitution value prt( "Subbed $ky with [$nt] [dbg & 8]\n" ) if ($dbg & 8); $stg =~ s/$ky/$nt/gm; # DO IT } else { prtw( "WARNING:$modstg Substitution for [$ky] is NOT in extracted reference!\n" ); @tmparr = keys(%{$rh2}); prt( "Got " ); foreach $nt (@tmparr) { prt("[$nt]"); } prt("\n"); return 0; } } # ================================== $dsp_stg .= $stg; # add now substituted string to DSP output string } else { prtw("WARNING:$modstg Unable to get fetch function [$key][$conf][$type]!\n"); return 0; } } $dsp_stg .= "!ENDIF \n"; $dsp_stg .= "\n"; $dsp_stg .= "# Begin Target\n"; $dsp_stg .= "\n"; # Name "-NEW_PROJECT_NAME- - Win32 Release" # Name "-NEW_PROJECT_NAME- - Win32 Debug" for ($i = 0; $i < $cnt; $i++) { $conf = ${$rconfarr}[$i][0]; # This is the FULL string, with quotes, like '"name - Win32 Debug"' $dsp_stg .= "# Name - $conf\n"; } ${$rs} = $dsp_stg; return 1; } sub get_def_lib_list() { my $ll = 'kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib'; return $ll; } # Windows Console Application # =========================== sub get_dsp_console_rel { my $dsp_head = < [ ['get_dsp_console_rel', \&get_dsp_console_rel], ['get_dsp_console_dbg', \&get_dsp_console_dbg] ], $app_windows_stg => [ ['get_dsp_app_rel' , \&get_dsp_app_rel ], ['get_dsp_app_dbg' , \&get_dsp_app_dbg ] ], $app_dynalib_stg => [ ['get_dsp_dynalib_rel', \&get_dsp_dynalib_rel], ['get_dsp_dynalib_dbg', \&get_dsp_dynalib_dbg] ], $app_statlib_stg => [ ['get_dsp_slib_rel' , \&get_dsp_slib_rel ], ['get_dsp_slib_dbg' , \&get_dsp_slib_dbg ] ] ); if (defined $type_2_functions{$type}) { my $ra = $type_2_functions{$type}; $msg = ${$ra}[$dbrel][0]; ${$rfunc} = ${$ra}[$dbrel][1]; } else { prtw("WARNING: type [$type] string NOT matched! [$conf]\n"); return 0; } prt( "Returning function '$msg' for [$conf] of [$type]...[dbg & 16]\n" ) if ($dbg & 16); return 1; } # ============================================================================ # ################################################################################ sub get_dsp_tail { my $dsp_tail = < {{{ }}} Package=<3> {{{ }}} ############################################################################### EOF return $raw_dswt; } sub get_dsp_header_text { my ($rm, $v) = @_; my $iok = 0; prtw( "WARNING: get_dsp_header_text: DEPRECIATED FUNCTION USED!\n" ); return $iok; } my $def_runtime_lts = "MD"; my $def_runtime_stg = "Multithreaded DLL"; my $def_runtime_val = 2; # 0 1 2 3 4 my @fg_runtimes_array = ( ["RuntimeLibrary", "MT", "Multithreaded", 0, 0], ["RuntimeLibrary", "MTd", "Multithreaded Debug", 1, 0], ["RuntimeLibrary", $def_runtime_lts, $def_runtime_stg, $def_runtime_val, 0], ["RuntimeLibrary", "MDd", "Multithreaded DLL Debug", 3, 0], ["RuntimeLibrary", "ML", "Single Thread", 4, 0], ["RuntimeLibrary", "MLd", "Single Thread Debug", 5, 0] ); sub fg_get_runtime_val_2_lts { my ($rtn) = shift; my $len = scalar @fg_runtimes_array; for (my $i = 0; $i < $len; $i++) { my $itm = $fg_runtimes_array[$i][3]; if ($itm == $rtn) { return "/" . $fg_runtimes_array[$i][1]; } } prtw( "WARNING: $rtn not found in runtimes array! Using default '$def_runtime_lts'!!\n" ); return "/$def_runtime_lts"; } sub get_app_conf_type { my ($ct) = shift; # per $app_windows_stg, 2 => $app_dynalib_stg, 4 => $app_statlib_stg, 10 => $app_utility_stg ); my $at = ''; if (defined $vc_cts{$ct}) { $at = $vc_cts{$ct}; } else { prtw( "WARNING: Failed to FIND '$ct' in v8_conftypes!\n" ); mydie( "ABORTING, in disgust ;=))\n" ); } return $at; } # $apptype = adjust_app_type_per_subsystem( $apptype, $adddeps ); sub adjust_app_type_per_subsystem { my ($capt,$ss,$dbg) = @_; # and if 1 ($app_windows), then per SubSystem # $app_console_stg, 2 => $app_windows_stg ); if (defined $vc_ss{$ss}) { my $napt = $vc_ss{$ss}; if ($capt eq $napt) { prt("Got APPTYPE: NO CHANGE [$capt] equals SubSystem ($ss) [$napt] ...\n" ) if ($dbg); } else { if ($capt eq $app_dynalib_stg) { if ($napt eq $app_windows_stg) { # these are NOT incompatible, so NO CHANGE prt("Got APPTYPE: NO CHANGE [$capt] EQUIVALENT to $ss ($napt) ...\n" ) if ($dbg); } else { prtw("WARNING: NO CHANGE but [$capt] NOT EQUIVALENT to $ss ($napt) ...\n" ); } } else { prt("Set APPTYPE: from [$capt], to [$napt] ($ss).\n" ) if ($dbg); $capt = $napt; } } } return $capt; } # function: get_balance_of_line_bump_offset # parameters passed: # $rt = reference to counter # $tx = balance of file string sub get_balance_of_line_bump_offset { my ($rt,$tx) = @_; my $ln = length($tx); my $ba = ''; for (my $k = 0; $k < $ln; $k++) { my $ch = substr($tx,$k,1); if ($ch eq "\n") { $$rt++; return $ba; } $ba .= $ch; $$rt++; } return $ba; } sub get_if_props { my ($txt) = shift; my @lns = split("\n",$txt); my $len = scalar @lns; my ($t, $ln, $iln, $idir); my $props = ''; my $pr = '#\\s+PROP\\s+Intermediate_Dir\\s+"(.+)".*'; for ($t = 0; $t < $len; $t++) { $ln = $lns[$t]; chomp $ln; if ($ln =~ /\!MESSAGE\s+/) { # ignore this } elsif ($ln =~ /\!IF\s+/) { $iln = $ln; prtw("WARNING:$t: NOT FIRST FOUND [$ln]\n") if length($props); $props = "\n$ln\n\n"; prt( "LINE $t: [$ln]\n" ) if ($dbg_props); $t++; for ( ; $t < $len; $t++) { $ln = $lns[$t]; chomp $ln; ##if ($ln =~ /#\s+PROP\s+Intermediate_Dir\s+"(.+)".*/) { if ($ln =~ /$pr/) { $idir = $1; $idir .= "\\Dupes"; $ln =~ s/$1/$idir/; $props .= $ln."\n\n"; $t++; prt( "ID $t = [$ln]\n" ) if ($dbg_props); last; } } } elsif ($ln =~ /\!ELSEIF\s+/) { $props .= "$ln\n\n"; prt( "LINE $t: [$ln]\n" ) if ($dbg_props); $t++; for ( ; $t < $len; $t++) { $ln = $lns[$t]; chomp $ln; ###if ($ln =~ /#\s+PROP\s+Intermediate_Dir\s+"(.+)".*/) { if ($ln =~ /$pr/) { $idir = $1; $idir .= "\\Dupes"; $ln =~ s/$1/$idir/; $props .= $ln."\n\n"; $t++; prt( "ID $t = [$ln]\n" ) if ($dbg_props); last; } } } elsif ($ln =~ /\!ENDIF\s+/) { $props .= "$ln\n\n"; prt( "LINE $t: [$ln]\n" ) if ($dbg_props); } } return $props; } sub add_dotrel_if_none { my ($fl) = shift; $fl = ".\\".$fl if !($fl =~ /^\./); return $fl; } # 2009/10/25 - special provision for RC files - not really duplicates # 20090910 - this version expects SOURCE file array to be in form # 0 1 2 3 +++ #push(@cs, [$sfile, $sgrp, $sflt, $hm] ); # if $hm is 1, then '# PROP Exclude_From_Build 1' is added after source # DEBUG # prt( "Processing project [$capname], $captyp, to $of\n" ) if ($dbg & 1); # prt( "CS: [$fil]\n" ) if ($dbg & 2); # prt( "HS: [$fil]\n" ) if ($dbg & 2); # prt("Note: There appears to be NO header files...\n") if ($dbg & 4); # prt( "Doing substitutions for [$conf] [$type]\n" ) if ($dbg & 8); # prt( "Subbed $ky with [$nt]\n" ) if ($dbg & 8); # prt( "Returning function '$msg' for [$conf] of [$type]...\n" ) if ($dbg & 16); # prt( "[dbg & 32] Got $cnt groups of headers [" ); and prt( "[dbg & 32] Got $cnt groups of sources [" ); sub write_hash_to_DSP3 { my ($of, $rh, $dbg) = @_; # say ('tempvcscan.dsp', \%h, 0); $g_write_dbg = $dbg; my ($val, $msg, $key, $cnt, $srcs, $captyp, $capname); my $isok = 1; # assume it IS ok my ($fnam, $ftyp, $i, $fil, $cnt2); my ($dupes, $nm, $dr, $ext, @dups, $props); my ($hm, $hm_msg, $tmp, $tmp2); # added 20090910 my ($rsa, $adde,$i2); # 2009/10/19 - check have SUBSTITUTES for ALL SUBS my ($key2, $hvers); my %dsrc = (); my $def_src_group = 'Source Files'; # added 20090915 my $def_hdr_group = 'Header Files'; # added 20090915 my $def_oth_group = 'Other Files'; # added 20090915 my $src_group = ''; my $hdr_group = ''; my $oth_group = ''; my %src_groups = (); my %hdr_groups = (); my $flag = 0; my @tarr = (); my $outsrccnt = 0; my $modstg = 'fgdsphdrs03:write_hash_to_DSP3'; my $grplen = 0; $tmp2 = ''; # clear this 20100116 $key = "CURR_DBGF"; ${$rh}{$key} = $dbg if (!defined ${$rh}{$key}); # store current DEBUG flag $hvers = get_hash_version($rh); prt("Hash version: [$hvers] (dbg & 0x8000)\n") if ($dbg & 0x8000); $key = "PROJECT_FLAGS"; if (defined ${$rh}{$key}) { $flag = ${$rh}{$key}[0]; $dbg |= ${$rh}{$key}[1]; } $msg = ''; $key = '-NEW_PROJECT_NAME-'; if (defined ${$rh}{$key}) { $capname = ${$rh}{$key}; } else { $key2 = 'PROJECT_NAME'; if (defined ${$rh}{$key2}) { $capname = ${$rh}{$key2}; $hvers = 1; } else { prtw( "WARNING:$modstg: No project NAME in hash... key=[$key]or[$key2]\n" ); $isok = 0; } } $act_proj_dsphdrs = $capname; if ($isok) { $key = get_APP_TYPE_string($rh); # $hvers ? 'PROJECT_TYPE' : 'APP_TYPE'; if (defined ${$rh}{$key}) { $captyp = ${$rh}{$key}; } else { prtw( "WARNING:$modstg: No application type in hash ... key=[$key]\n" ); $isok = 0; } } if ($isok) { prt( "\nProcessing project [$capname], $captyp... [dbg & 1]\n" ) if ($dbg & 1); if ($hvers) { $key = 'PROJECT_SRCS'; if (defined ${$rh}{$key}) { $srcs = ${$rh}{$key}; # = [@vc_c_sources]; $cnt = scalar @{$srcs}; if ($cnt == 0) { prtw( "WARNING:$modstg: No source files in hash ... key=[$key]\n" ); $isok = 0; } else { my $rsa = ${$srcs}[0]; $cnt = scalar @{$rsa}; if ($cnt < 4) { prtw( "WARNING:$modstg:1: (ref) Array of a source NOT enough depth (have $cnt, should be 4, or more ...\n" ); $isok = 0; } } } } else { $key = 'C_SOURCES'; if (defined ${$rh}{$key}) { $srcs = ${$rh}{$key}; # = [@vc_c_sources]; $cnt = scalar @{$srcs}; if ($cnt == 0) { prtw( "WARNING:$modstg: No source files in hash ... key=[$key]\n" ); $isok = 0; } else { my $rsa = ${$srcs}[0]; $cnt = scalar @{$rsa}; if ($cnt < 4) { prtw( "WARNING:$modstg:0: (ref) Array of a source NOT enough depth (have $cnt, should be 4, or more ...\n" ); $isok = 0; } } $key = 'H_SOURCES'; $cnt2 = 0; if (defined ${$rh}{$key}) { $srcs = ${$rh}{$key}; # = [@vc_h_sources]; $cnt2 = scalar @{$srcs}; } prt( "with $cnt source, $cnt2 headers files, to output $of [dbg & 1]\n" ) if (($dbg & 1) && $isok); } else { prtw( "WARNING:$modstg: No SOURCES in hash ... key=[$key]\n" ); $isok = 0; } } } if ($isok) { $isok = get_dsp_head_stg($rh, \$msg, $dbg); # get DSP header text, with substitutions DONE } ############################################ ### ABORT IF NOT OK ### ####################### if (! $isok) { # 2009/09/22 - since already generated a WARNING on teh problem, this should only be ADVICE prt( "ADVICE:$modstg: No DSP written... for reason shown...\n" ); return 0; } ############################################ ############################################### # scan for DUPLICATE - need SPECIAL treatment ############################################### prt( "SCAN THE SOURCES (for dupes) [dbg & 64]\n" ) if ($dbg & 64); $key = ($hvers ? 'PROJECT_SRCS' : 'C_SOURCES'); if (defined ${$rh}{$key}) { $srcs = ${$rh}{$key}; # = [@vc_c_sources]; $cnt = scalar @{$srcs}; } else { prtw( "WARNING:$modstg: No SOURCES in hash ... key=[$key]\n" ); $isok = 0; return 0; } $dupes = 0; @dups = (); # init duplicates %dsrc = (); $tmp = ''; for ($i = 0; $i < $cnt; $i++) { $i2 = $i + 1; # storage done in scanvc.pl - see # push(@{$src_ref}, [ $last_src, $fname, $flist, 0, '' ]); # and PUSH onto SOURCE stack $fil = ${$srcs}[$i][0]; # extract C SOURCE file $fnam = ${$srcs}[$i][1]; # extract 'folder' (group) name $ftyp = ${$srcs}[$i][2]; # its FILTER STRING $hm = ${$srcs}[$i][3]; # and if it has 'main' $adde = ${$srcs}[$i][4]; # and any POST stuff prt( "CS:$i2: [$fil] group:[$fnam] [dbg & 2]\n" ) if ($dbg & 2); ($nm,$dr,$ext) = fileparse( $fil, qr/\.[^.]*/ ); $nm = lc($nm); # if (is_c_source($fil)) 2009/10/21 - changed to 'extended' if (is_c_source_extended($fil)) { if (!defined $src_groups{$fnam}) { $src_groups{$fnam} = $ftyp; } if (defined $dsrc{$nm}) { if (lc($ext) ne '.rc') { $dupes++; push(@dups,$fil); prt("Check DUPLICATE [$nm] [$fil] vs [$dsrc{$nm}] [dbg & 64]\n") if ($dbg & 64); } } else { $dsrc{$nm} = $fil; } if (length($tmp) == 0) { $tmp = $fnam; } elsif (length($src_group) == 0) { if (($flag & 1)&&( $tmp ne $fnam )) { $src_group = $def_src_group; prt("NOTE: Due to multiple source GROUPS, like [$tmp] and [$fnam], using DEFAULT [$src_group]!\n"); } } } else { if ($hvers) { if ( is_h_source_extended($fil) || is_resource_file($fil) ) { if (!defined $hdr_groups{$fnam}) { $hdr_groups{$fnam} = $ftyp; } if (length($tmp2) == 0) { $tmp2 = $fnam; } elsif (length($hdr_group) == 0) { if (($flag & 1)&&($tmp2 ne $fnam)) { $hdr_group = $def_hdr_group; prt("NOTE: Due to multiple header GROUPS, like [$tmp2] and [$fnam], using DEFAULT [$hdr_group]!\n"); } } } elsif (is_config_file_like($fil)) { # this is special items like config.h-msvc, simgear-config.h.mc5, etc... IGNORE } elsif (is_text_ext_file($fil)) { # text file (*.txt)... IGNORE } else { prtw( "WARNING: File [$fil] in H_SOURCES key, BUT does NOT pass is_h_source()! group $fnam. CHECK IT OUT![1]\n" ); } } else { prtw( "WARNING: File [$fil] in C_SOURCES key, BUT does NOT pass is_c_source_extended()! group $fnam. CHECK IT OUT!!!\n" ); } } } @tarr = keys(%src_groups); $cnt = scalar @tarr; if ($cnt && ($dbg & 32)) { prt( "[dbg & 32] Got $cnt groups of sources [" ); foreach $tmp2 (@tarr) { prt( "$tmp2 " ); } prt("]\n"); } # scan through HEADER sources prt( "SCAN THE HEADERS (setting \%hdr_groups, per GROUP) [dbg & 64]\n" ) if ($dbg & 64); $key = 'H_SOURCES'; $cnt = 0; if (defined ${$rh}{$key}) { $srcs = ${$rh}{$key}; # = [@vc_c_sources]; $cnt = scalar @{$srcs}; $tmp2 = ''; for ($i = 0; $i < $cnt; $i++) { $i2 = $i + 1; $fil = ${$srcs}[$i][0]; # extract C SOURCE file $fnam = ${$srcs}[$i][1]; # extract 'folder' (group) name $ftyp = ${$srcs}[$i][2]; # its FILTER STRING $hm = ${$srcs}[$i][3]; # and if it has 'main' prt( "HS:$i2: [$fil] group:[$fnam] [dbg & 2]\n" ) if ($dbg & 2); ($nm,$dr,$ext) = fileparse( $fil, qr/\.[^.]*/ ); $nm = lc($nm); #if (is_h_source($fil)) # 2009/10/21 - change to 'extended' #if (is_h_source_extended($fil)) # 2009/10/25 - include RESOURCE files if ( is_h_source_extended($fil) || is_resource_file($fil) ) { if (!defined $hdr_groups{$fnam}) { $hdr_groups{$fnam} = $ftyp; } if (length($tmp2) == 0) { $tmp2 = $fnam; } elsif (length($hdr_group) == 0) { if (($flag & 1)&&($tmp2 ne $fnam)) { $hdr_group = $def_hdr_group; prt("NOTE: Due to multiple header GROUPS, like [$tmp2] and [$fnam], using DEFAULT [$hdr_group]!\n"); } } } elsif (is_config_file_like($fil)) { # this is special items like config.h-msvc, simgear-config.h.mc5, etc... IGNORE } elsif (is_text_ext_file($fil)) { # text file (*.txt)... IGNORE } else { prtw( "WARNING: File [$fil] in H_SOURCES key, BUT does NOT pass is_h_source_extended()! group $fnam. CHECK IT OUT![2]\n" ); } } } else { prt( "There are NO HEADERS! [dbg & 64]\n" ) if ($dbg & 64); } @tarr = keys(%hdr_groups); $cnt = scalar @tarr; if ($cnt && ($dbg & 32)) { prt( "[dbg & 32] Got $cnt groups of headers [" ); foreach $tmp2 (@tarr) { prt( "$tmp2 " ); } prt("]\n"); } $props = ''; if (@dups) { # we have one or more duplicates $props = get_if_props($msg); # prt("NOTE: Adding PROP, due to duplicates!\n[$props] CHECHME!\n"); prt("NOTE: Adding PROP, due to duplicates! CHECHME!\n"); prt("$props") if ($dbg & 0x8000); } prt( "OUTPUT THE SOURCES and HEADERS to [$of] [dbg & 64]\n" ) if ($dbg & 64); if ($flag & 1) { # ===================== # First the C/C++ files # ===================== prt( "Output reduced to TWO groups ONLY [dbg & 32]\n" ) if ($dbg & 32); $key = 'C_SOURCES'; $srcs = ${$rh}{$key}; # = [@vc_c_sources]; $cnt = scalar @{$srcs}; $fnam = $$srcs[0][1]; # extract FIRST 'folder' (group) name, $grplen = length($fnam); $grplen = 0 if ($fnam =~ /^\s$/); $grplen = 0 if ($fnam eq ''); $fnam = $src_group if (length($src_group)); # 20090915 - override with 'Source Files', if MULTIPLE groups $ftyp = $$srcs[0][2]; # its FILTER STRING $hm = $$srcs[0][3]; # and if it has 'main' if ($cnt) { # 31/05/2010 - do not add a GROUP if the group string is null if ($grplen) { $msg .= '# Begin Group "'.$fnam."\"\n"; $msg .= "\n"; $msg .= '# PROP Default_Filter "'.$ftyp."\"\n"; } for ($i = 0; $i < $cnt; $i++) { $fil = $$srcs[$i][0]; $hm = $$srcs[$i][3]; # and if it has 'main' $nm = lc($nm); $msg .= "# Begin Source File\n"; $msg .= "\n"; ###$msg .= "SOURCE=$fil\n"; $msg .= "SOURCE=".add_dotrel_if_none($fil)."\n"; $outsrccnt++ if (length($fil)); if ( length($props) && is_in_array($fil,@dups) ) { prt( "Added DUPE props for $fil ...\n" ) if ($dbg_props); $msg .= $props; } $msg .= "# PROP Exclude_From_Build 1\n" if $hm; $msg .= ${$srcs}[$i][4]; $msg .= "# End Source File\n"; } if ($grplen) { $msg .= "# End Group\n"; } } # ================== # OUTPUT THE HEADERS # ================== $key = 'H_SOURCES'; $cnt = 0; if (defined ${$rh}{$key}) { $srcs = ${$rh}{$key}; # = [@vc_h_sources]; $cnt = scalar @{$srcs}; $fnam = $$srcs[0][1]; $fnam = $hdr_group if (length($hdr_group)); # 20090915 - override with 'Header Files', if MULTIPLE groups $ftyp = $$srcs[0][2]; } if ($cnt) { if ($fnam ne '') { $msg .= '# Begin Group "'.$fnam."\"\n"; $msg .= "\n"; $msg .= '# PROP Default_Filter "'.$ftyp."\"\n"; } for ($i = 0; $i < $cnt; $i++) { $fil = $$srcs[$i][0]; $hm = $$srcs[$i][3]; $msg .= "# Begin Source File\n"; $msg .= "\n"; $msg .= "SOURCE=".add_dotrel_if_none($fil)."\n"; $outsrccnt++ if (length($fil)); # $msg .= "# PROP Exclude_From_Build 1\n" if $hm; $msg .= "# End Source File\n"; } $msg .= "# End Group\n" if ($fnam ne ''); } else { prt("Note: There appears to be NO header files... [dbg & 4]\n") if ($dbg & 4); } } else { prt( "Output SOURCES solely based on GROUP [dbg & 32]\n" ) if ($dbg & 32); foreach $fnam (keys %src_groups) { $ftyp = $src_groups{$fnam}; prt( "Group [$fnam], Filter [$ftyp] [dbg & 4]\n" ) if ($dbg & 4); $grplen = 0; if ( length($fnam) && ($fnam ne '')) { $msg .= '# Begin Group "'.$fnam."\"\n"; $msg .= "\n"; $msg .= '# PROP Default_Filter "'.$ftyp."\"\n"; $grplen = 1; } $key = ($hvers ? 'PROJECT_SRCS' : 'C_SOURCES'); if (defined ${$rh}{$key}) { $srcs = ${$rh}{$key}; # = [@vc_c_sources]; $cnt = scalar @{$srcs}; for ($i = 0; $i < $cnt; $i++) { $fil = ${$srcs}[$i][0]; $hm = ${$srcs}[$i][3]; if ($fnam eq ${$srcs}[$i][1]) { $msg .= "# Begin Source File\n"; $msg .= "\n"; $msg .= "SOURCE=".add_dotrel_if_none($fil)."\n"; $outsrccnt++ if (length($fil)); if ( length($props) && is_in_array($fil,@dups) ) { prt( "Added DUPE props for $fil ...\n" ) if ($dbg_props); $msg .= $props; } $msg .= "# PROP Exclude_From_Build 1\n" if $hm; $msg .= ${$srcs}[$i][4]; $msg .= "# End Source File\n"; } } } $key = 'H_SOURCES'; if (defined ${$rh}{$key}) { $srcs = ${$rh}{$key}; # = [@vc_h_sources]; $cnt = scalar @{$srcs}; for ($i = 0; $i < $cnt; $i++) { $fil = ${$srcs}[$i][0]; $hm = ${$srcs}[$i][3]; if ($fnam eq ${$srcs}[$i][1]) { $msg .= "# Begin Source File\n"; $msg .= "\n"; $msg .= "SOURCE=".add_dotrel_if_none($fil)."\n"; $outsrccnt++ if (length($fil)); $msg .= "# PROP Exclude_From_Build 1\n" if $hm; $msg .= "# End Source File\n"; } } } $msg .= "# End Group\n" if (($fnam ne '') && $grplen); } foreach $fnam (keys %hdr_groups) { $ftyp = $hdr_groups{$fnam}; prt( "Group [$fnam], Filter [$ftyp] [dbg & 4]\n" ) if ($dbg & 4); $grplen = 0; if (length($fnam) && ($fnam ne '')) { $msg .= '# Begin Group "'.$fnam."\"\n"; $msg .= "\n"; $msg .= '# PROP Default_Filter "'.$ftyp."\"\n"; $grplen = 1; } $key = ($hvers ? 'PROJECT_SRCS' : 'C_SOURCES'); if (defined ${$rh}{$key}) { $srcs = ${$rh}{$key}; # = [@vc_c_sources]; $cnt = scalar @{$srcs}; for ($i = 0; $i < $cnt; $i++) { $fil = ${$srcs}[$i][0]; $hm = ${$srcs}[$i][3]; if ($fnam eq ${$srcs}[$i][1]) { $msg .= "# Begin Source File\n"; $msg .= "\n"; $msg .= "SOURCE=".add_dotrel_if_none($fil)."\n"; $outsrccnt++ if (length($fil)); if ( length($props) && is_in_array($fil,@dups) ) { prt( "Added DUPE props for $fil ...\n" ) if ($dbg_props); $msg .= $props; } $msg .= "# PROP Exclude_From_Build 1\n" if $hm; $msg .= ${$srcs}[$i][4]; $msg .= "# End Source File\n"; } } } $key = 'H_SOURCES'; if (defined ${$rh}{$key}) { $srcs = ${$rh}{$key}; # = [@vc_h_sources]; $cnt = scalar @{$srcs}; for ($i = 0; $i < $cnt; $i++) { $fil = ${$srcs}[$i][0]; $hm = ${$srcs}[$i][3]; if ($fnam eq ${$srcs}[$i][1]) { $msg .= "# Begin Source File\n"; $msg .= "\n"; $msg .= "SOURCE=".add_dotrel_if_none($fil)."\n"; $outsrccnt++ if (length($fil)); $msg .= "# PROP Exclude_From_Build 1\n" if $hm; $msg .= "# End Source File\n"; } } } $msg .= "# End Group\n" if (($fnam ne '') && $grplen); } } if ($outsrccnt == 0) { $key = 'PROJECT_FILE'; $fnam = (defined ${$rh}{$key}) ? ${$rh}{$key} : 'UNKNOWN'; prtw( "ERROR:$modstg NO SOURCES in FILE [$fnam]!!! Aborting...\n" ); return 0; } $msg .= get_dsp_tail(); rename_2_old_bak_plus($of); write2file($msg,$of); # prt( "Written [$of] file ...\n" ); # up to caller to ADVISE, if desired... return 1; } sub get_proj_begin { my ($prj, $fil) = @_; my $ret = < Package=<5> {{{ }}} Package=<4> {{{ EOF return $ret; } sub get_proj_end { my $ret = <