comparison src/cs/layer1/tools/abc.pl @ 0:92470e5d0b9e

src: partial import from FC Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 15 May 2020 01:28:16 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:92470e5d0b9e
1 #!/usr/bin/perl -w
2
3 # This perl script is the core of a generic configuration system as
4 # described in TIDKs bugzilla Bug #3 The configuration system depends
5 # on a *.cfg file. This script will generate appropriate configuration
6 # include files (i.e. *.h files) from the *.cfg file.
7
8 # NOTE! If you think you need to edit this script, you are probably
9 # wrong or I forgot something, so please email me (mmj@ti.com)
10
11 # Known bugs/limitations:
12 # The comment character '#' cannot be embedded within quoted strings
13
14 # Notes:
15
16 # A target section in the master config file can include another
17 # section with a line "&SECTION". SECTION can be any section,
18 # including the special sub-sections which are just like a normal
19 # section but with the name prefixed by '&'. Only special thing about
20 # the sub-sections is that they cannot be built and they are not shown
21 # in the list printed by the -l option.
22
23 # TODO:
24
25 # Should we delete the configuration file for which there is no
26 # corresponding lines in the master config file, e.g. if there is no
27 # DSP_ lines, should we delete the dsp.cfg file? Or should it be an
28 # option (-od) Should we give a warning?
29
30 # Perhaps we should check for duplicate config lines. This is
31 # especially useful with the include feature, as this feature increase
32 # the risk of duplicate lines. As it is now, the lines are just copied
33 # into the corresponding config/*.cfg file so the compiler will
34 # complain
35
36
37 ###############################################################################
38 # Customization
39 ###############################################################################
40
41 # none!
42
43 ###############################################################################
44 # Globals
45 ###############################################################################
46
47 # Full list of valid configuration prefixes
48 @Prefixes = ();
49
50 # Target(s) from the global cfg file to build
51 @Targets = ();
52
53 # Default options (overridden by command line arguments)
54 $verbose = 1; # verbosity level
55 $nomake = 0; # don't invoke make at end of script
56 $dryrun = 0; # don't make actual config changes.
57 $listtargets = 0; # List all configs from master config
58 $printconfig = 0;
59 $printenv = 0; # Print out all ENV variables that are set.
60 $ConfigDir = "config"; # directory to put output config files
61 $makedb = 0; # Print out the make database to stdout (gnumake option -p)
62 $MakeParams = "";
63 $MakeFile = "";
64 $MasterConfigFile = "";
65
66 $warnings = 0;
67
68 $make_name = "gmake";
69
70 my %sections;
71 my $line = 0;
72 my $current_section = "";
73 my %expanded;
74 my %env_var;
75 my %cfg_file;
76
77 ####################################################################
78 # Main
79 ####################################################################
80
81 GetOpts();
82
83 # Find the configuration file to use
84 @ConfigFiles = glob("*.cfg");
85 $#ConfigFiles < 0 && die "No configuration file found\n";
86
87 # Check if MasterConfigFile was already set with the -f<cfg file> option
88 if ($MasterConfigFile eq "") {
89 $#ConfigFiles > 0 && die "Multiple config-files found! (@ConfigFiles)\n";
90 $MasterConfigFile = $ConfigFiles[0];
91 }
92
93 # Find name of make file, using the basename of the master config-file
94 if ($MakeFile eq "") {
95 @tmp = $MasterConfigFile =~ /(\w+)/;
96 $MakeFile = $tmp[0] . ".mak";
97 }
98
99 ReadMasterConfig($MasterConfigFile);
100
101 if ($listtargets) { ListTargets(); }
102 if ($printconfig) { PrintConfig(); }
103
104 foreach $build (@Targets) {
105
106 # >>>> Start Adding SB : 17/03/03
107 # Add an environment variable for master.mak
108 $RFname = "DELIVERY_BASENAME" ;
109 $RFvalue = $build ;
110 if ( defined( $ENV{"$RFname"} ) )
111 {
112 print STDERR " Warning : environement vartiable $RFname already set to $ENV{\"$RFname\"} updated to $RFvalue\n" ;
113 }
114 $ENV{"$RFname"} = $RFvalue ; # set environment variable
115 # >>>> Stop Adding SB : 17/03/03
116
117 verb(2,"ExpandMasterConfig for $build\n");
118 %expanded = ();
119 ExpandMasterConfig($build);
120
121 verb(1, "Building target: $build\n");
122 Process($build);
123 if ($nomake == 0) {
124 @args = ( "$make_name", "$MakeParams", "-f", "$MakeFile" );
125 if ($makedb == 1) {
126 push (@args,"-p");
127 }
128 verb(1, "Invoking make: @args \n\n");
129 system("@args");
130 }
131 }
132
133
134 ####################################################################
135 # Admin procedures
136 ####################################################################
137
138 sub GetOpts {
139 foreach (@ARGV) {
140 if (/^-n/) { $dryrun++; }
141 if (/^-c/) { $nomake++; }
142 if (/^-p/) { $printconfig++; }
143 if (/^-d/) { $makedb++; }
144 if (/^-l/) { $listtargets++; }
145 if (/^-e/) { $printenv++; }
146 if (/^-f(\w+\.?\w*)/) { $MasterConfigFile = $1; }
147 if (/^-m(\w+\.?\w*)/) { $MakeFile = $1; }
148 if (/^-x([^\s]+)/) {
149 $MakeParams = $1;
150 $MakeParams =~ tr/,/ /;
151 }
152 if (/^-o(\w+\.?\w*)/) { $ConfigDir = $1; }
153 if (/^-h|--help/) { Usage(); }
154 if (/^-v/) { $verbose++; }
155 if (/^-q/) { $verbose = -1; }
156 if (/^[^\-](\w+)/) {
157 push (@Targets,uc($_)); # push uppercased string
158 }
159 }
160 if ($#Targets < 0) { $Targets[0] = "DEFAULT"; }
161 }
162
163 sub PrintConfig {
164 foreach (@Targets) {
165 unless (/\&/) {
166 !defined($sections{$_}) && die "Target section $_ not found\n";
167 print "Target [$_]:\n";
168 %expanded = ();
169 ExpandSection ("$_",0,1);
170 print "\n\n";
171 }
172 }
173 exit(0);
174 }
175
176 sub ListTargets {
177 print "Targets:\n";
178 foreach (sort keys %sections) {
179 unless (/\&/) { print " [$_]\n"; }
180 }
181 exit(0);
182 }
183
184 sub Usage
185 {
186 print <<USAGE_END;
187 abc.pl v1.10. Automatic Building, Configuration and Dependencies System.
188 Copyright TI 2001.
189
190 Usage: [perl] abc.pl [OPTION]... [TARGETS]...
191
192 OPTIONS:
193 -h Display this help and exit
194 -c Only do configuration step. Do not invoke gnumake.
195 -n Dry run. Print what is going to be done without doing it.
196 -l List all configurations in master config file, then exit
197 -f<name> Specify which master configuration file to use.
198 Note that there must be no spaces between "-f" and the file name.
199 Default is to use the *.cfg file from the current directory.
200 -m<name> Specify which make file use.
201 Note that there must be no spaces between "-m" and the file name.
202 Default is to use the makefile <file>.mak file from the current
203 directory, where <file> corresponds to the basename of the
204 config file.
205 -o<name> Specify output directory name (where to put *.cfg files).
206 Default is 'config'.
207 Note that there must be no spaces between "-o" and the dir name.
208 -p Print out contents of the specified target(s)
209 -d Print make database (corresponds to gnumake -p)
210 -e Print out all ENVironment variables that are set
211 -v Be verbose (repeat several times to be more verbose)
212 -q Be quiet
213
214 TARGETS Name(s) of the target(s) to build.
215
216 Report bugs and suggestions to mmj\@ti.com or skl\@ti.com
217 USAGE_END
218 # -t Touch. Invoke make with additional parameter: -t
219 exit(0);
220 }
221
222
223 ####################################################################
224 ## Core procedures
225 ####################################################################
226
227 # Expand all section inclusions in each target
228 sub ExpandMasterConfig
229 {
230 my ($default_section) = @_;
231 if (defined($sections{$default_section})){
232 #print default section only
233 ExpandSection ($default_section);
234 } else {
235 #error in $default_section
236 verb (1,"Section [$default_section] is not defined in $MasterConfigFile \n");
237 exit 1;
238 }
239 }
240
241
242 sub ExpandSection
243 {
244 my ($section,$level,$show);
245 my $j;
246 my $var;
247 my @values;
248 my $indent;
249 my $egal_column = 40;
250
251 ($section,$level,$show) = @_;
252
253 verb (2,"Expanding [$section]\n");
254 if (!$level){$level = 1};
255
256 $indent = " "x$level."+- ";
257 if ($level > 9){
258 die "Including somewhat deep! Did you make a loop?\n";
259 }
260 @values = split(' ',$sections{"$_[0]"});
261 foreach $j (@values){
262 if($j =~ /^&/){
263 if ($show){
264 print "$indent$j\n";}
265 }else{
266 $j =~ /([^=]*)=(.*)/;
267 $var = $1;
268 $value = $2;
269 $value =~ s/\#.*$//;
270 $env_var = '';
271 if ($var =~ /^\$/){
272 $var =~ s/^\$//;
273 $env_var = '$';
274 }
275 if ( exists $expanded{$var} ) {
276 print STDERR "Warning : in [$section], $env_var{$var}$var = $expanded{$var} is overwritten by $env_var$var = $value\n";
277 }
278 $env_var{$var} = $env_var;
279 $expanded{$var} = $value;
280 if ($show){
281 $line = $indent.$var;
282 $points = "."x(40-length($line)-1);
283 print "$line$points = $value\n";
284 }
285 }
286 if ($j =~ /^&(\w*)/){
287 ExpandSection ($1,++$level,$show);
288 $level--;
289 }
290 }
291 }
292
293
294 sub ReadMasterConfig
295 {
296 my ($filename)=(@_);
297
298 verb(1, "Reading master config file: $filename\n");
299 [-e $filename] || die "File $filename not found\n";
300
301 #Gather informations from master.cfg
302 open (MASTER_CFG,"$filename") || die "Can't open $filename\n";
303 while (<MASTER_CFG>){
304
305 while (/[\r\n]$/){s/[\r\n]$//}
306
307 #line counter
308 $line++;
309
310 #ignore line comment
311 if (/^\s*\#/) {
312 verb(5, "Skip: comment line \n");
313 next};
314
315 #ignore blank lines
316 if (/^$/) {
317 verb(5, "Skip: empty line\n");
318 next};
319
320 #identify new section
321 if (/\[(\w*)\]/){
322 $current_section = uc($1);
323 verb(4, "Reading section: $current_section\n");
324 if (defined($sections{"$current_section"})){
325 print STDERR "Warning [$line]: Section $current_section is already defined\n";
326 die;
327 } else {
328 $sections{"$current_section"}="";
329 }
330 next;
331 }
332
333 #add section lines
334 if ($current_section eq ""){
335 die "Error [$line]: $filename must starts by a [section] definition\n";
336 }
337
338 s/ //g;
339 verb(5, "Read: $_\n");
340 $sections{"$current_section"} .= " $_";
341 if (/^\$?([^_]+)_\w+\s*=\s*.*/){
342 $Prefixes{$1}=1;
343 }
344 }
345
346 close (MASTER_CFG);
347 verb(4, "Successfully read configuration sections\n");
348 verb(3, "\n");
349 }
350
351
352 sub ReadConfigFile
353 {
354 my ($cfg)=(@_);
355 my (@list);
356 my ($prefix);
357
358 %cfg_file = ();
359
360 $filename = $cfg;
361 $filename =~ s@$cfg@$ConfigDir/\L$cfg\E.cfg@;
362
363 # If the file does not exist, just return empty list
364 if (-e $filename) {
365 verb(2, "Reading current config file: $filename\n");
366 }
367 else {
368 verb(2, "Config file $filename non-existing\n");
369 return;
370 }
371
372 $protect = "";
373 open (FH, "<$filename") || die "Can't open $filename\n";
374 while (<FH>)
375 {
376 chomp;
377 if (m/\#ifndef\s*(\w+)/){
378 $protect = $1;
379 }
380 # here we add the $cfg prefix to each line
381 if (m/\#define\s*([^ ]+)\s*(.*)/) {
382 $var = $1;
383 $val = $2;
384 if ($var =~ /$protect/i){
385 verb(6,"Ignore $protect define\n");
386 next;
387 }
388 verb(5, "Read: $var=$val\n");
389 $cfg_file{"${cfg}_$var"}=$val;
390 }
391 }
392 close (FH) || die "Can't close $filename\n";
393 }
394
395
396 sub Process
397 {
398 if (-e $ConfigDir) {
399 -d $ConfigDir || die "'$ConfigDir' is a file, should be a directory!\n";
400 }
401 else {
402 verb(4, "Config-dir $ConfigDir not found - creating it...\n");
403 @args = ("mkdir", "$ConfigDir");
404 system("@args");
405 }
406
407 foreach $cfg (keys (%Prefixes)){
408 $update = 0;
409 ReadConfigFile($cfg);
410 verb (2,"File read\n");
411 foreach $i (keys(%expanded)){
412 if ($i =~ /^${cfg}_/){
413 if (defined($cfg_file{$i})) {
414 if ($cfg_file{$i} ne $expanded{$i}){
415 $update = 1;
416 }
417 delete $cfg_file{$i};
418
419 } else {
420 $update = 1;
421 }
422 }
423 }
424 if (keys(%cfg_file) > 0){
425 verb (2,"Some variables are deleted.\n");
426 $update = 1;
427 }
428 #update ENV vars and cfg files
429 if ($update && !$dryrun) {
430 open (FH, ">$filename") || die "Can't open $filename\n";
431 print FH "#ifndef __$cfg\_CFG__\n";
432 print FH "#define __$cfg\_CFG__\n";
433 }
434 foreach $i (sort (keys(%expanded))){
435 if ($i =~ /^${cfg}_/){
436 $var = $i;
437 $var =~ s/^${cfg}_//;
438 if ($update && !$dryrun){
439 print FH "#define $var $expanded{$i}\n";
440 }
441 if ($env_var{$i}){
442 if (exists $ENV{$var}){
443 verb(1,"Warning environnement varaible is already set to $ENV{$i} in the system and is overwritten by $expanded{$i}\n");}
444 $ENV{$var}=$expanded{$i};
445 verb (2,"Setting $var environnement variable to $ENV{$var}\n");
446 }
447 }
448 }
449 if ($update && !$dryrun) {
450 print FH "#endif /* __$cfg\_CFG__ \*/ \n";
451 close (FH) || die "Can't close $filename\n";
452 }
453 if ($update){
454 verb(2, "Updating $filename.\n");
455 } else {
456 verb (2,"$cfg file leaved untouched.\n");
457 }
458 }
459 }
460
461
462
463
464 # Print trace message (without indentation if $level < 0)
465 sub verb
466 {
467 my ($level, $str) = @_;
468 my ($indent) = 0;
469 if ($level < 0) {
470 $level = -$level;
471 }
472 else {
473 $indent = ($level || 1) - 1;
474 }
475 if ($verbose >= $level) {
476 print " " x $indent . $str;
477 }
478 }
479
480 sub warning
481 {
482 my ($str) = @_;
483 print STDERR "WARNING: $str";
484 $warnings++;
485 }
486
487 sub error
488 {
489 my ($str) = @_;
490 print STDERR "ERROR: $str";
491 exit(1);
492 }