blob: a760c25befa333a302c5f9b55a1a4b1a2e0fbb00 [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# drv_feature_check.pl
41#
42# Description:
43# ------------
44# this script is used to do mmi feature check.
45#
46# Auther:
47# -------
48# Shinn Lin
49#
50# Note:
51# -----
52# none.
53#
54# Log:
55# -----
56# 2007/03/11 Create.
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 $g_mcuPath = '.';
70my $headerFilename = "MMI_features.h";
71my $switchFilename = "MMI_features_switch.h";
72my $headerFilepath = 'plutommi/mmi/inc';
73my $switchFilepath = 'plutommi/mmi/inc';
74
75my $checkcfg = 'TRUE'; # check feature configuration or NOT
76
77# list the modules which their *.inc will be added into include path
78my @includeMod = ('plutommi'); # include *.inc
79
80# additional path for include files
81my @addIncPath = ();
82
83# additional include files
84my @addIncFiles = ();
85
86# additional lines
87my @addLines = ();
88
89# additional features to watch
90my @addFeaturesToWatch = ();
91
92# remove temp file or not
93my $g_removeTempFile = 1;
94
95# also process disabled features or not
96my $alsoProcessDisabledFeatures = 1;
97
98# compiler
99my $compiler = "armcc";
100my $viaOption = "--via";
101
102my $macro_on = "__ON__";
103my $macro_off = "__OFF__";
104my $macro_auto = "__AUTO__";
105
106my $checkMainFilename;
107my $logFilename;
108
109my %featureList = ();
110my @sortedAllFeatures = ();
111my @defFeatures = ();
112my @undefFeatures = ();
113my %mismatchCFG = (); # structure: { mismatch-cfg => [0] original config }
114 # [1] result config
115my $allFeatureCount;
116my $defFeatureCount;
117my $undefFeatureCount;
118my $separation = "***********************************************************************";
119
120my $switch;
121my $mmidrvfile;
122my $modis_compiler;
123#******************************************************************************
124# Export Function
125#******************************************************************************
126
127#******************************************************************************
128# Internal Data
129#******************************************************************************
130my @fileData = ();
131my $logPath = "";
132my $prjName = "";
133my %ignoredCFG = ();
134my $mismatchCount;
135my $buildFolder="";
136
137#******************************************************************************
138# Program Start
139#******************************************************************************
140
141# get project name from input argument
142if (scalar(@ARGV) == 0)
143{
144 my @usage = ();
145 push @usage, "\nUsage 1: 'drv_feature_check.pl <project name> <compiler> <via option> <feature filename> <switch filename> <checkCfg : TRUE, FALSE> <returnErrorOrNot> <MMI or DRV> <MMI_DEF_DEFS make file> <output path> <modis_compiler>'\n\n";
146 push @usage, "Usage 2: 'drv_feature_check.pl <project name> <compiler> <via option> <filename> <filename> <checkCfg : TRUE, FALSE> <returnErrorOrNot> <MMI or DRV> <MMI_DEF_DEFS make file> <output path>'\n\n";
147 push @usage, "e.g. 'drv_feature_check.pl DRAGONFLY_DEMO armcc --via plutommi/mmi/inc/mmi_features.h plutommi/mmi/inc/mmi_features.h FALSE 0'\n\n";
148 die join('', @usage);
149}
150else
151{
152 ($buildFolder, $prjName, $compiler, $viaOption,
153 $headerFilename, $switchFilename, $checkcfg, $returnErrorCode, $mmidrvfile, $switch, $modis_compiler) = @ARGV;
154
155 $headerFilename = &splitPathName($headerFilename, \$headerFilepath);
156 $switchFilename = &splitPathName($switchFilename, \$switchFilepath);
157 push @addIncPath, $headerFilepath;
158 push @addIncPath, $switchFilepath;
159}
160
161if ($switch =~ /DRV/ig)
162{
163 open FILEHANDLE, "<$g_mcuPath/$headerFilepath/$headerFilename" or die "Cannot read $g_mcuPath/$headerFilepath/$headerFilename";
164 my @includeList = <FILEHANDLE>;
165 close FILEHANDLE;
166 my $Backup = $/;
167 undef $/;
168 my $fileContent = "";
169 foreach my $line (@includeList)
170 {
171 if ($line =~ /\#include \"(\S+)\"/)
172 {
173 if (-e "$g_mcuPath/$headerFilepath/$1")
174 {
175 open INPUTHANDLE, "<$g_mcuPath/$headerFilepath/$1";
176 my $content = <INPUTHANDLE>;
177 close INPUTHANDLE;
178 $content =~ s/\#ifndef\s+(__DRV_FEATURES_\w+_H__)\n\#define\s+(__DRV_FEATURES_\w+_H__)/#ifndef $1/i;
179 $fileContent .= "$content\n";
180 }
181 else
182 {
183 warn "Miss $g_mcuPath/$headerFilepath/$1\n";
184 }
185 }
186 }
187 $/ = $Backup;
188 if (-e "$g_mcuPath/$switchFilepath/$switchFilename")
189 {
190 warn "$g_mcuPath/$switchFilepath/$switchFilename shound not exist, overwrite !\n";
191 }
192 open FILEHANDLE, ">$g_mcuPath/$switchFilepath/$switchFilename" or die "Cannot write $g_mcuPath/$switchFilepath/$switchFilename\n";
193 print FILEHANDLE $fileContent;
194 close FILEHANDLE;
195}
196
197print "\nstart Drv feature check...\n";
198
199# all logs in the same folder
200$logFilename = $switchFilename;
201$logFilename = $headerFilename if ($switchFilename =~ /^MMI_features_switch\.h$/i);
202if ($logPath eq "")
203{
204 if ($genLogTogether)
205 {
206 $logPath = "$g_mcuPath/build";
207 $logFilename = "$logPath/".splitFilename($logFilename, 0)."$prjName.log";
208 }
209 # each log in its own project folder
210 else
211 {
212 $logPath = "$g_mcuPath/$buildFolder/bin/log";
213 $logFilename = "$logPath/".splitFilename($logFilename, 0).".log";
214 }
215}
216else
217{
218 $logFilename = "$logPath/".splitFilename($logFilename, 0).".log";
219}
220
221
222# get all feature list
223my @featureFileList = ("$g_mcuPath/$headerFilepath/$headerFilename",
224 "$g_mcuPath/$switchFilepath/$switchFilename");
225&getFeatureList(\@featureFileList, \%featureList);
226
227@sortedAllFeatures = sort(keys(%featureList));
228
229# add additional features to watch
230push @sortedAllFeatures, @addFeaturesToWatch;
231
232# get preprocess result
233&getMacroPreprocessResult($headerFilename, \%featureList, \@sortedAllFeatures,
234 \@defFeatures, \@undefFeatures);
235
236$allFeatureCount = @sortedAllFeatures;
237$defFeatureCount = @defFeatures;
238$undefFeatureCount = @undefFeatures;
239
240# check CFG
241$mismatchCount = checkConfig("$g_mcuPath/$switchFilepath/$switchFilename",
242 \%featureList, \%ignoredCFG, \%mismatchCFG);
243
244# output results
245genLog($logFilename, \%mismatchCFG, \@defFeatures, \%featureList,
246 \@undefFeatures, \@sortedAllFeatures, $switch, $mmidrvfile);
247
248# verify result
249my @tmpList = ();
250push @tmpList, splitPathName($_, 0) foreach @featureFileList;
251print "\n[".join(', ', @tmpList)."]\n";
252print "All feature count = $allFeatureCount\nDefined count = $defFeatureCount\nUndef count = $undefFeatureCount\n";
253
254print "\n[$switchFilename]\n";
255print "Mismatch Config count = $mismatchCount\n\n";
256print "DRV Feature Check - ";
257
258if ($returnErrorCode && $mismatchCount)
259{
260 print "Fail\n(Mismatch Config count = $mismatchCount, please check $logFilename)\n";
261 exit 1;
262}
263print "Done\n";
264exit 0;
265
266#******************************************************************************
267# Internal Function
268#******************************************************************************
269
270#******************************************************************************
271# FUNCTION
272# getMacroPreprocessResult
273# DESCRIPTION
274# xxx
275# PARAMETERS
276# xxx
277# RETURNS
278# none
279#******************************************************************************
280sub getMacroPreprocessResult()
281{
282 my ($targetFilename, $featureList_href, $sortedAllFeatures_aref,
283 $defFeatures_aref, $undefFeatures_aref) = @_;
284
285 my $checkMainFilename = "$g_mcuPath/$switchFilepath/~".splitFilename($targetFilename, 0)."_check";
286
287 # generate XXX_check.c
288 print "generate feature check file...\n";
289 genCheckDotC("$checkMainFilename.c", $targetFilename, $sortedAllFeatures_aref);
290
291 # validate features
292 print "validate features...[$checkMainFilename]\n";
293 processCheckDotC($checkMainFilename, "-E");
294
295 # check def/undef features in pre-processed file
296 print "check def/undef features for $targetFilename...\n";
297 checkFeatures("$checkMainFilename.obj", $featureList_href, $sortedAllFeatures_aref, $defFeatures_aref, $undefFeatures_aref);
298
299 if ($g_removeTempFile)
300 {
301 unlink("$checkMainFilename.c");
302 unlink("$checkMainFilename.obj");
303 }
304}
305
306
307#******************************************************************************
308# FUNCTION
309# getFeatureList
310# DESCRIPTION
311# get features from *.h (has exceptions, e.g. CFG_xxx, etc.)
312# PARAMETERS
313# xxx
314# RETURNS
315# none
316#******************************************************************************
317sub getFeatureList()
318{
319 my ($fileList_aref, $featureList_href) = @_;
320
321 foreach my $filePathname (@{$fileList_aref})
322 {
323 open(hFile, "<$filePathname") or die "can't open $filePathname";
324 @fileData = <hFile>;
325 close(hFile);
326
327 my $filename = splitPathName($filePathname, 0);
328 print "get feature list from $filename...\n";
329 my $fileWrapper = uc $filename;
330 $fileWrapper =~ s/\./_/;
331 foreach my $line (@fileData)
332 {
333 my $feature = "";
334
335 # also process marked "//" features or not
336 if ($alsoProcessDisabledFeatures)
337 {
338 if ($line =~ /^([\s]*([\/]{2,})?[\s]*)(#define[\s]+)([\w_]+)([\s]*)/)
339 {
340 $feature = $4;
341 }
342 }
343 else
344 {
345 if ($line =~ /^([\s]*)(#define[\s]+)([\w_]+)([\s]*)/)
346 {
347 $feature = $3;
348 }
349 }
350
351 # ignore empty one
352 if ($feature ne "")
353 {
354 if (($feature !~ /^((CFG_)|(OP_WARNING))/) && # skip CFG_XXX, OP_WARNING_XXX
355 ($feature !~ /^(([_]*$fileWrapper[_]*)|(__MMI_FEATURES__))$/)) # skip file wrapper, e.g. __XXX_H__
356 {
357 ${$featureList_href}{$feature} = "";
358 }
359 }
360 }
361 }
362}
363
364
365#******************************************************************************
366# FUNCTION
367# genCheckDotC
368# DESCRIPTION
369# xxx
370# PARAMETERS
371# xxx
372# RETURNS
373# none
374#******************************************************************************
375sub genCheckDotC()
376{
377 my $filename;
378 my $headerFilename;
379 my @fileData;
380 my $pUserData; # reference to data array
381
382 ($filename, $headerFilename, $pUserData) = @_;
383
384 open(hFile, ">$filename") or die "can't open $filename";
385
386 foreach my $line (@addLines)
387 {
388 print hFile $line;
389 }
390
391 # write header part
392
393 foreach my $inc (@addIncFiles)
394 {
395 print hFile "#include \"$inc\"\n";
396 }
397
398 print hFile "#include \"$headerFilename\"\n\n" if ($headerFilename ne "");
399
400 # write start tag
401 print hFile "static void * feature_check[] = {\n";
402
403 foreach my $data (@$pUserData)
404 {
405 print hFile "(void *)$data,\n";
406 }
407
408 # write end tag
409 print hFile "(void *)\"END FEATURE LIST\"};\n";
410
411 close(hFile);
412}
413
414
415#******************************************************************************
416# FUNCTION
417# processCheckDotC
418# DESCRIPTION
419# xxx
420# PARAMETERS
421# xxx
422# RETURNS
423# none
424#******************************************************************************
425sub processCheckDotC()
426{
427 my ($checkMainFilename, $compileOptions) = @_;
428
429 my $infoFilename = "$g_mcuPath/$buildFolder/bin/log/info.log";
430 print "infoFilename = $infoFilename\n";
431 my $defTmpFilename = "$checkMainFilename.def";
432 my $incTmpFilename = "$checkMainFilename.inc";
433 my @fileData;
434 my $inSection = 0;
435 my $incPaths = "";
436 my $commonOptions = "";
437
438 my $count = 0;
439
440 # read common options and common include path from info.log
441 open(hFile, "<$infoFilename") or die "can't open $infoFilename";
442 @fileData = <hFile>;
443 close(hFile);
444
445 foreach my $line (@fileData)
446 {
447 if ($line =~ /\[ COMMON OPTION \]/)
448 {
449 $inSection = 1;
450 next;
451 }
452 elsif ($line =~ /\[ COMMON INCLUDE PATH \]/)
453 {
454 $inSection = 2;
455 next;
456 }
457
458 if ($line =~ /(^[^\[][^\s][^\n]*)/)
459 {
460 if ($inSection == 1)
461 {
462 #print "$1\n";
463 if ($^O eq "MSWin32")
464 {
465 $commonOptions = "$commonOptions\n#define $1";
466 $commonOptions =~ s/=/ /g;
467 }
468 else
469 {
470 $commonOptions = "$commonOptions\n-D$1";
471 }
472 }
473 elsif ($inSection == 2)
474 {
475 my $inc = "$1";
476
477 if ($inc !~ /:/)
478 {
479 $inc = "$g_mcuPath/$inc";
480 }
481 #print "$inc\n";
482 $incPaths = "$incPaths\n-I$inc";
483 }
484 }
485 else
486 {
487 $inSection = 0;
488 }
489 }
490
491 # read inc from *.inc
492# foreach my $mod (@includeMod)
493# {
494# my @incFiles = ();
495# if (&getFileList("$g_mcuPath/$buildFolder/bin/module/$mod/*.inc /s", \@incFiles) > 0)
496# {
497# foreach my $incFilename (@incFiles)
498# {
499# open(hFile, "<$incFilename") or die "can't open $incFilename";
500# @fileData = <hFile>;
501# close(hFile);
502#
503# foreach my $line (@fileData)
504# {
505# if ($line =~ /(^[^\s]+)([\s]*$)/)
506# {
507# $incPaths = "$incPaths\n-I$g_mcuPath/$1";
508# }
509# }
510# }
511# }
512# }
513
514 # additional inc path
515 foreach my $inc (@addIncPath)
516 {
517 $incPaths = "$incPaths\n-I$g_mcuPath/$inc";
518 }
519
520 # read macro from *.def
521# foreach my $mod (@includeMod)
522# {
523# my @defFiles = ();
524# if (&getFileList("$g_mcuPath/$buildFolder/bin/module/$mod/*.def /s", \@defFiles) > 0)
525# {
526# foreach my $defFilename (@defFiles)
527# {
528# open(hFile, "<$defFilename") or die "can't open $defFilename";
529# @fileData = <hFile>;
530# close(hFile);
531#
532# foreach my $line (@fileData)
533# {
534# if ($line =~ /(^[^\s]+)([\s]*$)/)
535# {
536# $commonOptions = "$commonOptions\n-D$1";
537# }
538# }
539# }
540# }
541# }
542
543 #print "$commonOptions\n";
544 open(hFile, ">$defTmpFilename") or die "can't open $defTmpFilename";
545 print hFile "$commonOptions\n";
546 close(hFile);
547
548 #print "$incPaths\n";
549 open(hFile, ">$incTmpFilename") or die "can't open $incTmpFilename";
550 if($compiler =~/GCC/i)
551 {
552 $incPaths =~ s/\\/\//g;
553 }
554 print hFile "$incPaths\n";
555 close(hFile);
556
557 my $result = 0;
558 if($compiler =~/GCC/i)
559 {
560 if ($^O eq "MSWin32")
561 {
562 $result = system("\"$compiler\" $checkMainFilename.c -o $checkMainFilename.obj $compileOptions -imacros $defTmpFilename $viaOption$incTmpFilename");
563 }
564 else
565 {
566 $result = system("\"$compiler\" $checkMainFilename.c -o $checkMainFilename.obj $compileOptions $viaOption$defTmpFilename $viaOption$incTmpFilename");
567 }
568 }
569 else
570 {
571 if($modis_compiler =~ /CLANG/)
572 {
573 $result = system("\"$compiler\" $checkMainFilename.c /P /Fi$checkMainFilename.obj $viaOption$defTmpFilename $viaOption$incTmpFilename");
574 }
575 else
576 {
577 $result = system("\"$compiler\" $checkMainFilename.c -o $checkMainFilename.obj $compileOptions $viaOption $defTmpFilename $viaOption $incTmpFilename");
578 }
579 }
580 exit 1 if ($result);
581 if ($g_removeTempFile)
582 {
583 unlink("$defTmpFilename");
584 unlink("$incTmpFilename");
585 }
586
587 # post-process *.obj
588 open(hFile, "<$checkMainFilename.obj") or die "can't open $checkMainFilename.obj\n";
589 @fileData = <hFile>;
590 close(hFile);
591
592 # remove multi-CR/LF
593 my $tmpStr = join('',@fileData);
594 $tmpStr =~ s/\n([\s]+)\n/\n\n/g;
595 open(hFile, ">$checkMainFilename.obj") or die "can't open $checkMainFilename.obj\n";
596 print hFile $tmpStr;
597 close(hFile);
598}
599
600
601#******************************************************************************
602# FUNCTION
603# checkConfig
604# DESCRIPTION
605# xxx
606# PARAMETERS
607# xxx
608# RETURNS
609# none
610#******************************************************************************
611sub checkConfig()
612{
613 my $switchFilePathname;
614 my $featureHash_ref;
615 my $ignoredCFG_ref;
616 my $mismatchCFG_ref;
617
618 my @fileData;
619 my %cfgHash = ();
620 my @cfgList = ();
621
622 ($switchFilePathname, $featureHash_ref, $ignoredCFG_ref,
623 $mismatchCFG_ref) = @_;
624
625 open(hFile, "<$switchFilePathname") or die "can't open $switchFilePathname\n";
626 @fileData = <hFile>;
627 close(hFile);
628
629 # generate cfgHash from featureHash
630 while (my ($feature, $value) = each (%{$featureHash_ref}))
631 {
632 # remove head and tail '_'
633 $feature =~ s/(^[_]*)|([_]*$)//g;
634 $feature = "CFG_"."$feature";
635
636 $value =~ s/[\s]*//g; # remove empty
637 $value =~ s/(^[\(]*)|([\)]*$)//g; # remove headh '(' and tail ')'
638
639 $cfgHash{$feature} = $value;
640 }
641
642 foreach my $line (@fileData)
643 {
644 # get CFG_XXX
645 if ($line =~ /^[\s]*\#define[\s]*(CFG_[\w_]*)[\s]*([^\n\/]*)/)
646 {
647 my $cfg = $1;
648 my $value = $2;
649 my $mismatchValue = "";
650
651 $value =~ s/[\s]*//g; # remove empty
652 $value =~ s/(^[\(]*)|([\)]*$)//g; # remove headh '(' and tail ')'
653
654 # only check on/off type (skip auto and value type)
655 if (($value =~ /^(($macro_on)|($macro_off))$/) && !(${$ignoredCFG_ref}{$cfg}))
656 {
657 if (exists $cfgHash{$cfg})
658 {
659 # cfg = OFF, bug feature is defined
660 if ($value eq $macro_off)
661 {
662 $mismatchValue = $macro_on;
663 }
664 # cfg != feature value
665 elsif ($value ne $cfgHash{$cfg})
666 {
667 $mismatchValue = $cfgHash{$cfg};
668 }
669 }
670 # cfg = ON, but feature is undef
671 elsif ($value eq $macro_on)
672 {
673 $mismatchValue = $macro_off;
674 }
675
676 if ($mismatchValue ne "")
677 {
678 ${$mismatchCFG_ref}{$cfg}[0] = $value; # original config
679 ${$mismatchCFG_ref}{$cfg}[1] = $mismatchValue;
680 }
681 }
682 }
683 }
684
685 # filter out non-target CFG_xxx
686 if ($checkcfg eq 'TRUE')
687 {
688 my $switchMainFilename = &splitPathName($switchFilePathname, 0);
689 my %tmpMismatchCFG = %{$mismatchCFG_ref};
690 my @tmpMismatchList = keys(%tmpMismatchCFG);
691 my @tmpDefinedMismatch = ();
692 my @tmpUndefMismatch = ();
693 &getMacroPreprocessResult($switchMainFilename, \%tmpMismatchCFG, \@tmpMismatchList,
694 \@tmpDefinedMismatch, \@tmpUndefMismatch);
695 foreach my $cfg (@tmpUndefMismatch)
696 {
697 delete ${$mismatchCFG_ref}{$cfg}; # remove from hash
698 }
699 }
700 # return mismatch count
701 return (scalar(keys(%{$mismatchCFG_ref})));
702}
703
704
705#******************************************************************************
706# FUNCTION
707# checkFeatures
708# DESCRIPTION
709# xxx
710# PARAMETERS
711# xxx
712# RETURNS
713# none
714#******************************************************************************
715sub checkFeatures()
716{
717 my $filename; # preprocessed object filename
718 my $pFeatureList; # reference to hash of feature list,
719 # after this call, only contains defined features
720 my $pSortedAllFeatures; # reference to array of sorted all features
721 my $pDefFeatures; # reference to array of defined features
722 my $pUndefFeatures; # reference to array of undefined features
723
724 my @fileData;
725 my $isFeature = 0;
726 my $featureIndex;
727 my $defFeature;
728
729 ($filename, $pFeatureList, $pSortedAllFeatures,
730 $pDefFeatures, $pUndefFeatures) = @_;
731
732 open(hFile, "<$filename") or die "can't open $filename";
733 @fileData = <hFile>;
734 close(hFile);
735
736 foreach my $line (@fileData)
737 {
738 if ($isFeature)
739 {
740 if ($line =~ /(^\(void \*\)[\s]*)([^,]*)([\s]*,$)/)
741 {
742 $defFeature = $$pSortedAllFeatures[$featureIndex];
743
744 if ($2 eq $defFeature)
745 {
746 # undefined symbols ("_XXX_" shows)
747
748 push @$pUndefFeatures, $2;
749
750 # remove it from feature list
751 delete $$pFeatureList{$2};
752
753 #print "[U] $2\n";
754 }
755 else
756 {
757 # process defined symbols
758
759 push @$pDefFeatures, $defFeature;
760
761 # update value of feature list
762 $$pFeatureList{$defFeature} = $2;
763
764 #print "[D] $defFeature = $2\n";
765 }
766 }
767 # end of feature list
768 elsif ($line =~ /"END FEATURE LIST"}/)
769 {
770 $isFeature = 0;
771 }
772 elsif ($line !~ /^[\s]*$/)
773 {
774 print "[Not Processed] \"$line\"\n";
775 }
776
777 #print "[$featureIndex] $$pSortedAllFeatures[$featureIndex] $line\n";
778 $featureIndex++;
779 }
780
781 # check if begining of feature list
782 if ($line =~ /feature_check\[\]/)
783 {
784 $isFeature = 1;
785 $featureIndex = 0;
786 }
787 }
788}
789
790
791#******************************************************************************
792# FUNCTION
793# splitFilename
794# DESCRIPTION
795# xxx
796# PARAMETERS
797# $filename [IN] - filename
798# $refSubFilename [OUT] - reference to sub filename, may be NULL
799# RETURNS
800# main filename
801#******************************************************************************
802sub splitFilename()
803{
804 my $filename;
805 my $refSubFilename = "";
806 my $mainFilename = "";
807
808 ($filename, $refSubFilename) = @_;
809
810 if ($filename =~ /([^\s]*)(\.)([^\.]*$)/)
811 {
812 #print "$filename [$1][$3]\n";
813 $mainFilename = "$1";
814 if ($refSubFilename != 0)
815 {
816 $$refSubFilename = "$3";
817 }
818 }
819 return $mainFilename;
820}
821
822
823#******************************************************************************
824# FUNCTION
825# splitPathName
826# DESCRIPTION
827# split given filename to filename and path
828# PARAMETERS
829# $filename [IN] - filename
830# $refSubFilename [OUT] - reference to path, may be NULL
831# RETURNS
832# filename
833#******************************************************************************
834sub splitPathName()
835{
836 my $pathname;
837 my $path_ref;
838
839 ($pathname, $path_ref) = @_;
840
841 if ($pathname =~ /(^.*)[\\\/]([^\\\/]+$)/)
842 {
843 #print "path [$1] filename[$2]\n";
844 $$path_ref = $1 if ($path_ref != 0);
845 return $2;
846 }
847 else
848 {
849 $$path_ref = '.' if ($path_ref != 0); # current dir
850 return $pathname;
851 }
852}
853
854
855#******************************************************************************
856# FUNCTION
857# genLog
858# DESCRIPTION
859# xxx
860# PARAMETERS
861# $filename [IN] - log file pathname
862# RETURNS
863# none
864#******************************************************************************
865sub genLog()
866{
867 my $logFilePathname;
868 my $mismatchCFG_href;
869 my $defFeatures_aref;
870 my $featureData_href;
871 my $undefFeatures_aref;
872 my $sortedAllFeatures_aref;
873
874 my $col1LenMax = 0;
875 my $mismatchCount;
876 my $allFeatureCount;
877 my $defFeatureCount;
878 my $undefFeatureCount;
879 my $mismatchPrompt = "";
880 my $switch;
881 my $mmidrvfile;
882
883 ($logFilePathname, $mismatchCFG_href, $defFeatures_aref,
884 $featureData_href, $undefFeatures_aref, $sortedAllFeatures_aref, $switch, $mmidrvfile) = @_;
885
886 open(hLogFile, ">$logFilePathname") or die "can't open $logFilePathname\n";
887
888 open(MMI_DRV_DEFS, ">>$mmidrvfile") or die "1 can't open $mmidrvfile\n";
889 if ($switch =~ /MMI/ig) {
890 print MMI_DRV_DEFS "MMI_DEFS = \\\n";
891 }
892 if ($switch =~ /DRV/ig) {
893 print MMI_DRV_DEFS "DRV_DEFS = \\\n";
894 if (-e "$g_mcuPath/$switchFilepath/$switchFilename")
895 {
896 unlink "$g_mcuPath/$switchFilepath/$switchFilename";
897 }
898 else
899 {
900 warn "Fail in $g_mcuPath/$switchFilepath/$switchFilename\n";
901 }
902 }
903 if ($switch =~ /OPTR/ig) {
904 print MMI_DRV_DEFS "OPTR_DEFS = \\\n";
905 }
906
907 $mismatchCount = keys(%{$mismatchCFG_href});
908 $allFeatureCount = @$sortedAllFeatures_aref;
909 $defFeatureCount = @$defFeatures_aref;
910 $undefFeatureCount = @$undefFeatures_aref;
911
912 # result: summary
913 print hLogFile "\n$separation\n[Summary]\n$separation\n\n";
914 print hLogFile "Mismatch Config count = $mismatchCount\n";
915 print hLogFile "Defined Feature count = $defFeatureCount\n";
916 print hLogFile "Undefined Feature count = $undefFeatureCount\n";
917 print hLogFile "All Feature count = $allFeatureCount\n";
918 print hLogFile "\n";
919
920 # result: mismatch Configs
921
922 # calculate max. length of config name
923 foreach my $feature (keys(%{$mismatchCFG_href}))
924 {
925 $col1LenMax = length($feature) if (length($feature)>$col1LenMax);
926 }
927
928 if ($mismatchCount)
929 {
930 if ($returnErrorCode)
931 {
932 $mismatchPrompt = " *error*";
933 }
934 else
935 {
936 $mismatchPrompt = " *warning*";
937 }
938 }
939
940 print hLogFile "\n$separation\n[Mismatch Configs ($mismatchCount)]$mismatchPrompt\n$separation\n\n";
941 print hLogFile sprintf("%-*s%-15s%s\n", $col1LenMax+8, "<CFG name>", "<original>", "<result>") if ($mismatchCount);
942 print hLogFile "-----------------------------------------------------------------------\n" if ($mismatchCount);
943 foreach my $feature (keys(%{$mismatchCFG_href}))
944 {
945 print hLogFile sprintf("%-*s%-15s%s\n", $col1LenMax+8, $feature,
946 ${$mismatchCFG_href}{$feature}[0], ${$mismatchCFG_href}{$feature}[1]);
947 }
948 print hLogFile "\n";
949
950
951 $col1LenMax = 0;
952 foreach my $feature (@$sortedAllFeatures_aref)
953 {
954 $col1LenMax = length($feature) if (length($feature)>$col1LenMax);
955 }
956
957 # result: Defined Features
958 print hLogFile "\n$separation\n[Defined Features ($defFeatureCount/$allFeatureCount)]\n$separation\n\n";
959 foreach my $feature (@$defFeatures_aref)
960 {
961 print hLogFile sprintf("[D] %-*s%s\n", $col1LenMax+8,
962 $feature, ${$featureData_href}{$feature});
963 # Print to MMI_DEFS or DRV_DEFS
964 print MMI_DRV_DEFS "$feature \\\n";
965 }
966 print hLogFile "\n\n";
967 print MMI_DRV_DEFS "\n\n";
968 close MMI_DRV_DEFS;
969
970 # result: Undefined Features
971 print hLogFile "$separation\n[Undefined Features ($undefFeatureCount/$allFeatureCount)]\n$separation\n\n";
972 foreach my $feature (@$undefFeatures_aref)
973 {
974 print hLogFile "[U] $feature\n";
975 }
976 print hLogFile "\n\n";
977
978 # result: All Detected Features
979 print hLogFile "$separation\n[All Detected Features ($allFeatureCount)]\n$separation\n\n";
980 foreach my $feature (@$sortedAllFeatures_aref)
981 {
982 print hLogFile "$feature\n";
983 }
984 print hLogFile "\n";
985
986 close(hLogFile);
987 print "log generated at $logFilePathname\n";
988}
989
990
991#******************************************************************************
992# FUNCTION
993# getFileList
994# DESCRIPTION
995# get file/path list for given search string
996# PARAMETERS
997# xxx
998# RETURNS
999# xxx
1000#******************************************************************************
1001sub getFileList()
1002{
1003 my $dirStr;
1004 my $fileList_ref;
1005
1006 ($dirStr, $fileList_ref) = @_;
1007
1008 my @fileData = ();
1009
1010 # get file list
1011 my $tmpFilename = "~tmpFile.lst";
1012
1013 system("dir ".$dirStr." > $tmpFilename");
1014 open(hFile, "<$tmpFilename") or die "[ERROR] can't open $tmpFilename\n";
1015 @fileData = <hFile>;
1016 close(hFile);
1017 unlink("$tmpFilename");
1018
1019 my $currDir = "";
1020 foreach my $line (@fileData)
1021 {
1022 if ($line =~ /^[\s]*Directory of[\s]+([^\n]+)/i)
1023 {
1024 $currDir = $1;
1025 #print "[dir] $currDir\n";
1026 }
1027 elsif ($line =~ /[\s]+File\(s\)[\s]+/)
1028 {
1029 $currDir = "";
1030 }
1031 elsif ($currDir ne "")
1032 {
1033 # [time] [size] [filename] <= dir result
1034 if ($line =~ /\d\d:\d\d[\s]+([\d,]+)[\s]+([^\n]+)/)
1035 {
1036 my $size = $1;
1037 my $name = $2;
1038 #print "[size] $size\t[name] $name\n";
1039 push @{$fileList_ref}, "$currDir\\$name";
1040 }
1041 }
1042 }
1043 return scalar(@{$fileList_ref});
1044}