| #!/usr/bin/perl | |
| # | |
| # Copyright Statement: | |
| # -------------------- | |
| # This software is protected by Copyright and the information contained | |
| # herein is confidential. The software may not be copied and the information | |
| # contained herein may not be used or disclosed except with the written | |
| # permission of MediaTek Inc. (C) 2005 | |
| # | |
| # BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES | |
| # THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") | |
| # RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON | |
| # AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, | |
| # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF | |
| # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. | |
| # NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE | |
| # SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR | |
| # SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH | |
| # THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO | |
| # NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S | |
| # SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM. | |
| # | |
| # BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE | |
| # LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, | |
| # AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, | |
| # OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO | |
| # MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. | |
| # | |
| # THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE | |
| # WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF | |
| # LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND | |
| # RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER | |
| # THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC). | |
| # | |
| # | |
| #***************************************************************************** | |
| # | |
| # Filename: | |
| # --------- | |
| # objcheck.pl | |
| # | |
| # Description: | |
| # ------------ | |
| # this script is used to check run-time values, e.g. 'size of each element of union'. | |
| # | |
| # Auther: | |
| # ------- | |
| # Shinn Lin | |
| # | |
| # Note: | |
| # ----- | |
| # Support Status | |
| # 1. union/struct (o) | |
| # 2. multi-setting (o) | |
| # | |
| # Log: | |
| # ----- | |
| # 2008/02/22 Create. | |
| # | |
| #BEGIN { push @INC, "pcore/" , 'U:\\00MyPerlLib'} # add additional library path | |
| #package XXX; | |
| use strict; | |
| #****************************************************************************** | |
| # Global Data | |
| #****************************************************************************** | |
| my $g_settingFilename = "objcheck.txt"; | |
| my $g_logFile = "objcheck.log"; | |
| my $g_logCompileFile = "objcheck.compile.log"; | |
| my $g_htmlFile = "objcheck.html"; | |
| my $g_prjName = ''; | |
| my $g_mcuPath = "."; | |
| # remove temp file or not | |
| my $g_removeTempFile = 1; | |
| # also process disabled features or not | |
| my $g_alsoProcessDisabledFeatures = 1; | |
| my $g_compiler = 'armcc'; # default compiler | |
| my $g_viaOption = '--via'; # default 'via' option | |
| my $local_run = 1; # in local folder (1) or in mcu folder (0) | |
| my $checkMainFilename; | |
| my $separation = "***********************************************************************"; | |
| my $magicNumber = "26598088"; | |
| my $str_objcheck = "objcheck"; | |
| my $str_info = "info"; | |
| my $str_removeTmpFile = "removeTmpFile"; | |
| my $str_alsoProcessDisabledFeatures = "alsoProcessDisabledFeatures"; | |
| my $str_mcuPath = "mcuPath"; | |
| my $str_prjName = "prjName"; | |
| my $str_filename = "filename"; | |
| my $str_path = "path"; | |
| my $str_type = "type"; | |
| my $str_parsingInc = "parsingInc"; | |
| my $str_addModuleInc = "addModuleInc"; | |
| my $str_addIncPath = "addIncPath"; | |
| my $str_addIncFiles = "addIncFiles"; | |
| my $str_addLines = "addLines"; | |
| my $str_addPostLines = "addPostLines"; | |
| my $str_addFeaturesToWatch = "addFeaturesToWatch"; | |
| # tag name and in-tag/end-tag handler | |
| my %xmlTags = ( $str_objcheck => \&objcheck_tag_hdlr, | |
| $str_info => \&info_tag_hdlr, | |
| $str_addModuleInc => \&addModuleInc_tag_hdlr, | |
| $str_addIncPath => \&addIncPath_tag_hdlr, | |
| $str_addIncFiles => \&addIncFiles_tag_hdlr, | |
| $str_addLines => \&addLines_tag_hdlr, | |
| $str_addPostLines => \&addPostLines_tag_hdlr, | |
| $str_addFeaturesToWatch => \&addFeaturesToWatch_tag_hdlr); | |
| #****************************************************************************** | |
| # Export Function | |
| #****************************************************************************** | |
| #****************************************************************************** | |
| # Internal Data | |
| #****************************************************************************** | |
| my %settingData = (); | |
| #****************************************************************************** | |
| # Program Start | |
| #****************************************************************************** | |
| # get project name from input argument | |
| if (scalar(@ARGV) == 0) | |
| { | |
| my @usage = (); | |
| push @usage, "\nUsage 1:\n'objcheck.pl <project name> <compiler> <via option>'\n"; | |
| push @usage, "e.g. 'objcheck.pl DRAGONFLY_DEMO armcc --via'\n\n"; | |
| push @usage, "Usage 2: (in local directory)\n'objcheck.pl local <compiler> <via option>'\n"; | |
| die join('', @usage); | |
| } | |
| else | |
| { | |
| ($g_prjName, $g_compiler, $g_viaOption) = @ARGV; | |
| } | |
| if ($g_prjName !~ /^local$/i) | |
| { | |
| $g_settingFilename = "pcore\\tools\\".$g_settingFilename; | |
| $local_run = 0; | |
| } | |
| $g_logFile = "build\\$g_prjName\\log\\".$g_logFile if (!$local_run); | |
| system("del $g_logFile") if (-e "$g_logFile"); | |
| $g_logCompileFile = "build\\$g_prjName\\log\\".$g_logCompileFile if (!$local_run); | |
| system("del $g_logCompileFile") if (-e "$g_logCompileFile"); | |
| $g_htmlFile = "build\\$g_prjName\\log\\".$g_htmlFile if (!$local_run); | |
| system("del $g_htmlFile") if (-e "$g_htmlFile"); | |
| print "\nobjcheck: Start\n"; | |
| # write parameter | |
| open(hFile, ">>$g_logCompileFile") or die "can't open $g_logCompileFile"; | |
| print hFile "===========================================================\n"; | |
| print hFile "$g_prjName\n"; | |
| print hFile "$g_compiler\n"; | |
| print hFile "$g_viaOption\n"; | |
| print hFile "===========================================================\n"; | |
| close(hFile); | |
| # start processing | |
| &getSettings($g_settingFilename, \%settingData); | |
| print "objcheck: Log generated to $g_logFile\n"; | |
| &runMemLayout($g_htmlFile); | |
| print "objcheck: Html generated to $g_htmlFile\n"; | |
| print "objcheck: End\n\n"; | |
| exit 0; | |
| #****************************************************************************** | |
| # Internal Function | |
| #****************************************************************************** | |
| #****************************************************************************** | |
| # FUNCTION | |
| # startCheck | |
| # DESCRIPTION | |
| # start obj check | |
| # PARAMETERS | |
| # | |
| # RETURNS | |
| # none | |
| #****************************************************************************** | |
| sub startCheck() | |
| { | |
| my $settingData_href; | |
| ($settingData_href) = @_; | |
| my $targetFilepath = ${$settingData_href}{$str_path}; | |
| my $targetFilename = ${$settingData_href}{$str_filename}; | |
| my $parsingInc = ${$settingData_href}{$str_parsingInc}; | |
| my @fileData = (); | |
| my $type; | |
| my $retVal = 0; | |
| # list the modules which their *.inc will be added into include path | |
| my $includeMod = ${$settingData_href}{$str_addModuleInc}; # include *.inc | |
| # additional path for include files | |
| my $addIncPath = ${$settingData_href}{$str_addIncPath}; | |
| unshift @{${$settingData_href}{$str_addIncPath}}, $targetFilepath; | |
| # additional include files | |
| my $addIncFiles = ${$settingData_href}{$str_addIncFiles}; #("mmi_features.h"); | |
| # additional lines | |
| my $addLines = ${$settingData_href}{$str_addLines}; | |
| # additional features to watch | |
| my $addFeaturesToWatch = ${$settingData_href}{$str_addFeaturesToWatch}; | |
| print "objcheck: [$targetFilename] Begin\n"; | |
| while (($type = shift @{${$settingData_href}{$str_type}}) ne "") | |
| { | |
| my %featureList = (); | |
| my @unionInOrder = (); | |
| my @sortedAllFeatures = (); | |
| my @defFeatures = (); | |
| my @undefFeatures = (); | |
| my $allFeatureCount; | |
| my $defFeatureCount; | |
| my $undefFeatureCount; | |
| $checkMainFilename = "~".splitFilename($targetFilename, 0)."_check"; | |
| my $checkTmpMainFilename = "$checkMainFilename"."_tmp"; | |
| my $checkFile = "$g_mcuPath\\$targetFilepath\\$targetFilename"; | |
| # get all feature list | |
| if (!(-e $checkFile)) | |
| { | |
| print "objcheck: [Warning] $checkFile not exist!\n"; | |
| return; | |
| } | |
| open(hFile, "<$checkFile") or die "can't open $checkFile"; | |
| @fileData = <hFile>; | |
| close(hFile); | |
| print "objcheck: ($type) Begin\n"; | |
| &timeCheck(" --> ", ""); | |
| print "objcheck: --> Reading...\n"; | |
| if ($type eq 'macro') | |
| { | |
| # get macros | |
| getMacro(\@fileData, \%featureList); | |
| push @sortedAllFeatures, sort(keys(%featureList)); | |
| } | |
| elsif ($type eq 'obj') | |
| { | |
| # get union from target file | |
| my @targetUnionInOrder = (); | |
| getUnion(\@fileData, \@targetUnionInOrder) if ($parsingInc == 0); | |
| ##### | |
| # At this stage, we only need compile option (check member of union is turned on) | |
| # To speed up the -E and reading, try to modify array size to const | |
| ##### | |
| # gen shrinked target file | |
| my $shrinkTargetFilename = "~".splitFilename($targetFilename, 0)."_shrink.h"; | |
| open(hShrinkFile, ">$shrinkTargetFilename") or die "can't open $shrinkTargetFilename"; | |
| foreach my $line (@fileData) | |
| { | |
| if ($line =~ /([^\[]*)\[([^\]]*)\](\;.*)/) | |
| { | |
| print hShrinkFile $1 . "[1]" . $3 . "\n"; | |
| } | |
| else | |
| { | |
| print hShrinkFile "$line"; | |
| } | |
| } | |
| close(hShrinkFile); | |
| # gen pre-processed tmp file | |
| genCheckDotC($type . "_expand", "$checkTmpMainFilename.c", $shrinkTargetFilename, \@sortedAllFeatures, $settingData_href); | |
| processCheckDotC($checkTmpMainFilename, "-E", $settingData_href, $g_removeTempFile); | |
| $checkFile = "$checkTmpMainFilename.obj"; | |
| # remove shrinked target file | |
| if ($g_removeTempFile) | |
| { | |
| system("del $shrinkTargetFilename") if (-e "$shrinkTargetFilename"); | |
| } | |
| if (!(-e $checkFile)) | |
| { | |
| my $timeCost = &timeCheck(" --> ", ""); | |
| my $logTitle = "$targetFilename\t($type) (timeCost=$timeCost sec.)\n ($g_mcuPath\\$targetFilepath)"; | |
| genLogInfo($type, $g_logFile, $logTitle, "Skip due to compile error, check $g_logCompileFile"); | |
| print "objcheck: [Error] compile error! skip\n"; | |
| next; | |
| } | |
| # read pre-processed file | |
| open(hFile, "<$checkFile") or die "can't open $checkFile"; | |
| @fileData = <hFile>; | |
| close(hFile); | |
| # get union from pre-processed file (means it really exists) | |
| my %unionTmp = (); | |
| getUnion(\@fileData, \@unionInOrder, \%unionTmp); | |
| if ($parsingInc == 0) | |
| { | |
| foreach my $targetUnion (@targetUnionInOrder) | |
| { | |
| # if targetUnion really exists | |
| push @sortedAllFeatures, $targetUnion if (defined ${unionTmp}{$targetUnion}); | |
| } | |
| } | |
| else | |
| { | |
| push @sortedAllFeatures, @unionInOrder if (scalar(@unionInOrder)); | |
| } | |
| } | |
| elsif ($type eq 'obj2') | |
| { | |
| ##### | |
| # no compile option, no need to pre-process. | |
| ##### | |
| # get union from target file | |
| my @targetUnionInOrder = (); | |
| getUnion(\@fileData, \@targetUnionInOrder); | |
| foreach my $targetUnion (@targetUnionInOrder) | |
| { | |
| push @sortedAllFeatures, $targetUnion; | |
| } | |
| } | |
| else | |
| { | |
| print "[objcheck.pl][Warning] $type not supported!\n"; | |
| next; | |
| } | |
| # add additional features to watch | |
| push @sortedAllFeatures, @{$addFeaturesToWatch} if (defined $addFeaturesToWatch); | |
| $allFeatureCount = @sortedAllFeatures; | |
| # generate XXX_check.c | |
| print "objcheck: --> Generating...\n"; | |
| genCheckDotC($type, "$checkMainFilename.c", $targetFilename, \@sortedAllFeatures, $settingData_href); | |
| # validate features | |
| print "objcheck: --> Compiling...\n"; | |
| my $compileOption = "-c"; | |
| $compileOption = "-E" if ($type eq 'macro'); | |
| processCheckDotC($checkMainFilename, $compileOption, $settingData_href, $g_removeTempFile); | |
| if (!(-e "$checkMainFilename.obj")) | |
| { | |
| my $timeCost = &timeCheck(" --> ", ""); | |
| my $logTitle = "$targetFilename\t($type) (timeCost=$timeCost sec.)\n ($g_mcuPath\\$targetFilepath)"; | |
| genLogInfo($type, $g_logFile, $logTitle, "Skip due to compile error, check $g_logCompileFile"); | |
| print "objcheck: [Error] compile error! skip\n"; | |
| next; | |
| } | |
| # check def/undef features in pre-processed file | |
| print "objcheck: --> Checking...\n"; | |
| checkFeatures($type, "$checkMainFilename.obj", \%featureList, \@sortedAllFeatures, \@defFeatures, \@undefFeatures); | |
| $defFeatureCount = @defFeatures; | |
| $undefFeatureCount = @undefFeatures; | |
| if ($g_removeTempFile) | |
| { | |
| system("del $checkMainFilename.c") if (-e "$checkMainFilename.c"); | |
| system("del $checkMainFilename.obj") if (-e "$checkMainFilename.obj"); | |
| system("del $checkTmpMainFilename.c") if (-e "$checkTmpMainFilename.c"); | |
| system("del $checkTmpMainFilename.obj") if (-e "$checkTmpMainFilename.obj"); | |
| } | |
| # output results | |
| my $timeCost = &timeCheck(" --> ", ""); | |
| my $logTitle = "$targetFilename\t($type) (timeCost=$timeCost sec.)\n ($g_mcuPath\\$targetFilepath)"; | |
| genLog($type, $g_logFile, $logTitle, \@defFeatures, \%featureList, | |
| \@undefFeatures, \@sortedAllFeatures); | |
| print "objcheck: --> Log generated\n"; | |
| # verify result | |
| if ($allFeatureCount != ($defFeatureCount+$undefFeatureCount)) | |
| { | |
| print "[Error] all feature count($allFeatureCount) != defined count($defFeatureCount) + undef count($undefFeatureCount)\n"; | |
| $retVal = 1; | |
| } | |
| else | |
| { | |
| print "objcheck: Done! ([$targetFilename] [$type] defined count = $defFeatureCount)\n"; | |
| } | |
| print "objcheck: ($type) End\n"; | |
| } | |
| print "objcheck: [$targetFilename] End\nobjcheck:\n"; | |
| return $retVal; | |
| } | |
| #****************************************************************************** | |
| # FUNCTION | |
| # genCheckDotC | |
| # DESCRIPTION | |
| # xxx | |
| # PARAMETERS | |
| # xxx | |
| # RETURNS | |
| # none | |
| #****************************************************************************** | |
| sub genCheckDotC() | |
| { | |
| my $type; | |
| my $filename; | |
| my $targetFilename; | |
| my @fileData; | |
| my $pUserData; # reference to data array | |
| my $settingData_href; | |
| ($type, $filename, $targetFilename, $pUserData, $settingData_href) = @_; | |
| open(hFile, ">$filename") or die "can't open $filename"; | |
| print hFile "// addLines\n"; | |
| foreach my $line (@{${$settingData_href}{$str_addLines}}) | |
| { | |
| print hFile "$line\n"; | |
| } | |
| print hFile "// addLines by type\n"; | |
| foreach my $line (@{${$settingData_href}{$str_addLines . "_" . $type}}) | |
| { | |
| print hFile "$line\n"; | |
| } | |
| # write header part | |
| print hFile "// addIncFiles\n"; | |
| foreach my $inc (@{${$settingData_href}{$str_addIncFiles}}) | |
| { | |
| print hFile "#include \"$inc\"\n"; | |
| } | |
| print hFile "#include \"$targetFilename\"\n\n"; | |
| foreach my $data (@{${$settingData_href}{$str_addPostLines}}) | |
| { | |
| print hFile $data; | |
| } | |
| # write start tag | |
| print hFile "\nvoid * feature_check[] = {\n"; | |
| if ($type eq 'macro') | |
| { | |
| foreach my $data (@$pUserData) | |
| { | |
| print hFile "(void *)$data,\n"; | |
| } | |
| # write end tag | |
| print hFile "(void *)\"END FEATURE LIST\"\n"; | |
| } | |
| elsif (($type eq 'obj') || ($type eq 'obj2')) | |
| { | |
| print hFile "(void *)0x$magicNumber,\n"; | |
| foreach my $data (@$pUserData) | |
| { | |
| print hFile "(void *)($data),\n"; | |
| } | |
| # write end tag | |
| print hFile "(void *)0x$magicNumber\n"; | |
| } | |
| else | |
| { | |
| print hFile "0\n"; | |
| } | |
| print hFile "};\n"; | |
| close(hFile); | |
| } | |
| #****************************************************************************** | |
| # FUNCTION | |
| # processCheckDotC | |
| # DESCRIPTION | |
| # xxx | |
| # PARAMETERS | |
| # xxx | |
| # RETURNS | |
| # none | |
| #****************************************************************************** | |
| sub processCheckDotC() | |
| { | |
| my $mainFilename; | |
| my $compileOptions; | |
| my $settingData_href; | |
| my $removeTmpFile; | |
| ($mainFilename, $compileOptions, $settingData_href, $removeTmpFile) = @_; | |
| my $includeMod = ${$settingData_href}{$str_addModuleInc}; # include *.inc | |
| my $addIncPath = ${$settingData_href}{$str_addIncPath}; | |
| my $infoFilename = "$g_mcuPath\\build\\$g_prjName\\log\\info.log"; | |
| my $batFilename = "~makeCheck.bat"; | |
| my $defTmpFilename = "$mainFilename.def"; | |
| my $incTmpFilename = "$mainFilename.inc"; | |
| my @fileData; | |
| my $inSection = 0; | |
| my $incPaths = ""; | |
| my $count = 0; | |
| my $commonOptions = ""; | |
| # read common options and common include path from info.log | |
| open(hFile, "<$infoFilename") or die "can't open $infoFilename"; | |
| @fileData = <hFile>; | |
| close(hFile); | |
| foreach my $line (@fileData) | |
| { | |
| if ($line =~ /\[ COMMON OPTION \]/) | |
| { | |
| $inSection = 1; | |
| next; | |
| } | |
| elsif ($line =~ /\[ COMMON INCLUDE PATH \]/) | |
| { | |
| $inSection = 2; | |
| next; | |
| } | |
| if ($line =~ /(^[^\[][^\s]*)/) | |
| { | |
| if ($inSection == 1) | |
| { | |
| #print "$1\n"; | |
| $commonOptions = "$commonOptions\n-D$1"; | |
| } | |
| elsif ($inSection == 2) | |
| { | |
| my $inc = "$1"; | |
| if ($inc !~ /:/) | |
| { | |
| $inc = "$g_mcuPath\\$inc"; | |
| } | |
| #print "$inc\n"; | |
| $incPaths = "$incPaths\n-I$inc"; | |
| } | |
| } | |
| else | |
| { | |
| $inSection = 0; | |
| } | |
| } | |
| # read inc from *.inc | |
| foreach my $myMod (@{$includeMod}) | |
| { | |
| my @incFiles = (); | |
| if (&getFileList("$g_mcuPath\\build\\$g_prjName\\module\\$myMod\\*.inc", 1, \@incFiles) > 0) | |
| { | |
| foreach my $incFilename (@incFiles) | |
| { | |
| open(hFile, "<$incFilename") or die "can't open $incFilename"; | |
| @fileData = <hFile>; | |
| close(hFile); | |
| foreach my $line (@fileData) | |
| { | |
| if ($line =~ /(^[^\s]+)([\s]*$)/) | |
| { | |
| $incPaths = "$incPaths\n-I$g_mcuPath\\$1"; | |
| } | |
| } | |
| } | |
| } | |
| else | |
| { | |
| print "[Warning] can't find *.inc for $myMod\n"; | |
| } | |
| } | |
| # additional inc path | |
| foreach my $inc (@{$addIncPath}) | |
| { | |
| $incPaths = "$incPaths\n-I$g_mcuPath\\$inc"; | |
| } | |
| # read macro from *.def | |
| foreach my $myMod (@{$includeMod}) | |
| { | |
| my @defFiles = (); | |
| if (&getFileList("$g_mcuPath\\build\\$g_prjName\\module\\$myMod\\*.def", 1, \@defFiles) > 0) | |
| { | |
| foreach my $defFilename (@defFiles) | |
| { | |
| open(hFile, "<$defFilename") or die "can't open $defFilename"; | |
| @fileData = <hFile>; | |
| close(hFile); | |
| foreach my $line (@fileData) | |
| { | |
| if ($line =~ /(^[^\s]+)([\s]*$)/) | |
| { | |
| $commonOptions = "$commonOptions\n-D$1"; | |
| } | |
| } | |
| } | |
| } | |
| else | |
| { | |
| print "[Warning] can't find *.def for $myMod\n"; | |
| } | |
| } | |
| #print "$commonOptions\n"; | |
| open(hFile, ">$defTmpFilename") or die "can't open $defTmpFilename"; | |
| print hFile "$commonOptions\n"; | |
| close(hFile); | |
| #print "$incPaths\n"; | |
| open(hFile, ">$incTmpFilename") or die "can't open $incTmpFilename"; | |
| print hFile "$incPaths\n"; | |
| close(hFile); | |
| # prepare for compiler output | |
| open(hFile, ">>$g_logCompileFile") or die "can't open $g_logCompileFile"; | |
| print hFile "===========================================================Begin\n"; | |
| print hFile "[Processing...](".${$settingData_href}{$str_filename}.")\n"; | |
| close(hFile); | |
| open(hFile, ">$batFilename") or die "can't open $batFilename\n"; | |
| print hFile "\@echo off\n"; | |
| print hFile "$g_compiler $mainFilename.c -o $mainFilename.obj $compileOptions $g_viaOption $defTmpFilename $g_viaOption $incTmpFilename 2>>$g_logCompileFile\n"; | |
| print hFile "\@echo on\n"; | |
| close(hFile); | |
| #&timeCheck(); | |
| system("$batFilename"); | |
| #&timeCheck(); | |
| # end compiler output | |
| open(hFile, ">>$g_logCompileFile") or die "can't open $g_logCompileFile"; | |
| print hFile "=============================================================End\n\n"; | |
| close(hFile); | |
| # remove empty lines for -E | |
| if ($compileOptions =~ /-e([\s]+|$)/i) | |
| { | |
| open(hFile, "<$mainFilename.obj") or die "can't open $mainFilename.obj\n"; | |
| my $tmp = join('',<hFile>); | |
| close(hFile); | |
| $tmp =~ s/\n([\s]+)\n/\n\n/g; # reduce multi-CR/LF | |
| open(hFile, ">$mainFilename.obj") or die "can't open $mainFilename.obj for write\n"; | |
| print hFile $tmp; | |
| close(hFile); | |
| } | |
| if ($removeTmpFile) | |
| { | |
| system("del $batFilename"); | |
| system("del $defTmpFilename"); | |
| system("del $incTmpFilename"); | |
| } | |
| } | |
| #****************************************************************************** | |
| # FUNCTION | |
| # checkFeatures | |
| # DESCRIPTION | |
| # xxx | |
| # PARAMETERS | |
| # xxx | |
| # RETURNS | |
| # none | |
| #****************************************************************************** | |
| sub checkFeatures() | |
| { | |
| my $type; # 'obj' or 'macro' | |
| my $filename; # preprocessed object filename | |
| my $pFeatureList; # reference to hash of feature list | |
| my $pSortedAllFeatures; # reference to array of sorted all features | |
| my $pDefFeatures; # reference to array of defined features | |
| my $pUndefFeatures; # reference to array of undefined features | |
| my @fileData; | |
| my $isFeature = 0; | |
| my $featureIndex; | |
| my $defFeature; | |
| ($type, $filename, $pFeatureList, $pSortedAllFeatures, | |
| $pDefFeatures, $pUndefFeatures) = @_; | |
| if ($type eq 'macro') | |
| { | |
| open(hFile, "<$filename") or die "can't open $filename"; | |
| @fileData = <hFile>; | |
| close(hFile); | |
| open(hFile, ">>$g_logCompileFile") or die "can't open $g_logCompileFile"; | |
| print hFile "===========================================================Begin\n"; | |
| print hFile "[checkFeatures](".$filename.":".$type.")\n"; | |
| foreach my $line (@fileData) | |
| { | |
| if ($isFeature) | |
| { | |
| if ($line =~ /(^\(void \*\)[\s]*)(.*?)([\s]*,$)/) | |
| { | |
| $defFeature = $$pSortedAllFeatures[$featureIndex]; | |
| if ($2 eq $defFeature) | |
| { | |
| # undefined symbols ("_XXX_" shows) | |
| push @$pUndefFeatures, $2; | |
| # remove it from feature list | |
| delete $$pFeatureList{$2}; | |
| #print "[U] $2\n"; | |
| } | |
| else | |
| { | |
| # process defined symbols | |
| push @$pDefFeatures, $defFeature; | |
| # update value of feature list | |
| $$pFeatureList{$defFeature} = $2; | |
| #print "[D] $defFeature = $2\n"; | |
| } | |
| } | |
| # end of feature list | |
| elsif ($line =~ /"END FEATURE LIST"}/) | |
| { | |
| $isFeature = 0; | |
| } | |
| elsif ($line !~ /^[\s]*$/) | |
| { | |
| print hFile "[Not Processed] \"$line\"\n"; | |
| } | |
| #print "[$featureIndex] $$pSortedAllFeatures[$featureIndex] $line\n"; | |
| $featureIndex++; | |
| } | |
| # check if begining of feature list | |
| if ($line =~ /feature_check\[\]/) | |
| { | |
| $isFeature = 1; | |
| $featureIndex = 0; | |
| } | |
| } | |
| print hFile "=============================================================End\n\n"; | |
| close(hFile); | |
| } | |
| else # 'obj' | |
| { | |
| open(hFile, "<$filename") or die "can't open $filename"; | |
| binmode(hFile); | |
| my $binData; | |
| my $status = ''; | |
| while (read(hFile, $binData, 4)) | |
| { | |
| if ($status eq 'start') | |
| { | |
| my $value = ascii2dec_le($binData); | |
| if ($value == hex($magicNumber)) | |
| { | |
| #print "END\n"; | |
| last; | |
| } | |
| $defFeature = $$pSortedAllFeatures[$featureIndex]; | |
| $featureIndex++; | |
| push @$pDefFeatures, $defFeature; | |
| # update value of feature list | |
| $$pFeatureList{$defFeature} = $value; | |
| #print "$defFeature = $value\n"; | |
| } | |
| # begin of array | |
| if (ascii2dec_le($binData) == hex($magicNumber)) | |
| { | |
| $status = 'start'; | |
| $featureIndex = 0; | |
| #print "Start\n"; | |
| } | |
| } | |
| close(hFile); | |
| } | |
| } | |
| #****************************************************************************** | |
| # FUNCTION | |
| # getSettings | |
| # DESCRIPTION | |
| # get settings from file | |
| # PARAMETERS | |
| # $filename [IN] - setting file pathname | |
| # $targetHash_ref [IN] - reference to target hash | |
| # RETURNS | |
| # none | |
| #****************************************************************************** | |
| sub getSettings() | |
| { | |
| my $filename; | |
| my $settingData_href; | |
| ($filename, $settingData_href) = @_; | |
| my @fileData; | |
| #my %settingData = (); | |
| open(hFile, "<$filename") or die "can't open $filename\n"; | |
| @fileData = <hFile>; | |
| close(hFile); | |
| # parse setting file | |
| parseXmlLineData(\@fileData, \%xmlTags, $settingData_href); | |
| } | |
| sub objcheck_tag_hdlr() | |
| { | |
| my $taginfo_aref; | |
| my $para_href; | |
| ($taginfo_aref, $para_href) = @_; | |
| #print "tag hdlr [0]\n"; | |
| &startCheck($para_href); | |
| %{$para_href} = (); # reset setting data | |
| } | |
| sub info_tag_hdlr() | |
| { | |
| my $taginfo_aref; | |
| my $para_href; | |
| ($taginfo_aref, $para_href) = @_; | |
| #print "tag hdlr [1]\n"; | |
| while (my ($attr, $value) = each(%{$$taginfo_aref[0]})) | |
| { | |
| #print " attr [$attr] = $value\n"; | |
| ${$para_href}{$str_filename} = $value if ($attr eq $str_filename); | |
| ${$para_href}{$str_path} = $value if ($attr eq $str_path); | |
| ${$para_href}{$str_parsingInc} = $value if ($attr eq $str_parsingInc); | |
| if ($attr eq $str_type) | |
| { | |
| push @{${$para_href}{$str_type}}, split(',', $value); | |
| } | |
| $g_mcuPath = $value if (($attr eq $str_mcuPath) && ($str_mcuPath ne "")); | |
| $g_prjName = $value if (($attr eq $str_prjName) && ($str_prjName ne "")); | |
| $g_removeTempFile = $value if ($attr eq $str_removeTmpFile); | |
| $g_alsoProcessDisabledFeatures = $value if ($attr eq $str_alsoProcessDisabledFeatures); | |
| } | |
| } | |
| sub addModuleInc_tag_hdlr() | |
| { | |
| my $taginfo_aref; | |
| my $para_href; | |
| ($taginfo_aref, $para_href) = @_; | |
| #print "tag hdlr [2]\n"; | |
| push @{${$para_href}{$str_addModuleInc}}, trim($_) foreach (@{$$taginfo_aref[1]}); | |
| #print join(' ',@{${$para_href}{$str_addModuleInc}})."\n"; | |
| } | |
| sub addIncPath_tag_hdlr() | |
| { | |
| my $taginfo_aref; | |
| my $para_href; | |
| ($taginfo_aref, $para_href) = @_; | |
| #print "tag hdlr [3]\n"; | |
| push @{${$para_href}{$str_addIncPath}}, trim($_) foreach (@{$$taginfo_aref[1]}); | |
| #print join(' ',@{${$para_href}{$str_addIncPath}})."\n"; | |
| } | |
| sub addIncFiles_tag_hdlr() | |
| { | |
| my $taginfo_aref; | |
| my $para_href; | |
| ($taginfo_aref, $para_href) = @_; | |
| #print "tag hdlr [4]\n"; | |
| push @{${$para_href}{$str_addIncFiles}}, trim($_) foreach (@{$$taginfo_aref[1]}); | |
| #print join(', ',@{${$para_href}{$str_addIncFiles}})."\n"; | |
| } | |
| sub addLines_tag_hdlr() | |
| { | |
| my $taginfo_aref; | |
| my $para_href; | |
| ($taginfo_aref, $para_href) = @_; | |
| my $type = undef; | |
| # attribute | |
| while (my ($attr, $value) = each(%{$$taginfo_aref[0]})) | |
| { | |
| $type = $value if (($attr eq $str_type) && ($str_type ne "")); | |
| } | |
| #print "tag hdlr [5]\n"; | |
| if (!defined($type)) | |
| { | |
| push @{${$para_href}{$str_addLines}}, trim($_) foreach (@{$$taginfo_aref[1]}); | |
| } | |
| else | |
| { | |
| push @{${$para_href}{$str_addLines . "_" . $type}}, trim($_) foreach (@{$$taginfo_aref[1]}); | |
| } | |
| #print join(' ',@{${$para_href}{$str_addLines}})."\n"; | |
| } | |
| sub addPostLines_tag_hdlr() | |
| { | |
| my $taginfo_aref; | |
| my $para_href; | |
| ($taginfo_aref, $para_href) = @_; | |
| push @{${$para_href}{$str_addPostLines}}, trim($_)."\n" foreach (@{$$taginfo_aref[1]}); | |
| } | |
| sub addFeaturesToWatch_tag_hdlr() | |
| { | |
| my $taginfo_aref; | |
| my $para_href; | |
| ($taginfo_aref, $para_href) = @_; | |
| #print "tag hdlr [6]\n"; | |
| push @{${$para_href}{$str_addFeaturesToWatch}}, trim($_) foreach (@{$$taginfo_aref[1]}); | |
| #print join(' ',@{${$para_href}{$str_addFeaturesToWatch}})."\n"; | |
| } | |
| #****************************************************************************** | |
| # FUNCTION | |
| # getUnion | |
| # DESCRIPTION | |
| # get union from file | |
| # PARAMETERS | |
| # | |
| # RETURNS | |
| # none | |
| #****************************************************************************** | |
| sub getUnion() | |
| { | |
| my $srcDataRef; | |
| my $dataARef; | |
| my $dataHRef; | |
| ($srcDataRef, $dataARef, $dataHRef) = @_; | |
| # remove comments | |
| my $tmpStr = join('', @{$srcDataRef}); | |
| $tmpStr =~ s/(\/\*.*?\*\/)//gs; # remove all C comments | |
| $tmpStr =~ s/(\/\/.*)//g; # remove all C++ comments | |
| # find union | |
| while ($tmpStr =~ /[\s]+typedef[\s]+(union|struct)[\s]*\{([^\{\}]+?)\}[\s]*([\*]*)[\s]*([\w]+)[\s]*\;/sg) | |
| { | |
| #my $typedef = $1; | |
| my $type = $1; | |
| my $data = $2; | |
| my $ptrStr = $3; | |
| my $unionName = $4; | |
| my $str = ""; | |
| #print "====>>> [$unionName][$typedef] [$type] [$ptrStr]\n"; | |
| $str = "sizeof($unionName)"; | |
| push @{$dataARef}, $str if (defined $dataARef); | |
| ${$dataHRef}{$str} = "" if (defined $dataHRef); | |
| my @dataArray = (); | |
| @dataArray = split(';', $data); | |
| foreach my $line (@dataArray) | |
| { | |
| # [^:] => exclude bit-field | |
| if (($line =~ /[^:]+[\s]+[\*]*([\w]+)[\s]*$/) || | |
| ($line =~ /[^:]+[\s]+[\*]*([\w]+)[\s]*\[[^\]]+\][\s]*$/)) | |
| { | |
| if ($type eq 'union' || $type eq 'struct') | |
| { | |
| $str = "sizeof(($ptrStr($unionName *)0)->$1)"; | |
| push @{$dataARef}, $str if (defined $dataARef); | |
| ${$dataHRef}{$str} = "" if (defined $dataHRef); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| sub getMacro() | |
| { | |
| my $srcDataRef; | |
| my $dataHRef; | |
| ($srcDataRef, $dataHRef) = @_; | |
| foreach my $line (@{$srcDataRef}) | |
| { | |
| my $feature = ""; | |
| # also process marked "//" features or not | |
| if ($g_alsoProcessDisabledFeatures) | |
| { | |
| if ($line =~ /^([\s]*([\/]{2,})?[\s]*)(#define[\s]+)([\w_]+)([\s]+)([\w\(\)]+)/) | |
| { | |
| $feature = $4; | |
| } | |
| } | |
| else | |
| { | |
| if ($line =~ /^([\s]*)(#define[\s]+)([\w_]+)([\s]+)([\w\(\)]+)/) | |
| { | |
| $feature = $3; | |
| } | |
| } | |
| if ($feature ne "") | |
| { | |
| ${$dataHRef}{$feature} = ""; | |
| } | |
| } | |
| } | |
| #****************************************************************************** | |
| # FUNCTION | |
| # parseXmlLineData | |
| # DESCRIPTION | |
| # parse XML data lines (usage ref. ffcheck_any.pl) | |
| # PARAMETERS | |
| # $lineData_aref - ref. to array of line data | |
| # $interestXmlTags_aref - ref. to hash of interested xml tags | |
| # $taginfo_href - reference to tag info hash {tag => [0] {attr => value}} | |
| # [1] [] data lines | |
| # RETURNS | |
| # none | |
| #****************************************************************************** | |
| sub parseXmlLineData() | |
| { | |
| my $lineData_aref; # ref. to xml line data | |
| my $xmlTags_href; # ref. to interested xml tags | |
| my $para_href; # ref. to user parameter | |
| ($lineData_aref, $xmlTags_href, $para_href) = @_; | |
| my $inXmlTag = 0; | |
| my $currTag = ""; | |
| my @tagStack = (); | |
| my %taginfo; # parsed tag info | |
| # {tag => [0] {attr => value}} | |
| # [1] [] data lines | |
| my %attrInfo = (); | |
| foreach my $line (@$lineData_aref) | |
| { | |
| %taginfo = (); | |
| if (($line =~ /(^[ \t]*\#)|(^[\s]*$)/) && ($inXmlTag == 0)) | |
| { | |
| # ignore comments or empty line, except in Xml tag processing | |
| } | |
| elsif ($line =~ /(<)([^>]+)(>)/) | |
| { | |
| my $tagData = $2; | |
| my $newTag; | |
| %attrInfo = (); | |
| ($inXmlTag, $newTag) = processTagInt($tagData, \%taginfo); | |
| #print "ret val = $inXmlTag new[$newTag] curr[$currTag]\n"; | |
| #print "${$xmlTags_href}{$newTag}\n" if (exists ${$xmlTags_href}{$newTag}); | |
| %attrInfo = %{$taginfo{$newTag}[0]} if (defined($taginfo{$newTag}[0])); | |
| if ($inXmlTag == 0) | |
| { | |
| if (exists ${$xmlTags_href}{$newTag}) | |
| { | |
| # if tag found and hdlr exists, execute the hdlr after whole tag processed | |
| ${$xmlTags_href}{$newTag}($taginfo{$newTag}, $para_href) if (${$xmlTags_href}{$newTag} != 0); | |
| } | |
| pop @tagStack if ($newTag eq $currTag); | |
| } | |
| # update tag for in-tag process | |
| elsif ($newTag ne $currTag) # && ($inXmlTag == 1) | |
| { | |
| push @tagStack, $currTag if ($currTag ne ""); | |
| $currTag = $newTag; | |
| } | |
| } | |
| elsif ($line =~ /([^\n]+)(\n$)/) | |
| { | |
| if ($inXmlTag == 1) | |
| { | |
| $line =~ s/(^\s*)|(\s*$)//g; | |
| push @{$taginfo{$currTag}[1]}, $line if ($line ne ""); | |
| %{$taginfo{$currTag}[0]} = %attrInfo; | |
| if (exists ${$xmlTags_href}{$currTag}) | |
| { | |
| # if tag found and hdlr exists, execute the hdlr after whole tag processed | |
| ${$xmlTags_href}{$currTag}($taginfo{$currTag}, $para_href); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| #****************************************************************************** | |
| # FUNCTION | |
| # processTag | |
| # DESCRIPTION | |
| # process tag | |
| # PARAMETERS | |
| # para 1 - tag to process | |
| # para 2 - reference to attribute hash {tag => {attr => value}} | |
| # RETURNS | |
| # success (tag name) or not ("") | |
| #****************************************************************************** | |
| sub processTagInt() | |
| { | |
| my $tagToProcess; # tag to process | |
| my $result_href; # reference to result hash | |
| ($tagToProcess, $result_href) = @_; | |
| my $tagName = ""; | |
| my $inTag = 0; | |
| $tagToProcess =~ s/(^[\s]*)|([\s]*$)//g; | |
| if ($tagToProcess =~ /^([\w_]+)$/i) | |
| { | |
| # start of tag | |
| $tagName = $1; | |
| $inTag = 1; | |
| } | |
| elsif ($tagToProcess =~ /^\/[ \t]*([\w_]+)$/i) | |
| { | |
| # end of tag | |
| $tagName = $1; | |
| } | |
| elsif ($tagToProcess =~ /(^[\w_]+)[ \t]+(([\w_]+[ \t]*=[ \t]*([\"\'])[^\4]+\4[ \t]*)+)(\/?$)/i) | |
| { | |
| #print "$tagToProcess\n"; | |
| my @attrAll = split(' ',$2); | |
| $tagName = $1; | |
| # if tag ends with '/' | |
| $inTag = 1 if ($5 ne '/'); | |
| # parse each attr | |
| foreach my $attr (@attrAll) | |
| { | |
| #print "[$attr]\n"; | |
| if ($attr =~ /([\w_]+)[ \t]*=[ \t]*([\"\'])([^\2]+)\2/i) | |
| { | |
| ${$result_href}{$tagName}[0]{$1} = $3; | |
| #print "[$tagName] [$1] [$3]\n"; | |
| } | |
| } | |
| } | |
| else | |
| { | |
| #print "[$tagToProcess] not processed\n"; | |
| } | |
| return ($inTag, $tagName); | |
| } | |
| sub ascii2dec_le() | |
| { | |
| my $input; | |
| ($input) = @_; | |
| my $output = ord(substr($input, 3, 1))*256*256*256+ | |
| ord(substr($input, 2, 1))*256*256+ | |
| ord(substr($input, 1, 1))*256+ | |
| ord(substr($input, 0, 1)); | |
| #print "$input = $output"; | |
| } | |
| #****************************************************************************** | |
| # FUNCTION | |
| # splitFilename | |
| # DESCRIPTION | |
| # xxx | |
| # PARAMETERS | |
| # $filename [IN] - filename | |
| # $refSubFilename [OUT] - reference to sub filename, may be NULL | |
| # RETURNS | |
| # main filename | |
| #****************************************************************************** | |
| sub splitFilename() | |
| { | |
| my $filename; | |
| my $refSubFilename = ""; | |
| my $mainFilename = ""; | |
| ($filename, $refSubFilename) = @_; | |
| if ($filename =~ /([^\s]*)(\.)([^\.]*$)/) | |
| { | |
| #print "$filename [$1][$3]\n"; | |
| $mainFilename = "$1"; | |
| if ($refSubFilename != 0) | |
| { | |
| $$refSubFilename = "$3"; | |
| } | |
| } | |
| return $mainFilename; | |
| } | |
| #****************************************************************************** | |
| # FUNCTION | |
| # getFileList | |
| # DESCRIPTION | |
| # get file/path list for given search string | |
| # PARAMETERS | |
| # xxx | |
| # RETURNS | |
| # xxx | |
| #****************************************************************************** | |
| sub getFileList() | |
| { | |
| my $rootDir; | |
| my $incSubDir; # include sub dir (1) or not (0) | |
| my $fileList_ref; | |
| ($rootDir, $incSubDir, $fileList_ref) = @_; | |
| my @fileData = (); | |
| # get file list | |
| my $tmpFilename = "~tmpFile.lst"; | |
| my $dirStr = "$rootDir /b"; | |
| $dirStr .= " /s" if ($incSubDir); | |
| system("dir ".$dirStr." > $tmpFilename"); | |
| open(hFile, "<$tmpFilename") or die "[ERROR] can't open $tmpFilename\n"; | |
| @fileData = <hFile>; | |
| close(hFile); | |
| system("del $tmpFilename") if ($g_removeTempFile); | |
| foreach my $line (@fileData) | |
| { | |
| my $name = $line; | |
| push @{$fileList_ref}, $name if ($name !~ /^[\s]*$/); | |
| #print "$name"; | |
| } | |
| return scalar(@{$fileList_ref}); | |
| } | |
| #****************************************************************************** | |
| # FUNCTION | |
| # genLog | |
| # DESCRIPTION | |
| # xxx | |
| # PARAMETERS | |
| # $filename [IN] - log file pathname | |
| # RETURNS | |
| # none | |
| #****************************************************************************** | |
| sub genLog() | |
| { | |
| my $type; | |
| my $logFilePathname; | |
| my $logTitle; | |
| my $defFeatures_aref; | |
| my $featureData_href; | |
| my $undefFeatures_aref; | |
| my $sortedAllFeatures_aref; | |
| ($type, $logFilePathname, $logTitle, $defFeatures_aref, $featureData_href, | |
| $undefFeatures_aref, $sortedAllFeatures_aref) = @_; | |
| my $col1LenMax; | |
| my $col2LenMax; | |
| my $allFeatureCount; | |
| my $defFeatureCount; | |
| my $undefFeatureCount; | |
| # append file | |
| open(hLogFile, ">>$logFilePathname") or die "can't open $logFilePathname"; | |
| $allFeatureCount = @$sortedAllFeatures_aref; | |
| $defFeatureCount = @$defFeatures_aref; | |
| $undefFeatureCount = @$undefFeatures_aref; | |
| # title | |
| print hLogFile "\n$separation\n $logTitle\n$separation\n"; | |
| # result: Defined Features | |
| print hLogFile "\n$separation\n[Defined Values ($defFeatureCount/$allFeatureCount)]\n$separation\n\n"; | |
| if ($type eq 'macro') | |
| { | |
| $col1LenMax = 0; | |
| $col2LenMax = 0; | |
| foreach my $feature (@$sortedAllFeatures_aref) | |
| { | |
| # get max. len of feature name | |
| $col1LenMax = length($feature) if (length($feature)>$col1LenMax); | |
| # get max. len of feature value | |
| $col2LenMax = length(${$featureData_href}{$feature}) if (length(${$featureData_href}{$feature})>$col2LenMax); | |
| } | |
| foreach my $feature (@$defFeatures_aref) | |
| { | |
| print hLogFile sprintf("[D] %-*s%s\n", $col1LenMax+8, | |
| $feature, ${$featureData_href}{$feature}); | |
| } | |
| } | |
| else | |
| { | |
| my %nameHash = (); | |
| my %dataHash = (); | |
| # prepare data | |
| $col1LenMax = 0; | |
| $col2LenMax = 0; | |
| foreach my $data (@$defFeatures_aref) | |
| { | |
| my $name = ""; | |
| my $field = ""; | |
| if ($data =~ /sizeof\((\w+)\)/) | |
| { | |
| $name = $1; | |
| $nameHash{$name} = ${$featureData_href}{$data}; | |
| } | |
| elsif ($data =~ /sizeof\(\(\((\w+) \*\)0\)->(\w+)\)/) | |
| { | |
| $name = $1; | |
| $field = $2; | |
| $dataHash{$name}{$field} = ${$featureData_href}{$data}; | |
| # get max. len of feature name | |
| my $nameField = $name."->".$field; | |
| my $value = ${$featureData_href}{$data}; | |
| $col1LenMax = length($nameField) if (length($nameField)>$col1LenMax); | |
| # get max. len of feature value | |
| $col2LenMax = length($value) if (length($value)>$col2LenMax); | |
| } | |
| } | |
| foreach my $name (sort keys(%nameHash)) | |
| { | |
| print hLogFile sprintf("[D] %-*s%*s\n", $col1LenMax+8, | |
| $name, $col2LenMax+2, $nameHash{$name}); | |
| foreach my $field (sort {sortByValueDescending(\%{$dataHash{$name}})} keys(%{$dataHash{$name}})) | |
| { | |
| print hLogFile sprintf("[D] %-*s%*s\n", $col1LenMax+8, | |
| $name."->".$field, $col2LenMax+2, $dataHash{$name}{$field}); | |
| } | |
| } | |
| } | |
| print hLogFile "\n\n"; | |
| close(hLogFile); | |
| } | |
| sub genLogInfo() | |
| { | |
| my $type; | |
| my $logFilePathname; | |
| my $logTitle; | |
| my $logText; | |
| ($type, $logFilePathname, $logTitle, $logText) = @_; | |
| # append file | |
| open(hLogFile, ">>$logFilePathname") or die "can't open $logFilePathname"; | |
| # title | |
| print hLogFile "\n$separation\n $logTitle\n$separation\n"; | |
| # text | |
| print hLogFile $logText."\n"; | |
| print hLogFile "\n\n"; | |
| close(hLogFile); | |
| } | |
| sub sortByValueDescending | |
| { | |
| my ($hash_ref) = @_; | |
| return ${$hash_ref}{$b} <=> ${$hash_ref}{$a}; | |
| } | |
| sub trim() | |
| { | |
| my $str; | |
| ($str) = @_; | |
| $str =~ s/(^\s*)|(\s*$)//g; | |
| return $str; | |
| } | |
| #****************************************************************************** | |
| # FUNCTION | |
| # timeCheck | |
| # DESCRIPTION | |
| # print current time (in sec.) and time-difference to previous check if exists | |
| # PARAMETERS | |
| # none | |
| # RETURNS | |
| # current time and time difference if exists (both in sec.) | |
| #****************************************************************************** | |
| my $timePrev = 0; | |
| sub timeCheck() | |
| { | |
| my $prePrintStr; | |
| my $postPrintStr; | |
| my $timeCurr = time(); | |
| my $timeDiff = 0; | |
| ($prePrintStr, $postPrintStr) = @_; | |
| print "objcheck: "; | |
| print "$prePrintStr" if ($prePrintStr ne ""); | |
| print "[Time: ".$timeCurr." sec."; | |
| if ($timePrev > 0) # previous-time exists | |
| { | |
| $timeDiff = $timeCurr - $timePrev; | |
| print "(Diff = $timeDiff)"; | |
| } | |
| print "]"; | |
| print "$postPrintStr" if ($postPrintStr ne ""); | |
| print "\n"; | |
| $timePrev = $timeCurr; | |
| return $timeDiff; | |
| } | |
| sub runMemLayout | |
| { | |
| my $htmlFile; | |
| my $batFilename = "~objcheck_runmem.bat"; | |
| ($htmlFile) = @_; | |
| open(hFile, ">$batFilename") or die "can't open $batFilename\n"; | |
| print hFile "\@echo off\n"; | |
| print hFile "pcore\\tools\\python25\\python pcore\\tools\\py\\parse_mem_cfg.py --mcu . --proj $g_prjName 1>$htmlFile 2>>$g_logCompileFile\n"; | |
| print hFile "\@echo on\n"; | |
| close(hFile); | |
| #&timeCheck(); | |
| system("$batFilename"); | |
| #&timeCheck(); | |
| system("del $batFilename"); | |
| } |