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 } |
