blob: 08e8e8def943ce4296fd51040136be56a27ec3f5 [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# med_mem_check.pl
41#
42# Description:
43# ------------
44# this script is used to do med memory check.
45#
46# Auther:
47# -------
48# Vincent Cho
49#
50# Note:
51# -----
52# none.
53#
54# Log:
55# -----
56# 2008/02/19 Create (from MMI_feature_check.pl)
57#
58
59#BEGIN { push @INC, "pcore/" , 'U:\\00MyPerlLib'} # add additional library path
60#package XXX;
61use strict;
62
63#******************************************************************************
64# Global Data
65#******************************************************************************
66my $returnErrorCode = 0; # return error code or not
67my $genLogTogether = 0; # gen all logs in the same folder or not
68
69my $mcuPath = '.';
70my $headerFilename = "med_mem.h";
71my $headerFilepath = 'media\common\include';
72
73# list the modules which their *.inc will be added into include path
74my @includeMod = (); # include *.inc
75
76# additional path for include files
77my @addIncPath = ();
78
79# additional include files
80my @addIncFiles = ();
81
82# additional lines
83my @addLines = ();
84
85# additional features to watch
86my @addFeaturesToWatch = ();
87
88# remove temp file or not
89my $removeTempFile = 1;
90
91# also process disabled features or not
92my $alsoProcessDisabledFeatures = 1;
93
94# compiler
95my $compiler = "armcc";
96my $viaOption = "--via";
97
98my $macro_on = "__ON__";
99my $macro_off = "__OFF__";
100my $macro_auto = "__AUTO__";
101
102my $checkMainFilename;
103my $logFilename;
104
105my %featureList = ();
106my @sortedAllFeatures = ();
107my @defFeatures = ();
108my @undefFeatures = ();
109my %mismatchCFG = (); # structure: { mismatch-cfg => [0] original config }
110 # [1] result config
111my $allFeatureCount;
112my $defFeatureCount;
113my $undefFeatureCount;
114my $separation = "***********************************************************************";
115
116#******************************************************************************
117# Export Function
118#******************************************************************************
119
120#******************************************************************************
121# Internal Data
122#******************************************************************************
123my @fileData = ();
124my $logPath = "";
125my $prjName = "";
126my %ignoredCFG = ();
127my $mismatchCount;
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, "Usage: 'med_mem_check.pl <project name> <compiler> <via option> <filename> <path>'\n\n";
138 push @usage, "e.g. 'med_mem_check.pl DRAGONFLY_DEMO armcc --via med_mem.h media\\common\\include'\n\n";
139 die join('', @usage);
140}
141else
142{
143 ($prjName, $compiler, $viaOption,
144 $headerFilename, $headerFilepath) = @ARGV;
145
146 push @addIncPath, $headerFilepath;
147}
148
149print "\nstart MED Memory check...\n";
150
151# all logs in the same folder
152if ($genLogTogether)
153{
154 $logPath = "$mcuPath\\build";
155 $logFilename = "$logPath\\".splitFilename($headerFilename, 0)."$prjName.log";
156}
157# each log in its own project folder
158else
159{
160 $logPath = "$mcuPath\\build\\$prjName\\log";
161 $logFilename = "$logPath\\".splitFilename($headerFilename, 0).".log";
162}
163
164# get all feature list
165open(hFile, "<$mcuPath\\$headerFilepath\\$headerFilename") or die "can't open $mcuPath\\$headerFilepath\\$headerFilename";
166@fileData = <hFile>;
167close(hFile);
168
169print "get feature list from $headerFilename...\n";
170foreach my $line (@fileData)
171{
172 my $feature = "";
173
174 # also process marked "//" features or not
175 if ($alsoProcessDisabledFeatures)
176 {
177 if ($line =~ /^([\s]*([\/]{2,})?[\s]*)(#define[\s]+)([\w_]+)([\s]*)/)
178 {
179 $feature = $4;
180 }
181 }
182 else
183 {
184 if ($line =~ /^([\s]*)(#define[\s]+)([\w_]+)([\s]*)/)
185 {
186 $feature = $3;
187 }
188 }
189
190 # ignore empty one
191 if ($feature ne "")
192 {
193 if ($feature !~ /^CFG_/)
194 {
195 $featureList{$feature} = "";
196 }
197 # CFG_XXX
198 else
199 {
200 $ignoredCFG{$feature} = 1;
201 #print "ignored CFG [$feature]\n";
202 }
203 }
204}
205
206@sortedAllFeatures = sort(keys(%featureList));
207
208# add additional features to watch
209push @sortedAllFeatures, @addFeaturesToWatch;
210
211$allFeatureCount = @sortedAllFeatures;
212
213$checkMainFilename = "~".splitFilename($headerFilename, 0)."_check";
214
215# generate XXX_check.c
216print "generate feature check file...\n";
217genCheckDotC("$checkMainFilename.c", $headerFilename, \@sortedAllFeatures);
218
219# validate features
220print "validate features...\n";
221processCheckDotC("-E");
222
223# check def/undef features in pre-processed file
224print "check def/undef features in pre-processed file...\n";
225checkFeatures("$checkMainFilename.obj", \%featureList, \@sortedAllFeatures, \@defFeatures, \@undefFeatures);
226$defFeatureCount = @defFeatures;
227$undefFeatureCount = @undefFeatures;
228
229if ($removeTempFile)
230{
231 system("del $checkMainFilename.c");
232 system("del $checkMainFilename.obj");
233}
234
235
236# output results
237genLog($logFilename, \%mismatchCFG, \@defFeatures, \%featureList,
238 \@undefFeatures, \@sortedAllFeatures);
239
240# verify result
241print "\n[$headerFilename]\n";
242print "All feature count = $allFeatureCount\nDefined count = $defFeatureCount\nUndef count = $undefFeatureCount\n";
243
244print "MED Memory Check - Done\n";
245
246if ($returnErrorCode && $mismatchCount)
247{
248 exit 1;
249}
250exit 0;
251
252#******************************************************************************
253# Internal Function
254#******************************************************************************
255
256#******************************************************************************
257# FUNCTION
258# genCheckDotC
259# DESCRIPTION
260# xxx
261# PARAMETERS
262# xxx
263# RETURNS
264# none
265#******************************************************************************
266sub genCheckDotC()
267{
268 my $filename;
269 my $headerFilename;
270 my @fileData;
271 my $pUserData; # reference to data array
272
273 ($filename, $headerFilename, $pUserData) = @_;
274
275 open(hFile, ">$filename") or die "can't open $filename";
276
277 foreach my $line (@addLines)
278 {
279 print hFile $line;
280 }
281
282 # write header part
283
284 foreach my $inc (@addIncFiles)
285 {
286 print hFile "#include \"$inc\"\n";
287 }
288
289 print hFile "#include \"$headerFilename\"\n\n";
290
291 # write start tag
292 print hFile "static void * feature_check[] = {\n";
293
294 foreach my $data (@$pUserData)
295 {
296 print hFile "(void *)$data,\n";
297 }
298
299 # write end tag
300 print hFile "(void *)\"END FEATURE LIST\"};\n";
301
302 close(hFile);
303}
304
305
306#******************************************************************************
307# FUNCTION
308# processCheckDotC
309# DESCRIPTION
310# xxx
311# PARAMETERS
312# xxx
313# RETURNS
314# none
315#******************************************************************************
316sub processCheckDotC()
317{
318 my $infoFilename = "$mcuPath\\build\\$prjName\\log\\info.log";
319 my $defTmpFilename = "$checkMainFilename.def";
320 my $incTmpFilename = "$checkMainFilename.inc";
321 my $compileOptions;
322 my @fileData;
323 my $inSection = 0;
324 my $incPaths = "";
325 my $commonOptions = "";
326
327 my $incFilename;
328 my $count = 0;
329
330 ($compileOptions) = @_;
331
332 # read inc from *.inc
333 foreach my $mod (@includeMod)
334 {
335 $incFilename = "$mcuPath\\make\\$mod\\$mod.inc";
336 open(hFile, "<$incFilename") or die "can't open $incFilename";
337 @fileData = <hFile>;
338 close(hFile);
339
340 foreach my $line (@fileData)
341 {
342 if ($line =~ /(^[^\s]*)([\s]*$)/)
343 {
344 $incPaths = "$incPaths\n-I$mcuPath\\$1";
345 }
346 }
347 }
348
349 foreach my $inc (@addIncPath)
350 {
351 $incPaths = "$incPaths\n-I$mcuPath\\$inc";
352 }
353
354 # read common options and common include path from info.log
355 open(hFile, "<$infoFilename") or die "can't open $infoFilename";
356 @fileData = <hFile>;
357 close(hFile);
358
359 foreach my $line (@fileData)
360 {
361 if ($line =~ /\[ COMMON OPTION \]/)
362 {
363 $inSection = 1;
364 next;
365 }
366 elsif ($line =~ /\[ COMMON INCLUDE PATH \]/)
367 {
368 $inSection = 2;
369 next;
370 }
371
372 if ($line =~ /(^[^\[][^\s]*)/)
373 {
374 if ($inSection == 1)
375 {
376 #print "$1\n";
377 $commonOptions = "$commonOptions\n-D$1";
378 }
379 elsif ($inSection == 2)
380 {
381 my $inc = "$1";
382
383 if ($inc !~ /:/)
384 {
385 $inc = "$mcuPath\\$inc";
386 }
387 #print "$inc\n";
388 $incPaths = "$incPaths\n-I$inc";
389 }
390 }
391 else
392 {
393 $inSection = 0;
394 }
395 }
396 #print "$commonOptions\n";
397 open(hFile, ">$defTmpFilename") or die "can't open $defTmpFilename";
398 print hFile "$commonOptions\n";
399 close(hFile);
400
401 #print "$incPaths\n";
402 open(hFile, ">$incTmpFilename") or die "can't open $incTmpFilename";
403 print hFile "$incPaths\n";
404 close(hFile);
405
406 open(hFile, ">makeCheck.bat") or die "makeCheck.bat";
407 print hFile "\@echo off\n";
408 print hFile "\"$compiler\" $checkMainFilename.c -o $checkMainFilename.obj $compileOptions $viaOption $defTmpFilename $viaOption $incTmpFilename\n";
409 print hFile "\@echo on\n";
410 close(hFile);
411 system("makeCheck.bat");
412 if ($removeTempFile)
413 {
414 system("del makeCheck.bat");
415 system("del $defTmpFilename");
416 system("del $incTmpFilename");
417 }
418
419 # post-process *.obj
420 open(hFile, "<$checkMainFilename.obj") or die "can't open $checkMainFilename.obj\n";
421 @fileData = <hFile>;
422 close(hFile);
423
424 # remove multi-CR/LF
425 my $tmpStr = join('',@fileData);
426 $tmpStr =~ s/\n([\s]+)\n/\n\n/g;
427 open(hFile, ">$checkMainFilename.obj") or die "can't open $checkMainFilename.obj\n";
428 print hFile $tmpStr;
429 close(hFile);
430}
431
432
433#******************************************************************************
434# FUNCTION
435# checkConfig
436# DESCRIPTION
437# xxx
438# PARAMETERS
439# xxx
440# RETURNS
441# none
442#******************************************************************************
443sub checkConfig()
444{
445 my $switchFilePathname;
446 my $featureHash_ref;
447 my $ignoredCFG_ref;
448 my $mismatchCFG_ref;
449
450 my @fileData;
451 my %cfgHash = ();
452 my @cfgList = ();
453
454 ($switchFilePathname, $featureHash_ref, $ignoredCFG_ref,
455 $mismatchCFG_ref) = @_;
456
457 open(hFile, "<$switchFilePathname") or die "can't open $switchFilePathname\n";
458 @fileData = <hFile>;
459 close(hFile);
460
461 # generate cfgHash from featureHash
462 while (my ($feature, $value) = each (%{$featureHash_ref}))
463 {
464 # remove head and tail '_'
465 $feature =~ s/(^[_]*)|([_]*$)//g;
466 $feature = "CFG_"."$feature";
467
468 $value =~ s/[\s]*//g; # remove empty
469 $value =~ s/(^[\(]*)|([\)]*$)//g; # remove headh '(' and tail ')'
470
471 $cfgHash{$feature} = $value;
472 }
473
474 foreach my $line (@fileData)
475 {
476 # get CFG_XXX
477 if ($line =~ /^[\s]*\#define[\s]*(CFG_[\w_]*)[\s]*([^\n\/]*)/)
478 {
479 my $cfg = $1;
480 my $value = $2;
481 my $mismatchValue = "";
482
483 $value =~ s/[\s]*//g; # remove empty
484 $value =~ s/(^[\(]*)|([\)]*$)//g; # remove headh '(' and tail ')'
485
486 # only check on/off type (skip auto and value type)
487 if (($value =~ /^(($macro_on)|($macro_off))$/) && !(${$ignoredCFG_ref}{$cfg}))
488 {
489 if (exists $cfgHash{$cfg})
490 {
491 # cfg = OFF, bug feature is defined
492 if ($value eq $macro_off)
493 {
494 $mismatchValue = $macro_on;
495 }
496 # cfg != feature value
497 elsif ($value ne $cfgHash{$cfg})
498 {
499 $mismatchValue = $cfgHash{$cfg};
500 }
501 }
502 # cfg = ON, but feature is undef
503 elsif ($value eq $macro_on)
504 {
505 $mismatchValue = $macro_off;
506 }
507
508 if ($mismatchValue ne "")
509 {
510 ${$mismatchCFG_ref}{$cfg}[0] = $value; # original config
511 ${$mismatchCFG_ref}{$cfg}[1] = $mismatchValue;
512 }
513 }
514 }
515 }
516
517 # return mismatch count
518 return (scalar(keys(%{$mismatchCFG_ref})));
519}
520
521
522#******************************************************************************
523# FUNCTION
524# checkFeatures
525# DESCRIPTION
526# xxx
527# PARAMETERS
528# xxx
529# RETURNS
530# none
531#******************************************************************************
532sub checkFeatures()
533{
534 my $filename; # preprocessed object filename
535 my $pFeatureList; # reference to hash of feature list,
536 # after this call, only contains defined features
537 my $pSortedAllFeatures; # reference to array of sorted all features
538 my $pDefFeatures; # reference to array of defined features
539 my $pUndefFeatures; # reference to array of undefined features
540
541 my @fileData;
542 my $isFeature = 0;
543 my $featureIndex;
544 my $defFeature;
545
546 ($filename, $pFeatureList, $pSortedAllFeatures,
547 $pDefFeatures, $pUndefFeatures) = @_;
548
549 open(hFile, "<$filename") or die "can't open $filename";
550 @fileData = <hFile>;
551 close(hFile);
552
553 foreach my $line (@fileData)
554 {
555 if ($isFeature)
556 {
557 if ($line =~ /(^\(void \*\)[\s]*)([^,]*)([\s]*,$)/)
558 {
559 $defFeature = $$pSortedAllFeatures[$featureIndex];
560
561 if ($2 eq $defFeature)
562 {
563 # undefined symbols ("_XXX_" shows)
564
565 push @$pUndefFeatures, $2;
566
567 # remove it from feature list
568 delete $$pFeatureList{$2};
569
570 #print "[U] $2\n";
571 }
572 else
573 {
574 # process defined symbols
575
576 push @$pDefFeatures, $defFeature;
577
578 # update value of feature list
579 $$pFeatureList{$defFeature} = $2;
580
581 #print "[D] $defFeature = $2\n";
582 }
583 }
584 # end of feature list
585 elsif ($line =~ /"END FEATURE LIST"}/)
586 {
587 $isFeature = 0;
588 }
589 elsif ($line !~ /^[\s]*$/)
590 {
591 print "[Not Processed] \"$line\"\n";
592 }
593
594 #print "[$featureIndex] $$pSortedAllFeatures[$featureIndex] $line\n";
595 $featureIndex++;
596 }
597
598 # check if begining of feature list
599 if ($line =~ /feature_check\[\]/)
600 {
601 $isFeature = 1;
602 $featureIndex = 0;
603 }
604 }
605}
606
607
608#******************************************************************************
609# FUNCTION
610# splitFilename
611# DESCRIPTION
612# xxx
613# PARAMETERS
614# $filename [IN] - filename
615# $refSubFilename [OUT] - reference to sub filename, may be NULL
616# RETURNS
617# main filename
618#******************************************************************************
619sub splitFilename()
620{
621 my $filename;
622 my $refSubFilename = "";
623 my $mainFilename = "";
624
625 ($filename, $refSubFilename) = @_;
626
627 if ($filename =~ /([^\s]*)(\.)([^\.]*$)/)
628 {
629 #print "$filename [$1][$3]\n";
630 $mainFilename = "$1";
631 if ($refSubFilename != 0)
632 {
633 $$refSubFilename = "$3";
634 }
635 }
636 return $mainFilename;
637}
638
639
640#******************************************************************************
641# FUNCTION
642# genLog
643# DESCRIPTION
644# xxx
645# PARAMETERS
646# $filename [IN] - log file pathname
647# RETURNS
648# none
649#******************************************************************************
650sub genLog()
651{
652 my $logFilePathname;
653 my $mismatchCFG_href;
654 my $defFeatures_aref;
655 my $featureData_href;
656 my $undefFeatures_aref;
657 my $sortedAllFeatures_aref;
658
659 my $col1LenMax = 0;
660 my $mismatchCount;
661 my $allFeatureCount;
662 my $defFeatureCount;
663 my $undefFeatureCount;
664
665 ($logFilePathname, $mismatchCFG_href, $defFeatures_aref,
666 $featureData_href, $undefFeatures_aref, $sortedAllFeatures_aref) = @_;
667
668 open(hLogFile, ">$logFilePathname") or die "can't open $logFilePathname";
669
670 open(hMEDFile, "<~med_mem_info.log") or die "can't open ~med_mem_info.log";
671
672 while(<hMEDFile>){
673 print hLogFile $_;
674 }
675
676
677 #$mismatchCount = keys(%{$mismatchCFG_href});
678 $allFeatureCount = @$sortedAllFeatures_aref;
679 $defFeatureCount = @$defFeatures_aref;
680 $undefFeatureCount = @$undefFeatures_aref;
681
682 $col1LenMax = 0;
683 foreach my $feature (@$sortedAllFeatures_aref)
684 {
685 $col1LenMax = length($feature) if (length($feature)>$col1LenMax);
686 }
687
688 # result: Defined Features
689 print hLogFile "\n$separation\n[MED Scenarios ($defFeatureCount)]\n$separation\n\n";
690 foreach my $feature (@$defFeatures_aref)
691 {
692 print hLogFile sprintf("[D] %-*s%s\n", $col1LenMax+8,
693 $feature, ${$featureData_href}{$feature});
694 }
695 print hLogFile "\n\n";
696 close(hLogFile);
697 close(hMEDFile);
698
699 print "log generated at $logFilePathname\n";
700}