blob: a12b6457f5f88a50458f7f7057af70925f6efdcc [file] [log] [blame]
rjw6c1fd8f2022-11-30 14:33:01 +08001#!/usr/bin/perl
2#
3# Copyright Statement:
4# --------------------
5# This software is protected by Copyright and the information contained
6# herein is confidential. The software may not be copied and the information
7# contained herein may not be used or disclosed except with the written
8# permission of MediaTek Inc. (C) 2005
9#
10# BY OPENING THIS FILE, BUYER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
11# THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
12# RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO BUYER ON
13# AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
14# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
15# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
16# NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
17# SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
18# SUPPLIED WITH THE MEDIATEK SOFTWARE, AND BUYER AGREES TO LOOK ONLY TO SUCH
19# THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. MEDIATEK SHALL ALSO
20# NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO BUYER'S
21# SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN FORUM.
22#
23# BUYER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND CUMULATIVE
24# LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
25# AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
26# OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY BUYER TO
27# MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
28#
29# THE TRANSACTION CONTEMPLATED HEREUNDER SHALL BE CONSTRUED IN ACCORDANCE
30# WITH THE LAWS OF THE STATE OF CALIFORNIA, USA, EXCLUDING ITS CONFLICT OF
31# LAWS PRINCIPLES. ANY DISPUTES, CONTROVERSIES OR CLAIMS ARISING THEREOF AND
32# RELATED THERETO SHALL BE SETTLED BY ARBITRATION IN SAN FRANCISCO, CA, UNDER
33# THE RULES OF THE INTERNATIONAL CHAMBER OF COMMERCE (ICC).
34#
35#
36#*****************************************************************************
37#
38# Filename:
39# ---------
40# objcheck.pl
41#
42# Description:
43# ------------
44# this script is used to check run-time values, e.g. 'size of each element of union'.
45#
46# Auther:
47# -------
48# Shinn Lin
49#
50# Note:
51# -----
52# Support Status
53# 1. union/struct (o)
54# 2. multi-setting (o)
55#
56# Log:
57# -----
58# 2008/02/22 Create.
59#
60
61#BEGIN { push @INC, "pcore/" , 'U:\\00MyPerlLib'} # add additional library path
62#package XXX;
63use strict;
64
65#******************************************************************************
66# Global Data
67#******************************************************************************
68my $g_settingFilename = "objcheck.txt";
69my $g_logFile = "objcheck.log";
70my $g_logCompileFile = "objcheck.compile.log";
71my $g_htmlFile = "objcheck.html";
72
73my $g_prjName = '';
74my $g_mcuPath = ".";
75
76# remove temp file or not
77my $g_removeTempFile = 1;
78
79# also process disabled features or not
80my $g_alsoProcessDisabledFeatures = 1;
81
82my $g_compiler = 'armcc'; # default compiler
83my $g_viaOption = '--via'; # default 'via' option
84
85my $local_run = 1; # in local folder (1) or in mcu folder (0)
86
87my $checkMainFilename;
88
89my $separation = "***********************************************************************";
90
91my $magicNumber = "26598088";
92
93my $str_objcheck = "objcheck";
94my $str_info = "info";
95my $str_removeTmpFile = "removeTmpFile";
96my $str_alsoProcessDisabledFeatures = "alsoProcessDisabledFeatures";
97my $str_mcuPath = "mcuPath";
98my $str_prjName = "prjName";
99my $str_filename = "filename";
100my $str_path = "path";
101my $str_type = "type";
102my $str_parsingInc = "parsingInc";
103my $str_addModuleInc = "addModuleInc";
104my $str_addIncPath = "addIncPath";
105my $str_addIncFiles = "addIncFiles";
106my $str_addLines = "addLines";
107my $str_addPostLines = "addPostLines";
108my $str_addFeaturesToWatch = "addFeaturesToWatch";
109
110# tag name and in-tag/end-tag handler
111my %xmlTags = ( $str_objcheck => \&objcheck_tag_hdlr,
112 $str_info => \&info_tag_hdlr,
113 $str_addModuleInc => \&addModuleInc_tag_hdlr,
114 $str_addIncPath => \&addIncPath_tag_hdlr,
115 $str_addIncFiles => \&addIncFiles_tag_hdlr,
116 $str_addLines => \&addLines_tag_hdlr,
117 $str_addPostLines => \&addPostLines_tag_hdlr,
118 $str_addFeaturesToWatch => \&addFeaturesToWatch_tag_hdlr);
119
120#******************************************************************************
121# Export Function
122#******************************************************************************
123
124#******************************************************************************
125# Internal Data
126#******************************************************************************
127my %settingData = ();
128
129#******************************************************************************
130# Program Start
131#******************************************************************************
132
133# get project name from input argument
134if (scalar(@ARGV) == 0)
135{
136 my @usage = ();
137 push @usage, "\nUsage 1:\n'objcheck.pl <project name> <compiler> <via option>'\n";
138 push @usage, "e.g. 'objcheck.pl DRAGONFLY_DEMO armcc --via'\n\n";
139 push @usage, "Usage 2: (in local directory)\n'objcheck.pl local <compiler> <via option>'\n";
140 die join('', @usage);
141}
142else
143{
144 ($g_prjName, $g_compiler, $g_viaOption) = @ARGV;
145}
146
147if ($g_prjName !~ /^local$/i)
148{
149 $g_settingFilename = "pcore\\tools\\".$g_settingFilename;
150 $local_run = 0;
151}
152
153$g_logFile = "build\\$g_prjName\\log\\".$g_logFile if (!$local_run);
154system("del $g_logFile") if (-e "$g_logFile");
155
156$g_logCompileFile = "build\\$g_prjName\\log\\".$g_logCompileFile if (!$local_run);
157system("del $g_logCompileFile") if (-e "$g_logCompileFile");
158
159$g_htmlFile = "build\\$g_prjName\\log\\".$g_htmlFile if (!$local_run);
160system("del $g_htmlFile") if (-e "$g_htmlFile");
161
162print "\nobjcheck: Start\n";
163
164# write parameter
165open(hFile, ">>$g_logCompileFile") or die "can't open $g_logCompileFile";
166print hFile "===========================================================\n";
167print hFile "$g_prjName\n";
168print hFile "$g_compiler\n";
169print hFile "$g_viaOption\n";
170print hFile "===========================================================\n";
171close(hFile);
172
173# start processing
174&getSettings($g_settingFilename, \%settingData);
175print "objcheck: Log generated to $g_logFile\n";
176
177&runMemLayout($g_htmlFile);
178print "objcheck: Html generated to $g_htmlFile\n";
179
180print "objcheck: End\n\n";
181
182exit 0;
183
184
185#******************************************************************************
186# Internal Function
187#******************************************************************************
188
189#******************************************************************************
190# FUNCTION
191# startCheck
192# DESCRIPTION
193# start obj check
194# PARAMETERS
195#
196# RETURNS
197# none
198#******************************************************************************
199sub startCheck()
200{
201 my $settingData_href;
202
203 ($settingData_href) = @_;
204
205 my $targetFilepath = ${$settingData_href}{$str_path};
206 my $targetFilename = ${$settingData_href}{$str_filename};
207 my $parsingInc = ${$settingData_href}{$str_parsingInc};
208 my @fileData = ();
209 my $type;
210 my $retVal = 0;
211
212 # list the modules which their *.inc will be added into include path
213 my $includeMod = ${$settingData_href}{$str_addModuleInc}; # include *.inc
214
215 # additional path for include files
216 my $addIncPath = ${$settingData_href}{$str_addIncPath};
217 unshift @{${$settingData_href}{$str_addIncPath}}, $targetFilepath;
218
219 # additional include files
220 my $addIncFiles = ${$settingData_href}{$str_addIncFiles}; #("mmi_features.h");
221
222 # additional lines
223 my $addLines = ${$settingData_href}{$str_addLines};
224
225 # additional features to watch
226 my $addFeaturesToWatch = ${$settingData_href}{$str_addFeaturesToWatch};
227
228 print "objcheck: [$targetFilename] Begin\n";
229
230 while (($type = shift @{${$settingData_href}{$str_type}}) ne "")
231 {
232 my %featureList = ();
233 my @unionInOrder = ();
234 my @sortedAllFeatures = ();
235 my @defFeatures = ();
236 my @undefFeatures = ();
237 my $allFeatureCount;
238 my $defFeatureCount;
239 my $undefFeatureCount;
240
241 $checkMainFilename = "~".splitFilename($targetFilename, 0)."_check";
242 my $checkTmpMainFilename = "$checkMainFilename"."_tmp";
243 my $checkFile = "$g_mcuPath\\$targetFilepath\\$targetFilename";
244
245 # get all feature list
246 if (!(-e $checkFile))
247 {
248 print "objcheck: [Warning] $checkFile not exist!\n";
249 return;
250 }
251
252 open(hFile, "<$checkFile") or die "can't open $checkFile";
253 @fileData = <hFile>;
254 close(hFile);
255
256 print "objcheck: ($type) Begin\n";
257 &timeCheck(" --> ", "");
258 print "objcheck: --> Reading...\n";
259
260 if ($type eq 'macro')
261 {
262 # get macros
263 getMacro(\@fileData, \%featureList);
264 push @sortedAllFeatures, sort(keys(%featureList));
265 }
266 elsif ($type eq 'obj')
267 {
268 # get union from target file
269 my @targetUnionInOrder = ();
270 getUnion(\@fileData, \@targetUnionInOrder) if ($parsingInc == 0);
271
272 #####
273 # At this stage, we only need compile option (check member of union is turned on)
274 # To speed up the -E and reading, try to modify array size to const
275 #####
276
277 # gen shrinked target file
278 my $shrinkTargetFilename = "~".splitFilename($targetFilename, 0)."_shrink.h";
279 open(hShrinkFile, ">$shrinkTargetFilename") or die "can't open $shrinkTargetFilename";
280 foreach my $line (@fileData)
281 {
282 if ($line =~ /([^\[]*)\[([^\]]*)\](\;.*)/)
283 {
284 print hShrinkFile $1 . "[1]" . $3 . "\n";
285 }
286 else
287 {
288 print hShrinkFile "$line";
289 }
290 }
291 close(hShrinkFile);
292
293 # gen pre-processed tmp file
294 genCheckDotC($type . "_expand", "$checkTmpMainFilename.c", $shrinkTargetFilename, \@sortedAllFeatures, $settingData_href);
295 processCheckDotC($checkTmpMainFilename, "-E", $settingData_href, $g_removeTempFile);
296 $checkFile = "$checkTmpMainFilename.obj";
297
298 # remove shrinked target file
299 if ($g_removeTempFile)
300 {
301 system("del $shrinkTargetFilename") if (-e "$shrinkTargetFilename");
302 }
303
304 if (!(-e $checkFile))
305 {
306 my $timeCost = &timeCheck(" --> ", "");
307 my $logTitle = "$targetFilename\t($type) (timeCost=$timeCost sec.)\n ($g_mcuPath\\$targetFilepath)";
308 genLogInfo($type, $g_logFile, $logTitle, "Skip due to compile error, check $g_logCompileFile");
309 print "objcheck: [Error] compile error! skip\n";
310 next;
311 }
312
313 # read pre-processed file
314 open(hFile, "<$checkFile") or die "can't open $checkFile";
315 @fileData = <hFile>;
316 close(hFile);
317
318 # get union from pre-processed file (means it really exists)
319 my %unionTmp = ();
320 getUnion(\@fileData, \@unionInOrder, \%unionTmp);
321
322 if ($parsingInc == 0)
323 {
324 foreach my $targetUnion (@targetUnionInOrder)
325 {
326 # if targetUnion really exists
327 push @sortedAllFeatures, $targetUnion if (defined ${unionTmp}{$targetUnion});
328 }
329 }
330 else
331 {
332 push @sortedAllFeatures, @unionInOrder if (scalar(@unionInOrder));
333 }
334 }
335 elsif ($type eq 'obj2')
336 {
337 #####
338 # no compile option, no need to pre-process.
339 #####
340
341 # get union from target file
342 my @targetUnionInOrder = ();
343 getUnion(\@fileData, \@targetUnionInOrder);
344
345 foreach my $targetUnion (@targetUnionInOrder)
346 {
347 push @sortedAllFeatures, $targetUnion;
348 }
349 }
350 else
351 {
352 print "[objcheck.pl][Warning] $type not supported!\n";
353 next;
354 }
355
356 # add additional features to watch
357 push @sortedAllFeatures, @{$addFeaturesToWatch} if (defined $addFeaturesToWatch);
358
359 $allFeatureCount = @sortedAllFeatures;
360
361 # generate XXX_check.c
362 print "objcheck: --> Generating...\n";
363 genCheckDotC($type, "$checkMainFilename.c", $targetFilename, \@sortedAllFeatures, $settingData_href);
364
365 # validate features
366 print "objcheck: --> Compiling...\n";
367 my $compileOption = "-c";
368 $compileOption = "-E" if ($type eq 'macro');
369 processCheckDotC($checkMainFilename, $compileOption, $settingData_href, $g_removeTempFile);
370
371 if (!(-e "$checkMainFilename.obj"))
372 {
373 my $timeCost = &timeCheck(" --> ", "");
374 my $logTitle = "$targetFilename\t($type) (timeCost=$timeCost sec.)\n ($g_mcuPath\\$targetFilepath)";
375 genLogInfo($type, $g_logFile, $logTitle, "Skip due to compile error, check $g_logCompileFile");
376 print "objcheck: [Error] compile error! skip\n";
377 next;
378 }
379
380 # check def/undef features in pre-processed file
381 print "objcheck: --> Checking...\n";
382 checkFeatures($type, "$checkMainFilename.obj", \%featureList, \@sortedAllFeatures, \@defFeatures, \@undefFeatures);
383 $defFeatureCount = @defFeatures;
384 $undefFeatureCount = @undefFeatures;
385
386 if ($g_removeTempFile)
387 {
388 system("del $checkMainFilename.c") if (-e "$checkMainFilename.c");
389 system("del $checkMainFilename.obj") if (-e "$checkMainFilename.obj");
390 system("del $checkTmpMainFilename.c") if (-e "$checkTmpMainFilename.c");
391 system("del $checkTmpMainFilename.obj") if (-e "$checkTmpMainFilename.obj");
392 }
393
394 # output results
395 my $timeCost = &timeCheck(" --> ", "");
396 my $logTitle = "$targetFilename\t($type) (timeCost=$timeCost sec.)\n ($g_mcuPath\\$targetFilepath)";
397 genLog($type, $g_logFile, $logTitle, \@defFeatures, \%featureList,
398 \@undefFeatures, \@sortedAllFeatures);
399 print "objcheck: --> Log generated\n";
400
401 # verify result
402 if ($allFeatureCount != ($defFeatureCount+$undefFeatureCount))
403 {
404 print "[Error] all feature count($allFeatureCount) != defined count($defFeatureCount) + undef count($undefFeatureCount)\n";
405 $retVal = 1;
406 }
407 else
408 {
409 print "objcheck: Done! ([$targetFilename] [$type] defined count = $defFeatureCount)\n";
410 }
411 print "objcheck: ($type) End\n";
412 }
413
414 print "objcheck: [$targetFilename] End\nobjcheck:\n";
415 return $retVal;
416}
417
418#******************************************************************************
419# FUNCTION
420# genCheckDotC
421# DESCRIPTION
422# xxx
423# PARAMETERS
424# xxx
425# RETURNS
426# none
427#******************************************************************************
428sub genCheckDotC()
429{
430 my $type;
431 my $filename;
432 my $targetFilename;
433 my @fileData;
434 my $pUserData; # reference to data array
435 my $settingData_href;
436
437 ($type, $filename, $targetFilename, $pUserData, $settingData_href) = @_;
438
439 open(hFile, ">$filename") or die "can't open $filename";
440
441 print hFile "// addLines\n";
442 foreach my $line (@{${$settingData_href}{$str_addLines}})
443 {
444 print hFile "$line\n";
445 }
446
447 print hFile "// addLines by type\n";
448 foreach my $line (@{${$settingData_href}{$str_addLines . "_" . $type}})
449 {
450 print hFile "$line\n";
451 }
452
453 # write header part
454
455 print hFile "// addIncFiles\n";
456 foreach my $inc (@{${$settingData_href}{$str_addIncFiles}})
457 {
458 print hFile "#include \"$inc\"\n";
459 }
460
461 print hFile "#include \"$targetFilename\"\n\n";
462
463 foreach my $data (@{${$settingData_href}{$str_addPostLines}})
464 {
465 print hFile $data;
466 }
467
468 # write start tag
469 print hFile "\nvoid * feature_check[] = {\n";
470
471 if ($type eq 'macro')
472 {
473 foreach my $data (@$pUserData)
474 {
475 print hFile "(void *)$data,\n";
476 }
477
478 # write end tag
479 print hFile "(void *)\"END FEATURE LIST\"\n";
480 }
481 elsif (($type eq 'obj') || ($type eq 'obj2'))
482 {
483 print hFile "(void *)0x$magicNumber,\n";
484
485 foreach my $data (@$pUserData)
486 {
487 print hFile "(void *)($data),\n";
488 }
489
490 # write end tag
491 print hFile "(void *)0x$magicNumber\n";
492 }
493 else
494 {
495 print hFile "0\n";
496 }
497
498 print hFile "};\n";
499 close(hFile);
500}
501
502
503#******************************************************************************
504# FUNCTION
505# processCheckDotC
506# DESCRIPTION
507# xxx
508# PARAMETERS
509# xxx
510# RETURNS
511# none
512#******************************************************************************
513sub processCheckDotC()
514{
515 my $mainFilename;
516 my $compileOptions;
517 my $settingData_href;
518 my $removeTmpFile;
519
520 ($mainFilename, $compileOptions, $settingData_href, $removeTmpFile) = @_;
521
522 my $includeMod = ${$settingData_href}{$str_addModuleInc}; # include *.inc
523 my $addIncPath = ${$settingData_href}{$str_addIncPath};
524
525 my $infoFilename = "$g_mcuPath\\build\\$g_prjName\\log\\info.log";
526 my $batFilename = "~makeCheck.bat";
527 my $defTmpFilename = "$mainFilename.def";
528 my $incTmpFilename = "$mainFilename.inc";
529 my @fileData;
530 my $inSection = 0;
531 my $incPaths = "";
532
533 my $count = 0;
534 my $commonOptions = "";
535
536 # read common options and common include path from info.log
537 open(hFile, "<$infoFilename") or die "can't open $infoFilename";
538 @fileData = <hFile>;
539 close(hFile);
540
541 foreach my $line (@fileData)
542 {
543 if ($line =~ /\[ COMMON OPTION \]/)
544 {
545 $inSection = 1;
546 next;
547 }
548 elsif ($line =~ /\[ COMMON INCLUDE PATH \]/)
549 {
550 $inSection = 2;
551 next;
552 }
553
554 if ($line =~ /(^[^\[][^\s]*)/)
555 {
556 if ($inSection == 1)
557 {
558 #print "$1\n";
559 $commonOptions = "$commonOptions\n-D$1";
560 }
561 elsif ($inSection == 2)
562 {
563 my $inc = "$1";
564
565 if ($inc !~ /:/)
566 {
567 $inc = "$g_mcuPath\\$inc";
568 }
569 #print "$inc\n";
570 $incPaths = "$incPaths\n-I$inc";
571 }
572 }
573 else
574 {
575 $inSection = 0;
576 }
577 }
578
579 # read inc from *.inc
580 foreach my $myMod (@{$includeMod})
581 {
582 my @incFiles = ();
583 if (&getFileList("$g_mcuPath\\build\\$g_prjName\\module\\$myMod\\*.inc", 1, \@incFiles) > 0)
584 {
585 foreach my $incFilename (@incFiles)
586 {
587 open(hFile, "<$incFilename") or die "can't open $incFilename";
588 @fileData = <hFile>;
589 close(hFile);
590
591 foreach my $line (@fileData)
592 {
593 if ($line =~ /(^[^\s]+)([\s]*$)/)
594 {
595 $incPaths = "$incPaths\n-I$g_mcuPath\\$1";
596 }
597 }
598 }
599 }
600 else
601 {
602 print "[Warning] can't find *.inc for $myMod\n";
603 }
604 }
605
606 # additional inc path
607 foreach my $inc (@{$addIncPath})
608 {
609 $incPaths = "$incPaths\n-I$g_mcuPath\\$inc";
610 }
611
612 # read macro from *.def
613 foreach my $myMod (@{$includeMod})
614 {
615 my @defFiles = ();
616 if (&getFileList("$g_mcuPath\\build\\$g_prjName\\module\\$myMod\\*.def", 1, \@defFiles) > 0)
617 {
618 foreach my $defFilename (@defFiles)
619 {
620 open(hFile, "<$defFilename") or die "can't open $defFilename";
621 @fileData = <hFile>;
622 close(hFile);
623
624 foreach my $line (@fileData)
625 {
626 if ($line =~ /(^[^\s]+)([\s]*$)/)
627 {
628 $commonOptions = "$commonOptions\n-D$1";
629 }
630 }
631 }
632 }
633 else
634 {
635 print "[Warning] can't find *.def for $myMod\n";
636 }
637 }
638
639 #print "$commonOptions\n";
640 open(hFile, ">$defTmpFilename") or die "can't open $defTmpFilename";
641 print hFile "$commonOptions\n";
642 close(hFile);
643
644 #print "$incPaths\n";
645 open(hFile, ">$incTmpFilename") or die "can't open $incTmpFilename";
646 print hFile "$incPaths\n";
647 close(hFile);
648
649 # prepare for compiler output
650 open(hFile, ">>$g_logCompileFile") or die "can't open $g_logCompileFile";
651 print hFile "===========================================================Begin\n";
652 print hFile "[Processing...](".${$settingData_href}{$str_filename}.")\n";
653 close(hFile);
654
655 open(hFile, ">$batFilename") or die "can't open $batFilename\n";
656 print hFile "\@echo off\n";
657 print hFile "$g_compiler $mainFilename.c -o $mainFilename.obj $compileOptions $g_viaOption $defTmpFilename $g_viaOption $incTmpFilename 2>>$g_logCompileFile\n";
658 print hFile "\@echo on\n";
659 close(hFile);
660
661 #&timeCheck();
662 system("$batFilename");
663 #&timeCheck();
664
665 # end compiler output
666 open(hFile, ">>$g_logCompileFile") or die "can't open $g_logCompileFile";
667 print hFile "=============================================================End\n\n";
668 close(hFile);
669
670 # remove empty lines for -E
671 if ($compileOptions =~ /-e([\s]+|$)/i)
672 {
673 open(hFile, "<$mainFilename.obj") or die "can't open $mainFilename.obj\n";
674 my $tmp = join('',<hFile>);
675 close(hFile);
676 $tmp =~ s/\n([\s]+)\n/\n\n/g; # reduce multi-CR/LF
677 open(hFile, ">$mainFilename.obj") or die "can't open $mainFilename.obj for write\n";
678 print hFile $tmp;
679 close(hFile);
680 }
681
682 if ($removeTmpFile)
683 {
684 system("del $batFilename");
685 system("del $defTmpFilename");
686 system("del $incTmpFilename");
687 }
688}
689
690
691#******************************************************************************
692# FUNCTION
693# checkFeatures
694# DESCRIPTION
695# xxx
696# PARAMETERS
697# xxx
698# RETURNS
699# none
700#******************************************************************************
701sub checkFeatures()
702{
703 my $type; # 'obj' or 'macro'
704 my $filename; # preprocessed object filename
705 my $pFeatureList; # reference to hash of feature list
706 my $pSortedAllFeatures; # reference to array of sorted all features
707 my $pDefFeatures; # reference to array of defined features
708 my $pUndefFeatures; # reference to array of undefined features
709
710 my @fileData;
711 my $isFeature = 0;
712 my $featureIndex;
713 my $defFeature;
714
715 ($type, $filename, $pFeatureList, $pSortedAllFeatures,
716 $pDefFeatures, $pUndefFeatures) = @_;
717
718 if ($type eq 'macro')
719 {
720 open(hFile, "<$filename") or die "can't open $filename";
721 @fileData = <hFile>;
722 close(hFile);
723
724 open(hFile, ">>$g_logCompileFile") or die "can't open $g_logCompileFile";
725 print hFile "===========================================================Begin\n";
726 print hFile "[checkFeatures](".$filename.":".$type.")\n";
727
728 foreach my $line (@fileData)
729 {
730 if ($isFeature)
731 {
732 if ($line =~ /(^\(void \*\)[\s]*)(.*?)([\s]*,$)/)
733 {
734 $defFeature = $$pSortedAllFeatures[$featureIndex];
735
736 if ($2 eq $defFeature)
737 {
738 # undefined symbols ("_XXX_" shows)
739
740 push @$pUndefFeatures, $2;
741
742 # remove it from feature list
743 delete $$pFeatureList{$2};
744
745 #print "[U] $2\n";
746 }
747 else
748 {
749 # process defined symbols
750
751 push @$pDefFeatures, $defFeature;
752
753 # update value of feature list
754 $$pFeatureList{$defFeature} = $2;
755
756 #print "[D] $defFeature = $2\n";
757 }
758 }
759 # end of feature list
760 elsif ($line =~ /"END FEATURE LIST"}/)
761 {
762 $isFeature = 0;
763 }
764 elsif ($line !~ /^[\s]*$/)
765 {
766 print hFile "[Not Processed] \"$line\"\n";
767 }
768
769 #print "[$featureIndex] $$pSortedAllFeatures[$featureIndex] $line\n";
770 $featureIndex++;
771 }
772
773 # check if begining of feature list
774 if ($line =~ /feature_check\[\]/)
775 {
776 $isFeature = 1;
777 $featureIndex = 0;
778 }
779 }
780
781 print hFile "=============================================================End\n\n";
782 close(hFile);
783 }
784 else # 'obj'
785 {
786 open(hFile, "<$filename") or die "can't open $filename";
787 binmode(hFile);
788 my $binData;
789 my $status = '';
790 while (read(hFile, $binData, 4))
791 {
792 if ($status eq 'start')
793 {
794 my $value = ascii2dec_le($binData);
795 if ($value == hex($magicNumber))
796 {
797 #print "END\n";
798 last;
799 }
800
801 $defFeature = $$pSortedAllFeatures[$featureIndex];
802 $featureIndex++;
803
804 push @$pDefFeatures, $defFeature;
805 # update value of feature list
806 $$pFeatureList{$defFeature} = $value;
807 #print "$defFeature = $value\n";
808 }
809
810 # begin of array
811 if (ascii2dec_le($binData) == hex($magicNumber))
812 {
813 $status = 'start';
814 $featureIndex = 0;
815 #print "Start\n";
816 }
817 }
818 close(hFile);
819 }
820
821}
822
823
824#******************************************************************************
825# FUNCTION
826# getSettings
827# DESCRIPTION
828# get settings from file
829# PARAMETERS
830# $filename [IN] - setting file pathname
831# $targetHash_ref [IN] - reference to target hash
832# RETURNS
833# none
834#******************************************************************************
835sub getSettings()
836{
837 my $filename;
838 my $settingData_href;
839
840 ($filename, $settingData_href) = @_;
841
842 my @fileData;
843 #my %settingData = ();
844
845 open(hFile, "<$filename") or die "can't open $filename\n";
846 @fileData = <hFile>;
847 close(hFile);
848
849 # parse setting file
850 parseXmlLineData(\@fileData, \%xmlTags, $settingData_href);
851}
852
853
854sub objcheck_tag_hdlr()
855{
856 my $taginfo_aref;
857 my $para_href;
858
859 ($taginfo_aref, $para_href) = @_;
860
861 #print "tag hdlr [0]\n";
862
863 &startCheck($para_href);
864 %{$para_href} = (); # reset setting data
865}
866
867
868sub info_tag_hdlr()
869{
870 my $taginfo_aref;
871 my $para_href;
872
873 ($taginfo_aref, $para_href) = @_;
874
875 #print "tag hdlr [1]\n";
876
877 while (my ($attr, $value) = each(%{$$taginfo_aref[0]}))
878 {
879 #print " attr [$attr] = $value\n";
880 ${$para_href}{$str_filename} = $value if ($attr eq $str_filename);
881 ${$para_href}{$str_path} = $value if ($attr eq $str_path);
882 ${$para_href}{$str_parsingInc} = $value if ($attr eq $str_parsingInc);
883 if ($attr eq $str_type)
884 {
885 push @{${$para_href}{$str_type}}, split(',', $value);
886 }
887
888 $g_mcuPath = $value if (($attr eq $str_mcuPath) && ($str_mcuPath ne ""));
889 $g_prjName = $value if (($attr eq $str_prjName) && ($str_prjName ne ""));
890 $g_removeTempFile = $value if ($attr eq $str_removeTmpFile);
891 $g_alsoProcessDisabledFeatures = $value if ($attr eq $str_alsoProcessDisabledFeatures);
892 }
893}
894
895sub addModuleInc_tag_hdlr()
896{
897 my $taginfo_aref;
898 my $para_href;
899
900 ($taginfo_aref, $para_href) = @_;
901
902 #print "tag hdlr [2]\n";
903 push @{${$para_href}{$str_addModuleInc}}, trim($_) foreach (@{$$taginfo_aref[1]});
904 #print join(' ',@{${$para_href}{$str_addModuleInc}})."\n";
905}
906
907sub addIncPath_tag_hdlr()
908{
909 my $taginfo_aref;
910 my $para_href;
911
912 ($taginfo_aref, $para_href) = @_;
913
914 #print "tag hdlr [3]\n";
915 push @{${$para_href}{$str_addIncPath}}, trim($_) foreach (@{$$taginfo_aref[1]});
916 #print join(' ',@{${$para_href}{$str_addIncPath}})."\n";
917}
918
919sub addIncFiles_tag_hdlr()
920{
921 my $taginfo_aref;
922 my $para_href;
923
924 ($taginfo_aref, $para_href) = @_;
925
926 #print "tag hdlr [4]\n";
927 push @{${$para_href}{$str_addIncFiles}}, trim($_) foreach (@{$$taginfo_aref[1]});
928 #print join(', ',@{${$para_href}{$str_addIncFiles}})."\n";
929}
930
931sub addLines_tag_hdlr()
932{
933 my $taginfo_aref;
934 my $para_href;
935
936 ($taginfo_aref, $para_href) = @_;
937
938 my $type = undef;
939
940 # attribute
941 while (my ($attr, $value) = each(%{$$taginfo_aref[0]}))
942 {
943 $type = $value if (($attr eq $str_type) && ($str_type ne ""));
944 }
945
946 #print "tag hdlr [5]\n";
947 if (!defined($type))
948 {
949 push @{${$para_href}{$str_addLines}}, trim($_) foreach (@{$$taginfo_aref[1]});
950 }
951 else
952 {
953 push @{${$para_href}{$str_addLines . "_" . $type}}, trim($_) foreach (@{$$taginfo_aref[1]});
954 }
955 #print join(' ',@{${$para_href}{$str_addLines}})."\n";
956}
957
958sub addPostLines_tag_hdlr()
959{
960 my $taginfo_aref;
961 my $para_href;
962
963 ($taginfo_aref, $para_href) = @_;
964
965 push @{${$para_href}{$str_addPostLines}}, trim($_)."\n" foreach (@{$$taginfo_aref[1]});
966}
967
968sub addFeaturesToWatch_tag_hdlr()
969{
970 my $taginfo_aref;
971 my $para_href;
972
973 ($taginfo_aref, $para_href) = @_;
974
975 #print "tag hdlr [6]\n";
976 push @{${$para_href}{$str_addFeaturesToWatch}}, trim($_) foreach (@{$$taginfo_aref[1]});
977 #print join(' ',@{${$para_href}{$str_addFeaturesToWatch}})."\n";
978}
979
980
981#******************************************************************************
982# FUNCTION
983# getUnion
984# DESCRIPTION
985# get union from file
986# PARAMETERS
987#
988# RETURNS
989# none
990#******************************************************************************
991sub getUnion()
992{
993 my $srcDataRef;
994 my $dataARef;
995 my $dataHRef;
996
997 ($srcDataRef, $dataARef, $dataHRef) = @_;
998
999 # remove comments
1000 my $tmpStr = join('', @{$srcDataRef});
1001 $tmpStr =~ s/(\/\*.*?\*\/)//gs; # remove all C comments
1002 $tmpStr =~ s/(\/\/.*)//g; # remove all C++ comments
1003
1004 # find union
1005 while ($tmpStr =~ /[\s]+typedef[\s]+(union|struct)[\s]*\{([^\{\}]+?)\}[\s]*([\*]*)[\s]*([\w]+)[\s]*\;/sg)
1006 {
1007 #my $typedef = $1;
1008 my $type = $1;
1009 my $data = $2;
1010 my $ptrStr = $3;
1011 my $unionName = $4;
1012 my $str = "";
1013
1014 #print "====>>> [$unionName][$typedef] [$type] [$ptrStr]\n";
1015 $str = "sizeof($unionName)";
1016 push @{$dataARef}, $str if (defined $dataARef);
1017 ${$dataHRef}{$str} = "" if (defined $dataHRef);
1018
1019 my @dataArray = ();
1020 @dataArray = split(';', $data);
1021 foreach my $line (@dataArray)
1022 {
1023 # [^:] => exclude bit-field
1024 if (($line =~ /[^:]+[\s]+[\*]*([\w]+)[\s]*$/) ||
1025 ($line =~ /[^:]+[\s]+[\*]*([\w]+)[\s]*\[[^\]]+\][\s]*$/))
1026
1027 {
1028 if ($type eq 'union' || $type eq 'struct')
1029 {
1030 $str = "sizeof(($ptrStr($unionName *)0)->$1)";
1031 push @{$dataARef}, $str if (defined $dataARef);
1032 ${$dataHRef}{$str} = "" if (defined $dataHRef);
1033 }
1034 }
1035 }
1036 }
1037}
1038
1039
1040
1041sub getMacro()
1042{
1043 my $srcDataRef;
1044 my $dataHRef;
1045
1046 ($srcDataRef, $dataHRef) = @_;
1047
1048 foreach my $line (@{$srcDataRef})
1049 {
1050 my $feature = "";
1051
1052 # also process marked "//" features or not
1053 if ($g_alsoProcessDisabledFeatures)
1054 {
1055 if ($line =~ /^([\s]*([\/]{2,})?[\s]*)(#define[\s]+)([\w_]+)([\s]+)([\w\(\)]+)/)
1056 {
1057 $feature = $4;
1058 }
1059 }
1060 else
1061 {
1062 if ($line =~ /^([\s]*)(#define[\s]+)([\w_]+)([\s]+)([\w\(\)]+)/)
1063 {
1064 $feature = $3;
1065 }
1066 }
1067
1068 if ($feature ne "")
1069 {
1070 ${$dataHRef}{$feature} = "";
1071 }
1072 }
1073}
1074
1075
1076#******************************************************************************
1077# FUNCTION
1078# parseXmlLineData
1079# DESCRIPTION
1080# parse XML data lines (usage ref. ffcheck_any.pl)
1081# PARAMETERS
1082# $lineData_aref - ref. to array of line data
1083# $interestXmlTags_aref - ref. to hash of interested xml tags
1084# $taginfo_href - reference to tag info hash {tag => [0] {attr => value}}
1085# [1] [] data lines
1086# RETURNS
1087# none
1088#******************************************************************************
1089sub parseXmlLineData()
1090{
1091 my $lineData_aref; # ref. to xml line data
1092 my $xmlTags_href; # ref. to interested xml tags
1093 my $para_href; # ref. to user parameter
1094
1095 ($lineData_aref, $xmlTags_href, $para_href) = @_;
1096
1097 my $inXmlTag = 0;
1098 my $currTag = "";
1099 my @tagStack = ();
1100 my %taginfo; # parsed tag info
1101 # {tag => [0] {attr => value}}
1102 # [1] [] data lines
1103 my %attrInfo = ();
1104
1105 foreach my $line (@$lineData_aref)
1106 {
1107 %taginfo = ();
1108 if (($line =~ /(^[ \t]*\#)|(^[\s]*$)/) && ($inXmlTag == 0))
1109 {
1110 # ignore comments or empty line, except in Xml tag processing
1111 }
1112 elsif ($line =~ /(<)([^>]+)(>)/)
1113 {
1114 my $tagData = $2;
1115 my $newTag;
1116
1117 %attrInfo = ();
1118
1119 ($inXmlTag, $newTag) = processTagInt($tagData, \%taginfo);
1120 #print "ret val = $inXmlTag new[$newTag] curr[$currTag]\n";
1121 #print "${$xmlTags_href}{$newTag}\n" if (exists ${$xmlTags_href}{$newTag});
1122
1123 %attrInfo = %{$taginfo{$newTag}[0]} if (defined($taginfo{$newTag}[0]));
1124
1125 if ($inXmlTag == 0)
1126 {
1127 if (exists ${$xmlTags_href}{$newTag})
1128 {
1129 # if tag found and hdlr exists, execute the hdlr after whole tag processed
1130 ${$xmlTags_href}{$newTag}($taginfo{$newTag}, $para_href) if (${$xmlTags_href}{$newTag} != 0);
1131 }
1132
1133 pop @tagStack if ($newTag eq $currTag);
1134 }
1135 # update tag for in-tag process
1136 elsif ($newTag ne $currTag) # && ($inXmlTag == 1)
1137 {
1138 push @tagStack, $currTag if ($currTag ne "");
1139 $currTag = $newTag;
1140 }
1141 }
1142 elsif ($line =~ /([^\n]+)(\n$)/)
1143 {
1144 if ($inXmlTag == 1)
1145 {
1146 $line =~ s/(^\s*)|(\s*$)//g;
1147 push @{$taginfo{$currTag}[1]}, $line if ($line ne "");
1148
1149 %{$taginfo{$currTag}[0]} = %attrInfo;
1150
1151 if (exists ${$xmlTags_href}{$currTag})
1152 {
1153 # if tag found and hdlr exists, execute the hdlr after whole tag processed
1154 ${$xmlTags_href}{$currTag}($taginfo{$currTag}, $para_href);
1155 }
1156 }
1157 }
1158 }
1159}
1160
1161
1162#******************************************************************************
1163# FUNCTION
1164# processTag
1165# DESCRIPTION
1166# process tag
1167# PARAMETERS
1168# para 1 - tag to process
1169# para 2 - reference to attribute hash {tag => {attr => value}}
1170# RETURNS
1171# success (tag name) or not ("")
1172#******************************************************************************
1173sub processTagInt()
1174{
1175 my $tagToProcess; # tag to process
1176 my $result_href; # reference to result hash
1177
1178 ($tagToProcess, $result_href) = @_;
1179
1180 my $tagName = "";
1181 my $inTag = 0;
1182
1183 $tagToProcess =~ s/(^[\s]*)|([\s]*$)//g;
1184 if ($tagToProcess =~ /^([\w_]+)$/i)
1185 {
1186 # start of tag
1187 $tagName = $1;
1188 $inTag = 1;
1189 }
1190 elsif ($tagToProcess =~ /^\/[ \t]*([\w_]+)$/i)
1191 {
1192 # end of tag
1193 $tagName = $1;
1194 }
1195 elsif ($tagToProcess =~ /(^[\w_]+)[ \t]+(([\w_]+[ \t]*=[ \t]*([\"\'])[^\4]+\4[ \t]*)+)(\/?$)/i)
1196 {
1197 #print "$tagToProcess\n";
1198 my @attrAll = split(' ',$2);
1199 $tagName = $1;
1200
1201 # if tag ends with '/'
1202 $inTag = 1 if ($5 ne '/');
1203
1204 # parse each attr
1205 foreach my $attr (@attrAll)
1206 {
1207 #print "[$attr]\n";
1208 if ($attr =~ /([\w_]+)[ \t]*=[ \t]*([\"\'])([^\2]+)\2/i)
1209 {
1210 ${$result_href}{$tagName}[0]{$1} = $3;
1211 #print "[$tagName] [$1] [$3]\n";
1212 }
1213 }
1214 }
1215 else
1216 {
1217 #print "[$tagToProcess] not processed\n";
1218 }
1219
1220 return ($inTag, $tagName);
1221}
1222
1223
1224sub ascii2dec_le()
1225{
1226 my $input;
1227
1228 ($input) = @_;
1229
1230 my $output = ord(substr($input, 3, 1))*256*256*256+
1231 ord(substr($input, 2, 1))*256*256+
1232 ord(substr($input, 1, 1))*256+
1233 ord(substr($input, 0, 1));
1234 #print "$input = $output";
1235}
1236
1237
1238#******************************************************************************
1239# FUNCTION
1240# splitFilename
1241# DESCRIPTION
1242# xxx
1243# PARAMETERS
1244# $filename [IN] - filename
1245# $refSubFilename [OUT] - reference to sub filename, may be NULL
1246# RETURNS
1247# main filename
1248#******************************************************************************
1249sub splitFilename()
1250{
1251 my $filename;
1252 my $refSubFilename = "";
1253 my $mainFilename = "";
1254
1255 ($filename, $refSubFilename) = @_;
1256
1257 if ($filename =~ /([^\s]*)(\.)([^\.]*$)/)
1258 {
1259 #print "$filename [$1][$3]\n";
1260 $mainFilename = "$1";
1261 if ($refSubFilename != 0)
1262 {
1263 $$refSubFilename = "$3";
1264 }
1265 }
1266 return $mainFilename;
1267}
1268
1269
1270#******************************************************************************
1271# FUNCTION
1272# getFileList
1273# DESCRIPTION
1274# get file/path list for given search string
1275# PARAMETERS
1276# xxx
1277# RETURNS
1278# xxx
1279#******************************************************************************
1280sub getFileList()
1281{
1282 my $rootDir;
1283 my $incSubDir; # include sub dir (1) or not (0)
1284 my $fileList_ref;
1285
1286 ($rootDir, $incSubDir, $fileList_ref) = @_;
1287
1288 my @fileData = ();
1289
1290 # get file list
1291 my $tmpFilename = "~tmpFile.lst";
1292
1293 my $dirStr = "$rootDir /b";
1294 $dirStr .= " /s" if ($incSubDir);
1295
1296 system("dir ".$dirStr." > $tmpFilename");
1297 open(hFile, "<$tmpFilename") or die "[ERROR] can't open $tmpFilename\n";
1298 @fileData = <hFile>;
1299 close(hFile);
1300 system("del $tmpFilename") if ($g_removeTempFile);
1301
1302 foreach my $line (@fileData)
1303 {
1304 my $name = $line;
1305 push @{$fileList_ref}, $name if ($name !~ /^[\s]*$/);
1306 #print "$name";
1307 }
1308 return scalar(@{$fileList_ref});
1309}
1310
1311
1312#******************************************************************************
1313# FUNCTION
1314# genLog
1315# DESCRIPTION
1316# xxx
1317# PARAMETERS
1318# $filename [IN] - log file pathname
1319# RETURNS
1320# none
1321#******************************************************************************
1322sub genLog()
1323{
1324 my $type;
1325 my $logFilePathname;
1326 my $logTitle;
1327 my $defFeatures_aref;
1328 my $featureData_href;
1329 my $undefFeatures_aref;
1330 my $sortedAllFeatures_aref;
1331
1332 ($type, $logFilePathname, $logTitle, $defFeatures_aref, $featureData_href,
1333 $undefFeatures_aref, $sortedAllFeatures_aref) = @_;
1334
1335 my $col1LenMax;
1336 my $col2LenMax;
1337 my $allFeatureCount;
1338 my $defFeatureCount;
1339 my $undefFeatureCount;
1340
1341 # append file
1342 open(hLogFile, ">>$logFilePathname") or die "can't open $logFilePathname";
1343
1344 $allFeatureCount = @$sortedAllFeatures_aref;
1345 $defFeatureCount = @$defFeatures_aref;
1346 $undefFeatureCount = @$undefFeatures_aref;
1347
1348 # title
1349 print hLogFile "\n$separation\n $logTitle\n$separation\n";
1350
1351 # result: Defined Features
1352 print hLogFile "\n$separation\n[Defined Values ($defFeatureCount/$allFeatureCount)]\n$separation\n\n";
1353 if ($type eq 'macro')
1354 {
1355 $col1LenMax = 0;
1356 $col2LenMax = 0;
1357 foreach my $feature (@$sortedAllFeatures_aref)
1358 {
1359 # get max. len of feature name
1360 $col1LenMax = length($feature) if (length($feature)>$col1LenMax);
1361
1362 # get max. len of feature value
1363 $col2LenMax = length(${$featureData_href}{$feature}) if (length(${$featureData_href}{$feature})>$col2LenMax);
1364 }
1365
1366 foreach my $feature (@$defFeatures_aref)
1367 {
1368 print hLogFile sprintf("[D] %-*s%s\n", $col1LenMax+8,
1369 $feature, ${$featureData_href}{$feature});
1370 }
1371 }
1372 else
1373 {
1374 my %nameHash = ();
1375 my %dataHash = ();
1376
1377 # prepare data
1378 $col1LenMax = 0;
1379 $col2LenMax = 0;
1380 foreach my $data (@$defFeatures_aref)
1381 {
1382 my $name = "";
1383 my $field = "";
1384
1385 if ($data =~ /sizeof\((\w+)\)/)
1386 {
1387 $name = $1;
1388 $nameHash{$name} = ${$featureData_href}{$data};
1389 }
1390 elsif ($data =~ /sizeof\(\(\((\w+) \*\)0\)->(\w+)\)/)
1391 {
1392 $name = $1;
1393 $field = $2;
1394 $dataHash{$name}{$field} = ${$featureData_href}{$data};
1395
1396 # get max. len of feature name
1397 my $nameField = $name."->".$field;
1398 my $value = ${$featureData_href}{$data};
1399 $col1LenMax = length($nameField) if (length($nameField)>$col1LenMax);
1400
1401 # get max. len of feature value
1402 $col2LenMax = length($value) if (length($value)>$col2LenMax);
1403 }
1404 }
1405
1406 foreach my $name (sort keys(%nameHash))
1407 {
1408 print hLogFile sprintf("[D] %-*s%*s\n", $col1LenMax+8,
1409 $name, $col2LenMax+2, $nameHash{$name});
1410 foreach my $field (sort {sortByValueDescending(\%{$dataHash{$name}})} keys(%{$dataHash{$name}}))
1411 {
1412 print hLogFile sprintf("[D] %-*s%*s\n", $col1LenMax+8,
1413 $name."->".$field, $col2LenMax+2, $dataHash{$name}{$field});
1414 }
1415 }
1416 }
1417 print hLogFile "\n\n";
1418
1419 close(hLogFile);
1420}
1421
1422sub genLogInfo()
1423{
1424 my $type;
1425 my $logFilePathname;
1426 my $logTitle;
1427 my $logText;
1428
1429 ($type, $logFilePathname, $logTitle, $logText) = @_;
1430
1431 # append file
1432 open(hLogFile, ">>$logFilePathname") or die "can't open $logFilePathname";
1433
1434 # title
1435 print hLogFile "\n$separation\n $logTitle\n$separation\n";
1436
1437 # text
1438 print hLogFile $logText."\n";
1439
1440 print hLogFile "\n\n";
1441
1442 close(hLogFile);
1443}
1444
1445sub sortByValueDescending
1446{
1447 my ($hash_ref) = @_;
1448 return ${$hash_ref}{$b} <=> ${$hash_ref}{$a};
1449}
1450
1451sub trim()
1452{
1453 my $str;
1454 ($str) = @_;
1455
1456 $str =~ s/(^\s*)|(\s*$)//g;
1457 return $str;
1458}
1459
1460#******************************************************************************
1461# FUNCTION
1462# timeCheck
1463# DESCRIPTION
1464# print current time (in sec.) and time-difference to previous check if exists
1465# PARAMETERS
1466# none
1467# RETURNS
1468# current time and time difference if exists (both in sec.)
1469#******************************************************************************
1470my $timePrev = 0;
1471sub timeCheck()
1472{
1473 my $prePrintStr;
1474 my $postPrintStr;
1475 my $timeCurr = time();
1476 my $timeDiff = 0;
1477
1478 ($prePrintStr, $postPrintStr) = @_;
1479
1480 print "objcheck: ";
1481 print "$prePrintStr" if ($prePrintStr ne "");
1482 print "[Time: ".$timeCurr." sec.";
1483 if ($timePrev > 0) # previous-time exists
1484 {
1485 $timeDiff = $timeCurr - $timePrev;
1486 print "(Diff = $timeDiff)";
1487 }
1488 print "]";
1489 print "$postPrintStr" if ($postPrintStr ne "");
1490 print "\n";
1491 $timePrev = $timeCurr;
1492 return $timeDiff;
1493}
1494
1495sub runMemLayout
1496{
1497 my $htmlFile;
1498 my $batFilename = "~objcheck_runmem.bat";
1499
1500 ($htmlFile) = @_;
1501
1502 open(hFile, ">$batFilename") or die "can't open $batFilename\n";
1503 print hFile "\@echo off\n";
1504 print hFile "pcore\\tools\\python25\\python pcore\\tools\\py\\parse_mem_cfg.py --mcu . --proj $g_prjName 1>$htmlFile 2>>$g_logCompileFile\n";
1505 print hFile "\@echo on\n";
1506 close(hFile);
1507
1508 #&timeCheck();
1509 system("$batFilename");
1510 #&timeCheck();
1511
1512 system("del $batFilename");
1513}