#!/usr/bin/perl -w
# NAME: vcproj05.pl
# AIM: To scan a VCPROJ file, and show the results, and write (temp) DSP/DSW files.
# Since this is all about MSVC things, no attempt has been made to run it in unix.
# 2019-09-27 - Try to remove a persistent wanring on VCProjectUpgraderObjectName
# 2016-11-23 - Attempt some fixes for MSVC14
# 19/06/2016 - -v should list SOURCES found
# 24/04/2015 - Add escape_regex() service to escape a string
# 05/04/2015 - Further fixes when processiog
# 21/05/2013 - Small fix - was putting SRCS twice add_library(
# 17/05/2013 - Add -o option to set output directory of CMakeLists.txt
# 29/07/2012 - Another try at doing a cmake output - getting messy
# 19/06/2012 - Added 4996;4013;4018;4024;4047;4244
# 10/04/2012 - Extend to MSVC10 *.vcxproj files - looking good 14/04/2012
# 19/01/2012 - Output the 'temp' DSP written
# 04/11/2011 - Warn about wild card inputs...
# 28/10/2011 - Fix like tempcopydsp.bat to COPY the DSW
# 21/10/2011 - Add an input repsponse file - $in_input_file,...
# 18/10/2011 - Reduce output if NOT verbose!
# 13/07/2011 - If a DSP destination directory given, try to FIX all DSP file source relative to this directory
# 01/12/2010 - Some updates for VC90
# 24/11/2010 - Add in VC10 support -
# 04/08/2010 - More special fixes for various things...
# 2010/07/30 - Special fix of Simgear.cs to SimGear-cs to suit my system... see $dbg_sl_14
# 2010/05/31 - For FLTK project, include *.fl in 'C' sources
# 2010/05/01 - Fixed -dsp=. (ie a relative input) to absolute using like $sarg = File::Spec->rel2abs($tmp); # get ABSOLUTE path of output
# 2010/04/23 - Add -ll to load log, and -fix-rel, to FIX the relative source and /I to the dsp output directory
# 2010/04/18 - Remove WARNING: DOES NOT CONTAIN(12) 'Filter'?, and use a default filter
# 2010/03/08 - Remove write tempvcx.xml from scanvc.pl, or only to perl base directory...
# 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. Altered scanvc.pl to collect this, and fgdsphdrs03.pl to do substitution
# 2010/01/16 - Feeling confident of scans and dsp written - add write actual replacement!
# BUT first, begin to use File::Spec...
# 2009/11/11 - Final tidying up - seems to work fine...
# 2009/10/20 - support MULTIPLE configurations - not compatible with previous versions
# which alwasy had only 2 configurations - Debug and Release.
# 20090912 - add display of CWD, if can not find INPUT file name...
# This uses the services in scanvc.pl, to standardise the processing of a VCPROJ file
# so this is very different to vcproj03.pl, which had its own services to do the scan.
# 2009/09/22 - separarate into multiple 'temp' DSP outputs, using -NEW_PROJECT_NAME-
# but also avoid overwrtting previous out of same name...
# 2010/01/14 - add a DSP COMPARE, if one already exist, and if requested...
# 2009-06-05 also try to attempt to output what the project will create... exe,lib,dll,...
# 05/12/2008 geoff mclane http://geoffair.net/mperl
use strict;
use warnings;
use Cwd;
use File::Basename; # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] )
use File::Spec; # File::Spec->rel2abs($rel); # we are IN the SLN directory, get ABSOLUTE from RELATIVE
unshift(@INC, 'C:/GTools/perl');
require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl'! Check location and \@INC content.\n";
require 'lib_dsphdrs.pl' or die "Unable to load 'lib_dsphdrs.pl'! Check location and \@INC content.\n";
require 'lib_vcscan.pl' or die "Unable to load 'lib_vcscan.pl'! Check location and \@INC content.\n";
require 'lib_params.pl' or die "Unable to load 'lib_params.pl'! Check location and \@INC content.\n";
require 'lib_cmake.pl' or die "Unable to load 'lib_cmake.pl'! Check location and \@INC content.\n";
# log file stuff
our ($LF);
my $perl_base = "C:\\GTools\\perl"; # perl directory
my $PATH_SEP = "\\";
my $temp_dir = $perl_base;
my $pgmname = $0;
if ($pgmname =~ /\w{1}:\\.*/) {
my @tmpsp = split(/\\/,$pgmname);
$pgmname = $tmpsp[-1];
}
my $outfile = $perl_base."\\temp.$pgmname.txt";
open_log($outfile);
my $vers = "2016-11-23"; # some fixes for MSVC14 2015
#my $vers = "2016-06-19"; # -v to list the sources
#my $vers = "2015-04-24"; # removed some warnings mainly
#my $vers = "2014-01-03"; # removed some warnings mainly
#my $vers = "2012-07-19"; # more work on loading 1 vcproj file
#my $vers = "2012-06-19"; # try to include vcxproj files
#my $vers = "2012-04-10"; # try to include vcxproj files
#my $vers = "2011-11-04"; # minor fix
#my $vers = "2011-10-28"; # some fixes
# $vers = "2011-10-18"; # much reduced output with 'verbosity'
# $vers = "2011-07-13";
# features
my $sort_by_type = 1;
my $sort_by_name = 1;
my $load_log = 0; # load LOG file at end
my $write_dsp = 0;
my $use_lib_option_var = 1;
my $combine_lib_source = 1;
my $add_3rdparty_stuff = 0; # add the MSVC 3rdparty blob
my $out_dsp_dir = $perl_base; # this can be changed by -dsp=
my $g_had_dsp = 0; # if given an OUTPUT DSP directory
# my $dbg_val = 4+2; # 1=split defines, 2=no show defines, etc, 4=show sources;
my $dbg_val = 0; # 1=split defines, 2=no show defines, etc, 4=show sources;
#my $dbg4write = -1; # everything ON
my $dbg4write = 0; # nothing ON
#my $dbg4write = 1; # minimal ON
#my $dbg4write = 2; # show source files ON
my $comp_2_dsps = 0;
my $out_bat_file = $perl_base."\\tempcopydsp.bat";
my $fix_rel_paths = 0; # if given an output dsp directory, fix the releative source paths
my $debug_dsw_write = 0; # write DSW debug silently
#my $debug_dsw_write = -1; # add write DSW debug info
my $verbosity = 0;
my $proj_name = '';
sub get_write_dsp_files() { return $write_dsp; }
sub get_pgmname() { return $pgmname; }
sub get_PATH_SEP() { return $PATH_SEP; }
sub get_dsp_out_dir() { return $out_dsp_dir; }
my @system_libs = qw(kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib
ole32.lib oleaut32.lib uuid.lib ws2_32.lib);
sub is_system_lib($) {
my $lib = shift;
my $lclib = lc($lib);
my ($tst);
foreach $tst (@system_libs) {
return 1 if ($lclib eq $tst);
}
return 0;
}
sub VERB1() { return ($verbosity >= 1); }
sub VERB2() { return ($verbosity >= 2); }
sub VERB5() { return ($verbosity >= 5); }
sub VERB9() { return ($verbosity >= 9); }
# program variables
my $in_file = '';
my $sln_path = '';
my $active_project = ''; # active project during chk_relative_paths
my $in_input_file = 0;
my @user_inputs = ();
my $act_config = 0; # 0=Release 1=Debug
my $commdir = '';
my @proj_hash_array = (); # for each vcproj file processed, push the project $rh here
my %shown_warn = ();
# 20/06/2012 - output a cmake file
########################################
### SHARED RESOURCES, VALUES
### ========================
our $fix_relative_sources = 1;
our %g_user_subs = (); # supplied by USER INPUT
our %g_user_condits = (); # conditionals supplied by the user
# Auto output does the following -
# For libaries
# Debug: '/out:"lib\barD.lib"'
# Release:'/out:"lib\barD.lib"'
# for programs
# Debug: '/out:"bin\fooD.exe"'
# Release:'/out:"bin\foo.exe"'
# This also 'adds' missing 'include' files
#Bit: 1: Use 'Debug\$proj_name', and 'Release\$proj_name' for intermediate and out directories
#Bit: 2: Set output to lib, or bin, and names to fooD.lib/foo.lib or barD.exe/bar.exe
#Bit: 4: Set program dependence per library output directories
#Bit: 8: Add 'msvc' to input file directory, if no target directory given
#Bit: 16: Add program library dependencies, if any, to DSW file output.
#Bit: 32: Add all necessary headers to the DSP file. That is scan the sources for #include "foo.h", etc.
#Bit: 64: Write a blank header group even there are no header files for that component.
#Bit: 128: Add defined item of HAVE_CONFIG_H to all DSP files.
#Bit: 256: Exclude projects in SUBDIRS protected by a DEFINITION macro, else include ALL.
#Bit: 512: Unconditionally add ANY libraries build, and NOT excluded to the last application
#Bit:1024: If NO users conditional, do sustitution, if at all possible, regardless of TRUE or FALSE
#Bit:2048: Add User -L dependent libraries to each application
#Bit: These can be given as an integer, or the form 2+8, etc. Note using -1 sets ALL bits on.
#Bit: Bit 32 really slows down the DSP creation, since it involves scanning every line of the sources.
my $auto_max_bit = 512;
our $auto_on_flag = -1; #Bit: ALL ON by default = ${$rparams}{'CURR_AUTO_ON_FLAG'}
sub get_curr_auto_flag() { return $auto_on_flag; }
#my ($g_in_name, $g_in_dir);
#my ($root_file, $root_folder);
#sub get_root_dir() { return $root_folder; }
our $exit_value = 0;
# But SOME Makefile.am will use specific 'paths' so the above can FAIL to find
# a file, so the following two 'try harder' options, will do a full 'root'
# directory SCAN, and search for the file of that name in the scanned files
our $try_harder = 0;
our $try_much_harder = 0;
# ==============================================================================
our $process_subdir = 0;
our $warn_on_plus = 0;
# ==============================================================================
# NOTE: Usually a Makefile.am contains SOURCE file names 'relative' to itself,
# which is usually without any path. This options ADDS the path to the
# Makefile.am, and then substracts the 'root' path, to get a SOURCE file
# relative to the 'root' configure.ac, which is what is needed if the DSP
# is to be placed in a $target_dir, and we want the file relative to that
our $add_rel_sources = 1;
our $target_dir = '';
# ==============================================================================
our $ignore_EXTRA_DIST = 0;
our $added_in_init = '';
our $supp_make_in = 0; # Support Makefile.in scanning
our $project_name = ''; # a name to override any ac scanned name of the project
###my $dsp_files_skipped = 0;
### =============================
# offsets into REF_LIB_LIST array
our $RLO_MSG = 0;
our $RLO_PRJ = 1;
our $RLO_VAL = 2;
our $RLO_NAM = 3;
our $RLO_EXC = 4;
### =============================
my $out_cmake_dir = '';
my $write_cmake = 0;
my ($rparams); # the one and only, init per first file input
my $got_par = 0;
# my $rex = ${$rparams}{'AM_EXCLUDED_DIRS'}; # get stored EXCLUDED directory HASH (if any!)
# my $proj_root = ${$rparams}{'ROOT_FOLDER'};
# my $proj_title = ${$rparams}{'PROJECT_NAME_MASTER'};
# my $rprojsh = ${$rparams}{'REF_PROJECTS_HASH'};
# my $rlib_lists = ${$rparams}{'REF_LIB_LISTS'}; # make list of LIBRARIES written
# optional - my $rxj = ${$rparams}{'REF_JOINED_EXCLUDED'};
my $inst_hdr_path = 'include';
my $inst_lib_path = 'lib';
my $inst_bin_path = 'bin';
sub get_inst_hdr_path() { return $inst_hdr_path; }
sub get_inst_lib_path() { return $inst_lib_path; }
sub get_inst_hdr_bin() { return $inst_bin_path; }
sub get_write_cmake_files() { return $write_cmake; }
my %by_proj_includes = ();
my %by_proj_defines = ();
my %by_proj_defused = ();
my $proj_incs = ''; # like '/I "."' for -NEW_INCS- GLOBAL
my $proj_defs = ''; # like '/D "_CRT_SECURE_NO_WARNINGS"';
sub get_project_incs($) {
my $proj = shift;
my $pi = '';
$pi = $by_proj_includes{$proj} if (defined $by_proj_includes{$proj});
return $pi;
}
sub get_project_defs($) {
my $proj = shift;
my $pi = '';
$pi = $by_proj_defines{$proj} if (defined $by_proj_defines{$proj});
$by_proj_defused{$proj} = 1;
return $pi;
}
# FIX20110323 - changed from 'get_user_defs:' to 'get_user_incs:'
# should ALSO allow DEFINES (-D) to also be in a BY PROJECT basis
# my %by_proj_includes = ();
sub get_user_incs($$) {
my ($not_used,$proj) = @_;
my $pi = get_project_incs($proj);
$pi .= ' ' if (length($pi) && length($proj_incs));
$pi .= $proj_incs;
prt("[v9] get_user_incs: proj=$proj, return=[$pi]\n") if (VERB9());
return $pi;
}
sub get_user_defs($$) {
my ($not_used,$proj) = @_;
my $pd = get_project_defs($proj);
$pd .= ' ' if (length($pd) && length($proj_defs));
$pd .= $proj_defs;
prt("[v9] get_user_defs: proj=$proj, return=[$pd]\n") if (VERB9());
return $pd;
}
# ### DEBUG ##
my $dbg_01 = 0; # show commands
my $dbg_02 = 0; # show EACH tag
my $dbg_03 = 0; # tag stack debug - show open and close
my $dbg_04 = 0; # if $dbg_02, also show complete 'from' item
my $dbg_05 = 0; # show each configuration PUSHED
my $dbg_06 = 0; # show additional debug for get_rt_value/set_curr_config
my $dbg_07 = 0; # show ' Property: '...
my $dbg_08 = 0; # show ' ItemDef: '...
my $dbg_09 = 0; # show full tag stack if $dbg_02
my $dbg_10 = 0; # setting a unsetting of $incommand
if (-d "C:\\MDOS") {
$out_bat_file = "C:\\MDOS\\tempcopydsp.bat";
}
my $adj_inter = 0; # Adjust output and inter directories to "Release\\" and "Debug\\"
my $adj_out = 0; # Adjust output to "bin\\.exe" and "bin\\D.exe" for EXE and DLL
# projects, and "lib\\.lib" and "lib\\D.lib" for libraries.
my $adj_rt = ''; # Adjust runtime, D = /MD and /MDd, T = /MT and /MTd, accordingly.
my $del_ndl_all = 0;
my $del_dll_all = 0; # remove any DLL build if both DLL and static, or change to static if only DLL
my $del_spl_bld = 0; # remove any Special Tool Build blocks from DSP
my $debug_on = 0; # 0 for release, but on to load default input (when using the editor say)
my $def_in_file = 'C:\Projects\notepad-plus\PowerEditor\visual.net\notepadPlus.vcproj';
my $def_out_dsp_dir = 'C:\Projects\notepad-plus';
###my $def_in_file = 'C:\GTools\ConApps\test_simp\build\test_simp.sln';
###my $def_out_dsp_dir = 'C:\GTools\ConApps\test_simp\build';
#my $def_in_file = 'C:\Projects\lpng159\build\libpng.sln';
#my $def_in_file = 'C:\Projects\lpng159\build\INSTALL.vcxproj';
#my $def_in_file = 'C:\Projects\lpng159\build\ALL_BUILD.vcxproj';
#my $def_out_dsp_dir = 'C:\Projects\lpng159\build';
#my $def_in_file = 'C:\Projects\lpng159\temp-static\png15_static.vcxproj';
#my $def_out_dsp_dir = 'C:\Projects\lpng159\temp-static';
#my $def_in_file = 'C:\Projects\lpng159\temp-shared\png15.vcxproj';
#my $def_out_dsp_dir = 'C:\Projects\lpng159\temp-shared';
#my $def_in_file = 'C:\Projects\zlib-1.2.6\temp\zlib.vcxproj';
#my $def_out_dsp_dir = 'C:\Projects\zlib-1.2.6\temp';
#my $def_in_file = 'C:\FG\10\flightgear\build\src\FDM\YASim\yasim-proptest.vcxproj';
#my $def_out_dsp_dir = 'C:\FG\10\flightgear\build';
#my $def_in_file = 'C:\Projects\curl-7.20.1\lib\libcurl.vcproj';
#my $def_out_dsp_dir = 'C:\Projects\curl-7.20.1\packages\Win32\msvc';
my @warnings = ();
#-- get current directory
my $pwd = cwd();
my @dsp_file_list = (); # simple list
my @project_list = (); # [0]=name [1]=file
my $sln_root_dir = ''; # if given a SOLUTION FILE
# debug
my $dbg_sl_01 = 0;
my $dbg_sl_02 = 0;
my $dbg_sl_03 = 0;
my $dbg_sl_04 = 0; # show_hash_results3($rh) if ($dbg_sl_04);
my $dbg_sl_05 = 0; # prt( "[dbg_s105] $pgmname: Scanning [$in]...\n" ) if ($dbg_sl_05);
my $dbg_sl_06 = 0; # show parse_arg in detail
my $dbg_sl_07 = 0; # prt("[dbg_sl_07] Check relative vcd=[$vcd], out=[$outd]\n") if ($dbg_sl_07);
my $dbg_sl_08 = 0; # chk_relative_paths: show each config item
my $dbg_sl_09 = 0; # chk_relative_paths: show each source item, and any CHANGE
my $dbg_sl_10 = 0; # chk_relative_paths: show each other config item, and any CHANGE
my $dbg_sl_11 = 0; # chk_relative_paths: show any POST changes -NEW_POST-
my $dbg_sl_12 = 0; # debug sub get_new_post_string($$$$$) { # $v2,\$ok,$rp,$vcd,$outd);
my $dbg_sl_13 = 0;
my $dbg_sl_14 = 0;
my $dbg_sl_15 = 0; # prt( "Stored \$sln_projpath{$projname} = [0:$projfile,1:$projff,2:$relpath,3:$dspfile,4:$fdspfil]\n");
my $dbg_sl_16 = 0; # show each project, and its ID, as found
sub get_sl_debug_stg() {
my $stg = '';
if ($dbg_sl_01) { $stg .= "01 "; }; if ($dbg_sl_02) { $stg .= "02 "; };
if ($dbg_sl_03) { $stg .= "03 "; }; if ($dbg_sl_04) { $stg .= "04 "; };
if ($dbg_sl_05) { $stg .= "05 "; }; if ($dbg_sl_06) { $stg .= "06 "; };
if ($dbg_sl_07) { $stg .= "07 "; }; if ($dbg_sl_08) { $stg .= "08 "; };
if ($dbg_sl_09) { $stg .= "09 "; }; if ($dbg_sl_10) { $stg .= "10 "; }; if ($dbg_sl_11) { $stg .= "11 "; };
if ($dbg_sl_12) { $stg .= "12 "; }; if ($dbg_sl_13) { $stg .= "13 "; };
if ($dbg_sl_14) { $stg .= "14 "; };
$stg .= "dbg4Write=$dbg4write " if ($dbg4write);
$stg .= "debug_dsw_write=$debug_dsw_write " if ($debug_dsw_write);
return $stg;
}
sub set_sl_debug_val($) {
my ($v) = shift;
$dbg_sl_01 = $v; $dbg_sl_02 = $v; $dbg_sl_03 = $v; $dbg_sl_04 = $v; $dbg_sl_05 = $v;
$dbg_sl_06 = $v; $dbg_sl_07 = $v; $dbg_sl_08 = $v; $dbg_sl_09 = $v; $dbg_sl_10 = $v; $dbg_sl_11 = $v;
$dbg_sl_12 = $v; $dbg_sl_13 = $v; $dbg_sl_14 = $v;
}
sub set_sl_debug_on() { set_sl_debug_val(1); $load_log = 1; }
sub set_sl_debug_off() { set_sl_debug_val(0); }
my $curr_app_type = '';
# APP_TYPE
# $app_console_stg = 'Console Application' = get_dsp_head_console
# $app_windows_stg = 'Application' = get_dsp_head_app
# $app_dynalib_stg = 'Dynamic-Link Library' = get_dsp_head_dynalib
# $app_statlib_stg = 'Static Library' = get_dsp_head_slib
sub prtw($) {
my ($tx) = shift;
$tx =~ s/\n$//;
prt("$tx\n");
push(@warnings,$tx);
}
sub show_warnings() {
if (@warnings) {
prt( "\nGot ".scalar @warnings." WARNINGS ...\n" );
foreach my $line (@warnings) {
prt("$line\n" );
}
prt("\n");
} else {
prt("\nNo warnings issued.\n\n") if (VERB5());
}
}
sub pgm_exit($$) {
my ($val,$msg) = @_;
show_warnings();
#my $dbs = fgs_get_dbg_stg();
my $dbs = svc_get_dbg_stg();
if (length($dbs)) {
prt("WARNING: Debug is ON for [$dbs], in fgscanvc03.pl\n" );
}
$dbs = get_sl_debug_stg();
if (length($dbs)) {
prt("WARNING: Debug is ON for [$dbs], in $pgmname\n" );
} else {
prt("Appears no DEBUG item remain on...\n") if (VERB5());
}
if (length($msg)) {
$msg .= "\n" if ( !($msg =~ /\n$/) );
prt($msg);
}
close_log($outfile,$load_log);
# unlink($outfile); # delete output file
exit($val);
}
sub is_c_source_ext($) {
my ($fil) = shift;
my ($nm, $dir, $ext) = fileparse( $fil, qr/\.[^.]*/ );
my $lce = lc($ext);
return 1 if (($lce eq '.c') || ($lce eq '.cxx') || ($lce eq '.cpp') || ($lce eq '.cc'));
return 1 if ($lce eq '.fl'); # 2010-05-31 - added for FLTK projects
return 0;
}
sub is_sln_ext($) {
my ($fil) = shift;
my ($nm, $dir, $ext) = fileparse( $fil, qr/\.[^.]*/ );
my $lce = lc($ext);
if ($lce eq '.sln') {
return 1;
}
return 0;
}
sub is_vcproj_ext($) {
my ($fil) = shift;
my ($nm, $dir, $ext) = fileparse( $fil, qr/\.[^.]*/ );
my $lce = lc($ext);
return 1 if ($lce eq '.vcproj');
return 0;
}
sub is_vcxproj_ext($) {
my $fil = shift;
my ($nm, $dir, $ext) = fileparse( $fil, qr/\.[^.]*/ );
my $lce = lc($ext);
return 1 if ($lce eq '.vcxproj'); # 24/11/2010 VC10 support
return 0;
}
# escape ^ $ . | { } [ ] ( ) * + ? \
sub escape_regex($) {
my $txt = shift;
my $ntxt = '';
my $len = length($txt);
my ($i,$ch);
for ($i = 0; $i < $len; $i++) {
$ch = substr($txt,$i,1);
if (($ch eq '^')||($ch eq '$')||($ch eq '.')||($ch eq '|')||($ch eq '{')||($ch eq '}')) {
$ntxt .= '\\';
} elsif (($ch eq '\\')||($ch eq '/')||($ch eq '(')||($ch eq ')')||($ch eq '[')||($ch eq ']')) {
$ntxt .= '\\';
} elsif (($ch eq '*')||($ch eq '+')||($ch eq '?')) {
$ntxt .= '\\';
}
$ntxt .= $ch;
}
return $ntxt;
}
# ===================================================================
# -NEW_INCS- = [/I "." /I "..\include"], and
# -NEW_DEFS- = [/D "NDEBUG"... ]
# Maybe could -
# (a) ensure a certain /I "somepath", exists, adding it if NOT
# (b) adjust certain /I "..\path.x64" to a different /I "..\new\path"
# (c) delete duplicates
# (d) etc
# ===================================================================
# reduce the noise...
my $prev_inc_warn = '';
my $prev_def_warn = '';
my $prev_inc_added = '';
my $prev_def_added = '';
my $prev_sdk_added = '';
my $prev_alut_added = '';
my $prev_item_dump1 = '';
my $prev_item_dump2 = '';
sub get_new_inc_hash($$$$$$) {
my ($v,$rok,$rp,$vcd,$outd,$ky) = @_;
my $len = length($v);
my %hash = ();
my %dupes = ();
my ($i,$ch,$nc,$tag,$val,$pc,$ra,$nval,$i2,$qt);
my ($fp,$np,$had_al,$inc_tag,$had_crt,$def_tag,$had_alu,$had_dot,$had_cfg);
# process the line, char by char...
$had_al = 0;
$had_alu = 0;
$inc_tag = '';
$had_crt = 0;
$def_tag = '';
$had_dot = 0;
$had_cfg = 0;
$ch = '';
for ($i = 0; $i < $len; $i++) {
$i2 = $i + 1;
$pc = $ch; # keep PREVIOUS char
$ch = substr($v,$i,1);
$nc = ($i2 < $len) ? substr($v,$i2,1) : '';
if ( (($ch eq '/')||($ch eq '-')) && (length($nc)) ) {
$tag = $ch; # begin a SWITCH item
$i++; # bump to NEXT char
for (; $i < $len; $i++) {
$pc = $ch; # keep PREVIOUS char
$ch = substr($v,$i,1);
$nc = ($i2 < $len) ? substr($v,$i2,1) : '';
last if ($ch eq '"'); # found first QUOTE
last if ($ch =~ /\s/); # or found a SPACE
$tag .= $ch;
}
if ($ch =~ /\s/) { # if a SPACE, get to NEXT sig char
$i++;
for (; $i < $len; $i++) {
$pc = $ch; # keep PREVIOUS char
$ch = substr($v,$i,1);
last if ($ch eq '"');
last if ( !($ch =~ /\s/) );
}
}
$qt = ''; # assume NO 'quote'
$val = $ch; # start of a VALUE
$i2 = $i + 1;
if ($i2 < $len) {
if ( $ch eq '"' ) {
$i++; # ok, do have QUOTED text
$qt = $ch; # keep 'quote'
$pc = $ch; # keep PREVIOUS char
$ch = substr($v,$i,1); # and get NEXT char
$val .= $ch; # add to collected value
}
} else {
${$rok} = 0;
prtw("WARNING:1:$active_project: Ran out of char! With [$v] FAILED!\n");
return \%hash;
}
$i++;
if (length($qt)) {
# process until next 'quote' found, 2010-08-04 but NOT escaped with '\'
for (; $i < $len; $i++) {
$pc = $ch; # keep PREVIOUS char
$ch = substr($v,$i,1);
$val .= $ch;
last if ( ($ch eq $qt) && ($pc ne "\\") );
}
} else {
# or process until a space found
for (; $i < $len; $i++) {
$pc = $ch; # keep PREVIOUS char
$ch = substr($v,$i,1);
last if ($ch =~ /\s/);
$val .= $ch;
}
}
# we have (/|-)$tag ["]$val["]
# ============================
$nval = strip_quotes($val);
if ($nval eq '.') {
# this stays as is
$had_dot = 1;
} elsif ($tag =~ /^(-|\/)I$/) {
# its a /I "path" type - need new relative item?
prtw("WARNING:$active_project: Multiple I tags. Got [$inc_tag], NOW [$tag]! CHECK THIS\n") if (length($inc_tag) && ($tag ne $inc_tag));
$inc_tag = $tag;
$fp = $vcd;
# ====================================================================
$had_al = 1 if ($nval =~ /OpenAL/i); # if got an OpenAL (AL/al.h) include
$had_alu = 1 if ($nval =~ /alut/);
$nval =~ s/SimGear\.cs/simgear-cs/i; # SPECIAL FIX Fred vs Geoff
$nval =~ s/3rdParty\.x64/3rdParty/i; # SPECIAL FIX Fred vs Geoff
$nval =~ s/install(\\|\/)msvc90(\\|\/)OpenSceneGraph/OpenSceneGraph/i; # SPECIAL FIX Fred vs Geoff
$nval =~ s/install(\\|\/)msvc90-64(\\|\/)OpenSceneGraph/OpenSceneGraph/i; # SPECIAL FIX Fred vs Geoff
$nval =~ s/install(\\|\/)msvc71(\\|\/)OpenSceneGraph/OpenSceneGraph/i; # SPECIAL FIX Fred vs Geoff
# ====================================================================
$fp .= "\\" if ( !( ($fp =~ /(\\|\/)$/) || ($nval =~ /^(\\|\/)/) ) );
$fp .= $nval; # get the FULL (relative) path
$fp = fix_rel_path3($fp,'get_new_inc_hash');
$np = get_rel_dos_path($fp,$outd);
$np =~ s/(\\|\/)$//;
$val = add_quotes($np);
} elsif ($tag =~ /^(-|\/)D$/) {
prtw("WARNING:$active_project: Multiple D tags. Got [$def_tag], NOW [$tag]! CHECK THIS\n") if (length($def_tag) && ($tag ne $def_tag));
$def_tag = $tag;
$had_crt = 1 if ($nval =~ /_CRT_SECURE_NO_WARNINGS/);
$had_cfg = 1 if ($nval eq 'HAVE_CONFIG_H');
if ($nval =~ /^DEFAULT_USGS_MAPFILE/) {
prt("$active_project: SPECIAL FIX: Dumping tag [$tag $val]\n") if ($prev_item_dump1 ne $active_project);
$prev_item_dump1 = $active_project;
${$rok}++;
next;
}
if ($nval =~ /^DEFAULT_PRIORITIES_FILE/) {
prt("$active_project: SPECIAL FIX: Dumping tag [$tag $val]\n") if ($prev_item_dump2 ne $active_project);
$prev_item_dump2 = $active_project;
${$rok}++;
next;
}
}
if (defined $dupes{$val}) {
prtw("WARNING:$active_project:SPECIAL FIX: Avoided duplicate [$val]\n");
} else {
$hash{$tag} = [] if (!defined $hash{$tag});
$ra = $hash{$tag};
push(@{$ra},$val); # store item in HASH
$dupes{$val} = 1;
}
${$rok}++;
} elsif (($ch eq '/')||($ch eq '-')) {
prtw("WARNING:2:$active_project: Ran out of char! With [$v] FAILED!\n");
${$rok} = 0;
return \%hash;
} else {
if ($ch =~ /\s/) {
# forget spaces - just continue
} else {
prtw("WARNING:3:$active_project: Not A SWITCH! Got [$ch]? With [$v] FAILED!\n");
${$rok} = 0;
return \%hash;
}
}
} # char by char for the whole string
# =========================
# Other SPECIAL FIX items
# =========================
# -NEW_INCS-
if ( (length($inc_tag) > 0) && (defined $hash{$inc_tag}) ) {
$ra = $hash{$inc_tag};
if ($active_project =~ /simgear/i) {
prt("SPECIAL FIX: for [$active_project]\n");
if ( !$had_al ) {
$val = '"C:\Program Files\OpenAL 1.1 SDK\include"';
push(@{$ra},$val); # store item in HASH
prt("SPECIAL FIX: Added OpenAL SDK include [$val]\n") if ($active_project ne $prev_sdk_added);
$prev_sdk_added = $active_project;
${$rok}++;
}
if ( !$had_alu) {
$val = '"..\..\..\alut\include"';
push(@{$ra},$val); # store item in HASH
prt("$active_project:SPECIAL FIX: Added alut include [$val]\n") if ($active_project ne $prev_alut_added);
$prev_alut_added = $active_project;
${$rok}++;
}
}
if (!$had_dot) {
$val = '"."';
push(@{$ra},$val); # store item in HASH
prt("$active_project:SPECIAL FIX: Added [/I $val]\n") if ($active_project ne $prev_inc_added);
$prev_inc_added = $active_project;
${$rok}++;
}
} elsif ($ky eq '-NEW_INCS-') {
prtw("WARNING:$active_project: Potential SPECIAL FIXES missed for $ky! No /I tag in [$v]???\n") if ($active_project ne $prev_inc_warn);
$prev_inc_warn = $active_project;
}
# -NEW_DEFS-
if ( (length($def_tag) > 0) && (defined $hash{$def_tag}) ) {
$ra = $hash{$def_tag};
if ( ! $had_crt ) {
$val = '"_CRT_SECURE_NO_WARNINGS"';
push(@{$ra},$val); # store item in HASH
prt("$active_project:SPECIAL FIX: Added CRT [$val]\n");
${$rok}++;
}
if ( ! $had_cfg ) {
$val = '"HAVE_CONFIG_H"';
push(@{$ra},$val); # store item in HASH
prt("$active_project:SPECIAL FIX: Added CONFIG [$val]\n") if ($prev_def_added ne $active_project);
$prev_def_added = $active_project;
${$rok}++;
}
} elsif ($ky eq '-NEW_DEFS-') {
prtw("WARNING:$active_project: Potential SPECIAL FIXES missed for $ky! No /D tag in [$v]???\n") if ($active_project ne $prev_def_warn);
$prev_def_warn = $active_project;
}
return \%hash; # return hash{$tag} = [$val,[$val]]
}
# could have
# -NEW_POST- = [# Begin Special Build Tool
#SOURCE="$(InputPath)"
#PostBuild_Desc=
#PostBuild_Cmds=if not exist ..\..\..\..\lib md ..\..\..\..\lib copy "$(TargetDir)GLUT32.LIB" ..\..\..\..\lib copy "$(TargetDir)GLUT32.DLL" ..\..\..\..\lib if exist ..\..\..\..\progs\demos copy "$(TargetDir)GLUT32.DLL" ..\..\..\..\progs\demos
## End Special Build Tool
# that needs ADJUSTING - wow
sub get_new_post_string($$$$$) { # $v2,\$ok,$rp,$vcd,$outd);
my ($v,$rok,$rp,$vcd,$outd) = @_;
my $len = length($v);
my $nv = $v;
my $chg = 0;
my (@arr,$k,$l1,$itm,$chg1,$chg2,$i,$j,$c,$c2,@a2,@a3,$cmd,$l2,$l3,$np,$rd,$frp);
if ($len) {
@arr = split("\n",$v);
$l1 = scalar @arr;
for ($k = 0; $k < $l1; $k++) {
$itm = $arr[$k];
if ($itm =~ /^PostBuild_Cmds=(.+)$/) {
$cmd = $1;
@a2 = split("\t",$cmd);
$l2 = scalar @a2;
$chg2 = 0;
for ($i = 0; $i < $l2; $i++) {
$c = $a2[$i];
if ($c =~ /\.\./) {
prt("[dbg_sl_12] Needs adjustment [$c]\n") if ($dbg_sl_12);
@a3 = split(/\s/,$c);
$l3 = scalar @a3;
$chg1 = 0;
for ($j = 0; $j < $l3; $j++) {
$c2 = $a3[$j];
if ($c2 =~ /\.\./) {
$rd = $vcd.$c2;
$frp = fix_rel_path3($rd,'get_new_post_string');
$np = get_rel_dos_path($frp,$outd);
$np =~ s/(\\|\/)$//;
prt("REL [$rd]\nnew [$frp]\n") if ($dbg_sl_12);
prt(" This one [$c2] to [$np]?\n") if ($dbg_sl_12);
if ($np ne $c2) {
$a3[$j] = $np;
$chg1++;
}
}
}
if ($chg1) {
$np = '';
foreach $c2 (@a3) {
$np .= ' ' if (length($np));
$np .= $c2;
}
$a2[$i] = $np;
$chg2++;
}
}
}
if ($chg2) {
$rd = '';
foreach $c (@a2) {
$rd .= "\t" if (length($rd));
$rd .= $c;
}
$arr[$k] = $rd;
$chg++;
prt("old [$cmd]\nnew [$rd]\n") if ($dbg_sl_12);
}
}
}
if ($chg) {
$nv = '';
foreach $itm (@arr) {
$nv .= "\n" if (length($nv));
$nv .= $itm;
}
if ($v ne $nv) {
prt("old [$v]\nnew [$nv]\n") if ($dbg_sl_12);
${$rok} = 1;
}
}
prt("rel=[$rp], vcd=[$vcd], od=[$outd]\n") if ($dbg_sl_12);
#pgm_exit(1,"TEMP EXIT");
}
return $nv;
}
# check input libraries to link with
# $v = current value
# $rok = ref to set if changed
# $rp = get_rel_dos_path($vcd,$outd); # changing the PATH
# $vcd = directory of the vcproj file
# $outd = output directory
# can add, substrct, change list
# eg
# [ul_d.lib sg_d.lib zlibd.lib gdal_id.lib /libpath:"..\..\..\..\plib" /libpath:"..\..\..\..\3rdParty\lib"]
# needs to be changed to
# [ul_d.lib sg_d.lib zlibd.lib gdal_id.lib /libpath:"..\..\..\plib" /libpath:"..\..\..\3rdParty\lib"]
sub get_new_libs_string($$$$$) { # $v2,\$ok,$rp,$vcd,$outd);
my ($v,$rok,$rp,$vcd,$outd) = @_;
my $len = length($v);
my $nv = $v;
my $chg = 0;
#prt("get_new_libs_string: from [$v]\n");
my @arr = space_split($v); # split on space, but honor inside inverted commas
my ($itm,$dir,$fp,$tmp,$rdd,$nitm);
my @narr = ();
foreach $itm (@arr) {
if ($itm =~ /^\/libpath:/) {
$dir = strip_quotes(substr($itm,9));
$fp = $vcd;
$fp .= "\\" if ( !($fp =~ /(\/|\\)$/) );
$fp .= $dir;
$tmp = fix_rel_path3($fp,'get_new_libs_string');
# my $out_dsp_dir = $perl_base; # this can be changed by -dsp=
# my $g_had_dsp = 0; # if given an OUTPUT DSP directory
$rdd = get_rel_dos_path($tmp,$out_dsp_dir); # changing the PATH
$rdd =~ s/\\$//;
$nitm = '/libpath:'.add_quotes($rdd);
push(@narr,$nitm);
#prt("Changed\nfrom [$itm]\nto [$nitm]\n");
###pgm_exit(1,"CHECK ME");
$chg++;
} else {
push(@narr,$itm);
}
}
if ($chg) {
$nv = '';
foreach $itm (@narr) {
$nv .= ' ' if (length($nv));
$nv .= $itm;
}
${$rok} = $chg;
}
return $nv;
}
sub Get_Default_Group($) {
my ($src) = @_;
my ($grp,$flt);
if (is_c_source_extended($src)) {
$grp = get_def_src_grp();
$flt = get_def_src_filt();
} elsif (is_h_source_extended($src)) {
$grp = get_def_hdr_grp();
$flt = get_def_hdr_filt();
} elsif (is_resource_file($src)) {
$grp = get_def_rcs_grp();
$flt = get_def_rcs_filt();
} else {
$grp = "Other Files";
$flt = '';
}
return $grp,$flt;
}
# ======================================================================================
# ok, need to change sources from perhaps '.\src.cxx' to '..\..\lib\src.cxx' - a big job
# and LOTS of other things...
# ======================================================================================
my $prev_src_fix = '';
sub chk_relative_paths($$$) {
my ($rh,$outd,$vcd) = @_;
my ($key,$val,$acnt,$i,$src,$grp,$flt,$rp);
my ($i2,$rsb,@karr,$scnt,$msg,$ky,$v2,$rih,$ok);
my ($k3,$v3,$v,$nv,$tmp,$tmp2);
$rp = get_rel_dos_path($vcd,$outd); # changing the PATH
##my $rp2 = get_rel_dos_path($outd,$vcd); # how to get from where we were to now out directory
# this would be used to move say 'windows\VC8\mesa\mesa.dsp' to windows\MSVC
prt("[dbg_sl_07] Check relative vcd=[$vcd], out=[$outd]\n") if ($dbg_sl_07);
prt("chk_relative_paths: [$rp],\n from vcd=[$vcd],\n target =[$outd]\n");
$key = 'PROJECT_NAME';
if (! defined ${$rh}{$key}) {
pgm_exit(1,"INTERNAL ERROR: HASH WITHOUT PROJECT_NAME! Can ONLY exit!");
}
$active_project = ${$rh}{$key};
my @not_found = ();
foreach $key (keys %{$rh}) {
$val = ${$rh}{$key};
if ( $key =~ /^CURR_/ ) {
# ignore these CURRENT state items
} else {
if ($key eq 'PROJECT_SRCS') {
$acnt = scalar @{$val};
prt("$key - $acnt sources to fix path...\n"); # 'PROJECT_SRCS'
for ($i = 0; $i < $acnt; $i++) {
$src = ${$val}[$i][0];
$grp = ${$val}[$i][1];
$flt = ${$val}[$i][2];
# SPECIAL FIX - Fred vs Geoff
if ($active_project =~ /simgear/i) {
($grp,$flt) = Get_Default_Group($src);
${$val}[$i][1] = $grp;
${$val}[$i][2] = $flt;
prt("SPECIAL FIX for [$active_project] [$src] [$grp] [$flt]\n") if ($prev_src_fix ne $active_project);
$prev_src_fix = $active_project;
}
$src =~ s/^\.(\\|\/)//;
#$nv = $rp.$src;
$tmp = $vcd.$src;
$tmp2 = fix_rel_path3($tmp,'chk_relative_paths');
if (-f $tmp2) {
$ok = 'ok';
} else {
$ok = 'NF';
push(@not_found,$tmp2);
}
my ($fnm,$fdir) = fileparse($tmp2);
$nv = get_rel_dos_path($fdir,$outd);
# 2010/05/06 - why ??? $nv =~ s/(\\|\/)$//;
$nv .= "\\" if (length($nv) && !($nv =~ /(\\|\/)$/));
$nv .= $fnm; # add back the file name
if ($nv eq $src) {
prt("Source [$src] not changed. [$grp] [$flt]\n") if ($dbg_sl_09 || VERB1());
} else {
prt("Was [$src] GOT CHANGE...\n") if ($dbg_sl_09 || VERB5());;
prt("int [$tmp2]\n") if ($dbg_sl_09 || VERB9());;
prt("New [$nv] [$grp] [$flt] $ok\n") if ($dbg_sl_09 || VERB1());
${$val}[$i][0] = $nv;
}
}
} elsif ($key eq 'PROJECT_CFGS') {
# my $rcfgs = ${$rh}{'PROJECT_CFGS'};
# 0 1 2 3
# push(@{$rcfgs}, [ $pname, $var1, $conf, $dsp_sub_sub ]);
# -NEW_INCS- = [/I "." /I "..\include"]
$acnt = scalar @{$val};
prt("$key - $acnt configs...\n");
for ($i = 0; $i < $acnt; $i++) {
$i2 = $i + 1;
$src = ${$val}[$i][0];
$grp = ${$val}[$i][1];
$flt = ${$val}[$i][2];
$rsb = ${$val}[$i][3];
@karr = keys(%{$rsb});
$scnt = scalar @karr;
$msg = sprintf("%3d:",$i2);
# prt( "$msg: [$src] [$grp] [$flt] = $scnt\n" );
prt( "$msg: [$src] [$flt] = $scnt config items\n" );
foreach $ky (@karr) {
$v2 = ${$rsb}{$ky};
###prt("Doing [$ky], value [$v2]\n");
$nv = '';
if (($ky eq '-NEW_INCS-')||($ky eq '-NEW_DEFS-')) {
# also need to fix things like '/I "..\include"', but NOT '/I "."'
$ok = 0;
$rih = get_new_inc_hash($v2,\$ok,$rp,$vcd,$outd,$ky);
if ($ok) {
prt(" = $ky = [") if ($dbg_sl_10);
$nv = '';
foreach $k3 (keys %{$rih}) {
$v3 = ${$rih}{$k3};
foreach $v (@{$v3}) {
$nv .= ' ' if (length($nv));
$nv .= "$k3 $v";
}
}
if ($nv eq $v2) {
prt(" [$nv] NO CHANGE\n") if ($dbg_sl_10);
} else {
prt("\nnew [$nv], \nwas [$v2]\n") if ($dbg_sl_10);
${$rsb}{$ky} = $nv;
#${$val}[$i][3] = $rsb;
}
} else {
prt( " $ky = [$v2] FAILED REF\n" );
}
} elsif ($ky eq '-NEW_POST-') {
# could have
# -NEW_POST- = [# Begin Special Build Tool
#SOURCE="$(InputPath)"
#PostBuild_Desc=
#PostBuild_Cmds=if not exist ..\..\..\..\lib md ..\..\..\..\lib copy "$(TargetDir)GLUT32.LIB" ..\..\..\..\lib copy "$(TargetDir)GLUT32.DLL" ..\..\..\..\lib if exist ..\..\..\..\progs\demos copy "$(TargetDir)GLUT32.DLL" ..\..\..\..\progs\demos
## End Special Build Tool
# that needs ADJUSTING - wow
$ok = 0;
$nv = get_new_post_string($v2,\$ok,$rp,$vcd,$outd);
if ($ok) {
prt( " $ky CHANGED ok\nwas [$v2]\nnew [$nv]\n") if ($dbg_sl_11);
${$rsb}{$ky} = $nv;
} else {
prt( " $ky = [$v2] NO CHANGES\n" ) if ($dbg_sl_11);
}
} elsif ($ky eq '-NEW_OUTD-') {
$nv = strip_quotes($v2);
$nv =~ s/^\.\.\\//;
$nv .= "\\" if (!($nv =~ /(\\|\/)$/));
$nv .= $active_project;
$nv = add_quotes($nv);
prt( " $ky CHANGED ok\nwas [$v2]\nnew [$nv]\n") if ($dbg_sl_11);
${$rsb}{$ky} = $nv;
} elsif ($ky eq '-NEW_INTER-') {
$nv = strip_quotes($v2);
$nv =~ s/^\.\.\\//;
$nv .= "\\" if (!($nv =~ /(\\|\/)$/));
$nv .= $active_project;
$nv = add_quotes($nv);
prt( " $ky CHANGED ok\nwas [$v2]\nnew [$nv]\n") if ($dbg_sl_11);
${$rsb}{$ky} = $nv;
} elsif ($ky eq '-NEW_LIBS-') {
$nv = strip_quotes($v2);
$ok = 0;
$nv = get_new_libs_string($v2,\$ok,$rp,$vcd,$outd);
if ($ok) {
prt( " $ky CHANGED ok\nwas [$v2]\nnew [$nv]\n") if ($dbg_sl_11);
${$rsb}{$ky} = $nv;
} else {
prt( " $ky = [$v2] NO CHANGES\n" ) if ($dbg_sl_11);
}
} else {
prt( " $ky = [$v2] NOT CHANGED\n" ) if ($dbg_sl_08);
}
###prt( "NEXT KEY after $ky [$v2] [$nv]\n");
}
}
} else {
# dealt with 'PROJECT_SRCS' and 'PROJECT_CFGS' above
# What about PROJECT_NAME, PROJECT_CCNT, PROJECT_FDIR, PROJECT_FILE
# PROJECT_TYPE, PROJECT_DSPF, PROJECT_VERS, PROJECT_APTP, PROJECT_FLAG, PROJECT_MSCV?
$tmp = '';
if ($key eq 'PROJECT_NAME') {
# $tmp = "Like change name from [$val]?";
} elsif ($key eq 'PROJECT_CCNT') {
# $tmp = "Like config count [$val]?";
} elsif ($key eq 'PROJECT_FDIR') {
# $tmp = "Like FDIR [$val]?";
} elsif ($key eq 'PROJECT_FILE') {
# $tmp = "Like FILE [$val]?";
} elsif ($key eq 'PROJECT_TYPE') {
$tmp = "Like TYPE [$val]?";
} elsif ($key eq 'PROJECT_DSPF') {
$tmp = "Like DSP FILE [$val]?";
} elsif ($key eq 'PROJECT_VERS') {
# $tmp = "Like VERS [$val]?";
} elsif ($key eq 'PROJECT_APTP') {
$tmp = "Like APTP [$val]?";
} elsif ($key eq 'PROJECT_FLAG') {
# $tmp = "Like FLAG [$val]?";
} elsif ($key eq 'PROJECT_MSCV') {
# $tmp = "Like FLAG [$val]?";
} elsif ($key eq 'PROJECT_AM_FILE') {
} elsif ($key eq 'PROJECT_ROOT') {
} else {
$tmp = "Like UNCASED [$val]?";
pgm_exit(1,"CHECKME:chk_relative_paths: key [$key] UNCASED, with val [$val]");
}
prt("$key ... any items to change? $tmp\n") if (length($tmp) && $dbg_sl_10);
}
}
}
if (@not_found && VERB1()) {
$tmp = scalar @not_found;
prtw("WARNING: Project $active_project has $tmp MISSING sources!\n");
foreach $src (@not_found) {
prt("$src\n");
}
}
# pgm_exit(1,"Temp stop to check");
}
# ensure -NEW_LIBS- hash ref does NOT contain LIBS already in default
sub fix_lib_list($) {
my ($rh) = @_;
my $key = 'PROJECT_CFGS';
my $chgd = 0;
my $def = get_def_lib_list();
my @a2 = split(/\s/,$def);
if (defined ${$rh}{$key}) {
my $val = ${$rh}{$key};
my $k2 = '-NEW_LIBS-';
my $acnt = scalar @{$val};
for (my $i = 0; $i < $acnt; $i++) {
my $rsb = ${$val}[$i][3]; # get -NEW_LIBS- hash ref
if (defined ${$rsb}{$k2}) {
my $v2 = ${$rsb}{$k2};
prt("[dbg_sl_13] [$v2],\nwith default [$def]\n") if ($dbg_sl_13);
my @a1 = split(/\s/,$v2);
my $chg = 0;
my @arr = ();
my ($lib, $lib2,$fnd,$lclib);
foreach $lib (@a1) {
$lclib = lc($lib);
if ($lib =~ /^\/libpath:/i) { # no change in these
push(@arr,$lib);
} else {
$fnd = 0; # else check if already in DEFAULTS
foreach $lib2 (@a2) {
if ($lclib eq lc($lib2)) {
$fnd = 1;
last;
}
}
if ($fnd) {
$chg++; # dump this DUPLICATE
} else {
push(@arr,$lib); # else keep this
}
}
}
if ($chg) {
$lib = join(" ",@arr);
${$rsb}{$k2} = $lib;
prt(" Set NEW [$lib]\n") if ($dbg_sl_13);
$chgd++;
}
}
} # for each configuration
if ($chgd) {
# pgm_exit(1,"TEMP EXIT");
}
}
}
sub show_project_hash($) {
my $rh = shift;
my @arr = keys(%{$rh});
my $cnt = scalar @arr;
my $rc_files = ${$rh}{'PROJECT_C_SOURCES'}; # = \@c_files;
my $rh_files = ${$rh}{'PROJECT_H_SOURCES'}; # = \@h_files;
my $ro_files = ${$rh}{'PROJECT_O_SOURCES'}; # = \@o_files;
my $name = ${$rh}{'PROJECT_NAME'}; # = $name;
my $sdir = ${$rh}{'PROJECT_SDIR'}; # = $sdir;
my $type = ${$rh}{'PROJECT_TYPE'}; # = $type;
my $rincs = ${$rh}{'PROJECT_INCS'}; # = \%inc_hash;
my $rdefs = ${$rh}{'PROJECT_DEFS'}; # = \%def_hash;
my $ccnt = scalar @{$rc_files};
my $hcnt = scalar @{$rh_files};
my $ocnt = scalar @{$ro_files};
my $icnt = scalar keys(%{$rincs});
my $dcnt = scalar keys(%{$rdefs});
prt("Project [$name], type [$type], $ccnt C/C++, $hcnt Hdrs, $ocnt Other, $icnt INCS, $dcnt DEFS\n");
my ($key,$val);
foreach $key (@arr) {
$val = ${$rh}{$key};
if (($key eq 'PROJECT_NAME')||($key eq 'PROJECT_TYPE')||($key eq 'PROJECT_SDIR')) {
prt("$key = $val\n");
} elsif (($key eq 'PROJECT_INCS')||($key eq 'PROJECT_DEFS')) {
$cnt = scalar keys(%{$val});
prt("$key with $cnt item keys in hash ref\n");
} elsif (($key eq 'PROJECT_C_SOURCES')||($key eq 'PROJECT_H_SOURCES')||($key eq 'PROJECT_O_SOURCES')) {
$cnt = scalar @{$val};
prt("$key with $cnt items in ref array\n");
} else {
prtw("WARNING: Uncased KEY [$key] FIX ME! 4\n");
}
}
}
sub get_hash_results($$) {
my ($nhr,$dsp) = @_;
my @arr = keys( %{$nhr} );
my $cnt = scalar @arr;
my ($key,$name,$val,$inf,$acnt,$src);
my ($grp,$flt,$min1,$min2,$len);
my ($i,$i2,$msg,$rsb,$scnt,@karr);
my ($ky,$v2,$sdir,$ff,$ok,$type);
$key = 'PROJECT_NAME';
$name = ${$nhr}{$key};
$key = 'PROJECT_FDIR';
$sdir = ${$nhr}{$key};
$key = 'PROJECT_APTP';
$type = ${$nhr}{$key};
prt( "Show of NEW hash ref., up to $cnt keys... project [$name]\n" ) if ($dsp);
$cnt = 0;
my $rpki = get_prj_key_info_ref();
my @c_files = ();
my @h_files = ();
my @o_files = ();
my %inc_hash = ();
my %def_hash = ();
foreach $key (@arr) {
$val = ${$nhr}{$key};
next if ($key =~ /^TEMP_/);
if ( $key =~ /^CURR_/ ) {
# ignore these CURRENT state items
} else {
$cnt++;
if (defined ${$rpki}{$key}) {
$inf = ${$rpki}{$key};
if (($inf =~ /^/)||($inf =~ /^/)) {
prt( "$key $inf =[$val]\n" ) if ($dsp);
} else {
$acnt = scalar @{$val};
prt( "$key $inf =(ARRAY of count $acnt)\n" ) if ($dsp);
if ($key eq 'PROJECT_SRCS') {
$min1 = 0;
$min2 = 0;
for ($i = 0; $i < $acnt; $i++) {
$src = ${$val}[$i][0];
$grp = ${$val}[$i][1];
$flt = ${$val}[$i][2];
$len = length($src);
$min1 = $len if ($len > $min1);
$len = length($grp);
$min2 = $len if ($len > $min2);
}
for ($i = 0; $i < $acnt; $i++) {
$i2 = $i + 1;
$src = ${$val}[$i][0];
$grp = ${$val}[$i][1];
$flt = ${$val}[$i][2];
if ($src =~ /^\w{1}:(\\|\/)/) { # this appears to be a FULL FILE NAME like C:
$ff = $src;
} else {
$ff = fix_rel_path3($sdir.$src,'show_hash_results3'); # in fgutils02.pl
}
$ok = (-f $ff) ? 'ok' : 'NF';
if (is_c_source_extended($src)) {
push(@c_files,$src);
} elsif (is_h_source($src)) {
push(@h_files,$src);
} else {
push(@o_files,$src);
}
# setup for display
$src .= ' ' while(length($src) < $min1);
$grp .= ' ' while(length($grp) < $min2);
$msg = sprintf("%3d:",$i2);
prt( "$msg $src $grp $flt $ok\n" ) if ($dsp);
}
} elsif ($key eq 'PROJECT_CFGS') {
# my $rcfgs = ${$rh}{'PROJECT_CFGS'};
# 0 1 2 3
# push(@{$rcfgs}, [ $pname, $var1, $conf, $dsp_sub_sub ]);
for ($i = 0; $i < $acnt; $i++) {
$i2 = $i + 1;
$src = ${$val}[$i][0];
$grp = ${$val}[$i][1];
$flt = ${$val}[$i][2];
$rsb = ${$val}[$i][3];
@karr = keys(%{$rsb});
$scnt = scalar @karr;
$msg = sprintf("%3d:",$i2);
prt( "$msg $src $grp $flt $scnt\n" ) if ($dsp);
foreach $ky (@karr) {
$v2 = ${$rsb}{$ky};
prt( " $ky = [$v2]\n" ) if ($dsp);
if ($ky eq '-NEW_INCS-') {
set_inc_hash(\%inc_hash,$v2);
} elsif ($ky eq '-NEW_DEFS-') {
set_def_hash(\%def_hash,$v2);
}
}
}
}
}
} else {
my $wmsg = "[$key] NOT IN INFO LIST!";
if (!defined $shown_warn{$key}) {
prtw( "WARNING:vcpoj05: $wmsg, see sub get_prj_key_info_ref() & \%prj_key_info\n" );
$shown_warn{$key} = 1;
}
}
}
}
prt("Done show of $cnt keys... project [$name]\n") if ($dsp);
my %hash = ();
$hash{'PROJECT_C_SOURCES'} = \@c_files;
$hash{'PROJECT_H_SOURCES'} = \@h_files;
$hash{'PROJECT_O_SOURCES'} = \@o_files;
$hash{'PROJECT_NAME'} = $name;
$hash{'PROJECT_SDIR'} = $sdir;
$hash{'PROJECT_TYPE'} = $type;
$hash{'PROJECT_INCS'} = \%inc_hash;
$hash{'PROJECT_DEFS'} = \%def_hash;
return \%hash;
}
# dbg_show_entering_files();
# dbg_show_source_files();
# dbg_show_output_files(); # { $dbg_v21 = 1; $dbg_v24 = 1; }
# 2009/10/29 - make it work for TWO different forms of VC HASH
# 13/07/2011 - if ($out_dsp_dir ne $perl_base), then try to also ADJUST sources
sub process_vcproj_file($$) {
my ($in, $outd) = @_;
my ($key,$pnam,$out,$cnt,$dsp);
my ($prjf,$nm,$dir,$ext,$dspf,$tmp2);
my ($msg);
my ($rdspf,$fprjf,$fdspf,$dprjf,$type);
prt( "[dbg_sl_05] $pgmname: Scanning [$in]...\n" ) if ($dbg_sl_05);
my ($vc_name,$vc_dir) = fileparse($in);
$vc_dir = $pwd."\\" if ($vc_dir =~ /^\.(\\|\/)$/);
my $rh = process_VCPROJ3($in);
# FIX20120718 - some 'fixes' if NOT already defined
if (!defined ${$rh}{'PROJECT_ROOT'}) {
${$rh}{'PROJECT_ROOT'} = $vc_dir;
}
if (!defined ${$rh}{'PROJECT_AM_FILE'}) {
${$rh}{'PROJECT_AM_FILE'} = $in;
}
# check for application type over-ride...
if (length($curr_app_type)) {
$key = 'APP_TYPE';
$key = 'PROJECT_APTP' if (!defined ${$rh}{$key});
if (defined ${$rh}{$key}) {
$tmp2 = ${$rh}{$key};
${$rh}{$key} = $curr_app_type;
if ($tmp2 ne $curr_app_type) {
prt("Overrode $key with [$curr_app_type], from [$tmp2]\n");
}
}
}
$type = "NOT DEFINED";
$key = 'APP_TYPE';
$key = 'PROJECT_APTP' if (!defined ${$rh}{$key});
if (defined ${$rh}{$key}) {
$type = ${$rh}{$key};
}
# 2010-01-15 - get appropriate DSP file name (real = to replace existing, if any)
$key = 'PROJECT_FILE';
$fprjf = '';
$rdspf = '';
$fdspf = '';
if (defined ${$rh}{$key}) {
$fprjf = ${$rh}{$key};
($nm,$dprjf,$ext) = fileparse($fprjf, qr/\.[^.]*/);
$fdspf = $dprjf.$nm.".dsp"; # this may/should be ABSOLUTE
} else {
pgm_exit(1,"ERROR: key [$key] NOT IN hash! AND IT MUST BE!! Aborting!!!\n");
}
# FIX20120718 - If NO project name, then use the input project file name as default
if (!defined ${$rh}{'-NEW_PROJECT_NAME-'} && !defined ${$rh}{'PROJECT_NAME'}) {
${$rh}{'PROJECT_NAME'} = $nm;
prt("No project name, so using project file name [$nm]!\n");
}
$pnam = "NO PROJECT NAME";
$key = '-NEW_PROJECT_NAME-';
$key = 'PROJECT_NAME' if (!defined ${$rh}{$key});
if (defined ${$rh}{$key}) {
$pnam = ${$rh}{$key}; # get the PROJECT NAME
}
# show_hash_results3($rh) if ($dbg_sl_04); # this would be BEFORE any changes made in chk_relative_paths...
$key = '-NEW_PROJECT_NAME-';
$key = 'PROJECT_NAME' if (!defined ${$rh}{$key});
if (defined ${$rh}{$key}) {
$pnam = ${$rh}{$key}; # get the PROJECT NAME
$dsp = $pnam.".dsp"; # make a DSP file name
${$rh}{'PROJECT_DSPF'} = $dsp;
$outd .= "\\" if ( !($outd =~ /[\\\/]$/) ); # ensure out directory ends '\'
$out = $outd; # using OUT directory
$out .= "temp.".$dsp; # form a TEMPORARY DSP file name
fix_lib_list($rh);
# crude game to ensure TEMP DSP name for this project is UNIQUE
$cnt = 0;
while ( is_in_array($out, @dsp_file_list) ) {
$cnt++; # already have a DSP of that name, so
$out = $outd; # get OUT directory again, and
$out .= "temp.".$pnam.$cnt.".dsp"; # add a COUNT to name
}
if ($fix_rel_paths) {
# ======================================================================================
# ok, need to change sources from perhaps '.\src.cxx' to '..\..\lib\src.cxx' - a big job
# and LOTS of other things...
# UGH - calling this HERE, is BEFORE the %results hash is built
chk_relative_paths($rh,$outd,$vc_dir); # was $perl_base; # this can be changed by -dsp=
# ======================================================================================
} else {
prt("No relative path change: vcd=[$vc_dir] out=[$outd]\n") if (VERB9());
}
# 2011-10-18 - Make other ADSJUTMENTS to DSP HASH
adjust_inter_out_dirs($rh) if ($adj_inter);
adjust_runtime_to($rh,$adj_rt) if (length($adj_rt));
adjust_output_name($rh) if ($adj_out);
# remove like -NEW_LIBS- = [wsock32.lib comctl32.lib /libpath:"..\lib" /nodefaultlib:"libcmtd"]
$tmp2 = ''; # clear $tmp2
delete_nodefaultlib_all($rh,\$tmp2) if ($del_ndl_all);
if (length($tmp2) && VERB5()) {
prt("[v5] Removed /nodefaultlib [$tmp2]\n");
}
if ($dbg_sl_04 || VERB1()) {
my $rh2 = show_hash_results3($rh); # if ($dbg_sl_04 || VERB5())
show_project_hash($rh2);
}
# *** WRITE DSP FILE - FIRST TO A 'TEMP' FILE, to do a compare, if needed ***
# ===========================================================================
if ($write_dsp > 0) {
prt("Doing write_hash_to_DSP3 $out (debug=$dbg4write)\n") if (VERB9());
if ( write_hash_to_DSP3( $out, $rh, $dbg4write ) ) {
push(@dsp_file_list,$out); # store name
# project_list 0 1 2
#push(@project_list, [ $tmp, $dsp, $out ]);
push(@project_list, [ $pnam, $fdspf, $out ]);
$key = 'PROJECT_FILE';
if (defined ${$rh}{$key}) {
$prjf = ${$rh}{$key};
prt( "For '$prjf' written '$out'\n" ) if (VERB5());
# Uses cmp2dsps[?].pl, external to here...
if ($comp_2_dsps) {
($nm,$dir,$ext) = fileparse($prjf, qr/\.[^.]*/);
$dspf = $dir.$nm.".dsp";
if (( -f $dspf)&&( -f $out)) {
$msg = "cmp2dsps $dspf $out";
$msg .= " -l" if ($load_log);
prt("Doing $msg...\n");
system("$msg");
} else {
$msg = "No compare done! ";
if ( !(-f $dspf) ) {
$msg .= "Missing [$dspf]?";
}
if ( !(-f $out) ) {
$msg .= "Missing [$out]??";
}
prtw("WARNING: $msg\n");
}
}
# =======================================
}
} else {
prtw("WARNING: No DSP written for [$pnam] project.\n" );
}
} else {
prt("Project: $pnam: No DSP written - Use -dsp[:dsp_dir] to enable!\n");
}
} else {
if ($dbg_sl_04 || VERB1()) {
my $rh2 = show_hash_results3($rh); # if ($dbg_sl_04 || VERB5())
show_project_hash($rh2);
}
prtw("WARNING: NO PROJECT NAME! = NO DSP WRITTEN!\n");
}
if (do_hash_cmake_test($rh)) {
prtw("WARNING: PROJECT $pnam $type FAILED CMAKE HASH TEST!\n");
} else {
my $rcph = get_cmake_proj_hash_ref(); # = return \@my_cmake_proj_hashes;
push(@{$rcph},$rh); # add $rh to @my_cmake_proj_hashes
prt("Added: PROJECT $pnam $type my_cmake_proj_hashes\n");
}
push(@proj_hash_array,$rh);
return $rh;
}
sub fix_rel_path2($$) {
my ($root,$rel) = @_;
my $cd = cwd();
my ($fp,$msg,$tmp);
if (chdir($root)) {
$fp = File::Spec->rel2abs($rel); # we are IN the SLN directory, get ABSOLUTE from RELATIVE
chdir($cd); # and get us back to where we were...
$msg = "1:File::Spec:";
} else {
$fp = fix_rel_path3($root.$rel,'fix_rel_path2'); # else use internal service
$msg = "2:fix_rel_path3:"
}
if (-f $fp) {
$msg .= " ok";
} else {
$msg .= " NOT FOUND";
if ($fp =~ /\\SimGear\.cs\\/) {
$tmp = $fp;
$tmp =~ s/\\SimGear\.cs\\/\\SimGear-cs\\/;
if (-f $tmp) {
$fp = $tmp;
$msg = "ok $msg";
}
}
if ($msg =~ /^1/) {
$tmp = fix_rel_path3($root.$rel,'fix_rel_path2'); # else use internal service
if (-f $tmp) {
$fp = $tmp;
$msg .= ", but OK with fix_rel_path3!!!";
} else {
$msg .= ", NOR from fix_rel_path3 [$tmp]"
}
}
}
prt("From: [$root] [$rel], got [$fp] $msg\n") if ($dbg_sl_14);
return $fp; # hopefully, return ABSOLUTE path
}
# Read and store contents of SOLUTION (.sln) file
# 22/04/2008 - Extract DEPENDENCIES from solution file, and add to DSW output
# 24/11/2010 - Support for VC10 XML files
sub process_SLN_file2($) {
my ($sln_fil_in) = shift;
my ($cnt, $line, $vers, @arr, $mver, $par, $ff, $itmnum);
my ($projname, $projfile, $projff, $gotproj, $relpath);
my ($tnm,$tpth);
my ($inproj, $tline, $projid, $inpdeps, $projdeps);
my ($nmdeps, $depid, $pn, $fnd, $list);
my ($msg,$text,$dspfile,$fdspfil,$name);
my $fil = File::Spec->rel2abs($sln_fil_in);
open IF, "<$fil" or mydie( "ERROR: Unable to open [$fil]... $! ...\n" );
my @lines = ;
close IF;
$cnt = scalar @lines;
($name,$sln_path) = fileparse($fil); # get the NAME, and SOLUTION PATH (should be ABSOLUTE, NOT relative)
my %hash = ();
my %sln_projects = ();
my %sln_projpath = ();
my %sln_depends = ();
my %sln_projids = ();
my %missed_vcprojs = ();
prt( "\nProcessing $cnt lines ... n=[$name] p=[$sln_path] ...\n" ) if (VERB1());
$projname = '';
$projfile = '';
$projff = '';
$gotproj = 0;
$inproj = 0;
$inpdeps = 0;
foreach $line (@lines) {
$tline = trim_all($line);
if ($line =~ /.+Format\s+Version\s+(\d+\.\d+)$/i) {
$vers = $1; # get n.nn version
@arr = split(/\./,$vers);
$mver = $arr[0];
prt( "Is MSVC Version $mver ...\n" );
} elsif ($line =~ /^Project\s*\(/) {
# seek like
#Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ALL_BUILD", "ALL_BUILD.vcxproj", "{4BB0374F-3B6E-4EC8-9BE0-4BE8947B80E3}"
#Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "abyss", "abyss.vcproj", "{8B384B8A-2B72-4DC4-8DF1-E3EF32F18850}"
#Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fgadmin", "fgadmin\fgadmin.vcxproj", "{7004E589-7EA0-4AFD-B432-3D5E00B55049}"
# ProjectSection(ProjectDependencies) = postProject
# {22540CD3-D3CA-4C86-A773-80AEEE3ACDED} = {22540CD3-D3CA-4C86-A773-80AEEE3ACDED}
# EndProjectSection
#EndProject
###prt( "Got project [$line] ...\n" );
$inproj = 1;
@arr = split( '=', $line );
$cnt = scalar @arr;
if ($cnt == 2) {
$par = $arr[1]; # get 2nd part, like say '"abyss", "abyss.vcproj", "{8B384B8A-2B72-4DC4-8DF1-E3EF32F18850}"'
@arr = split(',', $par);
$cnt = scalar @arr;
if ($cnt == 3) {
$projname = strip_quotes(trim_all($arr[0])); # project NAME
$projfile = strip_quotes(trim_all($arr[1])); # vcproj FILE (sometimes)
$projid = strip_quotes(trim_all($arr[2])); # project ID
$projff = fix_rel_path2($sln_path,$projfile); # return ABSOLUTE
# if ((length($projname)) && (is_vcproj_ext($projfile)) && (-f $projff)) {
# 01/12/2010 - Remove need for the file to EXIST
#if ((length($projname)) && (is_vcproj_ext($projfile)) ) {
if ((length($projname)) && (is_vcproj_ext($projfile) || is_vcxproj_ext($projfile)) ) {
if (-f $projff) {
# and file
} else {
$missed_vcprojs{$projname} = $projff;
}
$gotproj = 1;
($tnm,$tpth,$text) = fileparse($projff,qr/\.[^.]*/);
$fdspfil = $tpth.$tnm.".dsp"; # this is a DSP EQUIVALENT to the vcproj location
# BUT, we may have been given a DIFFERENT DSP output dir through
# -dsp= ($out_dsp_dir) and $g_had_dsp, and maybe '-fix-rel' ($fix_rel_paths)
if ($g_had_dsp) {
$fdspfil = $out_dsp_dir;
$fdspfil .= "\\" if ( !($fdspfil =~ /(\\|\/)$/) );
$fdspfil .= $tnm.".dsp";
}
$relpath = get_rel_dos_path($tpth, $sln_path);
($tnm,$tpth,$text) = fileparse($projfile,qr/\.[^.]*/);
$dspfile = $tpth.$tnm.".dsp";
prt( "Got PROJECT name=$projname, file=[$projfile], ff=[$projff], rel=[$relpath].\n" ) if ($dbg_sl_01);
if (defined $sln_projects{$projname}) {
mydie( "A PROBLEM: Already GOT this project name $projname!!!\n" );
} else {
$sln_projects{$projname} = $projff;
# $sln_projpath{$projname} = $relpath; # can be BLANK, or say 'BvMath/'
# 0 1 2 3 4
$sln_projpath{$projname} = [$projfile,$projff,$relpath,$dspfile,$fdspfil]; # relative project file, like '..\alut\path\alut.vcproj'
prt( "Stored \$sln_projpath{$projname} = [0:$projfile,1:$projff,2:$relpath,3:$dspfile,4:$fdspfil]\n") if ($dbg_sl_15);
$sln_projids{$projname} = $projid;
$sln_depends{$projname} = ''; # start dependencies, if any
if ($dbg_sl_16) {
my $msg = $projname;
$msg .= ' ' while (length($msg) < 24);
$msg .= $projid;
prt("$msg\n");
}
}
### pgm_exit(1,"TEMP EXIT");
} else {
# CARE: Vers 11 MSVC10 can have projects with NO file extension
# Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lua51", "Lua51", "{1CBEAA34-BA34-497D-A775-B9AF6F905696}"
# Seems these are project GROUPS, with no project file, so NO warning required
if ($projname eq $projfile) {
# forget these groups
$gotproj = 1; # pretent we got the project
} else {
$msg = "WARNING: ";
if (!length($projname)) {
$msg .= "Failed to get a project name! ";
} elsif ( !is_vcproj_ext($projfile) && !is_vcxproj_ext($projfile)) {
$msg .= "Name [$projfile] NOT a VCPROJ nor VCXPROJ name! ";
} else {
$msg .= "Unable to locate file [$projff]! ";
}
$msg .= " Line is (trimmed)\n$tline";
prtw("$msg\n");
}
}
} else {
prtw( "Warning: Part 2 of Project line did NOT split into 3 on comma!???\n" );
}
} else {
prtw( "Warning: Project line did NOT split in 2 on equal sign!???\n" );
}
# to switch on $tryharder requires additional work on parsing this line
# =====================================================================
prtw("WARNING: line [$line] ...\n") if (!$gotproj);
# =====================================================================
} elsif ($inproj) {
# in the Project section - look for END of section, and DEPENDENCIES
# ProjectSection(ProjectDependencies)
if ($tline eq 'EndProject') {
###if ($line =~ /^EndProject\s*/)
$inproj = 0;
} else {
if ($inpdeps) {
if ($tline eq 'EndProjectSection' ) {
$inpdeps = 0;
} else {
# collect dependencies
@arr = split( '=', $line );
$cnt = scalar @arr;
if ($cnt == 2) {
$arr[0] = trim_all($arr[0]);
$arr[1] = trim_all($arr[1]);
if ($arr[0] eq $arr[1]) {
$projdeps = $sln_depends{$projname}; # extract dependencies, if any
$projdeps .= '|' if (length($projdeps));
$projdeps .= $arr[0];
prt( "$pgmname: Proj $projname, dependant on $arr[0] ...\n" ) if ($dbg_sl_02);
##prt( "Proj $projname, dependant on $projdeps ...\n" );
$sln_depends{$projname} = $projdeps;
} else {
prtw( "Warning: Found different IDS '$arr[0]' NE '$arr[1]'!!! \n" );
}
} else {
prtw( "Warning: Project DEPENDENCY line did NOT split in 2 on equal sign!???\n" );
prtw( "line=$line" );
}
}
} elsif ($line =~ /ProjectSection\s*\(\s*ProjectDependencies\s*\)/) {
$inpdeps = 1;
}
}
}
}
###prt( "Done $fil ... got ".scalar @proj_files." project files ...\n" );
prt( "Done $fil ... got ".scalar keys(%sln_projects)." project files ...\n" );
# resolve dependencies, if possible - warn if NOT ...
#resolve_depends();
# Have STORED
# $sln_projects{$projname} = $projff;
# $sln_projpath{$projname} = $relpath; # can be BLANK, or say 'BvMath/'
# 0 1 2 3 4
#$sln_projpath{$projname} = [$projfile,$projff,$relpath,$dspfile,$fdspfil]; # relative project file, like '..\alut\path\alut.vcproj'
#prt( "Stored \$sln_projpath{$projname} = [0:$projfile,1:$projff,2:$relpath,3:$dspfile,4:$fdspfil]\n") if ($dbg_sl_15);
# $sln_projids{$projname} = $projid;
# $sln_depends{$projname} = ''; # start dependencies, if any
foreach $projname (keys %sln_projects) {
$projdeps = $sln_depends{$projname};
if (length($projdeps)) {
# there is LENGTH, convert giant CID to simple project names
@arr = split( /\|/, $projdeps ); # split em up
$cnt = scalar @arr; # get count of split
#prt( "Proj $projname, depends on $cnt = $projdeps ...\n" );
$nmdeps = ''; # build simple NAME set
foreach $depid (@arr) {
# find project MATCHING that ID, in full list of IDs
$fnd = 0;
$list = '';
foreach $pn (keys %sln_projids) {
if ($pn ne $projname) {
$projid = $sln_projids{$pn};
$list .= "|$projid";
if ($depid eq $projid) {
$nmdeps .= '|' if (length($nmdeps));
$nmdeps .= $pn;
$fnd = 1;
last;
}
}
}
if (!$fnd) {
prtw("Warning: Failed to FIND [$depid], in list \n[$list]\n!");
}
}
@arr = split( /\|/, $nmdeps );
prt( "$pgmname: proj $projname, depends on $nmdeps ...\n" ) if ($dbg_sl_03);
if ($cnt != scalar @arr) { # YEEK - Does NOT match - OH WELL
prtw( "WARNING: proj [$projname] with depends [$projdeps] Failed to get SAME count $cnt - got ".scalar @arr." on split [$nmdeps]\n" );
pgm_exit(1,"");
}
$sln_depends{$projname} = $nmdeps;
}
}
# ====================================================================
$hash{'SOLUTION'} = $fil; # keep the SOLUTION files also
$hash{'PROJECTS'} = { %sln_projects };
$hash{'PROJPATH'} = { %sln_projpath }; # array refs [$projfile,$projff,$relpath]
$hash{'DEPENDS'} = { %sln_depends };
$hash{'PROJIDS'} = { %sln_projids };
$hash{'MISSED_FILES'} = { %missed_vcprojs }; # not found on DISK
return \%hash;
}
sub remove_base_path($$) {
my ($ln, $bs) = @_;
my $len1 = length($ln);
my $len2 = length($bs);
if ($len1 < $len2) {
return $ln;
}
my ($i,$c1,$c2);
for ($i = 0; $i < $len2; $i++) {
$c1 = lc(substr($ln,$i,1));
$c2 = lc(substr($bs,$i,1));
if ($c1 ne $c2) {
return $ln;
}
}
return substr($ln,$len2);
}
sub return_common_dir($$) {
my ($d1,$d2) = @_;
my ($ll,$k,$com);
$com = '';
$ll = length($d1);
$ll = length($d2) if (length($d2) < $ll); # get SHORTEST
for ($k = 0; $k < $ll; $k++) { # process for SHORTEST length
last if (lc(substr($d1,$k,1)) ne lc(substr($d2,$k,1))); # end on first NOT SAME
$com .= substr($d1,$k,1); # else add to common
}
return $com;
}
sub get_common_dir($) {
my ($rffh) = @_;
my $cdir = '';
my @keys = keys %{$rffh};
my $kcnt = scalar @keys;
my ($ky1,$ky2,$k,$com);
for ($k = 0; ($k+1) < $kcnt; $k++) {
$ky1 = $keys[$k];
$ky2 = $keys[$k+1];
$com = return_common_dir($ky1,$ky2);
if (length($com) == 0) {
return ""; # no COMMON
}
if (length($cdir)) {
$com = return_common_dir($com,$cdir);
if (length($com) == 0) {
return ""; # no COMMON
}
}
$cdir = $com; # update the COMMON
}
return $cdir;
}
# sub mycmp_decend {
sub mysort2 {
return 1 if (${$a}[2] lt ${$b}[2]);
return -1 if (${$a}[2] gt ${$b}[2]);
return 0;
}
sub mysort0 {
return -1 if (lc(${$a}[0]) lt lc(${$b}[0]));
return 1 if (lc(${$a}[0]) gt lc(${$b}[0]));
return 0;
}
sub sort_ref_results_by_type($) {
my ($rr) = @_;
my @arr = sort mysort2 @{$rr};
return \@arr;
}
sub sort_ref_results_by_name($) {
my ($rr) = @_;
my @arr = sort mysort0 @{$rr};
return \@arr;
}
sub show_sln_results($) {
my ($rsh) = @_;
my ($cnt,$min1,$min2,$min3,$cnt2);
my ($val,$val2,$val3,$len);
my ($k,$i,$dspf,$j);
my ($tdsp,$vcpf);
$k = 'RESULTS';
if (! defined ${$rsh}{$k}) {
prtw("WARNING: Soluion hash reference does NOT contain [$k]!\n");
return 1;
}
# push(@results, [$k, $nm, $captyp, $ff]); # stored in 'RESULTS'
# 0 1 2 3 4 5 6
# push(@results, [$k, $nm, $captyp, $relpf, $fdspf, 0, 0]); # stored in 'RESULTS'
my $results = ${$rsh}{$k};
$k = 'PROJECT_LIST';
if (! defined ${$rsh}{$k}) {
prtw("WARNING: Soluion hash reference does NOT contain [$k]!\n");
return 1;
}
my $plist = ${$rsh}{$k};
$k = 'PROJECT_FILE';
if (! defined ${$rsh}{$k}) {
prtw("WARNING: Soluion hash reference does NOT contain [$k]!\n");
return 1;
}
my $in = ${$rsh}{$k};
$cnt = scalar @{$results};
if ($cnt == 0) {
prt("\nNo projects found!\n");
return;
}
# get lengths, for neat output
$min1 = 0;
$min2 = 0;
$min3 = 0;
# 0 1 2 4
# push(@project_list, [ $tmp, $dsp, $out, $fdspf]);
$cnt2 = scalar @{$plist};
# 0 1 2 3 4 5 6
# push(@results, [$name, $file, $type, $relpf, $fdspf, 0, 0]); # stored in 'RESULTS'
if ($sort_by_name) {
$results = sort_ref_results_by_name($results);
}
if ($sort_by_type) {
$results = sort_ref_results_by_type($results);
}
my %types = ();
for ($i = 0; $i < $cnt; $i++) {
$val = ${$results}[$i][0];
$val2 = ${$results}[$i][1];
$val3 = ${$results}[$i][2];
$len = length($val);
$min1 = $len if ($len > $min1);
$len = length($val2);
$min2 = $len if ($len > $min2);
$len = length($val3);
$min3 = $len if ($len > $min3);
if (defined $types{$val3}) {
$types{$val3}++;
} else {
$types{$val3} = 1;
}
}
prt("\nSolution file [$in], has $cnt projects...($cnt2)\n");
if (VERB1()) {
if ($cnt) {
# about to output something like
# testcon testcon.vcproj Console Application testcon.dsp (C:\GTools\perl\temp.testcon.dsp)
# Setup a HEADING line
$val = "Name";
$val2 = "File";
$val3 = "Type";
$val .= ' ' while (length($val) < $min1);
$val2 .= ' ' while (length($val2) < $min2);
$val3 .= ' ' while (length($val3) < $min3);
prt("$val $val2 $val3"); # set HEADINGS
prt(" DSP File") if (VERB5());
prt("\n");
}
for ($i = 0; $i < $cnt; $i++) {
$val = ${$results}[$i][0]; # extract the project NAME
$dspf = 'UNKNOWN';
$tdsp = $dspf;
for ($j = 0; $j < $cnt2; $j++) {
if (${$plist}[$j][0] eq $val) {
$dspf = ${$plist}[$j][1];
$tdsp = ${$plist}[$j][2];
last;
}
}
$val2 = ${$results}[$i][1];
$val3 = ${$results}[$i][2];
# 0 1 2 3 4 5 6
# push(@results, [$projfile,$projff,$relpath,$dspfile,$fdsp, 0, 0]); # relative project file, like '..\alut\path\alut.dsp'
$vcpf = ${$results}[$i][3]; # destination, relative DSP file, for DSW write
if ($tdsp ne $dspf) {
$dspf = "$dspf ($tdsp)";
}
$val .= ' ' while (length($val) < $min1);
$val2 .= ' ' while (length($val2) < $min2);
$val3 .= ' ' while (length($val3) < $min3);
#prt("$val $val2 $val3 $dspf\n");
# tgvpf tgvpf.vcproj Console Application .\tgvpf.dsp (C:\FG\28\terragear-cs\projects\msvc\temp.tgvpf.dsp) [tgvpf\tgvpf.dsp]
prt("$val $val2 $val3\n");
###prt(" $dspf [$vcpf]") if (VERB5());
###prt("\n");
}
}
prt("Counts per type: ");
foreach $val (keys %types) {
if (length($val) == 0) {
prt(" = $types{$val} ");
} else {
prt("$val = $types{$val} ");
}
}
prt("\n");
prt( "$pgmname: Done $cnt vcproj processing...\n" ) if (VERB1());
}
# If an $out directory given, try to adjust all SOURCE relative to this folder
sub sln_file_processing($$$) {
my ($flg,$in,$out) = @_;
my ($k,$rsh,$val,$ff,$key,$captyp,$nm,$dir,$cnt,$i,$min1,$min2,$val2,$len);
my ($refhash,$min,$cnt2,$dspf,$j,$val3,$min3,$ok);
my ($ext,$k2,$relpf,$fdspf);
my @results = ();
($nm,$sln_root_dir) = fileparse($in);
$rsh = process_SLN_file2($in);
if (VERB9()) {
prt( "$pgmname: KEYS in SLN hash = " );
foreach $k (keys %{$rsh}) { prt( "$k " ); }
prt("\n");
}
# =====================================
$k = 'PROJECTS';
$k2 = 'PROJPATH';
if ((defined ${$rsh}{$k})&&(defined ${$rsh}{$k2})) {
# $sln_projects{$projname} = $projff;
$val = ${$rsh}{$k}; # extract projects HASH
$val2 = ${$rsh}{$k2}; # extract project paths HASH
$min = 0;
$cnt = 0;
$min1 = 0;
my %ffhash = ();
foreach $k (keys %{$val}) {
$ff = ${$val}{$k};
$len = length($k);
$min = $len if ($len > $min);
if (is_vcproj_ext($ff) || is_vcxproj_ext($ff)) {
$ffhash{$ff} = 1;
$cnt++;
} else {
$ffhash{$ff} = 0;
}
$len = length($ff);
$min1 = $len if ($len > $min1);
}
$commdir = get_common_dir( \%ffhash );
if (length($commdir)) {
prt("All $cnt vcproj files in a COMMON PATH: [$commdir]\n");
if (length($commdir) < $min1) {
$min1 -= length($commdir);
}
}
prt("SLN path=[$sln_root_dir]\n") if ($commdir ne $sln_root_dir);
if (VERB1()) {
foreach $k (keys %{$val}) {
$ff = ${$val}{$k};
# 0 1 2 3
# $sln_projpath{$projname} = [$projfile,$projff,$relpath,$dspfile]; # relative project file, like '..\alut\path\alut.dsp'
# and later
# push(@results, [$k, $nm, $captyp, $relpf, $fdspf]); # stored in 'RESULTS'
$val3 = ${$val2}{$k};
$relpf = ${$val3}[3]; # relative DSP file, for DSW write
$ok = (( -f $ff ) ? "ok" : "NOT FOUND!");
($nm, $dir, $ext) = fileparse( $ff, qr/\.[^.]*/ );
$dspf = $dir.$nm.".dsp";
$ok .= "2" if (-f $dspf);
$ff = remove_base_path($ff,$commdir) if (length($commdir));
$k .= ' ' while (length($k) < $min);
$ff .= ' ' while (length($ff) < $min1);
prt("$k - $ff ($ok) $relpf\n" ); # this DSP rel.path may need to be changed later, if -dsp=
}
prt( "\nNow to process EACH of the $cnt projects...\n" );
}
# --------------------------------------------------
foreach $k (keys %{$val}) {
$ff = ${$val}{$k};
# prt("$k - $ff\n" );
($nm, $dir) = fileparse($ff);
# if (is_vcproj_ext($ff))
# 01/12/2010 - add an existance check
#if (is_vcproj_ext($ff) && (-f $ff)) {
# 14/04/2012 - add check for vcxproj
if (-f $ff) {
if (is_vcproj_ext($ff)) {
$refhash = process_vcproj_file($ff, $out);
} elsif (is_vcxproj_ext($ff)) {
$refhash = process_vcxproj_file($ff, $out);
}
$key = 'APP_TYPE';
if ( ! defined ${$refhash}{$key}) {
$key = 'PROJECT_APTP';
}
if (defined ${$refhash}{$key}) {
$captyp = ${$refhash}{$key};
} else {
$captyp = "Unknown - key=[$key] NOT SET";
}
# 0 1 2 3 4
# $sln_projpath{$projname} = [$projfile,$projff,$relpath,$rdsp,$fdsp]; # relative project file, like '..\alut\path\alut.dsp'
$val3 = ${$val2}{$k};
$relpf = ${$val3}[3]; # relative DSP file, for DSW consumption (see write_proj_DSW3)
$fdspf = ${$val3}[4];
if ($fix_rel_paths && $g_had_dsp) {
my ($tn,$td) = fileparse($relpf);
$relpf = ".\\$tn";
}
# 0 1 2 3 4 5 6
push(@results, [$k, $nm, $captyp, $relpf, $fdspf, 0, 0]); # stored in 'RESULTS'
}
}
} else {
pgm_exit(1,"ERROR: key [$k] NOT found in hash!\n");
}
$k = 'RESULTS';
${$rsh}{$k} = [@results];
$k = 'PROJECT_LIST';
${$rsh}{$k} = [@project_list]; # keep project list, including output DSP file, if written
$k = 'PROJECT_FILE';
${$rsh}{$k} = $in;
return $rsh;
}
# ==============================================
# 10/04/2012 - begin to process files with a BOM
# LOAD without a BOM
my $strip_bom = 1;
my $curr_file_bom = '';
my @BOM_list = (
[ "UTF-8", 3, [0xEF,0xBB,0xBF ] ], # 239 187 191
[ "UTF-16 (BE)", 2, [0xFE,0xFF ] ], # 254 255
[ "UTF-16 (LE)", 2, [0xFF,0xFE ] ], # 255 254
[ "UTF-32 (BE)", 4, [0x00,0x00,0xFE,0xFF] ], # 0 0 254 255
[ "UTF-32 (LE)", 4, [0xFF,0xFE,0x00,0x00] ], # 255 254 0 0
[ "UTF-7a" , 4, [0x2B,0x2F,0x76,0x38] ], # 2B 2F 76 39 2B 2F 76 2B 2B 2F 76 2F
[ "UTF-7b" , 4, [0x2B,0x2F,0x76,0x39] ], # 2B 2F 76 39 2B 2F 76 2B 2B 2F 76 2F
[ "UTF-7c" , 4, [0x2B,0x2F,0x76,0x2B] ], # 2B 2F 76 39 2B 2F 76 2B 2B 2F 76 2F
[ "UTF-7d" , 4, [0x2B,0x2F,0x76,0x2F] ], # 2B 2F 76 39 2B 2F 76 2B 2B 2F 76 2F
[ "UTF-1" , 3, [0xF7,0x64,0x4C ] ], # 247 100 76
[ "UTF-EBCDIC" , 4, [0xDD,0x73,0x66,0x73] ], # 221 115 102 115
[ "SCSU" , 3, [0x0E,0xFE,0xFF ] ], # 14 254 255
[ "BOCU-1" , 3, [0xFB,0xEE,0x28 ] ], # 251 238 40
[ "GB-18030" , 4, [0x84,0x31,0x95,0x33] ] # 132 49 149 51
);
sub line_has_bom($$) {
my ($line,$rname) = @_;
my $max = scalar @BOM_list;
my $len = length($line);
my ($i,$j,$name,$cnt,$ra,$ch,$val);
for ($i = 0; $i < $max; $i++) {
$name = $BOM_list[$i][0]; # name
$cnt = $BOM_list[$i][1]; # length
$ra = $BOM_list[$i][2]; # ref array of values
if ($len > $cnt) { # make sure line length GT BOM
for ($j = 0; $j < $cnt; $j++) {
$ch = substr($line,$j,1); # extract CHAR
$val = ord($ch); # get VALUE
last if ($val != ${$ra}[$j]); # compare
}
if ($j == $cnt) { # if ALL values found
${$rname} = $name; # give back 'name'
return $cnt; # and return count
}
}
}
return 0; # no BOM found
}
sub remove_utf_bom($$) {
my ($ff,$ra) = @_;
my $line = ${$ra}[0]; # get first line
my $name = '';
my $len = line_has_bom($line,\$name);
if ($len) {
$curr_file_bom = substr($line,0,$len);
$line = substr($line,$len); # truncate line
${$ra}[0] = $line; # and return minus BOM
my ($nm,$dr) = fileparse($ff); # just show name
prt("[v9] NOTE: File [$nm] is $name encoding. BOM($len) removed.\n") if (VERB9());
}
}
sub load_file_lines($$) {
my ($ff,$ra) = @_;
my $lncnt = 0;
$curr_file_bom = '';
if (open INF, "<$ff") {
@{$ra} = ;
close INF;
$lncnt = scalar @{$ra};
remove_utf_bom($ff,$ra) if ($strip_bom);
} else {
prtw("WARNING: Unable to open [$ff]!\n");
}
return $lncnt;
}
sub get_xml_ref_array($$) {
my ($ff,$rla) = @_;
my $max = scalar @{$rla};
my ($i,$line,$len,$ch,$inquote,$qc,$tag,$txt,$intag,$lnn,$dnline);
$inquote = 0;
$intag = 0;
my @xlines = ();
$lnn = 0;
$tag = '';
$txt = '';
$dnline = 0;
foreach $line (@{$rla}) {
chomp $line; # = trim_all($line);
$len = length($line);
$lnn++;
$dnline = 0;
for ($i = 0; $i < $len; $i++) {
$ch = substr($line,$i,1);
if ($inquote) {
if ($intag) {
$tag .= $ch;
} else {
$txt .= $ch;
}
if ($ch eq $qc) {
$inquote = 0;
}
} else {
if ($intag) {
$tag .= $ch;
if ($ch eq '>') {
$intag = 0;
push(@xlines,[$lnn,$txt,$tag,$dnline]);
$txt = ''; # clear text
$tag = ''; # and tag
$dnline++;
} elsif (($ch eq '"') || ($ch eq "'")) {
$qc = $ch;
$inquote = 1;
}
} else {
if ($ch eq '<') {
$tag = $ch;
$intag = 1;
} else {
$txt .= $ch;
if (($ch eq '"') || ($ch eq "'")) {
$qc = $ch;
$inquote = 1;
}
}
}
}
}
if ($inquote) {
prtw("WARNING:$lnn: Going to next line while in quotes [$qc]!\n file [$ff]\n");
$inquote = 0;
}
if (!$intag && (length($txt) || !$dnline)) {
push(@xlines,[$lnn,$txt,$tag,$dnline]);
$txt = ''; # clear any text
}
}
return \@xlines;
}
sub write_xml_lines($$) {
my ($ff,$rxml) = @_;
my ($name,$dir) = fileparse($ff);
my $tmp_out = $temp_dir.$PATH_SEP."temp.$name.xml";
my $cnt = scalar @{$rxml};
if ($cnt == 0) {
prt("Array for [$ff] is BLANK!\n");
return;
}
my ($i,$rt,$msg,$lnn,$plnn,$txt,$tag);
$msg = $curr_file_bom;
$rt = ${$rxml}[0];
$plnn = ${$rt}[0];
$txt = '';
$tag = '';
for ($i = 0; $i < $cnt; $i++) {
$rt = ${$rxml}[$i];
# 0 1 2 3
# push(@xlines,[$lnn,$txt,$tag,$dnline]);
$lnn = ${$rt}[0];
$txt = ${$rt}[1];
$tag = ${$rt}[2];
if ($lnn != $plnn) {
$msg .= "\n";
$plnn = $lnn;
}
$msg .= $txt;
$msg .= $tag;
}
$msg .= "\n";
write2file($msg,$tmp_out);
prt("Array written to [$tmp_out], for [$ff]\n");
}
sub get_tag_hash($$) {
my ($itag,$r2t) = @_;
my $tag = $itag;
my %h = ();
my $len = length($tag);
if ($len) {
if (($tag =~ /^) && ($tag =~ />$/)) {
$tag = substr($tag,1,$len-2);
my @attribs = space_split($tag);
$tag = $attribs[0];
${$r2t} = $tag;
my @arr = ();
my $len = scalar @attribs;
my ($i,$key,$val);
for ($i = 1; $i < $len; $i++) {
push(@arr,$attribs[$i]);
}
%h = array_2_hash_on_equals(@arr);
} else {
prtw("WARNING: Tag NOT complete [$tag]\n");
}
}
return \%h;
}
sub show_tag_hash($$$$) {
my ($tag,$rh,$itag,$ra) = @_;
my ($key,$val);
my $rth = ${$rh}{'CURR_RTH'};
my $lnn = ${$rh}{'CURR_LNN'};
my $txt = trim_all(${$rh}{'CURR_TXT'});
my $cnt = scalar @{$ra};
#my $tag = ${$rh}{'CURR_TAG'};
#if (VERB9()) {
if ($dbg_02) {
prt("[02]$lnn: ");
prt("Txt [$txt] ") if (length($txt));
prt("Tag [$tag] ");
foreach $key (keys %{$rth}) {
$val = ${$rth}{$key};
prt(" $key=$val");
}
prt(" from [$itag]") if ($dbg_04);
$txt = $cnt ? ${$ra}[-1] : "Empty";
prt(" nts [$txt]$cnt");
prt("\n");
}
if ($dbg_09) {
prt("[09]$lnn:$cnt:");
$cnt = 0;
foreach $txt (@{$ra}) {
$cnt++;
prt(" $cnt");
prt("[$txt]");
}
prt("\n");
}
}
sub set_curr_config($$) {
my ($rh,$conf) = @_;
prt("Setting CONFIG for [$conf]\n") if ($dbg_06);
my $lnn = ${$rh}{'CURR_LNN'};
my $rcfgs = get_project_configs($rh); # 'PROJECT_CFGS'
# short 'Release' full 'Release|Win32'
# push(@{$rcfgs}, [ $confname, "", $conf, $dsp_sub_sub ]); # ONLY STORE OF 'PROJECT_CFGS'
my ($cfg,$tconf,$fnd,$dsp_sub_sub);
$fnd = 0;
foreach $cfg (@{$rcfgs}) {
$tconf = ${$cfg}[2];
if ($conf eq $tconf) {
$fnd = 1;
$dsp_sub_sub = ${$cfg}[3];
prtw("$lnn: WARNING: Not a VALID \$dsp_sub_sub!\n") if (is_valid_dsp_sub_sub($dsp_sub_sub));
${$rh}{'CURR_DSUB'} = $dsp_sub_sub;
${$rh}{'CURR_CFG'} = $conf; # like 'Release|Win32' etc
last;
}
}
if (!$fnd) {
prt("$lnn: WARNING: Unable to locate CONFIG for [$conf]\n");
}
}
sub get_rt_value($$) {
my ($rh,$test) = @_;
if (!defined ${$rh}{'CURR_RTH'}) {
pgm_exit(1,"ERROR: get_rt_value: passed ref.hash does NOT contain 'CURR'RTH'!\n");
}
my $rt = ${$rh}{'CURR_RTH'};
my $lnn = ${$rh}{'CURR_LNN'};
my $fil = ${$rh}{'PROJECT_FDIR'}.${$rh}{'PROJECT_FILE'}; # = $nam.$ext; # 2010/05/07 - was $fil
my $val = '';
if (defined ${$rt}{$test}) {
$val = strip_quotes(${$rt}{$test});
# special for 'Condition' #
# and
if ($test eq 'Condition') {
if ($val =~ /^\s*exists\('(.+)'\)/) {
# TODO **TBD** mayeb load the 'Include file
} else {
prt("$lnn: Getting RT VALUE for 'Condition'\n") if ($dbg_06);
my @arr = split(/==/,$val);
if (scalar @arr == 2) {
my $tmp = strip_single_quotes($arr[1]);
$act_config = get_act_config_type($tmp); # test /Release/i and /Debug/i and others
$val = "CONFIG=$tmp";
set_curr_config($rh,$tmp);
} else {
prtw("$lnn: WARNING: Condition did NOT split into 2 on '=='! [$val]! CHECK ME!\n file [$fil]\n");
}
}
}
}
return $val;
}
sub merge_library_list($) {
my ($rh) = shift;
my $rlibs = ${$rh}{'CURR_LIBS'}; # = \%liblist;
my $rdirs = ${$rh}{'CURR_LDIRS'}; # = \%dirs;
my $var1 = '-NEW_LIBS-';
my $dsp_sub_sub = ${$rh}{'CURR_DSUB'};
my $conf = ${$rh}{'CURR_CFG'};
my $lnn = ${$rh}{'CURR_LNN'};
my @arrd = keys(%{$rdirs});
my $dlist = '';
if (@arrd) {
$dlist = join(" ",@arrd);
$dlist = get_libpaths_string($dlist);
}
my @arr1 = keys(%{$rlibs});
my @arr2 = ();
my ($clist,$lib);
if (defined ${$dsp_sub_sub}{$var1}) {
$clist = ${$dsp_sub_sub}{$var1};
@arr2 = split(/\s+/,$clist);
}
if (@arr1) {
foreach $lib (@arr1) {
next if (length($lib) == 0);
push(@arr2,$lib) if (!is_in_array_nc($lib,\@arr2));
}
}
$clist = join(" ",@arr2);
if (length($dlist)) {
$clist .= " " if (length($clist));
$clist .= $dlist;
}
${$dsp_sub_sub}{$var1} = $clist;
prt("[v5] $lnn:SET: -NEW_LIBS-: cfg [$conf] = [$clist]\n") if (VERB5());
}
# $seek = 'AdditionalIncludeDirectories'; # -NEW_INCS_[DBG|REL]-
# sub get_default_sub3(0=rel,1=debug) {
# ItemDef: ClCompile: AdditionalIncludeDirectories = [C:/FG/10/3rdparty/include;C:/Projects/lpng159/temp;C:/Projects/lpng159;%(AdditionalIncludeDirectories)], cond idg [CONFIG=Debug|Win32] op []
sub merge_inc_directories($$) {
my ($rh,$txt) = @_;
return if (length($txt) == 0);
my $var1 = '-NEW_INCS-';
my $dsp_sub_sub = ${$rh}{'CURR_DSUB'};
my $conf = ${$rh}{'CURR_CFG'};
my $lnn = ${$rh}{'CURR_LNN'};
my @arr = split(/;+/,$txt);
# my $istg = get_includes_string($txt);
my $istg = '';
my ($inc);
foreach $inc (@arr) {
next if ($inc =~ /^%/);
$istg .= ' ' if (length($istg));
$istg .= '/I "'.$inc.'"';
}
my $ilist = '';
if (defined ${$dsp_sub_sub}{$var1}) {
$ilist = ${$dsp_sub_sub}{$var1};
prtw("$lnn: WARNING: Need MERGE of old [$ilist], with [$istg]\n") if (length($ilist) && length($istg));
}
${$dsp_sub_sub}{$var1} = $istg;
prt("[v5] $lnn:SET: -NEW_INCS-: cfg [$conf] = [$istg]\n") if (VERB5());
}
sub split_defines_dlist($) {
my $txt = shift;
my @arr = split(/\/D\s+/,$txt);
my $max = scalar @arr;
my ($i,$def);
for ($i = 0; $i < $max; $i++) {
$def = $arr[$i];
$def = strip_quotes($def);
$arr[$i] = $def;
}
return @arr;
}
# 94: ItemDef: ClCompile: PreprocessorDefinitions = [WIN32;_WINDOWS;_DEBUG;PNG_CONFIGURE_LIBPNG;_CRT_SECURE_NO_DEPRECATE;CMAKE_INTDIR="Debug";PNG_BUILD_DLL;%(PreprocessorDefinitions)], cond idg [CONFIG=Debug|Win32] op [] -NEW_DEFS-
# LOTS of goodies like
# _DEBUG;_WINDOWS;WIN32;_VISUALC_;NeedFunctionPrototypes;_LIB;WIN32;WIN32_LEAN_AND_MEAN;HAVE_WINCODEC_H;WEBP_USE_THREAD;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
sub set_preprocessor_defines($$) {
my ($rh,$txt) = @_;
return if (length($txt) == 0);
my $var1 = '-NEW_DEFS-';
my $dsp_sub_sub = ${$rh}{'CURR_DSUB'};
my $conf = ${$rh}{'CURR_CFG'};
my $lnn = ${$rh}{'CURR_LNN'};
my @arr2 = ();
if (defined ${$dsp_sub_sub}{$var1}) {
@arr2 = split_defines_dlist(${$dsp_sub_sub}{$var1});
}
my @arr1 = split(/;+/,$txt);
my ($def);
foreach $def (@arr1) {
next if ($def =~ /^%/);
next if (length($def) == 0);
$def = strip_quotes($def);
next if (length($def) == 0);
$def =~ s/"/"/g;
push(@arr2,$def) if (!is_in_array($def,@arr2));
}
my $list = '';
foreach $def (@arr2) {
next if (length($def) == 0);
$def = strip_quotes($def);
next if (length($def) == 0);
$list .= ' ' if (length($list));
$list .= "/D \"$def\""; # FIX20140103 Not /I but /D
}
${$dsp_sub_sub}{$var1} = $list;
prt("[v5] $lnn:SET: -NEW_DEFS-: cfg [$conf] to [$list]\n") if (VERB5());
}
# 92: ItemDef: ClCompile: RuntimeLibrary = [MultiThreadedDebugDLL], cond idg [CONFIG=Debug|Win32] op [] -NEW_RT-
sub set_runtime_library($$) {
my ($rh,$txt) = @_;
return if (length($txt) == 0);
my $var1 = '-NEW_RT-';
my $dsp_sub_sub = ${$rh}{'CURR_DSUB'};
my $conf = ${$rh}{'CURR_CFG'};
my $lnn = ${$rh}{'CURR_LNN'};
my $rt = '';
my $crt = '';
my $msg = '';
if ($txt eq 'MultiThreadedDebugDLL') {
$rt = "/MDd";
} elsif ($txt eq 'MultiThreadedDLL') {
$rt = "/MD";
} elsif ($txt eq 'MultiThreaded') {
$rt = "/MT";
} elsif ($txt eq 'MultiThreadedDebug') {
$rt = "/MTd";
}
if (length($rt)) {
if (defined ${$dsp_sub_sub}{$var1}) {
$crt = ${$dsp_sub_sub}{$var1};
if ($crt eq $rt) {
$msg .= 'same as before';
} else {
$msg .= "changed from [$crt]";
}
}
${$dsp_sub_sub}{$var1} = $rt;
prt("[v5] $lnn:SET: -NEW_RT-: cfg [$conf], to [$rt] $msg\n") if (VERB5());
} else {
prtw("$lnn: WARNING: TODO: Set RUNTIME for cfg [$conf] for [$txt] FIX ME! 5\n");
}
}
# from CMake source
# std::string configType = "";
# switch(this->Target->GetType())
# {
# case cmTarget::SHARED_LIBRARY:
# case cmTarget::MODULE_LIBRARY:
# configType += "DynamicLibrary";
# break;
# case cmTarget::OBJECT_LIBRARY:
# case cmTarget::STATIC_LIBRARY:
# configType += "StaticLibrary";
# break;
# case cmTarget::EXECUTABLE:
# configType += "Application";
# break;
# case cmTarget::UTILITY:
# configType += "Utility";
# break;
# }
# configType += "\n";
# PROJECT_APTP - application TYPE
# $app_console_stg = 'Console Application' = get_dsp_head_console
# $app_windows_stg = 'Application' = get_dsp_head_app
# $app_dynalib_stg = 'Dynamic-Link Library' = get_dsp_head_dynalib
# $app_statlib_stg = 'Static Library' = get_dsp_head_slib
# $app_utility_stg = 'Utility' = *TBD*
my %configs_shown = ();
sub set_configuration_type($$) {
my ($rh,$txt) = @_;
return if (length($txt) == 0);
my $lnn = ${$rh}{'CURR_LNN'};
pgm_exit(1,"ERROR: in set_configuration_type() \${\$rh}{'CURR_CFG'} NOT DEFINED!\n") if (!defined ${$rh}{'CURR_CFG'});
my $conf = ${$rh}{'CURR_CFG'};
my $app = '';
if ($txt eq 'DynamicLibrary') {
$app = 'Dynamic-Link Library';
} elsif ($txt eq 'StaticLibrary') {
$app = 'Static Library';
} elsif ($txt eq 'Application') {
$app = 'Application';
} elsif ($txt eq 'Utility') {
$app = 'Utility'; # $app_utility_stg = 'Utility' = *TBD*
}
if (length($app)) {
${$rh}{'PROJECT_APTP'} = $app;
if (VERB9() || !defined $configs_shown{$conf}) {
prt("$lnn:SET: project type [$app] for cfg [$conf]\n");
if (!defined $configs_shown{$conf}) {
$configs_shown{$conf} = [];
}
my $ra = $configs_shown{$conf};
push(@{$ra},$app);
}
} else {
prtw("$lnn: WARNING: Uncased ConfigurationType: [$txt]! FIX ME! 6\n");
}
}
sub process_rxml_vcxproj($$$) {
my ($inff,$rxml,$outd) = @_;
my ($vcname,$vcdir,$vcext) = fileparse($inff, qr/\.[^.]*/);
my $tmp_out = $temp_dir.$PATH_SEP."temp.$vcname.xml";
my $cnt = scalar @{$rxml};
if ($cnt == 0) {
prt("Array for [$inff] is BLANK!\n");
return;
}
my ($i,$rth,$rtx,$msg,$lnn,$plnn,$txt,$tag,$inproj,$incommand,$command,$initemgroup,$inpropgroup,$impgroup);
my ($idefgroup,$rtag,$label,$val,$ptag,$show,$opcond,$pgcond,$tvers);
my ($tver,$dtargs); # attribs of
my ($ltag,$otag,$nxtstag,$tagtype,$attcnt,$idconf,$lnnbcmd,$tmp,$idopntag);
my ($itemlabel,$pglabel,$inprojcfg,$incustom,$inmessage,$inprojref,$prjcfg);
my ($dsp_sub_sub,$confname,$var1,$platform,$cdsub,$pcfginc,$relpath,$conf,$innone);
my (@arr,$wmsg);
my ($inprepro,$inrescomp,$RootNamespace);
my ($inexcl,$inobjfname);
# '-fix-rel' ($fix_rel_paths)
my $fixrel = $fix_rel_paths;
if (! -d $outd) {
$fixrel = 0; # not valid destination for DSP file
}
$msg = $curr_file_bom;
$tmp = ${$rxml}[0];
$plnn = ${$tmp}[0]; # get first line value
$txt = '';
$tag = '';
$ptag = '';
$rtag = '';
$idopntag = '';
$itemlabel = '';
$pglabel = '';
$nxtstag = '';
$inproj = 0;
$incommand = 0;
$command = '';
$initemgroup = 0;
$inpropgroup = 0;
$idefgroup = 0;
$impgroup = 0;
$inprojcfg = 0;
$incustom = 0;
$inmessage = 0;
$inprojref = 0;
$inprepro = 0;
$inrescomp = 0;
$innone = 0;
$inexcl = 0;
$inobjfname = 0;
$prjcfg = '';
$pcfginc = '';
$RootNamespace = '';
my $inoptim = 0;
my $inbasicrtc = 0;
$tvers = 'UNKNOWN';
$val = '*\$val NOT SET*';
my @sources = ();
my @tag_stack = ();
my $rh = get_default_ref_hash($inff); # get the DEFAULT reference HASH - lib_vcscan.pl
my $rcfgs = get_project_configs($rh); # 'PROJECT_CFGS'
# just name like 'Release' full name 'Debug|Win32'
# prt("[v40] STORE:$tmp: In rcfgs (ra)[$confname], [$var1], [$conf], & \$dsp_sub_sub ] )\n") if ($dbg_v40); # ONLY STORE OF 'PROJECT_CFGS'
# push(@{$rcfgs}, [ $confname, $var1, $conf, $dsp_sub_sub ]); # ONLY STORE OF 'PROJECT_CFGS'
# ${$rh}{'PROJECT_CCNT'}++; # count of stored 'PROJECT_CFGS
# ${$rh}{'CURR_DSUB'} = $dsp_sub_sub;
${$rh}{'CURR_DCFG'} = 0; # no configuration done yet
${$rh}{'PROJECT_NAME'} = $vcname; # always have a NAME, even if it is the project file name
for ($i = 0; $i < $cnt; $i++) {
$rtx = ${$rxml}[$i];
# 0 1 2 3
# push(@xlines,[$lnn,$txt,$tag,$dnline]);
$lnn = ${$rtx}[0];
$txt = ${$rtx}[1];
$tag = ${$rtx}[2];
${$rh}{'CURR_LNN'} = $lnn;
${$rh}{'CURR_TXT'} = $txt;
${$rh}{'CURR_TAG'} = $tag;
if ($lnn != $plnn) {
$msg .= "\n";
}
$msg .= $txt;
$msg .= $tag;
if ($inproj) {
# SETUP
# ==============================
#if ($incommand && ($initemgroup || $idefgroup)) {
if ($incommand) {
# STAY to complete the command!!!
$command .= "\n" if ($lnn != $plnn);
$command .= $txt;
if ($tag =~ /<\/Command>$/) {
$ptag = $rtag;
$rth = get_tag_hash($tag,\$rtag);
${$rh}{'CURR_RTH'} = $rth;
show_tag_hash($rtag,$rh,$tag,\@tag_stack);
$otag = substr($rtag,1);
if (@tag_stack) {
$ltag = pop @tag_stack;
$nxtstag = ((@tag_stack) ? $tag_stack[-1] : "EMPTY STACK");
prt("[09] POPPED [$ltag] from tag_stack. nxt [$nxtstag] incommand\n") if ($dbg_09);
if ($otag ne $ltag) {
prtw("WARNING: $lnn: Got close [$otag], but last on stack is [$ltag]! nxt [$nxtstag]\n file [$inff]\n");
}
} else {
$nxtstag = "EMPTY STACK";
prtw("WARNING: $lnn: Got close [$otag], but NONE ON STACK!\n file [$inff]\n");
}
prt("$lnn: CLOSE tag $otag [$tag] next [$nxtstag]\n") if ($dbg_03);
if (VERB9()) {
prt("$command\n") if ($dbg_01);
$tmp = length($command);
prt("$lnn:[v9]: End command bgn=$lnnbcmd, len=$tmp\n");
}
if ($initemgroup) {
prt("[10] $lnn:fall through to UNSET incommnd\n") if ($dbg_10);
} else {
$command = '';
$incommand = 0; # this done LATER
prt("\n[10] $lnn: CLEARED incommnd\n\n") if ($dbg_10);
}
} else {
next;
}
} else {
$ptag = $rtag;
$rth = get_tag_hash($tag,\$rtag);
${$rh}{'CURR_RTH'} = $rth;
show_tag_hash($rtag,$rh,$tag,\@tag_stack);
$attcnt = scalar keys(%{$rth}); # get attribute COUNT for tag - note for <... /> the '/' is counted
if (defined ${$rth}{'/'}) {
prt("$lnn: COMP tag $rtag [$tag]\n") if ($dbg_03);
$tagtype = 0; # a compete TAG
} elsif ($rtag =~ /^\//) {
$tagtype = 1; # a close TAG
$otag = substr($rtag,1);
if (@tag_stack) {
$ltag = pop @tag_stack;
$nxtstag = ((@tag_stack) ? $tag_stack[-1] : "EMPTY STACK");
prt("[09] POPPED [$ltag] from tag_stack. nxt [$nxtstag]\n") if ($dbg_09);
if ($otag ne $ltag) {
prtw("WARNING: $lnn: Got close [$otag], but last on stack is [$ltag]!\n file [$inff]\n");
}
} else {
prtw("WARNING: $lnn: Got close [$otag], but NONE ON STACK!\n file [$inff]\n");
}
prt("$lnn: CLOSE tag $otag [$tag] next [$nxtstag]\n") if ($dbg_03);
} elsif ($rtag =~ /\/$/) {
# self-closing tag - like - do NOT add to stack
$tagtype = 0; # a compete TAG
} else {
$opcond = get_rt_value($rh,'Condition');
$tagtype = 2; # an open tag
$nxtstag = ((@tag_stack) ? $tag_stack[-1] : "EMPTY STACK");
prt("$lnn: OPEN tag $rtag [$tag] prev [$nxtstag]\n") if ($dbg_03);
push(@tag_stack,$rtag);
prt("[09] ADDED [$rtag] to tag_statck prev [$nxtstag] itmg=$initemgroup idefg=$idefgroup pgrp=$inpropgroup impgrp=$impgroup\n") if ($dbg_09);
}
}
# ======================================================================
# after SETUP
# =======================================================================
# 1 = ItemGroup
if ($initemgroup) {
if ($incommand) {
# $command .= "\n" if ($lnn != $plnn);
# $command .= $txt;
if ($tag =~ /<\/Command>$/) {
#if (VERB9()) {
# prt("$command\n") if ($dbg_01);
# prt("$lnn:[v9]: End command\n");
#}
$command = '';
$incommand = 0;
prt("\n[10] $lnn: CLEARED incommnd initemgroup\n\n") if ($dbg_10);
}
} else {
if ($tag =~ /^<\/ItemGroup>/) {
prt("$lnn:[v9]: End ItemGroup\n") if (VERB9());
$initemgroup = 0;
${$rh}{'CURR_DCFG'} = 1;
if ($itemlabel eq "ProjectConfigurations") { # no configuration done yet
${$rh}{'CURR_DCFG'} = 1;
if (VERB9()) {
prt("$lnn: ProjectConfigurations: ");
prt("Got ".${$rh}{'PROJECT_CCNT'}." configs."); # count of stored 'PROJECT_CFGS
$rcfgs = get_project_configs($rh); # 'PROJECT_CFGS'
# short 'Release' full 'Release|Win32'
# push(@{$rcfgs}, [ $confname, "", $val, $dsp_sub_sub ]); # ONLY STORE OF 'PROJECT_CFGS'
foreach $tmp (@{$rcfgs}) {
prt(" ".${$tmp}[2]);
}
prt("\n");
}
}
} elsif ($tag =~ /^setlocal
# "C:\Program Files (x86)\CMake 2.8\bin\cmake.exe" -HC:/FG/10/flightgear -BC:/FG/10/flightgear/build --check-stamp-file C:\FG\10\flightgear\build\src\FDM\YASim\CMakeFiles\generate.stamp
# if %errorlevel% neq 0 goto :cmEnd
$incommand = 1;
prt("\n[10] $lnn:initemgroup: SETTING incommnd\n\n") if ($dbg_10);
prt("$lnn:[v9]: ItemGroup\n") if (VERB9());
$lnnbcmd = $lnn;
$command = '';
} elsif ($inprojcfg || ($itemlabel eq 'ProjectConfigurations')) {
#
#
# Debug
# Win32
#
#
# Release
# Win32
#
#
if ($rtag eq 'ProjectConfiguration') {
#
$pcfginc = get_rt_value($rh,'Include');
$inprojcfg = 1;
${$rh}{'CURR_CONF'} = '';
${$rh}{'CURR_CON1'} = '';
} elsif ($rtag eq '/ProjectConfiguration') {
$confname = ${$rh}{'CURR_CONF'}; # Configuration
$platform = ${$rh}{'CURR_CON1'}; # Platform
if ( length($platform) && length($confname) ) {
$val = $confname.'|'.$platform; # join Configuration|Platform
$tmp = get_act_config_type($confname); # test /Release/i and /Debug/i and others
$dsp_sub_sub = get_default_sub3($tmp);
$rcfgs = get_project_configs($rh); # 'PROJECT_CFGS'
# short 'Release' full 'Release|Win32'
push(@{$rcfgs}, [ $confname, "", $val, $dsp_sub_sub ]); # ONLY STORE OF 'PROJECT_CFGS'
${$rh}{'PROJECT_CCNT'}++; # count of stored 'PROJECT_CFGS
${$rh}{'CURR_DSUB'} = $dsp_sub_sub;
prtw("WARNING: ProjectCOnfiguration Include=$pcfginc NOT EQUAL merge [$val]!\n") if ($pcfginc ne $val);
if (VERB5() || $dbg_05) {
prt("$lnn: [v5] STORED:$tmp:".${$rh}{'PROJECT_CCNT'}.": ");
prt("[[$confname], [], [$val], \$dsp_sub_sub ] cmp [$pcfginc]\n");
}
} else {
prtw("WARNING: $lnn: CONFIG NOT CREATED! WHY? [$tag]\n");
}
$inprojcfg = 0;
} elsif (($rtag eq 'Configuration')||($rtag eq 'Platform')) {
# entering...
} elsif ($rtag eq '/Configuration') {
${$rh}{'CURR_CONF'} = $txt;
} elsif ($rtag eq '/Platform') {
${$rh}{'CURR_CON1'} = $txt;
} else {
prtw("WARNING: $lnn:ItemGroup: tag text $val = $txt NOT HANDLED! FIX ME! 7\n");
}
} elsif (($tag =~ /^
#
#
$val = get_rt_value($rh,'Include');
if ($val && length($val)) {
####$last_src = strip_dotrel(strip_quotes(trim_all($var1)));
my ($last_src,$last_nm,$last_dir,$last_ext,$fname,$flist,$src_ref,$ok,$ff);
$last_src = $val;
if ($val =~ /^\w{1}:/) {
$ff = $val;
} else {
$ff = $vcdir;
$ff .= $PATH_SEP if (!($ff =~ /(\\|\/)$/));
$ff .= $val;
}
$ff = path_u2d($ff);
$ff = fix_rel_path($ff);
$ok = 'NF';
$ok = 'ok' if (-f $ff);
# Prior to MSVC10 this was a RELATIVE PATH - like
#
# this is the RELATIVE PATH - relative to the vcproj file being scanned
# Now would be a good time to ADJUST this PATH, for any NEW location
# of the final DSP file!!! BUT, this is done back in vcproj05.pl
# in the sub chk_relative_paths()...
# BUT in MSVC10 this 'can' be an absolute path, like
# C:\FG\10\flightgear\src\FDM\YASim\Wing.cpp
# =========================
if ($fixrel) {
my $cd = cwd();
# prt("Last source [$last_src]\n");
if ( ( -d $outd ) && chdir($outd) ) {
$last_src = File::Spec->rel2abs($last_src); # we are IN the SLN directory, get ABSOLUTE from RELATIVE
chdir($cd); # and get us back to where we were...
}
}
($last_nm,$last_dir,$last_ext) = fileparse( $last_src, qr/\.[^.]*/ );
# =========================
if ($fixrel) {
$relpath = get_relative_path4($last_dir,$outd);
$last_src = $relpath.$last_nm.$last_ext;
}
$fname = '';
$flist = '';
$src_ref = get_project_srcs_ref($rh); # 'PROJECT_SRCS'
${$rh}{'CURR_LOFF'} = scalar @{$src_ref}; # get current source OFFSET
# ======================
# *** STORING SOURCE ***
# ======================
if ($ok eq 'ok') {
push(@{$src_ref}, [ $last_src, $fname, $flist, 0, '' ]); # and PUSH onto SOURCE stack
${$rh}{'CURR_LSRC'} = $last_src;
${$rh}{'CURR_LNME'} = $last_nm;
${$rh}{'CURR_LDIR'} = $last_dir;
${$rh}{'CURR_LEXT'} = $last_ext;
if ($last_src eq $val) {
prt("[v1] $lnn: SOURCE: [$val] $ok\n") if (VERB1());
} else {
prt("[v1] $lnn: SOURCE: [$last_src] [$val] $ok\n") if (VERB1());
}
push(@sources,[$last_src,$val]);
} else {
prt("$lnn: SRC NOT FOUND: [$last_src] [$val] $ok\n");
}
} else {
prtw("WARNING: $lnn: No Include [$tag] CHECKME\n");
}
} else {
$show = 0;
if (($rtag eq 'CustomBuild')||($rtag eq 'CustomBuildStep')) {
$incustom = 1;
} elsif (($rtag eq '/CustomBuild')||($rtag eq '/CustomBuildStep')) {
$incustom = 0;
} elsif (($rtag eq 'Message')||($rtag eq 'WarningLevel')) {
$inmessage = 1;
} elsif (($rtag eq '/Message')||($rtag eq '/WarningLevel')) {
$inmessage = 0;
} elsif ($rtag eq 'ProjectReference') {
$inprojref = 1;
} elsif ($rtag eq '/ProjectReference') {
$inprojref = 0;
} elsif ($rtag eq 'PreprocessorDefinitions') {
$inprepro = 1;
} elsif ($rtag eq '/PreprocessorDefinitions') {
$inprepro = 0;
} elsif ($rtag eq 'ResourceCompile') {
$inrescomp = 1;
} elsif ($rtag eq '/ResourceCompile') {
$inrescomp = 0;
} elsif ($rtag eq 'ExcludedFromBuild') {
$inexcl = 1;
} elsif ($rtag eq '/ExcludedFromBuild') {
$inexcl = 0;
} elsif ($rtag eq 'ObjectFileName') {
$inobjfname = 1;
} elsif ($rtag eq '/ObjectFileName') {
$inobjfname = 0;
} elsif ($rtag eq 'Optimization') {
$inoptim = 1;
} elsif ($rtag eq '/Optimization') {
$inoptim = 0;
} elsif ($rtag eq 'BasicRuntimeChecks') {
$inbasicrtc = 1;
} elsif ($rtag eq '/BasicRuntimeChecks') {
$inbasicrtc = 0;
} elsif ($rtag eq 'CompileAs') {
$inrescomp = 1;
# $incompas = 1;
} elsif ($rtag eq '/CompileAs') {
$inrescomp = 0;
# $incompas = 0;
} elsif (($rtag eq 'None') && ($tagtype == 0)) {
$innone++;
} else {
if ($incustom || $inmessage || $inprojref || $inprepro ||
$inrescomp || $inexcl || $inobjfname || $inoptim ||
$inbasicrtc ) {
if ($rtag =~ /^\//) {
$val = substr($rtag,1);
prt("$lnn:[v9] ItemGroup: tag text $val = $txt\n") if (VERB9());
if ($incustom) {
# already collecting the command
} elsif ($inmessage) {
# nothing special here
} elsif ($inprojref) {
# nothing special here
} elsif ($inprepro) {
# like NDEBUG;$(NoInherit));%(PreprocessorDefinitions)
# or _DEBUG;$(NoInherit));%(PreprocessorDefinitions)
} elsif ($inrescomp) {
# compiling a rc file
} elsif ($inexcl) {
# get/set if excluded
} elsif ($inobjfname) {
# get/set object file, like [$(IntDir)alpha.2.obj]
} elsif ($inoptim) {
# ...
} elsif ($inbasicrtc) {
# ...
} else {
prgm_exit(1,"ERROR: $lnn: ItemGroup type NOT HANDLED! [$tag]\n");
}
}
} else {
if ($rtag eq '/ClCompile') {
# just close of a compile, where there are properties added
# # a CLOSED ClCompile
# # an OPEN ClCompile
# $(IntDir)alpha.2.obj
# $(IntDir)alpha.2.obj
#
} else {
$wmsg = "ItemGroup: NOT in conf [$rtag]";
if (!defined $shown_warn{$wmsg}) {
prtw("WARNING: $lnn: $wmsg [$txt] FIX ME! 8\n file [$inff]\n");
$shown_warn{$wmsg} = 1;
}
}
}
}
}
}
# 2 - PropertyGroup
} elsif ($inpropgroup) {
if ($tag =~ /^<\/PropertyGroup>/) {
prt("$lnn:[v9]: End PropertyGroup\n") if (VERB9());
$inpropgroup = 0;
} else {
#
# <_ProjectFileVersion>10.0.20506.1
# C:\FG\10\flightgear\build\src\FDM\YASim\Debug\
# yasim-proptest.dir\Debug\
# yasim-proptest
# .exe
# true
# true
# C:\FG\10\flightgear\build\src\FDM\YASim\Release\
# yasim-proptest.dir\Release\
# yasim-proptest
# .exe
# false
# true
#
#
# {DADB5FFC-3724-4318-BC6E-1DE2291A71F2}
# Win32Proj
# Win32
# yasim-proptest
#
$show = 0;
if ($rtag =~ /^\//) {
# on CLOSING tag, get TEXT
if ($pglabel eq 'Globals') {
if (($rtag eq '/ProjectGUID')||($rtag eq '/ProjectGuid')) {
$show = 1;
} elsif ($rtag eq '/Keyword') {
$show = 1;
} elsif ($rtag eq '/Platform') {
$show = 1;
} elsif ($rtag eq '/ProjectName') {
${$rh}{'PROJECT_NAME'} = $txt;
$show = 1;
} elsif ($rtag eq '/RootNamespace') {
$show = 1;
$RootNamespace = $txt;
} elsif ($rtag eq '/WindowsTargetPlatformVersion') {
# '/WindowsTargetPlatformVersion'
$show = 1;
} elsif ($rtag eq '/VCProjectUpgraderObjectName') {
$show = 1;
}
} else {
if ($rtag eq '/_ProjectFileVersion') {
$show = 1;
} elsif ($rtag eq '/OutDir') {
# -NEW_OUTD-
${$rh}{'CURR_ODIR'} = $txt;
$dsp_sub_sub = ${$rh}{'CURR_DSUB'};
if (defined ${$dsp_sub_sub}{'-NEW_OUTD-'}) {
${$dsp_sub_sub}{'-NEW_OUTD-'} = add_quotes($txt) if (length($txt));
} else {
prtw("WARNING: current \$dsp_sub_sub does not have '-NEW_OUTD-'!\n");
}
$show = 1;
} elsif ($rtag eq '/IntDir') {
# -NEW_INTER-
$dsp_sub_sub = ${$rh}{'CURR_DSUB'};
if (defined ${$dsp_sub_sub}{'-NEW_INTER-'}) {
${$dsp_sub_sub}{'-NEW_INTER-'} = add_quotes($txt) if (length($txt));
} else {
prtw("WARNING: current \$dsp_sub_sub does not have '-NEW_INTER-'!\n");
}
$show = 1;
} elsif ($rtag eq '/TargetName') {
${$rh}{'CURR_TNAME'} = $txt;
$show = 1;
} elsif ($rtag eq '/TargetExt') {
# adds a BIG clue to the project TYPE
# dll = DLL
# lib = LIB (static)
# exe = console or windows type
${$rh}{'CURR_TEXT'} = $txt;
$show = 1;
} elsif ($rtag eq '/LinkIncremental') {
$show = 1;
} elsif ($rtag eq '/GenerateManifest') {
$show = 1;
} elsif ($rtag eq '/CharacterSet') {
$show = 1;
} elsif ($rtag eq '/ConfigurationType') {
set_configuration_type($rh,$txt);
$show = 1;
} elsif ($rtag eq '/UseOfMfc') {
$show = 1;
} elsif ($rtag eq '/WholeProgramOptimization') {
$show = 1;
} elsif ($rtag eq '/IgnoreImportLibrary') {
$show = 1;
} elsif ($rtag eq '/CodeAnalysisRuleSet') {
$show = 1;
} elsif ($rtag eq '/PlatformToolset') {
$show = 1;
#} elsif ($rtag eq '/...') {
# $show = 1;
}
}
if ($show) {
$val = substr($rtag,1);
prt("[v9] $lnn: Property: $pglabel: $val = [$txt], cond pg [$pgcond] oc [$opcond]\n") if (VERB9() || $dbg_07);
} elsif ($rtag =~ /^\//) {
prtw("WARNING: $lnn: $pglabel: Unmanaged PropertyGroup [$rtag] [$txt]\n file [$inff]\n");
}
if (defined ${$rh}{'CURR_ODIR'} && defined ${$rh}{'CURR_TNAME'} && defined ${$rh}{'CURR_TEXT'}) {
if (length(${$rh}{'CURR_ODIR'}) && length(${$rh}{'CURR_TNAME'}) && length(${$rh}{'CURR_TEXT'}) ) {
$tmp = ${$rh}{'CURR_ODIR'};
$tmp .= $PATH_SEP if (!($tmp =~ /(\\|\/)$/));
$tmp .= ${$rh}{'CURR_TNAME'};
$tmp .= ${$rh}{'CURR_TEXT'};
$conf = ${$rh}{'CURR_CFG'};
$dsp_sub_sub = ${$rh}{'CURR_DSUB'};
${$dsp_sub_sub}{'-NEW_OUT-'} = $tmp;
prt("[v5] SET: -NEW_OUT-: cfg [$conf] with [$tmp]\n") if (VERB5());
}
}
}
}
} elsif ($idefgroup) {
if ($tag =~ /<\/ItemDefinitionGroup>/) {
$idefgroup = 0;
prt("$lnn:[v9]: End ItemDefinitionGroup\n") if (VERB9());
$idopntag = ''; # clear the OPEN tag group
} elsif ($tag =~ /^
#
# /Zm1000 %(AdditionalOptions)
# C:/FG/10/3rdparty/include;C:/FG/10/Boost-1.49;C:/FG/10/3rdparty/3rdParty/include;C:/FG/10/flightgear/src;C:/FG/10/flightgear/build/src;C:/FG/10/flightgear/build/src/Include;C:/FG/10/flightgear;%(AdditionalIncludeDirectories)
# EnableFastChecks
# CompileAsCpp
# ProgramDatabase
# Sync
# Disabled
# Disabled
# MultiThreadedDebugDLL
# true
# Level3
# WIN32;_WINDOWS;NOMINMAX;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;__CRT_NONSTDC_NO_WARNINGS;_REENTRANT;_DEBUG;HAVE_CONFIG_H;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)
# Debug
# $(IntDir)
# C:/FG/10/flightgear/build/src/FDM/YASim/Debug/yasim-proptest.pdb
#
#
# WIN32;_WINDOWS;NOMINMAX;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;__CRT_NONSTDC_NO_WARNINGS;_REENTRANT;_DEBUG;HAVE_CONFIG_H;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)
# C:/FG/10/3rdparty/include;C:/FG/10/Boost-1.49;C:/FG/10/3rdparty/3rdParty/include;C:/FG/10/flightgear/src;C:/FG/10/flightgear/build/src;C:/FG/10/flightgear/build/src/Include;C:/FG/10/flightgear;%(AdditionalIncludeDirectories)
#
#
# C:/FG/10/3rdparty/include;C:/FG/10/Boost-1.49;C:/FG/10/3rdparty/3rdParty/include;C:/FG/10/flightgear/src;C:/FG/10/flightgear/build/src;C:/FG/10/flightgear/build/src/Include;C:/FG/10/flightgear;%(AdditionalIncludeDirectories)
# $(IntDir)
# %(Filename).h
# %(Filename).tlb
# %(Filename)_i.c
# %(Filename)_p.c
#
#
# /machine:X86 /debug %(AdditionalOptions)
# kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;C:\FG\10\3rdparty\lib\sgenvironmentd.lib;C:\FG\10\3rdparty\lib\sgnasald.lib;C:\FG\10\3rdparty\lib\sgtsyncd.lib;C:\FG\10\3rdparty\lib\sgbucketd.lib;C:\FG\10\3rdparty\lib\sgrouted.lib;C:\FG\10\3rdparty\lib\sgiod.lib;C:\FG\10\3rdparty\lib\sgseriald.lib;C:\FG\10\3rdparty\lib\sgmathd.lib;C:\FG\10\3rdparty\lib\sgpropsd.lib;C:\FG\10\3rdparty\lib\sgstructured.lib;C:\FG\10\3rdparty\lib\sgtimingd.lib;C:\FG\10\3rdparty\lib\sgxmld.lib;C:\FG\10\3rdparty\lib\sgmiscd.lib;C:\FG\10\3rdparty\lib\sgthreadsd.lib;C:\FG\10\3rdparty\lib\sgdebugd.lib;C:\FG\10\3rdparty\lib\sgmagvard.lib;C:\FG\10\3rdparty\lib\zlib1.lib;winmm.lib;ws2_32.lib
# %(AdditionalLibraryDirectories)
# MultiplyDefinedSymbolOnly
# true
# C:/FG/10/flightgear/build/src/FDM/YASim/Debug/yasim-proptest.lib
# true
# C:/FG/10/flightgear/build/src/FDM/YASim/Debug/yasim-proptest.pdb
# 10000000
# Console
#
#
#
# false
#
#
#
# setlocal
#"C:\Program Files (x86)\CMake 2.8\bin\cmake.exe" -DBUILD_TYPE=$(Configuration) -P cmake_install.cmake
#if %errorlevel% neq 0 goto :cmEnd
#:cmEnd
#endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
#:cmErrorLevel
#exit /b %1
#:cmDone
#if %errorlevel% neq 0 goto :VCEnd
#
#
if ($tagtype == 1) { # a close TAG
$show = 0;
if ($nxtstag eq 'ClCompile') {
if ($rtag eq '/AdditionalOptions') {
$show = 1;
} elsif ($rtag eq '/AdditionalIncludeDirectories') {
# $seek = 'AdditionalIncludeDirectories'; # -NEW_INCS_[DBG|REL]-
# sub get_default_sub3(0=rel,1=debug) {
merge_inc_directories($rh,$txt);
$show = 1;
} elsif ($rtag eq '/BasicRuntimeChecks') {
$show = 1;
} elsif ($rtag eq '/CompileAs') {
$show = 1;
} elsif ($rtag eq '/DebugInformationFormat') {
$show = 1;
} elsif ($rtag eq '/ExceptionHandling') {
$show = 1;
} elsif ($rtag eq '/InlineFunctionExpansion') {
$show = 1;
} elsif ($rtag eq '/Optimization') {
$show = 1;
} elsif ($rtag eq '/RuntimeLibrary') {
# 92: ItemDef: ClCompile: RuntimeLibrary = [MultiThreadedDebugDLL], cond idg [CONFIG=Debug|Win32] op [] -NEW_RT-
set_runtime_library($rh,$txt);
$show = 1;
} elsif ($rtag eq '/RuntimeTypeInfo') {
$show = 1;
} elsif ($rtag eq '/WarningLevel') {
$show = 1;
} elsif ($rtag eq '/PreprocessorDefinitions') {
# 94: ItemDef: ClCompile: PreprocessorDefinitions = [WIN32;_WINDOWS;_DEBUG;PNG_CONFIGURE_LIBPNG;_CRT_SECURE_NO_DEPRECATE;CMAKE_INTDIR="Debug";PNG_BUILD_DLL;%(PreprocessorDefinitions)], cond idg [CONFIG=Debug|Win32] op [] -NEW_DEFS-
set_preprocessor_defines($rh,$txt);
$show = 1;
} elsif ($rtag eq '/AssemblerListingLocation') {
$show = 1;
} elsif ($rtag eq '/ObjectFileName') {
$show = 1;
} elsif ($rtag eq '/ProgramDataBaseFileName') {
$show = 1;
} elsif ($rtag eq '/FunctionLevelLinking') {
# false
$show = 1;
} elsif ($rtag eq '/SuppressStartupBanner') {
$show = 1;
} elsif ($rtag eq '/MinimalRebuild') {
$show = 1;
} elsif ($rtag eq '/PrecompiledHeaderOutputFile') {
$show = 1;
} elsif ($rtag eq '/PrecompiledHeader') {
$show = 1;
} elsif ($rtag eq '/StringPooling') {
$show = 1;
} elsif ($rtag eq '/DisableSpecificWarnings') {
# like 4996;4013;4018;4024;4047;4244
$show = 1;
} elsif ($rtag eq '/BufferSecurityCheck') {
$show = 1;
} elsif ($rtag eq '/TreatWChar_tAsBuiltInType') {
$show = 1;
} elsif ($rtag eq '/ForceConformanceInForLoopScope') {
$show = 1;
} elsif ($rtag eq '/IntrinsicFunctions') {
$show = 1;
} elsif ($rtag eq '/FavorSizeOrSpeed') {
$show = 1;
} elsif ($rtag eq '/OmitFramePointers') {
$show = 1;
} elsif ($rtag eq '/PreprocessToFile') {
$show = 1;
} elsif ($rtag eq '/PreprocessSuppressLineNumbers') {
$show = 1;
} elsif ($rtag eq '/PreprocessKeepComments') {
$show = 1;
} elsif ($rtag eq '/BrowseInformation') {
$show = 1;
} elsif ($rtag eq '/ForcedIncludeFiles') {
$show = 1;
} elsif ($rtag eq '/OpenMPSupport') {
$show = 1;
} elsif ($rtag eq '/PrecompiledHeaderFile') {
$show = 1;
} elsif ($rtag eq '/UseUnicodeForAssemblerListing') {
$show = 1;
} elsif ($rtag eq '/WholeProgramOptimization') {
$show = 1;
} elsif ($rtag eq '/MultiProcessorCompilation') {
$show = 1;
} elsif ($rtag eq '/StructMemberAlignment') {
$show = 1;
} else {
$wmsg = "Uncased 'ClCompile' [$tag]";
if (!defined $shown_warn{$wmsg}) {
prtw("WARNING: $lnn: $wmsg FIX ME! 1\n");
$shown_warn{$wmsg} = 1;
}
}
} elsif ($nxtstag eq 'ResourceCompile') {
if ($rtag eq '/PreprocessorDefinitions') {
# _DEBUG;%(PreprocessorDefinitions)
$show = 1;
} elsif ($rtag eq '/AdditionalIncludeDirectories') {
$show = 1;
} elsif ($rtag eq '/Culture') {
# 0x0809
$show = 1;
} else {
prtw("WARNING: $lnn: Uncased 'ResourceCompile' [$tag] FIX ME! 9\n");
}
} elsif ($nxtstag eq 'Midl') {
if ($rtag eq '/AdditionalIncludeDirectories') {
$show = 1;
} elsif ($rtag eq '/OutputDirectory') {
$show = 1;
} elsif ($rtag eq '/HeaderFileName') {
$show = 1;
} elsif ($rtag eq '/TypeLibraryName') {
$show = 1;
} elsif ($rtag eq '/InterfaceIdentifierFileName') {
$show = 1;
} elsif ($rtag eq '/ProxyFileName') {
$show = 1;
} elsif ($rtag eq '/SuppressStartupBanner') {
$show = 1;
} elsif ($rtag eq '/PreprocessorDefinitions') {
$show = 1;
} elsif ($rtag eq '/MkTypLibCompatible') {
$show = 1;
} elsif ($rtag eq '/TargetEnvironment') {
$show = 1;
} else {
prtw("WARNING: $lnn: Uncased 'Midl' [$tag] FIX ME! 10\n");
}
} elsif ($nxtstag eq 'Link') {
if ($rtag eq '/AdditionalOptions') {
$show = 1;
} elsif ($rtag eq '/AdditionalDependencies') {
# like elsif ($pname eq 'VCLinkerTool')
$var1 = '-NEW_LIBS-';
# get the list, and add need libraries
# kernel32.lib;user32.lib;gdi32.lib;winspool.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;comdlg32.lib;advapi32.lib;C:\FG\10\3rdparty\lib\sgenvironmentd.lib;C:\FG\10\3rdparty\lib\sgnasald.lib;C:\FG\10\3rdparty\lib\sgtsyncd.lib;C:\FG\10\3rdparty\lib\sgbucketd.lib;C:\FG\10\3rdparty\lib\sgrouted.lib;C:\FG\10\3rdparty\lib\sgiod.lib;C:\FG\10\3rdparty\lib\sgseriald.lib;C:\FG\10\3rdparty\lib\sgmathd.lib;C:\FG\10\3rdparty\lib\sgpropsd.lib;C:\FG\10\3rdparty\lib\sgstructured.lib;C:\FG\10\3rdparty\lib\sgtimingd.lib;C:\FG\10\3rdparty\lib\sgxmld.lib;C:\FG\10\3rdparty\lib\sgmiscd.lib;C:\FG\10\3rdparty\lib\sgthreadsd.lib;C:\FG\10\3rdparty\lib\sgdebugd.lib;C:\FG\10\3rdparty\lib\sgmagvard.lib;C:\FG\10\3rdparty\lib\zlib1.lib;winmm.lib;ws2_32.lib
@arr = split(";",$txt);
my %liblist = ();
my %dirs = ();
foreach $tmp (@arr) {
if ($tmp =~ /\.lib$/i) {
my ($n,$d) = fileparse($tmp);
$d = '' if ($d =~ /^\.(\\|\/)$/);
if (is_system_lib($n)) {
# we know about these
} else {
$liblist{$n} = 1;
$dirs{$d} = 1 if (length($d));
}
} elsif ($tmp =~ /\.res$/i) {
# a RESOURCE file dependency
} elsif ($tmp eq '%(AdditionalDependencies)') {
# ignore this
} elsif ($tmp eq '/MACHINE:X86') {
# 20140103 ignore this
} else {
prtw("WARNING: $lnn: AdditionalDependencies: This is NOT .lib WHAT is IT? [$tmp]\n");
}
}
@arr = sort keys(%liblist);
$tmp = scalar @arr;
$val = (@arr) ? join(" ",@arr) : '';
if (@arr && VERB5()) {
prt("[v5] $lnn: LIBRARIES: AdditionalDependencies: Got $tmp additional libraries [$val]\n");
}
@arr = keys %dirs;
$tmp =scalar @arr;
if (@arr && VERB5()) {
prt("[v5] $lnn: LIBDIRS: AdditionalDependencies: In $tmp dirs [".join(" ",@arr)."]\n");
}
${$rh}{'CURR_LIBS'} = \%liblist;
${$rh}{'CURR_LDIRS'} = \%dirs;
merge_library_list($rh);
$show = 1;
} elsif ($rtag eq '/AdditionalLibraryDirectories') {
$show = 1;
} elsif ($rtag eq '/ForceFileOutput') {
$show = 1;
} elsif ($rtag eq '/GenerateDebugInformation') {
$show = 1;
} elsif ($rtag eq '/ImportLibrary') {
$show = 1;
} elsif ($rtag eq '/LinkIncremental') {
$show = 1;
} elsif ($rtag eq '/ProgramDataBaseFileName') {
$show = 1;
} elsif ($rtag eq '/StackReserveSize') {
$show = 1;
} elsif ($rtag eq '/SubSystem') {
if ($txt =~ /Console/i) {
if (defined ${$rh}{'PROJECT_APTP'}) {
$val = ${$rh}{'PROJECT_APTP'};
if ($val eq 'Application') {
${$rh}{'PROJECT_APTP'} = 'Console Application';
prt("$lnn: SubSystem: Console: Changes App Type to 'Console Application'\n");
}
} else {
${$rh}{'PROJECT_APTP'} = 'Console Application';
}
} elsif ($txt =~ /Windows/i) {
if (defined ${$rh}{'PROJECT_APTP'}) {
$val = ${$rh}{'PROJECT_APTP'};
if ($val ne 'Application') {
${$rh}{'PROJECT_APTP'} = 'Application';
prt("$lnn: SubSystem: Windows: Changes App Type from [$val] to 'Application'\n");
}
} else {
${$rh}{'PROJECT_APTP'} = 'Application';
}
} else {
prtw("WARNING: $lnn: 'SubSystem' NOT 'Console'! IS [$txt]! FIX ME! 11\n");
}
$show = 1;
} elsif ($rtag eq '/Version') {
$show = 1;
} elsif ($rtag eq '/SuppressStartupBanner') {
$show = 1;
} elsif ($rtag eq '/OutputFile') {
$show = 1;
} elsif ($rtag eq '/ModuleDefinitionFile') {
$show = 1;
} elsif ($rtag eq '/TargetMachine') {
$show = 1;
} elsif ($rtag eq '/OptimizeReferences') {
$show = 1;
} elsif ($rtag eq '/EnableCOMDATFolding') {
$show = 1;
} elsif ($rtag eq '/ProgramDatabaseFile') {
$show = 1;
} elsif ($rtag eq '/IgnoreSpecificDefaultLibraries') {
$show = 1;
} elsif ($rtag eq '/LinkDLL') {
$show = 1;
} elsif ($rtag eq '/BaseAddress') {
$show = 1;
} elsif ($rtag eq '/RandomizedBaseAddress') {
$show = 1;
} elsif ($rtag eq '/DataExecutionPrevention') {
$show = 1;
} elsif ($rtag eq '/Profile') {
$show = 1;
} elsif ($rtag eq '/IgnoreEmbeddedIDL') {
$show = 1;
} elsif ($rtag eq '/ImageHasSafeExceptionHandlers') {
$show = 1;
} elsif ($rtag eq '/IgnoreAllDefaultLibraries') {
$show = 1;
} elsif ($rtag eq '/LinkTimeCodeGeneration') {
$show = 1;
} elsif ($rtag eq '/ProgramDataBaseFile') {
$show = 1;
} else {
$wmsg = "Uncased 'Link' [$tag]";
if (!defined $shown_warn{$wmsg}) {
prtw("WARNING: $lnn: $wmsg [$txt] FIX ME! 12\n");
$shown_warn{$wmsg} = 1;
}
}
} elsif ($nxtstag eq 'ProjectReference') {
if ($rtag eq '/LinkLibraryDependencies') {
$show = 1;
} else {
prtw("WARNING: $lnn: Uncased 'ProjectReference' [$tag] FIX ME! 13\n");
}
} elsif ($nxtstag eq 'ItemDefinitionGroup') {
# close of group
} elsif ($nxtstag eq 'PostBuildEvent') {
# close a postbuildevent
} elsif ($nxtstag eq 'Bscmake') {
# true
# .\Debug\test_static\test_static.bsc
#
} elsif ($nxtstag eq 'Lib') {
#
# true
# .\Debug\test_static\test_static.lib
#
} elsif ($nxtstag eq 'Message') {
# ???
} elsif ($nxtstag eq 'CustomBuildStep') {
# ???
} elsif ($nxtstag eq 'PreBuildEvent') {
# 20151113 ???
} else {
prtw("WARNING: $lnn: ItemDefinitionGroup: Uncased Next [$nxtstag] curr tag [$tag] FIX ME! 14\n file [$inff]\n");
}
if ($show) {
$val = substr($rtag,1);
prt("[v9] $lnn: ItemDef: nxt $nxtstag: $val = [$txt], cond idg [$idconf] op [$opcond]\n") if (VERB9() || $dbg_08);
#} elsif ($rtag =~ /^\//) {
# prtw("WARNING: $lnn: Unmanaged PropertyGroup [$rtag] [$txt]\n");
}
} elsif ($tagtype == 2) {
if (($nxtstag ne 'ItemDefinitionGroup') && ($nxtstag ne $idopntag)) {
#
#if ($ntag eq 'Command') { # like =~ /^/) {
prt("$lnn:[v9]: End ImportGroup\n") if (VERB9());
$impgroup = 0;
}
} elsif (length($tag)) {
if ($tag =~ /^setlocal
# "C:\Program Files (x86)\CMake 2.8\bin\cmake.exe" -HC:/FG/10/flightgear -BC:/FG/10/flightgear/build --check-stamp-file C:\FG\10\flightgear\build\src\FDM\YASim\CMakeFiles\generate.stamp
# if %errorlevel% neq 0 goto :cmEnd
$incommand = 1;
prt("\n[10] $lnn:outsied ItemGroup: SETTING incommnd\n\n") if ($dbg_10);
#prt("$lnn:[v9]: Start command\n") if (VERB9());
prtw("WARNING: $lnn: Start command OUTSIDE ItemGroup!\n"); # should NOT happen
$command = '';
} elsif ($tag =~ /^
$itemlabel = get_rt_value($rh,'Label');
prt("$lnn:[v9]: Start ItemGroup $itemlabel\n") if (VERB9());
$initemgroup = 1;
} elsif ($tag =~ /^$/) {
prt("$lnn:[v9]: Comp PropertyGroup\n") if (VERB9());
} else {
#
#
$pgcond = get_rt_value($rh,'Condition');
$pglabel = get_rt_value($rh,'Label');
prt("$lnn:[v9]: Start PropertyGroup [$pgcond] [$pglabel]\n") if (VERB9());
$inpropgroup = 1;
${$rh}{'CURR_ODIR'} = '';
${$rh}{'CURR_TNAME'} = '';
${$rh}{'CURR_TEXT'} = '';
}
} elsif ($tag =~ /^$/) {
$inproj = 0;
prt("$lnn:[v9]: End project\n") if (VERB9());
} elsif (($tag =~ /^$/)) {
#
} else {
prtw("WARNING:$lnn: Tag not handled: [$tag]\n");
}
}
} else {
#
if ($tag =~ /^ 1,
'PACKAGE' => 1,
'WIN32' => 1,
'WIN32_LEAN_AND_MEAN' => 1,
'_CONSOLE' => 1,
'_CRT_NONSTDC_NO_WARNINGS' => 1,
'_CRT_SECURE_NO_WARNINGS' => 1,
'_DEBUG' => 1,
'_LIB' => 1,
'_MBCS' => 1,
# '_VISUALC_' => 1,
'_WIN32' => 1,
'_WINDOWS' => 1,
'__CONSOLE__' => 1
);
# __WIN32__
# @arr = filter_defines_list(\@arr);
sub filter_defines_list($) {
my $ra = shift; # \@arr;
my @arr = ();
my %dupes = ();
my ($def);
my $excl = 0;
my $dups = 0;
my $cnt = scalar @{$ra};
foreach $def (@{$ra}) {
if (defined $exclude_defines{$def}) {
$excl++;
} elsif (defined $dupes{$def}) {
$dups++;
} else {
push(@arr,$def);
$dupes{$def} = 1;
}
}
my $rcnt = scalar @arr;
prt("[v5] Of original $cnt, defines, excluded $excl, and dups $dups, with $rcnt remaining.\n") if (VERB5());
return @arr;
}
sub get_comm_part($$) {
my ($d1,$d2) = @_;
my @arr1 = split(/\//,$d1);
my @arr2 = split(/\//,$d2);
my $len1 = scalar @arr1;
my $len2 = scalar @arr2;
my $len = ($len1 < $len2) ? $len1 : $len2;
my $c = '';
my ($i);
for ($i = 0; $i < $len; $i++) {
$d1 = $arr1[$i];
$d2 = $arr2[$i];
if ($d1 eq $d2) {
$c .= '/' if (length($c));
$c .= $d1;
} else {
last;
}
}
return $c;
}
sub get_common_path($$$) {
my ($m_ras,$m_rah,$m_sd) = @_;
my $comp = '';
my ($src,$ff,$n,$d,$rel,$mlen);
foreach $src (@{$m_ras}) {
$ff = File::Spec->rel2abs($m_sd.$src);
($n,$d) = fileparse($ff);
$rel = get_relative_path4($d,$out_cmake_dir);
$ff = $rel.$n;
my $nsrc = path_d2u($ff);
my ($nn,$nd) = fileparse($nsrc);
$nd =~ s/\/$//;
$mlen = length($comp);
if ($mlen) {
if ($comp ne $nd) {
$comp = get_comm_part($comp,$nd);
}
} else {
$comp = $nd;
}
}
foreach $src (@{$m_rah}) {
$ff = File::Spec->rel2abs($m_sd.$src);
($n,$d) = fileparse($ff);
$rel = get_relative_path4($d,$out_cmake_dir);
$ff = $rel.$n;
my $nsrc = path_d2u($ff);
my ($nn,$nd) = fileparse($nsrc);
$nd =~ s/\/$//;
$mlen = length($comp);
if ($mlen) {
if ($comp ne $nd) {
$comp = get_comm_part($comp,$nd);
}
} else {
$comp = $nd;
}
}
return $comp;
}
sub try_another_cmake($) {
my $rparams = shift;
my $cnt = scalar @proj_hash_array;
return 0 if ($cnt == 0);
my ($rh2);
my $cmake = '';
my ($var1,$var2,$var3,$rel,$ff,$n,$d,$src,$scnt,$tmp);
my (@arr);
my %inc_dirs = ();
my %def_items = ();
my $cmake_exe = '';
$cnt = 0;
my $leader = '';
my $exe_cnt = 0;
my $ecomm_path = '';
foreach $rh2 (@proj_hash_array) {
my $rh = get_hash_results($rh2,0);
my $rc_files = ${$rh}{'PROJECT_C_SOURCES'}; # = \@c_files;
my $rh_files = ${$rh}{'PROJECT_H_SOURCES'}; # = \@h_files;
my $ro_files = ${$rh}{'PROJECT_O_SOURCES'}; # = \@o_files;
my $name = ${$rh}{'PROJECT_NAME'}; # = $name;
my $sdir = ${$rh}{'PROJECT_SDIR'}; # = $sdir;
my $type = ${$rh}{'PROJECT_TYPE'}; # = $type;
my $rincs = ${$rh}{'PROJECT_INCS'}; # = \%inc_hash;
my $rdefs = ${$rh}{'PROJECT_DEFS'}; # = \%def_hash;
# get FILE counts
# =============================
my $ccnt = scalar @{$rc_files};
my $hcnt = scalar @{$rh_files};
my $ocnt = scalar @{$ro_files};
# =============================
my $icnt = scalar keys(%{$rincs});
my $dcnt = scalar keys(%{$rdefs});
my $pn = $name;
$rel = get_relative_path4($sdir,$out_cmake_dir);
ut_fix_directory(\$sdir);
prt("Project [$name], type [$type], $ccnt C/C++, $hcnt Hdrs, $ocnt Other, $icnt INCS, $dcnt DEFS\n");
prt("File dir [$sdir], out [$out_cmake_dir], rel = [$rel]\n");
$var1 = '';
$var2 = '';
$var3 = '';
if ($ccnt) {
if (length($proj_name) == 0) {
$proj_name = $name;
${$rparams}{'PROJECT_NAME_MASTER'} = $proj_name;
}
my $comm_path = get_common_path($rc_files,$rh_files,$sdir);
foreach $src (keys %{$rincs}) {
$ff = File::Spec->rel2abs($sdir.$src);
ut_fix_directory(\$ff);
$ff .= "temp.txt";
($n,$d) = fileparse($ff);
$rel = get_relative_path4($d,$out_cmake_dir);
$rel = path_d2u($rel);
#next if ($rel =~ /\$\{dir\}/);
accumulate_incs(\%inc_dirs,$rel);
}
foreach $src (keys %{$rdefs}) {
$def_items{$src} = 1;
}
$leader = "\n# Project [$name], type [$type], $ccnt C/C++, $hcnt Hdrs, $ocnt Other, $icnt INCS, $dcnt DEFS\n";
$leader .= "# File dir [$sdir], out [$out_cmake_dir], rel = [$rel]\n";
$var1 = "\${name}_SRCS";
$scnt = scalar @{$rc_files};
$leader .= "set(name $name)\n";
$leader .= "set(dir $comm_path)\n";
$leader .= "set( $var1";
# if GT 2 put on a NEW line
$leader .= "\n" if ($scnt > 2);
$tmp = '';
@arr = ();
$comm_path =~ s/\//\\\//;
foreach $src (sort @{$rc_files}) {
$ff = File::Spec->rel2abs($sdir.$src);
($n,$d) = fileparse($ff);
$rel = get_relative_path4($d,$out_cmake_dir);
$ff = $rel.$n;
$src = path_d2u($ff);
$ecomm_path = escape_regex($comm_path);
$src =~ s/$ecomm_path/\$\{dir\}/;
if ($scnt > 2) {
$tmp .= " $src\n";
} else {
$tmp .= " $src"; # stay on SAME line for short list
}
push(@arr,$src);
}
if ($scnt > 2) {
#$tmp =~ s/\n$/ \)\n/;
$tmp .= " )\n";
} else {
$tmp .= " )\n";
}
$leader .= $tmp;
if ($hcnt) {
$var2 = "\${name}_HDRS";
$leader .= "set( $var2";
$leader .= "\n" if ($hcnt > 2);
foreach $src (sort @{$rh_files}) {
$ff = File::Spec->rel2abs($sdir.$src);
($n,$d) = fileparse($ff);
$rel = get_relative_path4($d,$out_cmake_dir);
$ff = $rel.$n;
$rel =~ s/\/$//;
accumulate_incs(\%inc_dirs,$rel);
$src = path_d2u($ff);
$ecomm_path = escape_regex($comm_path);
$src =~ s/$ecomm_path/\$\{dir\}/;
if ($hcnt > 2) {
$leader .= " $src\n";
} else {
$leader .= " $src";
}
#accumulate_incs(\%inc_dirs,$src);
}
if ($hcnt > 2) {
$leader =~ s/\n$/ )\n/;
} else {
$leader .= " )\n";
}
}
if ($ocnt) {
$var3 = $name."_OTHERS";
$leader .= "set( $var3\n";
foreach $src (sort @{$ro_files}) {
$ff = File::Spec->rel2abs($sdir.$src);
($n,$d) = fileparse($ff);
$rel = get_relative_path4($d,$out_cmake_dir);
$ff = $rel.$n;
$src = path_d2u($ff);
$leader .= " $src\n";
}
$leader =~ s/\n$/ )\n/;
}
if (($type eq 'Dynamic-Link Library') || ($type eq 'Static Library')) {
$cmake .= $leader;
$cmake .= "if (BUILD_ONE_LIBRARY)\n";
$cmake .= " list(APPEND lib_SOURCES \${$var1})\n"; # keep FULL SOURCE list
$cmake .= " list(APPEND lib_HEADERS \${$var2})\n" if (length($var2)); # and HEADERS
$cmake .= "else ()\n";
$cmake .= " add_library( \${name} ";
if ($use_lib_option_var) {
$cmake .= '${LIB_TYPE}';
} else {
if ($type eq 'Dynamic-Link Library') {
$cmake .= 'SHARED';
} else {
$cmake .= 'STATIC';
}
}
###$cmake .= "\n";
$cmake .= " \${$var1}";
if (length($var2)) {
$cmake .= " \${$var2}";
}
###$cmake =~ s/\n$//;
$cmake .= " )\n";
$cmake .= " list(APPEND add_LIBS \${name})\n"; # add to LINK libraries
$cmake .= "endif ()\n";
} else {
$exe_cnt++;
$cmake_exe .= $leader;
$cmake_exe .= "add_executable( \${name}";
$cmake_exe .= " \${$var1}";
if (length($var2)) {
$cmake_exe .= " \${$var2}";
}
$cmake_exe .= " )\n";
$cmake_exe .= "target_Link_libraries(\${name} \${add_LIBS} )\n";
$cmake_exe .= "if (MSVC)\n";
$cmake_exe .= " set_target_properties(\${name} PROPERTIES DEBUG_POSTFIX d )\n";
$cmake_exe .= "endif ()\n";
}
$cnt++;
}
}
$cmake .= "if (BUILD_ONE_LIBRARY)\n";
$cmake .= " add_library( $proj_name \${LIB_TYPE}";
$cmake .= " \${lib_SOURCES} \${lib_HEADERS} ";
$cmake .= " )\n";
$cmake .= " list(APPEND add_LIBS $proj_name)\n"; # add to LINK libraries
$cmake .= "endif ()\n";
# ====================================
# add executables AFTER libraries
if (length($cmake_exe)) {
$cmake .= "\n### $exe_cnt executables #############################################\n";
$cmake .= $cmake_exe;
}
# ====================================
@arr = sort keys %inc_dirs;
$var2 = scalar @arr;
if ($var2) {
$var1 = "# Add $var2 include directories indicated\n";
# hmmm, why add 'SYSTEM' here - need to check meaning
$var1 .= "include_directories( \n";
foreach $src (@arr) {
$var1 .= " $src\n";
}
$var1 =~ s/\n$//;
$var1 .= " )\n\n";
$cmake = $var1.$cmake;
}
# 20140103 - Need to FILTER this list
@arr = sort keys %def_items;
$var1 = scalar @arr;
@arr = filter_defines_list(\@arr);
$var2 = scalar @arr;
if ($var2) {
$var1 = "# Adding $var2 of $var1 defines indicated.\n";
$var1 .= "add_definitions( \n";
foreach $src (@arr) {
$var1 .= " -D$src\n";
}
$var1 =~ s/\n$//;
$var1 .= " )\n\n";
$cmake = $var1.$cmake;
}
$var1 = "# CMakeLists.txt generated ".lu_get_YYYYMMDD_hhmmss(time())."\n";
$var1 .= "# by $pgmname from $in_file\n\n";
$var1 .= "# local CMake Scripts.\n";
$var1 .= "# set(CMAKE_MODULE_PATH \${CMAKE_SOURCE_DIR}/CMakeModules )\n\n";
$var1 .= "cmake_minimum_required (VERSION 2.8.8)\n\n";
$var1 .= "project ($proj_name)\n\n";
# add usual header blob
$var1 .= get_cmake_blob();
if ($add_3rdparty_stuff) {
$var1 .= get_cmake_blob2();
}
$cmake .= "\n# deal with install, if required\n";
$cmake .= "# install(TARGETS \${inst_LIBS}\n";
$cmake .= "# RUNTIME DESTINATION bin\n";
$cmake .= "# LIBRARY DESTINATION lib\n";
$cmake .= "# ARCHIVE DESTINATION lib )\n";
$cmake .= "# install(TARGETS \${inst_BINS} DESTINATION bin)\n";
$cmake .= "# install(FILES \${inst_HDRS} DESTINATION include)\n";
$cmake = $var1.$cmake."\n# eof\n";
$ff = $out_cmake_dir;
ut_fix_directory(\$ff);
$ff .= "CMakeLists.txt";
rename_2_old_bak($ff) if (-f $ff);
write2file($cmake,$ff);
prt("cmake output written to [$ff]\n");
return $cnt;
}
sub write_cmake_output() {
if (get_write_cmake_files()) {
if (!defined ${$rparams}{'AM_EXCLUDED_DIRS'}) {
my %excluded = ();
my $rex = \%excluded;
${$rparams}{'AM_EXCLUDED_DIRS'} = $rex;
}
#my $rparams = get_ref_params();
# need to set
# my $rex = ${$rparams}{'AM_EXCLUDED_DIRS'}; # get stored EXCLUDED directory HASH (if any!)
# my $proj_root = ${$rparams}{'ROOT_FOLDER'};
# my $proj_title = ${$rparams}{'PROJECT_NAME_MASTER'};
# my $rprojsh = ${$rparams}{'REF_PROJECTS_HASH'};
# my $rlib_lists = ${$rparams}{'REF_LIB_LISTS'}; # make list of LIBRARIES written
#if (write_project_cmake_files($rparams)) {
if (!try_another_cmake($rparams)) {
prt("Write CMAKE FAILED!\n");
}
#}
} else {
prt("Write CMAKE is disabled! Use -cmake:dir to enable.\n");
}
}
# ==========================================================
# MAIN
############################################################
my $args_ref = parse_args(@ARGV);
prt("By $pgmname, Version: $vers, on ".lu_get_YYYYMMDD_hhmmss(time())."\n");
foreach $in_file (@{$args_ref}) {
prt("[v9] Processing file [$in_file]...\n") if (VERB9());
if (is_vcxproj_ext($in_file)) {
process_vcxproj_file($in_file, $out_dsp_dir);
} elsif (is_vcproj_ext($in_file)) {
process_vcproj_file($in_file, $out_dsp_dir);
} elsif (is_sln_ext($in_file)) {
my $rsh = sln_file_processing(0, $in_file, $out_dsp_dir);
show_sln_results($rsh);
if (@project_list) {
my $out_dsw = $out_dsp_dir."\\temp.$pgmname.DSW";
# write_proj_DSW3( $out_dsp_dir."\\temp.$pgmname.DSW", \@project_list);
# DEBUG:
# $dbg & 128 = get_configs_array3()
# prt("[dbg & 1] write_proj_DSW3: 'temp' DSP file [$odsp]\n") if ($g_write_dbg & 1);
# prt("[dbg & 2] write_proj_DSW3: 'absolute' DSP file [$fdsp]\n") if ($g_write_dbg & 2);
# $debug_dsw_write = 3;
prt("\nDoing write_proj_DSW3 to [$out_dsw]. Debug=[3]\n");
write_proj_DSW3( $out_dsw, $rsh, $out_bat_file, 3);
}
} else {
prtw( "WARNING: Unprocessed file extension! [$in_file]!\n" );
}
}
write_cmake_output();
pgm_exit(0,"");
##########################################################
sub chk_arg {
my ($arg, @av) = @_;
fatal( "Invalid $arg - needs value ... -? for help ... aborting!\n" ) if !(@av);
}
sub need_arg {
my ($a, @b) = @_;
if (!@b) {
prt( "Error: $a argument requires additional item! Try -?\n" );
pgm_exit(1,"COMMAND ERROR");
}
}
sub load_arg_file($$);
sub load_arg_file($$) {
my ($fil,$lev) = @_;
if (! open INF, "<$fil") {
pgm_exit(1,"ERROR: Unable to open file [$fil]!\n");
}
my @lines = ;
close INF;
my ($line,@arr,$lncnt,$i,$tmp,$sarg);
@arr = ();
$lncnt = scalar @lines;
for ($i = 0; $i < $lncnt; $i++) {
$line = $lines[$i];
$line = trim_all($line);
next if (length($line) == 0);
if ($line =~ /^\s*\#\s*include\s+"(.+)"/) {
$sarg = $1;
if (-f $sarg) {
prt("Loading #include [$sarg]...\n") if (VERB1());
load_arg_file($sarg,$lev+1);
} else {
pgm_exit(1,"ERROR: INCLUDE file #include \"$sarg\" NOT FOUND\n");
}
next;
}
next if ($line =~ /^#/);
while ($line =~ /\\$/) {
# got continuation of this line
$i++;
$tmp = trim_all($lines[$i]);
next if ($tmp =~ /^#/);
last if (length($tmp) == 0);
$line =~ s/\\$//;
$line = trim_all($line);
$line .= $tmp; #add this to the line
}
# store argument from file
if ($line =~ /\s/) {
my @a = space_split($line);
foreach $tmp (@a) {
push(@arr,$tmp);
}
} else {
push(@arr,$line);
}
}
if (@arr) {
$in_input_file++;
parse_args(@arr);
$in_input_file--;
}
}
sub has_wild_cards($) {
my $fil = shift;
return 1 if ($fil =~ /(\?|\*)/);
return 0;
}
sub first_colon_split($) {
my $txt = shift;
my $ind = index( $txt, ':');
my @arr = ();
prt("[v9] Splitting on first colon [$txt]\n") if VERB9();
if ($ind > 2) {
my ($tmp);
$tmp = substr($txt,0,$ind);
push(@arr, $tmp);
prt("[v9] Added [$tmp]\n") if (VERB9());
$tmp = substr($txt,$ind+1);
push(@arr, $tmp);
prt("[v9] Added [$tmp]\n") if (VERB9());
} else {
prt("[v9] No colon found!\n") if (VERB9());
push(@arr,$txt);
}
return @arr;
}
# watch out for -cmake:out;C:\..."
sub set_cmake_options($) {
my $sarg = shift;
$write_cmake = 1;
# 20161123 - Restore this
my @arr = split(":",$sarg);
###my @arr = first_colon_split($sarg);
my $cnt = scalar @arr;
my ($i,$opt,@arr2,$msg);
$msg = '';
# NOTE:1: skipping 'cmake:'
for ($i = 1; $i < $cnt; $i++) {
$opt = $arr[$i];
$msg = "Option: " if (length($msg) == 0);
if (($opt eq '?')||($opt =~ /help/i)) {
show_cmake_help();
pgm_exit(0,"cmake HELP exit(0)\n");
} elsif ($opt =~ /^it;.+/) {
$opt =~ s/^it;//;
$inst_hdr_path = $opt;
$msg .= "Inst. hdrs to [$opt] ";
} elsif ($opt =~ /^lt;.+/) {
$opt =~ s/^lt;//;
$inst_lib_path = $opt;
$msg .= "Inst. libs to [$opt] ";
} elsif ($opt =~ /^bt;.+/) {
$opt =~ s/^bt;//;
$inst_bin_path = $opt;
$msg .= "Inst. bins to [$opt] ";
} elsif ($opt =~ /^out;.+/) {
$opt =~ s/^out;//;
$out_cmake_dir = File::Spec->rel2abs($opt);
# $sarg = File::Spec->rel2abs($tmp); # get ABSOLUTE path of input
# prt( "Setting to output cmake to abs=[$sarg]\n" ) if (VERB1());
# $out_cmake_dir = $sarg;
if (-d $out_cmake_dir) {
$msg .= "Root dir to [$out_cmake_dir] ";
} else {
pgm_exit(1,"ERROR: Root dir [$out_cmake_dir] DOES NOT EXIST!\n");
}
} else {
pgm_exit(1,"ERROR: Unknown cmake option [$opt] arg=$sarg (1)\n");
}
}
prt("Set to write CMake files $msg.\n");
}
sub parse_args { # @ARGV
my (@av) = @_;
my $dn = scalar @av;
my ($arg,$tmp,$i,$sarg,$val,@arr);
if ($dbg_sl_06) {
prt( "[dbg01] parsing $dn arguments... " );
for ($i = 0; $i < $dn; $i++) {
prt( "[".$av[$i]."]" );
}
prt("\n");
}
$dn = 0;
my $had_frp = 0;
my $first_in = "";
$got_par = 0;
while (@av) {
$dn++;
$arg = $av[0];
prt( "[dbg01] $dn: $arg\n" ) if ($dbg_sl_06);
if (substr($arg,0,1) eq '-') {
$sarg = substr($arg,1);
$sarg = substr($sarg,1) while ($sarg =~ /^-/);
if (($sarg eq '?')||($sarg eq 'h')||($sarg eq '-help')) {
give_help();
pgm_exit(0,"HELP_EXIT");
} elsif ($sarg =~ /^\@/) {
$sarg = substr($sarg,1);
load_arg_file($sarg,0);
} elsif ($sarg =~ /^adj-inter$/) {
$adj_inter = 1;
prt("Set to adjust output and inter dirs to \"Release\\\" and \"Debug\\\"\n") if (VERB1());
} elsif ($sarg =~ /^adj-out$/) {
$adj_out = 1;
prt("Set to adjust output to \"bin\\[D].exe\" EXE and DLL and \"lib\\...\" libs.\n") if (VERB1());
} elsif ($sarg =~ /^adj-rt$/) {
need_arg(@av);
shift @av;
$dn++;
$sarg = $av[0];
if (($sarg eq 'D')||($sarg eq 'T')) {
$adj_rt = $sarg;
if ($sarg eq 'D') {
$tmp = "D = /MD and /MDd";
} else {
$tmp = "T = /MT and /MTd";
}
prt("Set to adjust RUNTIME to $tmp, accordingly.\n") if (VERB1());
} else {
pgm_exit(1,"ERROR: Argument $arg can ONLY be follwed by 'D' or 'T'! NOT [$sarg].\n");
}
} elsif ($sarg =~ /^del-ndl-all$/) {
$del_ndl_all = 1;
prt( "Set to delete /nodefaultlib:\"*...*\"...\n" ) if (VERB1());
} elsif ($sarg =~ /^del-dll-all$/) {
$del_dll_all = 1;
prt("Set to remove any DLL build if both DLL and static, or change to static is only DLL\n") if (VERB1());
} elsif ($sarg =~ /^del-spl-bld$/) {
$del_spl_bld = 1;
prt("Remove any Special Tool Build blocks from DSP\n") if (VERB1());
} elsif ($sarg =~ /^in=(.+)$/) {
$in_file = $1;
if (has_wild_cards($in_file)) {
@arr = glob($in_file);
prt("Potential inputs: ".join(" ",@arr)."\n") if (@arr);
prt("ERROR: At present do not support wild card inputs like [$arg]\n");
pgm_exit(1,"but do support multiple file inputs...\n");
}
if (-f $in_file) {
prt( "Set in file to [$in_file] ...\n" ) if (VERB1());
push(@user_inputs,$in_file);
$first_in = $in_file if (length($first_in)==0);
if (!$got_par) {
prt("Calling 'init_common_subs($in_file)' from -in=file\n") if (VERB5());
$rparams = init_common_subs($in_file); # note: sets ROOT_FOLDER - where a CMakeLists.txt could be written
$got_par = 1;
}
} else {
prt( "Current Work Directory = [$pwd]\n" );
mydie( "ERROR: Can NOT locate IN FILE [$in_file]! check name, location! aborting...\n" );
}
} elsif ($arg eq '-l') {
$load_log = 1;
prt( "Set in load log at end...\n" ) if (VERB1());
} elsif ($arg eq '-in') {
need_arg(@av);
shift @av;
$dn++;
$arg = $av[0];
prt("[dbg01] $dn: $arg\n") if ($dbg_sl_06);
if (has_wild_cards($arg)) {
@arr = glob($arg);
prt("Potential inputs: ".join(" ",@arr)."\n") if (@arr);
prt("ERROR: At present do not support wild card inputs like [$arg]\n");
pgm_exit(1,"but do support multiple file inputs...\n");
}
#$in_file = $arg;
$in_file = File::Spec->rel2abs($arg); # get ABSOLUTE path of input
if (-f $in_file) {
prt( "Set in file to [$in_file] ...\n" ) if (VERB1());
push(@user_inputs,$in_file);
$first_in = $in_file if (length($first_in)==0);
if (!$got_par) {
prt("Calling 'init_common_subs($in_file)' from in file\n") if (VERB5());
$rparams = init_common_subs($in_file); # note: sets ROOT_FOLDER - where a CMakeLists.txt could be written
$got_par = 1;
}
} else {
prt( "Current Work Directory = [$pwd]\n" );
pgm_exit(1,"ERROR: Can NOT locate IN FILE [$in_file]! check name, location! aborting...\n" );
}
} elsif ($arg eq '-cmp') {
$comp_2_dsps = 1;
prt("Set compare NEW and any OLD DSP file.\n") if (VERB1());
} elsif ($arg eq '-debug') {
set_sl_debug_on();
svc_set_dbg_on();
$dbg4write = -1; # all write DEBUG on
} elsif ($arg =~ /^-cmake/) {
$sarg = substr($arg,1);
set_cmake_options($sarg);
$dn++;
#} elsif ($sarg =~ /^cmake:(.+)$/) {
# $tmp = $1;
# $sarg = File::Spec->rel2abs($tmp); # get ABSOLUTE path of input
# prt( "Setting to output cmake to abs=[$sarg]\n" ) if (VERB1());
# $out_cmake_dir = $sarg;
# $write_cmake = 1;
} elsif ($arg eq '-dsp') {
$dn++;
prt("[dbg01] $dn: $arg\n") if ($dbg_sl_06);
$write_dsp = 1;
$g_had_dsp = 1;
prt( "Setting to output a DSP to [$out_dsp_dir]\n" ) if (VERB1());
} elsif ($sarg =~ /^dsp:(.+)$/) {
$tmp = $1;
$sarg = File::Spec->rel2abs($tmp); # get ABSOLUTE path of input
prt( "Setting output file to abs=[$sarg] ($tmp), from [$out_dsp_dir]...\n" ) if (VERB1());
#$out_dsp_dir = $tmp;
$out_dsp_dir = $sarg;
$write_dsp = 1;
$g_had_dsp = 1;
} elsif ($sarg =~ /^n/) {
need_arg(@av);
shift @av;
$sarg = $av[0];
$proj_name = $sarg;
} elsif ($sarg =~ /^o/) {
need_arg(@av);
shift @av;
$sarg = $av[0];
$out_cmake_dir = File::Spec->rel2abs($sarg);
$write_cmake = 1;
if (-d $out_cmake_dir) {
prt("Set cmake root dir to [$out_cmake_dir].\n");
} else {
pgm_exit(1,"ERROR: Root dir [$out_cmake_dir] DOES NOT EXIST!\n");
}
} elsif ($arg =~ /^-type=(CA|WA|DLL|SL)$/) {
$tmp = $1;
if ( get_app_type_4_short($tmp,\$curr_app_type) && length($curr_app_type) ) {
prt( "Set proj type override to [$curr_app_type] ($tmp)...\n" ) if (VERB1());
} else {
mydie( "ERROR: Unknown option [$arg] ... try -? ... aborting!\n" );
}
} elsif (($arg eq '-fix-rel')||($arg eq '-fix_rel')) {
$fix_rel_paths = 1;
prt("Set to fix relative paths of sources.\n") if (VERB1());
$had_frp = 1;
} elsif ($sarg =~ /^svc-dbg=(\d+)/) {
$val = $1;
prt("[dbg01] $dn: $arg\n") if ($dbg_sl_06);
if (svc_set_dbg_item($val,1)) {
pgm_exit(1,"ERROR: Unable to set lib_vcscan.pl dbg_v$val... aborting!\n" );
}
} elsif ($sarg =~ /^svc-dbg$/) {
need_arg(@av);
shift @av;
$dn++;
$sarg = $av[0];
prt("[dbg01] $dn: $arg $sarg\n") if ($dbg_sl_06 || VERB9());
if ( !($sarg =~ /^\d+$/) || ( svc_set_dbg_item($sarg,1) ) ) {
pgm_exit(1,"ERROR: [$arg] [$sarg] Unable to set lib_vcscan.pl dbg_v$sarg... aborting!\n" );
}
} elsif ($sarg =~ /^show-hash$/) {
$dbg_sl_04 = 1; # Show DSP hash results (for debug).
prt("Set to show DSP hash results (for debug).\n") if (VERB1());
} elsif ($sarg eq 'type') {
need_arg(@av);
shift @av;
$dn++;
$arg = $av[0];
prt("[dbg01] $dn: $arg\n") if ($dbg_sl_06 || VERB9());
if ($arg =~ /^(CA|WA|DLL|SL)$/) {
$tmp = $1;
if ( get_app_type_4_short($tmp,\$curr_app_type) && length($curr_app_type) ) {
prt( "Set proj type override to [$curr_app_type] ($tmp)...\n" ) if (VERB1());
} else {
pgm_exit(1,"ERROR: Unknown option [-type $arg] ... try -? ... aborting!\n" );
}
} else {
pgm_exit(1,"ERROR: Unknown option [$arg]! Expected one {CA|WA|DLL|SL]!! try -? ... aborting!\n" );
}
} elsif ($sarg =~ /^v/) {
if ($sarg =~ /^v(\d+)$/) {
$verbosity = $1;
} else {
while ($sarg =~ /^v/) {
$verbosity++;
$sarg = substr($sarg,1);
}
}
$dbg4write = -1 if (VERB9()); # all write DEBUG on
prt("Set verbosity to [$verbosity]\n") if (VERB1());
} elsif ($arg eq '-ll') {
$load_log = 1;
prt("Set to load log at end.\n") if (VERB1());
} else {
pgm_exit(1,"ERROR: Unknown option [$arg] ... try -? ... aborting!\n" );
}
} else {
# bare item - assume an INPUT file
#$in_file = $arg;
if (has_wild_cards($arg)) {
@arr = glob($arg);
prt("Potential inputs: ".join(" ",@arr)."\n") if (@arr);
prt("ERROR: At present do not support wild card inputs like [$arg]\n");
pgm_exit(1,"but do support multiple file inputs...\n");
}
$in_file = File::Spec->rel2abs($arg); # get ABSOLUTE path of input
if (-f $in_file) {
# does this call 'set_params_ref'??? Looks like it DOES
prt( "Set in file to [$in_file] ...\n" ) if (VERB1());
push(@user_inputs,$in_file);
$first_in = $in_file if (length($first_in)==0);
if (!$got_par) {
prt("Calling 'init_common_subs($in_file)' from bare file\n") if (VERB5());
$rparams = init_common_subs($in_file); # note: sets ROOT_FOLDER - where a CMakeLists.txt could be written
$got_par = 1;
}
} else {
prt( "Current Work Directory = [$pwd]\n" );
pgm_exit(1,"ERROR: Can NOT locate IN FILE [$in_file]! check name, location! aborting...\n" );
}
}
shift @av;
}
if ($in_input_file) {
return;
}
if ($had_frp && !$g_had_dsp) {
pgm_exit(1,"ERROR: Option conflict! Had -fix_rel, but no -dsp= for output.\n");
}
$dn = scalar @user_inputs;
if (!$dn && $debug_on && length($def_in_file) && (-f $def_in_file) && length($def_out_dsp_dir) && (-d $def_out_dsp_dir)) {
$in_file = $def_in_file;
push(@user_inputs,$in_file);
$out_dsp_dir = $def_out_dsp_dir;
$fix_rel_paths = 1;
#$load_log = 1;
#$verbosity = 9;
#$dbg4write = -1;
prt("DEBUG ON: Set input to [$in_file], and out [$out_dsp_dir]\n");
$rparams = init_common_subs($in_file) if (!$got_par); # note: sets ROOT_FOLDER - where a CMakeLists.txt could be written
$got_par = 1;
$write_cmake = 1;
}
$dn = scalar @user_inputs;
if ($dn) {
prt("Got $dn items to process...\n");
} else {
# no file(s), and not $debug_on
### give_help();
pgm_exit(1,"ERROR: No input file found!\n");
}
if (length($out_dsp_dir) == 0) {
pgm_exit(1,"ERROR: No DSP out directory givent! Aborting...");
} elsif (! -d $out_dsp_dir) {
pgm_exit(1,"ERROR: DSP out directory [$out_dsp_dir] does NOT exist! Aborting...");
}
if ($write_cmake) {
#my $out_cmake_dir = '';
}
if (length($first_in)) {
if (defined $rparams) {
if (! defined ${$rparams}{'PROJECT_AM_FILE'}) {
${$rparams}{'PROJECT_AM_FILE'} = $first_in;
prt("Set rparams'PROJECT_AM_FILE' to [$first_in]\n") if (VERB5());
} else {
prt("Note rparams['PROJECT_AM_FILE'] set to [".${$rparams}{'PROJECT_AM_FILE'}."]\n") if (VERB5());
}
if (length($proj_name)) {
${$rparams}{'PROJECT_NAME_MASTER'} = $proj_name;
}
} else {
prtw("WARNING: Appears 'rparams' NOT defined!\n");
}
}
return \@user_inputs;
}
# -cmp - If an existing DSP file, compare NEW and OLD.
# -cmake[:dir] - Write cmake file to this root directory. Default to in file directory if none given.
sub give_help {
my $help = <" and "Debug\\"
-adj-out - Adjust output to "bin\\.exe" and "bin\\D.exe" for EXE and DLL
projects, and "lib\\.lib" and "lib\\D.lib" for libraries.
-adj-rt - Adjust runtime, D = /MD and /MDd, T = /MT and /MTd, accordingly.
-cmake[:opt] - Enable CMake output. See options below.
-del-ndl-all - To delete /nodefaultlib:\"*...*\", if found
-del-dll-all - Remove any DLL build if both DLL and static, or change to static is only DLL
-del-spl-bld - Remove any Special Tool Build blocks from DSP
-dsp[:dsp_dir] - Write DSP file(s) to this directory. (def=$out_dsp_dir).
-in=in_file - Alternative to set input file.
-ll - Load LOG at end.
-fix-rel - Fix relative paths, if an output directory, relative to source, given.
-svc-dbg= - Set this debug item in the lib_vcscan.pl module.
-show-hash - Show DSP hash results (for debug \$dbg_v04).
-type=TYPE - Override project type. TYPES = [CA|WA|DLL|SL] only.
CA=Console App, WA=Windows App, DLL=Dynamic-Link, Lib SL=Static Library.
-out (-o) - Set the CMakeLists.txt output directory.
-name - Set project name.\
-v[n] - Bump (or set) verbosity. Def=$verbosity
The 'input file' can be either a single 'vcproj' file, of a 'sln' file.
If a solution file (*.sln) is given, then all the project files if contains (*.vcproj) will
first be extracted, and then processed one-by-one.
EOF
prt( $help );
prt(" -cmake[:opt[:opt...]] = Enable CMakeLists.txt ouput, to out;dir, or -o .\n");
show_cmake_help();
}
sub show_cmake_help {
prt(" Can be followed by a list of colon separated special cmake options.\n");
prt(" it;targ = Set special 'install' headers option, like it;include/plib for PLIB.\n");
prt(" lt;targ = Set special 'install' libraries option, like lt;sbin for a system utility.\n");
prt(" bt;targ = Set special 'install' binary option, perhaps like bt;bin/tg.\n");
prt(" out;targ = Set target root output directory.\n");
prt(" Other otions to follow as they are identified.\n");
}
# eof - vcproj05.pl