#!/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"); | |
} |