blob: 038c784150b98bece7d182793296c9a0cf7a47f4 [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) 2007
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# Filename:
38# ---------
39# operator_feature_check.pl
40#
41# Description:
42# ------------
43# To generate dummy C files and pre-process them to get macro values.
44#
45# Auther:
46# -------
47# Frank Wu
48#
49# Note:
50# -----
51# none.
52#
53# Log:
54# -----
55# 2007/04/01 Create.
56#
57use strict;
58
59#******************************************************************************
60# Global Data
61#******************************************************************************
62my $returnErrorCode = 0; # return error code or not
63
64my $mcuPath = "$ARGV[1]";
65my $headerFilename = "$ARGV[2]";
66my $operatorHeaderFile = "$ARGV[3]";
67my $headerFilepath = "$ARGV[4]";
68my $IsResult = "$ARGV[6]";#1: To get finial values. 0: To get original values.
69
70# list the modules which their *.inc will be added into include path
71my @includeMod = (); # include *.inc
72
73# additional path for include files
74my @addIncPath = ($headerFilepath);
75
76# additional include files
77my @addIncFiles = ();
78
79# additional lines
80my @addLines = ();
81
82# additional features to watch
83my @addFeaturesToWatch = ();
84
85# remove temp file or not
86my $removeTempFile = 1;
87
88# also process disabled features or not
89my $alsoProcessDisabledFeatures = 0;
90
91# compiler
92my $compiler = "$ARGV[7]";
93my $VIA = "$ARGV[8]";
94
95my $checkMainFilename;
96my $logFilename;
97
98my %featureList = ();
99my @sortedAllFeatures = ();
100my @defFeatures = ();
101my @undefFeatures = ();
102
103my $allFeatureCount;
104my $defFeatureCount;
105my $undefFeatureCount;
106
107#******************************************************************************
108# Export Function
109#******************************************************************************
110
111#******************************************************************************
112# Internal Data
113#******************************************************************************
114my @fileData = ();
115my $logPath = "";
116my $prjName = "";
117
118#******************************************************************************
119# Program Start
120#******************************************************************************
121
122# get project name from input argument
123if (scalar(@ARGV) == 0)
124{
125 die "\nUsage: operator_feature_check.pl <project name> <mcu path>
126 <customer header file> <operator header file> <customer header file path>
127 <operator path> <1: To get final values 0: To get initial values>
128 <compiler path> <compiler via argument>\n";
129}
130else
131{
132 $prjName = $ARGV[0];
133}
134
135print "\nStart Header File Feature Check...\n";
136
137$logPath = $ARGV[5];
138
139# get all feature list
140open(hFile, "<$logPath\\$headerFilename") or die "can't open $logPath\\$headerFilename";
141@fileData = <hFile>;
142close(hFile);
143
144print "get feature list from $headerFilename...\n";
145foreach my $line (@fileData)
146{
147 my $feature = "";
148
149 # also process marked "//" features or not
150 if ($alsoProcessDisabledFeatures)
151 {
152 if ($line =~ /^([\s]*([\/]{2,})?[\s]*)(#define[\s]+)([\w_]+)([\s]*)/)
153 {
154 $feature = $4;
155 }
156 }
157 else
158 {
159 if ($line =~ /^([\s]*)(#define[\s]+)([\w_]+)([\s]*)/)
160 {
161 $feature = $3;
162 } elsif ($line =~ /^([\s]*([\/]{2,})[\s]*)\{(.+)\}/) {
163 $feature = $3;
164 }
165 }
166
167 # ignore empty one
168 if ($feature ne "")
169 {
170 $featureList{$feature} = "";
171 }
172}
173
174@sortedAllFeatures = sort(keys(%featureList));
175
176# add additional features to watch
177push @sortedAllFeatures, @addFeaturesToWatch;
178
179$allFeatureCount = @sortedAllFeatures;
180
181$checkMainFilename = "~".splitFilename($headerFilename, 0)."_check";
182
183# generate XXX_check.c
184print "generate feature check file...\n";
185genCheckDotC("$checkMainFilename.c", $headerFilename, \@sortedAllFeatures);
186
187# validate features
188print "validate features...\n";
189processCheckDotC("-E");
190
191# check def/undef features in pre-processed file
192print "check def/undef features in pre-processed file...\n";
193checkFeatures("$checkMainFilename.obj", \%featureList, \@sortedAllFeatures, \@defFeatures, \@undefFeatures);
194$defFeatureCount = @defFeatures;
195$undefFeatureCount = @undefFeatures;
196
197if ($removeTempFile)
198{
199 system("del /F /Q $checkMainFilename.c");
200 system("del /F /Q $checkMainFilename.obj");
201}
202$logFilename = splitFilename($headerFilename, 0)."_$prjName.log";
203
204checkConfig("$logPath\\$operatorHeaderFile", \%featureList, $logFilename);
205
206if ($returnErrorCode)
207{
208 exit 1;
209}
210exit 0;
211
212#******************************************************************************
213# Internal Function
214#******************************************************************************
215
216#******************************************************************************
217# FUNCTION
218# genCheckDotC
219# DESCRIPTION
220# xxx
221# PARAMETERS
222# xxx
223# RETURNS
224# none
225#******************************************************************************
226sub genCheckDotC()
227{
228 my $filename;
229 my $headerFilename;
230 my @fileData;
231 my $pUserData; # reference to data array
232
233 ($filename, $headerFilename, $pUserData) = @_;
234
235 open(hFile, ">$filename") or die "can't open $filename";
236
237 foreach my $line (@addLines)
238 {
239 print hFile $line;
240 }
241
242 # write header part
243
244 foreach my $inc (@addIncFiles)
245 {
246 print hFile "#include \"$inc\"\n";
247 }
248
249 print hFile "#include \"$headerFilename\"\n\n";
250
251 # write start tag
252 print hFile "static void * feature_check[] = {\n";
253
254 foreach my $data (@$pUserData)
255 {
256 print hFile "(void *)$data,\n";
257 }
258
259 # write end tag
260 print hFile "(void *)\"END FEATURE LIST\"};\n";
261
262 close(hFile);
263}
264
265
266#******************************************************************************
267# FUNCTION
268# processCheckDotC
269# DESCRIPTION
270# xxx
271# PARAMETERS
272# xxx
273# RETURNS
274# none
275#******************************************************************************
276sub processCheckDotC()
277{
278 my $infoFilename = "$mcuPath\\build\\$prjName\\log\\info.log";
279 my $defTmpFilename = "$checkMainFilename.def";
280 my $incTmpFilename = "$checkMainFilename.inc";
281 my $compileOptions;
282 my @fileData;
283 my $inSection = 0;
284 my $incPaths = "";
285 my $commonOptions = "";
286
287 my $incFilename;
288 my $count = 0;
289
290 ($compileOptions) = @_;
291
292 # read inc from *.inc
293 foreach my $mod (@includeMod)
294 {
295 $incFilename = "$mcuPath\\make\\$mod\\$mod.inc";
296 open(hFile, "<$incFilename") or die "can't open $incFilename";
297 @fileData = <hFile>;
298 close(hFile);
299
300 foreach my $line (@fileData)
301 {
302 if ($line =~ /(^[^\s]*)([\s]*$)/)
303 {
304 $incPaths = "$incPaths\n-I$mcuPath\\$1";
305 }
306 }
307 }
308
309 foreach my $inc (@addIncPath)
310 {
311 $incPaths = "$incPaths\n-I$mcuPath\\$inc";
312 }
313
314 # read common options and common include path from info.log
315 open(hFile, "<$infoFilename") or die "can't open $infoFilename";
316 @fileData = <hFile>;
317 close(hFile);
318
319 foreach my $line (@fileData)
320 {
321 if ($line =~ /\[ COMMON OPTION \]/)
322 {
323 $inSection = 1;
324 next;
325 }
326 elsif ($line =~ /\[ COMMON INCLUDE PATH \]/)
327 {
328 $inSection = 2;
329 next;
330 }
331
332 if ($line =~ /(^[^\[][^\s]*)/)
333 {
334 if ($inSection == 1)
335 {
336 $commonOptions = "$commonOptions\n-D$1";
337 }
338 elsif ($inSection == 2)
339 {
340 my $inc = "$1";
341
342 if ($inc !~ /:/)
343 {
344 $inc = "$mcuPath\\$inc";
345 }
346 $incPaths = "$incPaths\n-I$inc";
347 }
348 }
349 else
350 {
351 $inSection = 0;
352 }
353 }
354 open(hFile, ">$defTmpFilename") or die "can't open $defTmpFilename";
355 print hFile "$commonOptions\n";
356 close(hFile);
357
358 open(hFile, ">$incTmpFilename") or die "can't open $incTmpFilename";
359 print hFile "$incPaths\n";
360 close(hFile);
361
362 open(hFile, ">makeCheck.bat") or die "makeCheck.bat";
363 print hFile "\@echo off\n";
364 print hFile "$compiler $checkMainFilename.c -o $checkMainFilename.obj $compileOptions $VIA $defTmpFilename $VIA $incTmpFilename\n";
365 print hFile "\@echo on\n";
366 close(hFile);
367 system("makeCheck.bat");
368 if ($removeTempFile)
369 {
370 system("del /F /Q makeCheck.bat");
371 system("del /F /Q $defTmpFilename");
372 system("del /F /Q $incTmpFilename");
373 }
374
375 # post-process *.obj
376 open(hFile, "<$checkMainFilename.obj") or die "can't open $checkMainFilename.obj\n";
377 @fileData = <hFile>;
378 close(hFile);
379
380 # remove multi-CR/LF
381 my $tmpStr = join('',@fileData);
382 $tmpStr =~ s/\n([\s]+)\n/\n\n/g;
383 open(hFile, ">$checkMainFilename.obj") or die "can't open $checkMainFilename.obj\n";
384 print hFile $tmpStr;
385 close(hFile);
386}
387
388
389#******************************************************************************
390# FUNCTION
391# checkConfig
392# DESCRIPTION
393# xxx
394# PARAMETERS
395# xxx
396# RETURNS
397# none
398#******************************************************************************
399sub checkConfig()
400{
401 my $switchFilePathname;
402 my $featureHash_ref;
403 my %featureHash_temp = ();
404 my $logname = "";
405 my @fileData;
406 my %cfgHash = ();
407 my @cfgList = ();
408
409 ($switchFilePathname, $featureHash_ref, $logname) = @_;
410 open(hFile, "<$switchFilePathname") or die "can't open $switchFilePathname. $!\n";
411 @fileData = <hFile>;
412 close(hFile);
413
414 open(hFile, ">$logname") or die "can't open $logname:$!\n";
415 $switchFilePathname =~ /.+\\(.+)\./;
416 my $headerfile = $1;
417 if ($IsResult){
418 open(writeRsultValue,">$1_ResultValue.log") or die "Error: $!\n";
419 } else {
420 open(writeOriginalValue,">$1_OriginalValue.log") or die "Error: $!\n";
421 }
422 # generate cfgHash from featureHash
423 while (my ($feature, $value) = each (%{$featureHash_ref}))
424 {
425 $feature =~ s/(^[_]*)|([_]*$)//g;
426
427 $value =~ s/[\s]*//g; # remove empty
428 $value =~ s/(^[\(]*)|([\)]*$)//g; # remove head '(' and tail ')'
429 if ($IsResult){
430 print writeRsultValue "$feature = $value\n";
431 } else {
432 print writeOriginalValue "$feature = $value\n";
433 }
434 $featureHash_temp{$feature} = "$value";
435
436 $cfgHash{$feature} = $value;
437
438 }
439 foreach my $feature (%featureHash_temp){
440 if ($feature =~ /OP_WARNING_(.+)/){
441 if (index($featureHash_temp{$feature},"OPERATOR_CHECK_MESSAGE_ON")>=0){
442 print hFile "$1's value was modified\n";
443 }
444 }
445 }
446
447 close(hFile);
448}
449
450
451#******************************************************************************
452# FUNCTION
453# checkFeatures
454# DESCRIPTION
455# xxx
456# PARAMETERS
457# xxx
458# RETURNS
459# none
460#******************************************************************************
461sub checkFeatures()
462{
463 my $filename; # preprocessed object filename
464 my $pFeatureList; # reference to hash of feature list,
465 # after this call, only contains defined features
466 my $pSortedAllFeatures; # reference to array of sorted all features
467 my $pDefFeatures; # reference to array of defined features
468 my $pUndefFeatures; # reference to array of undefined features
469
470 my @fileData;
471 my $isFeature = 0;
472 my $featureIndex;
473 my $defFeature;
474
475 ($filename, $pFeatureList, $pSortedAllFeatures,
476 $pDefFeatures, $pUndefFeatures) = @_;
477
478 open(hFile, "<$filename") or die "Cannot open $filename. Error:$!\n";
479 @fileData = <hFile>;
480 close(hFile);
481
482 foreach my $line (@fileData)
483 {
484 if ($isFeature)
485 {
486 if ($line =~ /(^\(void \*\)[\s]*)([^,]*)([\s]*,$)/)
487 {
488 $defFeature = $$pSortedAllFeatures[$featureIndex];
489
490 if ($2 eq $defFeature)
491 {
492 # undefined symbols ("_XXX_" shows)
493 # When the symbol was not defined, the obj will show the symbol name directly.
494 # If the symbol name was shown, we know the symbol was not defined.
495 # If the symbol was defined, the evaluated value will be shown.
496 push @$pUndefFeatures, $2;
497
498 # remove it from feature list
499 delete $$pFeatureList{$2};
500 }
501 else
502 {
503 # process defined symbols
504
505 push @$pDefFeatures, $defFeature;
506
507 # update value of feature list
508 $$pFeatureList{$defFeature} = $2;
509 }
510 }
511 # end of feature list
512 elsif ($line =~ /"END FEATURE LIST"}/)
513 {
514 $isFeature = 0;
515 }
516 elsif ($line !~ /^[\s]*$/)
517 {
518 print "[Not Processed] \"$line\"\n";
519 }
520 $featureIndex++;
521 }
522
523 # check if begining of feature list
524 if ($line =~ /feature_check\[\]/)
525 {
526 $isFeature = 1;
527 $featureIndex = 0;
528 }
529 }
530}
531
532
533#******************************************************************************
534# FUNCTION
535# splitFilename
536# DESCRIPTION
537# xxx
538# PARAMETERS
539# $filename [IN] - filename
540# $refSubFilename [OUT] - reference to sub filename, may be NULL
541# RETURNS
542# main filename
543#******************************************************************************
544sub splitFilename()
545{
546 my $filename;
547 my $refSubFilename = "";
548 my $mainFilename = "";
549
550 ($filename, $refSubFilename) = @_;
551
552 if ($filename =~ /([^\s]*)(\.)([^\.]*$)/)
553 {
554 #print "$filename [$1][$3]\n";
555 $mainFilename = "$1";
556 if ($refSubFilename != 0)
557 {
558 $$refSubFilename = "$3";
559 }
560 }
561 return $mainFilename;
562}
563
564