FreeCalypso > hg > ffs-editor
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 } |