1 | #!/usr/bin/perl |
---|
2 | |
---|
3 | package main ; |
---|
4 | |
---|
5 | use strict ; |
---|
6 | |
---|
7 | # |
---|
8 | # Perl script to beautify and enhance RTEMS automake Makefile.ams |
---|
9 | # |
---|
10 | # Reads from stdin and writes to stdout |
---|
11 | # |
---|
12 | # usage: |
---|
13 | # <path-to>/ampolish <Makefile.am >Makefile.am~ |
---|
14 | # mv Makefile.am~ Makefile.am |
---|
15 | # |
---|
16 | |
---|
17 | my @vars ; |
---|
18 | my @conditions = ( "" ) ; |
---|
19 | my @buffer = (); |
---|
20 | my %var_ ; |
---|
21 | |
---|
22 | define_variable( "\$(AUTOMAKE_OPTIONS)", ( "foreign", "1.4" ) ); |
---|
23 | define_variable( "\$(VPATH)", ( "\@srcdir\@" ) ); |
---|
24 | |
---|
25 | # find relative up-path to configure.in |
---|
26 | my $rtems_cfg = find_file(".","configure.in"); |
---|
27 | |
---|
28 | # find relative up-path from configure.in to VERSION |
---|
29 | my $rtems_top = find_file("$rtems_cfg","VERSION"); |
---|
30 | |
---|
31 | if ( "$rtems_top" eq "." ) { $rtems_top = "" ; } |
---|
32 | else { $rtems_top .= "/" ; } |
---|
33 | |
---|
34 | { |
---|
35 | # PASS1: |
---|
36 | # read input file and concatenate multiple lines into single lines. |
---|
37 | |
---|
38 | my @ibuf = () ; |
---|
39 | |
---|
40 | while( <STDIN> ) |
---|
41 | { # consume header |
---|
42 | last if ( /^[^#].*$/ ) ; |
---|
43 | push @ibuf, "$_" ; |
---|
44 | } |
---|
45 | |
---|
46 | push @ibuf, "§header\n" ; |
---|
47 | |
---|
48 | do |
---|
49 | { |
---|
50 | if ( /^(#.*)$/o ) |
---|
51 | { # preserve comments |
---|
52 | push @ibuf, "$_" ; |
---|
53 | } |
---|
54 | elsif ( /^(\t.*)\\[\s]*$/o ) |
---|
55 | { # multilines for scripts |
---|
56 | my $line = "$1§" ; |
---|
57 | while( <STDIN> ) |
---|
58 | { |
---|
59 | if ( /^(.*)\\[\s]*$/o ) |
---|
60 | { |
---|
61 | $line .= "$1§" ; |
---|
62 | } |
---|
63 | else |
---|
64 | { |
---|
65 | $line .= "$_" ; |
---|
66 | push @ibuf, $line ; |
---|
67 | last ; |
---|
68 | } |
---|
69 | } |
---|
70 | } |
---|
71 | elsif ( /^(.*)\\[\s]*$/o ) |
---|
72 | { # multilines |
---|
73 | my $line = "$1" ; |
---|
74 | while( <STDIN> ) |
---|
75 | { |
---|
76 | if ( /^(.*)\\[\s]*$/o ) |
---|
77 | { |
---|
78 | $line .= "$1" ; |
---|
79 | } |
---|
80 | else |
---|
81 | { |
---|
82 | $line .= "$_" ; |
---|
83 | $line =~ s%[\s]+% %g ; |
---|
84 | push @ibuf, "$line\n" ; |
---|
85 | last ; |
---|
86 | } |
---|
87 | } |
---|
88 | } |
---|
89 | else |
---|
90 | { |
---|
91 | push @ibuf, "$_" ; |
---|
92 | } |
---|
93 | } while ( <STDIN> ) ; |
---|
94 | @buffer = @ibuf ; |
---|
95 | } |
---|
96 | |
---|
97 | { |
---|
98 | # PASS2: |
---|
99 | # fix obsolete constructs |
---|
100 | my @ibuf = () ; |
---|
101 | |
---|
102 | foreach ( @buffer ) |
---|
103 | { |
---|
104 | # tr /\{\}/\(\)/ ; |
---|
105 | |
---|
106 | if ( /^(TMP|PRE)INSTALL_FILES[\s]*=(.*)$/o ) |
---|
107 | { # force "+=" |
---|
108 | push @ibuf, "$1INSTALL_FILES +=$2\n" ; |
---|
109 | } |
---|
110 | elsif ( /^(VPATH|EXTRA_DIST)[\s]*\+=(.*)$/o ) |
---|
111 | { # force "=" |
---|
112 | push @ibuf, "$1 = $2\n" ; |
---|
113 | } |
---|
114 | elsif ( /^[\s]*ACLOCAL[\s]*=[\s]*\@ACLOCAL\@.*$/o ) |
---|
115 | { # remove the line |
---|
116 | } |
---|
117 | elsif ( /^[\s]*(ACLOCAL_AMFLAGS)[\s\t]*[\+]*=[\s]*(.*)[\s]*$/o ) |
---|
118 | { # remove the line |
---|
119 | } |
---|
120 | elsif ( /^[\s]*(AM_CFLAGS)[\s\t]*[\+]*=[\s]*\$\(CFLAGS_OS_V\)[\s]*$/o ) |
---|
121 | { # remove the line |
---|
122 | } |
---|
123 | elsif ( /^[\s]*debug-am:.*$/o ) |
---|
124 | { # remove the line |
---|
125 | } |
---|
126 | elsif ( /^[\s]*all(\-am):(.*)$/o ) |
---|
127 | { # replace the line |
---|
128 | push @ibuf, "all-local:$2\n" ; |
---|
129 | } |
---|
130 | elsif ( /^[\s]*profile-am:.*$/o ) |
---|
131 | { # remove the line |
---|
132 | } |
---|
133 | elsif ( /^[\s]*include[\s\t]*\$\(RTEMS_ROOT\)\/make\/lib.cfg[\s]*$/o ) |
---|
134 | { |
---|
135 | push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/lib.am\n" ; |
---|
136 | } |
---|
137 | elsif ( /^[\s]*include[\s\t]*.*compile.am[\s]*$/o ) |
---|
138 | { |
---|
139 | # remove the line |
---|
140 | } |
---|
141 | elsif ( /^(.*[^\s])[\s]*$/o ) |
---|
142 | { # remove trailing spaces |
---|
143 | push @ibuf, "$1\n" ; |
---|
144 | } |
---|
145 | else |
---|
146 | { |
---|
147 | push @ibuf, "$_" ; |
---|
148 | } |
---|
149 | } |
---|
150 | @buffer = @ibuf ; |
---|
151 | } |
---|
152 | |
---|
153 | # print STDERR "<tmp>\n", @buffer, "</tmp>\n" ; |
---|
154 | |
---|
155 | { |
---|
156 | my @ibuf = () ; |
---|
157 | foreach ( @buffer ) |
---|
158 | { |
---|
159 | if ( /^#(.*)$/o ) |
---|
160 | { |
---|
161 | push @ibuf, "#$1\n" ; |
---|
162 | } |
---|
163 | elsif ( /^[\s]*if[\s\t]+([a-zA-Z0-9_]+)[\s\t]*$/o ) |
---|
164 | { |
---|
165 | push @conditions, "\@" . $1 . "_TRUE\@" ; |
---|
166 | push @ibuf, "if $1\n" ; |
---|
167 | } |
---|
168 | elsif ( /^[\s]*else[\s\t]*$/o ) |
---|
169 | { |
---|
170 | @conditions[$#conditions] =~ s/_TRUE\@$/_FALSE\@/; |
---|
171 | push @ibuf, "else\n" ; |
---|
172 | } |
---|
173 | elsif ( /^[\s]*endif[\s\t]*$/o ) |
---|
174 | { |
---|
175 | pop @conditions ; |
---|
176 | push @ibuf, "endif\n" ; |
---|
177 | } |
---|
178 | elsif ( /^§.*$/o ) |
---|
179 | { |
---|
180 | push @ibuf, "$_" ; |
---|
181 | } |
---|
182 | elsif ( /^[\s]*(VPATH)[\s\t]*([\+]*)=[\s]*(.*)[\s]*$/o ) |
---|
183 | { |
---|
184 | my $lh = "\$($1)" ; |
---|
185 | my @rh = split( /:/,"$3"); |
---|
186 | if ( $#conditions > 0 ) |
---|
187 | { |
---|
188 | print STDERR "WARNING: $1 must not be set inside of conditionals!\n" |
---|
189 | } |
---|
190 | define_variable( "$lh", @rh ); |
---|
191 | |
---|
192 | } |
---|
193 | elsif ( /^[\s]*(AUTOMAKE_OPTIONS)[\s\t]*([\+]*)=[\s]*(.*)$/o ) |
---|
194 | { |
---|
195 | my $lh = "\$($1)" ; |
---|
196 | my @rh = &split_vars("$3"); |
---|
197 | |
---|
198 | if ( $#conditions > 0 ) |
---|
199 | { |
---|
200 | print STDERR "WARNING: $1 must not be set inside of conditionals!\n" |
---|
201 | } |
---|
202 | |
---|
203 | define_variable( "$lh", @rh ); |
---|
204 | } |
---|
205 | elsif ( /^[\s]*([a-zA-Z0-9_]+)[\s\t]*([\+]*)=[\s]*(.*)$/o ) |
---|
206 | { |
---|
207 | my $lh = join ('',@conditions) . "\$($1)" ; |
---|
208 | my @rh = &split_vars("$3"); |
---|
209 | my $seen = variable_seen( "$lh" ) ; |
---|
210 | |
---|
211 | if ( $#conditions > 0 ) |
---|
212 | { |
---|
213 | define_variable( "\$($1)", () ); |
---|
214 | } |
---|
215 | |
---|
216 | define_variable( "$lh", @rh ); |
---|
217 | |
---|
218 | if ( not $seen ) |
---|
219 | { |
---|
220 | push @ibuf, "§$2var_$lh\n" ; |
---|
221 | } |
---|
222 | } |
---|
223 | elsif ( /^[\s]*include[\s\t]*\$\(top_srcdir\)[\.\/]*automake\/(.*)\.am$/o ) |
---|
224 | { |
---|
225 | if ( "$1" eq "lib" ) |
---|
226 | { |
---|
227 | push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/compile.am\n" ; |
---|
228 | push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/$1.am\n" ; |
---|
229 | } |
---|
230 | elsif ( "$1" eq "local" ) |
---|
231 | { |
---|
232 | $main::seen_local = 1 ; |
---|
233 | } |
---|
234 | elsif ( "$1" eq "host" ) |
---|
235 | { |
---|
236 | $main::seen_host = 1 ; |
---|
237 | } |
---|
238 | } |
---|
239 | elsif ( /^[\s]*include[\s\t]*\$\(RTEMS_ROOT\)\/make\/(.*)\.cfg$/o ) |
---|
240 | { |
---|
241 | if ( "$1" eq "leaf" ) |
---|
242 | { |
---|
243 | push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/compile.am\n" ; |
---|
244 | push @ibuf, "include \$(RTEMS_ROOT)/make/$1.cfg\n" ; |
---|
245 | } |
---|
246 | else |
---|
247 | { |
---|
248 | push @ibuf, "include \$(RTEMS_ROOT)/make/$1.cfg\n" ; |
---|
249 | } |
---|
250 | } |
---|
251 | elsif ( /^[\s]*include[\s\t]*(.*)$/o ) |
---|
252 | { |
---|
253 | push @ibuf, "include $1\n" ; |
---|
254 | } |
---|
255 | elsif ( /^\t(.*)$/o ) |
---|
256 | { |
---|
257 | push @ibuf, "\t$1\n" ; |
---|
258 | } |
---|
259 | elsif ( /^(.*)\:(.*)$/o ) |
---|
260 | { |
---|
261 | push @ibuf, "$1:$2\n" ; |
---|
262 | } |
---|
263 | elsif ( /^[\s]*$/o ) |
---|
264 | { |
---|
265 | push @ibuf, "\n" ; |
---|
266 | } |
---|
267 | else |
---|
268 | { |
---|
269 | die "ERROR: Don't know how to handle <$_>" ; |
---|
270 | } |
---|
271 | } # for |
---|
272 | @buffer = @ibuf ; |
---|
273 | } # while |
---|
274 | |
---|
275 | die "Conditional stack corrupted" if ( $#conditions != 0 ); |
---|
276 | |
---|
277 | foreach( @vars ) |
---|
278 | { |
---|
279 | purge( \@{$var_{"$_"}} ); |
---|
280 | } |
---|
281 | |
---|
282 | # print STDERR "<tmp>\n", @buffer, "</tmp>\n" ; |
---|
283 | |
---|
284 | |
---|
285 | { |
---|
286 | my @ibuf = () ; |
---|
287 | foreach( @buffer ) |
---|
288 | { |
---|
289 | if ( /^#.*$/o ) |
---|
290 | { |
---|
291 | push @ibuf, "$_" ; |
---|
292 | } |
---|
293 | elsif( /^§header$/o ) |
---|
294 | { |
---|
295 | my $l = $var_{"\$(AUTOMAKE_OPTIONS)"} ; |
---|
296 | push @ibuf, "\nAUTOMAKE_OPTIONS = @{$l}\n" ; |
---|
297 | if ( "$rtems_cfg" eq "." ) |
---|
298 | { |
---|
299 | push @ibuf, "ACLOCAL_AMFLAGS = -I \$(RTEMS_TOPdir)/aclocal\n" ; |
---|
300 | } |
---|
301 | if ( defined( @{$var_{"\$(VPATH)"}} ) ) |
---|
302 | { |
---|
303 | if ( $#{$var_{"\$(VPATH)"}} > 0 ) |
---|
304 | { |
---|
305 | my $l = join (':',@{$var_{"\$(VPATH)"}}) ; |
---|
306 | push @ibuf, "\nVPATH = $l\n" ; |
---|
307 | } |
---|
308 | } |
---|
309 | push @ibuf, "\n" ; |
---|
310 | } |
---|
311 | elsif ( /^§(\+|)var_(.*)\$\((.*)\)$/o ) |
---|
312 | { |
---|
313 | print_var(\@ibuf, "$3 $1=", $var_{"$2\$($3)"}) ; |
---|
314 | } |
---|
315 | elsif ( /^\t.*$/o ) |
---|
316 | { |
---|
317 | &print_script(\@ibuf, "$_"); |
---|
318 | } |
---|
319 | elsif ( /^[\s]*if[\s]+([a-zA-Z0-9_]+)[\s\t]*$/o ) |
---|
320 | { |
---|
321 | push @conditions, "\@$1_TRUE\@" ; |
---|
322 | push @ibuf, "if $1\n" ; |
---|
323 | } |
---|
324 | elsif ( /^[\s]*else[\s]*$/o ) |
---|
325 | { |
---|
326 | @conditions[$#conditions] =~ s/_TRUE\@$/_FALSE\@/; |
---|
327 | push @ibuf, "else\n" ; |
---|
328 | } |
---|
329 | elsif ( /^[\s]*endif[\s]*$/o ) |
---|
330 | { |
---|
331 | pop @conditions ; |
---|
332 | push @ibuf, "endif\n" ; |
---|
333 | } |
---|
334 | else |
---|
335 | { |
---|
336 | print_line(\@ibuf,$_); |
---|
337 | } |
---|
338 | } |
---|
339 | |
---|
340 | if ( variable_seen("\$(SUBDIRS)") ) |
---|
341 | { |
---|
342 | push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/subdirs.am\n" ; |
---|
343 | } |
---|
344 | |
---|
345 | if ( defined( $main::seen_host ) ) |
---|
346 | { |
---|
347 | push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/host.am\n" ; |
---|
348 | } |
---|
349 | else |
---|
350 | { |
---|
351 | push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/local.am\n" ; |
---|
352 | } |
---|
353 | |
---|
354 | @buffer = @ibuf ; |
---|
355 | } |
---|
356 | |
---|
357 | #print STDERR "<tmp>\n", @buffer, "</tmp>\n" ; |
---|
358 | |
---|
359 | { ## pretty print |
---|
360 | my $out = join ('',@buffer) ; |
---|
361 | $out =~ s/\s\#\n(\#\n)+/\n/g ; |
---|
362 | $out =~ s/\n\n\#\n\n/\n/g ; |
---|
363 | $out =~ s/\n\n[\n]*/\n\n/g ; |
---|
364 | print $out ; |
---|
365 | } |
---|
366 | |
---|
367 | exit 0; |
---|
368 | |
---|
369 | # find a relative up-path to a file $file, starting at directory $pre |
---|
370 | sub find_file($$) |
---|
371 | { |
---|
372 | my $pre = $_[0] ; |
---|
373 | my $file= $_[1] ; |
---|
374 | |
---|
375 | my $top = "." ; |
---|
376 | if (not "$pre") { $pre = "." ; } |
---|
377 | |
---|
378 | for ( my $str = "$pre" . "/" . "$top" ; |
---|
379 | ( -d "$str" ) ; |
---|
380 | $str = "$pre" . "/" . "$top" ) |
---|
381 | { |
---|
382 | if ( -f "${str}/${file}" ) |
---|
383 | { |
---|
384 | return $top ; |
---|
385 | } |
---|
386 | if ( "$top" eq "." ) |
---|
387 | { |
---|
388 | $top = ".." ; |
---|
389 | } |
---|
390 | else |
---|
391 | { |
---|
392 | $top .= "/.." ; |
---|
393 | } |
---|
394 | } ; |
---|
395 | die "Can't find file ${file}\n" ; |
---|
396 | } |
---|
397 | |
---|
398 | sub variable_seen($) |
---|
399 | { |
---|
400 | my $label = "$_[0]" ; |
---|
401 | my $res = defined $var_{"$label"}; |
---|
402 | #print STDERR "SEEN: $label ->$res<\n" ; |
---|
403 | return $res ; |
---|
404 | } |
---|
405 | |
---|
406 | sub define_variable($$) |
---|
407 | { |
---|
408 | my ($label,@value) = @_ ; |
---|
409 | |
---|
410 | if ( not variable_seen("$label") ) |
---|
411 | { |
---|
412 | #print STDERR "DEFINING: $label\n" ; |
---|
413 | push @vars, "$label" ; |
---|
414 | } |
---|
415 | |
---|
416 | foreach my $i ( @{value} ) |
---|
417 | { |
---|
418 | push @{$var_{"$label"}}, $i ; |
---|
419 | } |
---|
420 | } |
---|
421 | |
---|
422 | # Strip off duplicate entries from a list |
---|
423 | sub purge($) |
---|
424 | { |
---|
425 | my $list = $_[0] ; # Reference to list ! |
---|
426 | my (@tmp) = () ; |
---|
427 | |
---|
428 | foreach my $l ( @{$list} ) |
---|
429 | { |
---|
430 | my $i = 1 ; |
---|
431 | foreach my $t (@tmp) |
---|
432 | { |
---|
433 | if ( $t eq $l ) |
---|
434 | { |
---|
435 | $i = 0 ; |
---|
436 | last ; |
---|
437 | } |
---|
438 | } |
---|
439 | push @tmp,$l if ($i) ; |
---|
440 | } |
---|
441 | |
---|
442 | @{$list} = @tmp ; |
---|
443 | } |
---|
444 | |
---|
445 | # |
---|
446 | # Break the right hand side of a variable assignment into separate chunks |
---|
447 | # |
---|
448 | sub split_vars($) |
---|
449 | { |
---|
450 | my $line = $_[0] ; |
---|
451 | my (@buf) = split(//,"$line") ; |
---|
452 | |
---|
453 | my $begin = 0 ; |
---|
454 | my @res = () ; |
---|
455 | |
---|
456 | my $depth = 0 ; |
---|
457 | my $state = 0 ; |
---|
458 | |
---|
459 | my $len = $#buf + 1 ; |
---|
460 | for ( my $i = 0 ; $i < $len ; $i++ ) |
---|
461 | { |
---|
462 | my $c = @buf[$i] ; |
---|
463 | if ( $state == 0 ) |
---|
464 | { |
---|
465 | if ( "$c" ne " " ) |
---|
466 | { # token |
---|
467 | $begin = $i ; |
---|
468 | $state++ ; |
---|
469 | } |
---|
470 | if ( "$c" eq "\$" ) |
---|
471 | { # variable |
---|
472 | $depth++ ; |
---|
473 | } |
---|
474 | } |
---|
475 | elsif ( $state == 1 ) |
---|
476 | { |
---|
477 | if ( ( "$c" eq "\)" ) or ( "$c" eq "\}" ) ) |
---|
478 | { # variable |
---|
479 | $depth-- ; |
---|
480 | } |
---|
481 | elsif ( ("$c" eq " " ) and ( $depth == 0 ) ) |
---|
482 | { |
---|
483 | push @res, substr($line,$begin,$i-$begin); |
---|
484 | $state-- ; |
---|
485 | } |
---|
486 | elsif ( "$c" eq "\$" ) |
---|
487 | { # variable |
---|
488 | $depth++ ; |
---|
489 | } |
---|
490 | } |
---|
491 | else |
---|
492 | { |
---|
493 | die "split_vars: unknown mode\n" ; |
---|
494 | } |
---|
495 | } |
---|
496 | |
---|
497 | if ( $state > 0 ) |
---|
498 | { |
---|
499 | push @res, substr($line,$begin,$len-$begin); |
---|
500 | $state = 0 |
---|
501 | } |
---|
502 | return @res ; |
---|
503 | } |
---|
504 | |
---|
505 | sub print_var($$$) |
---|
506 | { |
---|
507 | my ($ibuf,$line,$l) = @_ ; # $l .. reference to list |
---|
508 | |
---|
509 | foreach (@{$l}) { |
---|
510 | if ( ( length($line) + length($_) ) < 76 ) |
---|
511 | { |
---|
512 | $line .= " $_"; |
---|
513 | } |
---|
514 | else |
---|
515 | { |
---|
516 | push @{$ibuf}, "$line \\\n"; |
---|
517 | $line = " $_" ; |
---|
518 | } |
---|
519 | } |
---|
520 | push @{$ibuf}, "$line\n" ; |
---|
521 | } |
---|
522 | |
---|
523 | sub print_line($$) |
---|
524 | { |
---|
525 | my ($ibuf,$input) = @_ ; |
---|
526 | my @l = split( / /, $input ); |
---|
527 | my $line = shift @l ; |
---|
528 | |
---|
529 | foreach my $i (@l) { |
---|
530 | if ( ( length($line) + length($i) ) < 76 ) |
---|
531 | { |
---|
532 | $line .= " $i"; |
---|
533 | } |
---|
534 | else |
---|
535 | { |
---|
536 | push @{$ibuf}, "$line \\\n"; |
---|
537 | $line = " $i" ; |
---|
538 | } |
---|
539 | } |
---|
540 | push @{$ibuf}, "$line" ; |
---|
541 | } |
---|
542 | |
---|
543 | sub print_script($$) |
---|
544 | { |
---|
545 | my ($ibuf,$input) = @_ ; |
---|
546 | $input =~ s%§%\\\n%g ; |
---|
547 | push @{$ibuf}, $input ; |
---|
548 | } |
---|