summaryrefslogblamecommitdiffstats
path: root/tools/update/ampolish
blob: af267e8bb91ce1e6a37025e5caff491a9c657bfb (plain) (tree)
1
2
3
4
5
6

               



              








                                                                 
 























































































































                                                                           



                                                       





















































































                                                                               
                                                                                










                                                                           











                                                                                




















































































































                                                                            

                                                                     
                 






                                  
                                         


















                                   





                                        

 
                       
 
                           
 
                                    
   

                                    

   


                                  
   








                                          
   

                        
     




                     
     
                          
   



















                                                                          
   
































                                                  
   

                   
   

                                                
   
















                                                      
   

                            
 
                  
 















                                              
 
 





                          
#!/usr/bin/perl

package main ;

use strict ;

#
# Perl script to beautify and enhance RTEMS automake Makefile.ams
#
# Reads from stdin and writes to stdout
#
# usage: 
# <path-to>/ampolish <Makefile.am >Makefile.am~
# mv Makefile.am~ Makefile.am
#

my @vars ;
my @conditions = ( "" ) ;
my @buffer = ();
my %var_ ;

define_variable( "\$(AUTOMAKE_OPTIONS)", ( "foreign",  "1.4" ) );
define_variable( "\$(VPATH)", ( "\@srcdir\@" ) );

# find relative up-path to configure.in
my $rtems_cfg = find_file(".","configure.in");

# find relative up-path from configure.in to VERSION
my $rtems_top = find_file("$rtems_cfg","VERSION");

if ( "$rtems_top" eq "." ) { $rtems_top = "" ; } 
else { $rtems_top .= "/" ; }  

{
# PASS1:
# read input file and concatenate multiple lines into single lines.

  my @ibuf = () ;

  while( <STDIN> )
  { # consume header
    last if ( /^[^#].*$/ ) ;
    push @ibuf, "$_" ;
  }

  push @ibuf, "§header\n" ;

  do
  {
    if ( /^(#.*)$/o )
    { # preserve comments
        push @ibuf, "$_" ;
    }
    elsif ( /^(\t.*)\\[\s]*$/o )
      { # multilines for scripts
        my $line = "$1§" ;
        while( <STDIN> )
        {
          if ( /^(.*)\\[\s]*$/o )
          {
            $line .= "$1§" ;
          }
	  else
          {
            $line .= "$_" ;
            push @ibuf, $line ;
            last ;
          }
        }
      }
    elsif ( /^(.*)\\[\s]*$/o )
      { # multilines
        my $line = "$1" ;
        while( <STDIN> )
        {
          if ( /^(.*)\\[\s]*$/o )
          {
            $line .= "$1" ;
          }
	  else
          {
            $line .= "$_" ;
	    $line =~ s%[\s]+% %g ;
            push @ibuf, "$line\n" ;
            last ;
          }
        }
      }
    else
      {
        push @ibuf, "$_" ;
      }
  } while ( <STDIN> ) ;
  @buffer = @ibuf ;
}

{
# PASS2:
# fix obsolete constructs
  my @ibuf = () ;

  foreach ( @buffer )
  {
#    tr /\{\}/\(\)/ ;

    if ( /^(TMP|PRE)INSTALL_FILES[\s]*=(.*)$/o )
    { # force "+="
      push @ibuf, "$1INSTALL_FILES +=$2\n" ;
    }
    elsif ( /^(VPATH|EXTRA_DIST)[\s]*\+=(.*)$/o )
    { # force "="
      push @ibuf, "$1 = $2\n" ;
    }
    elsif ( /^[\s]*ACLOCAL[\s]*=[\s]*\@ACLOCAL\@.*$/o )
    { # remove the line
    }
    elsif ( /^[\s]*(ACLOCAL_AMFLAGS)[\s\t]*[\+]*=[\s]*(.*)[\s]*$/o )
    { # remove the line
    }
    elsif ( /^[\s]*(AM_CFLAGS)[\s\t]*[\+]*=[\s]*\$\(CFLAGS_OS_V\)[\s]*$/o )
    { # remove the line
    }
    elsif ( /^[\s]*debug-am:.*$/o )
    { # remove the line
    }
    elsif ( /^[\s]*all(\-am):(.*)$/o )
    { # replace the line
      push @ibuf, "all-local:$2\n" ;
    }
    elsif ( /^[\s]*profile-am:.*$/o )
    { # remove the line
    }
    elsif ( /^[\s]*include[\s\t]*\$\(RTEMS_ROOT\)\/make\/lib.cfg[\s]*$/o )
    {
      push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/lib.am\n" ;
    }
    elsif ( /^[\s]*include[\s\t]*.*compile.am[\s]*$/o )
    {
      # remove the line
    }
    elsif ( /^(.*[^\s])[\s]*$/o )
    { # remove trailing spaces
      push @ibuf, "$1\n" ;
    }
    else
    {
      push @ibuf, "$_" ;
    }
  }
  @buffer = @ibuf ;
}

# print STDERR "<tmp>\n", @buffer, "</tmp>\n" ;

{
  my @ibuf = () ;
  foreach ( @buffer )
  {
    if ( /^#(.*)$/o )
    {
      push @ibuf, "#$1\n" ;
    }
    elsif ( /^[\s]*if[\s\t]+([a-zA-Z0-9_]+)[\s\t]*$/o )
    {
      push @conditions, "\@" . $1 . "_TRUE\@" ;
      push @ibuf, "if $1\n" ;
    }
    elsif ( /^[\s]*else[\s\t]*$/o )
    {
      @conditions[$#conditions] =~ s/_TRUE\@$/_FALSE\@/;
      push @ibuf, "else\n" ;
    }
    elsif ( /^[\s]*endif[\s\t]*$/o )
    {
      pop @conditions ;
      push @ibuf, "endif\n" ;
    }
    elsif ( /^§.*$/o )
    {
      push @ibuf, "$_" ;
    }
    elsif ( /^[\s]*(VPATH)[\s\t]*([\+]*)=[\s]*(.*)[\s]*$/o )
    {
      my $lh = "\$($1)" ;
      my @rh = split( /:/,"$3");
      if ( $#conditions  > 0 )
      {
        print STDERR "WARNING: $1 must not be set inside of conditionals!\n"
      }
      define_variable( "$lh", @rh );

    }
    elsif ( /^[\s]*(AUTOMAKE_OPTIONS)[\s\t]*([\+]*)=[\s]*(.*)$/o )
    { 
      my $lh = "\$($1)" ;
      my @rh = &split_vars("$3");

      if ( $#conditions > 0 )
      {
        print STDERR "WARNING: $1 must not be set inside of conditionals!\n"
      }

      define_variable( "$lh", @rh );
    }
    elsif ( /^[\s]*([a-zA-Z0-9_]+)[\s\t]*([\+]*)=[\s]*(.*)$/o )
    { 
      my $lh = join ('',@conditions) . "\$($1)" ;
      my @rh = &split_vars("$3");
      my $seen = variable_seen( "$lh" ) ;

      if ( $#conditions > 0 )
      {
        define_variable( "\$($1)", () );
      }

      define_variable( "$lh", @rh );

      if ( not $seen )
      {
        push @ibuf, "§$2var_$lh\n" ;
      }
    }
    elsif ( /^[\s]*include[\s\t]*\$\(top_srcdir\)[\.\/]*automake\/(.*)\.am$/o )
    {
      if ( "$1" eq "lib" )
      {
        push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/compile.am\n" ;
        push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/$1.am\n" ;
      }
      elsif ( "$1" eq "local" )
      {
        $main::seen_local = 1 ;
      }
      elsif ( "$1" eq "host" )
      {
        $main::seen_host = 1 ;
      }
    }
    elsif ( /^[\s]*include[\s\t]*\$\(RTEMS_ROOT\)\/make\/(.*)\.cfg$/o )
    {
      if ( "$1" eq "leaf" )
      {
        push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/compile.am\n" ;
        push @ibuf, "include \$(RTEMS_ROOT)/make/$1.cfg\n" ;
      }
      else
      {
        push @ibuf, "include \$(RTEMS_ROOT)/make/$1.cfg\n" ;
      }
    }
    elsif ( /^[\s]*include[\s\t]*(.*)$/o )
    {
      push @ibuf, "include $1\n" ;
    }
    elsif ( /^\t(.*)$/o )
    {
      push @ibuf, "\t$1\n" ;
    }
    elsif ( /^(.*)\:(.*)$/o )
    {
      push @ibuf, "$1:$2\n" ;
    }
    elsif ( /^[\s]*$/o )
    {
      push @ibuf, "\n" ;
    }
    else
    {
      die "ERROR: Don't know how to handle <$_>" ;
    }
  } # for
  @buffer = @ibuf ;
} # while

die "Conditional stack corrupted" if ( $#conditions != 0 );

foreach( @vars )
{
  purge( \@{$var_{"$_"}} );
}

# print STDERR "<tmp>\n", @buffer, "</tmp>\n" ;


{
  my @ibuf = () ;
  foreach( @buffer )
  {
    if ( /^#.*$/o )
    {
      push @ibuf, "$_" ;
    }
    elsif( /^§header$/o )
    {
      my $l = $var_{"\$(AUTOMAKE_OPTIONS)"} ;
      push @ibuf, "\nAUTOMAKE_OPTIONS = @{$l}\n" ;
      if ( "$rtems_cfg" eq "." )
      {
        push @ibuf, "ACLOCAL_AMFLAGS = -I \$(RTEMS_TOPdir)/aclocal\n" ;
      }
      if ( defined( @{$var_{"\$(VPATH)"}} ) )
      {
        if ( $#{$var_{"\$(VPATH)"}} > 0 )
        {
          my $l = join (':',@{$var_{"\$(VPATH)"}}) ;
          push @ibuf, "\nVPATH = $l\n" ;
        }
      }
      push @ibuf, "\n" ;
    }
    elsif ( /^§(\+|)var_(.*)\$\((.*)\)$/o )
    {
      print_var(\@ibuf, "$3 $1=", $var_{"$2\$($3)"}) ;
    }
    elsif ( /^\t.*$/o )
    {
      &print_script(\@ibuf, "$_");
    }
    elsif ( /^[\s]*if[\s]+([a-zA-Z0-9_]+)[\s\t]*$/o )
    {
      push @conditions, "\@$1_TRUE\@" ;
      push @ibuf, "if $1\n" ;
    }
    elsif ( /^[\s]*else[\s]*$/o )
    {
      @conditions[$#conditions] =~ s/_TRUE\@$/_FALSE\@/;
      push @ibuf, "else\n" ;
    }
    elsif ( /^[\s]*endif[\s]*$/o )
    {
      pop @conditions ;
      push @ibuf, "endif\n" ;
    }
    else
    {
      print_line(\@ibuf,$_);
    }
  }

  if ( variable_seen("\$(SUBDIRS)") )
  {
    push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/subdirs.am\n" ;
  }

  if ( defined( $main::seen_host ) )
  {
    push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/host.am\n" ;
  }
  else
  {
    push @ibuf, "include \$(top_srcdir)/${rtems_top}automake/local.am\n" ;
  }

  @buffer = @ibuf ;
}

#print STDERR "<tmp>\n", @buffer, "</tmp>\n" ;

{ ## pretty print
  my $out = join ('',@buffer) ;
  $out =~ s/\s\#\n(\#\n)+/\n/g ;
  $out =~ s/\n\n\#\n\n/\n/g ;
  $out =~ s/\n\n[\n]*/\n\n/g ;
  print $out ;
}

exit 0;

# find a relative up-path to a file $file, starting at directory $pre
sub find_file($$)
{
  my $pre = $_[0] ;
  my $file= $_[1] ;

  my $top = "." ;
  if (not "$pre") { $pre = "." ; }

  for ( my $str = "$pre" . "/" . "$top" ;
    ( -d "$str" ) ;
    $str = "$pre" . "/" . "$top" )
  {
    if ( -f "${str}/${file}" )  
    {
      return $top ; 
    }
    if ( "$top" eq "." )
    {
      $top = ".." ;
    }
    else
    {
      $top .= "/.." ;
    }
  } ;
  die "Can't find file ${file}\n" ;
}

sub variable_seen($)
{
  my $label = "$_[0]" ;
  my $res = defined $var_{"$label"};
#print STDERR "SEEN: $label ->$res<\n" ;
  return $res ;
}

sub define_variable($$)
{
  my ($label,@value) = @_ ;

  if ( not variable_seen("$label") )
  {
#print STDERR "DEFINING: $label\n" ;
    push @vars, "$label" ;
  }

  foreach my $i ( @{value} ) 
  { 
    push @{$var_{"$label"}}, $i ; 
  }
}

# Strip off duplicate entries from a list
sub purge($)
{
  my $list = $_[0] ; # Reference to list !
  my (@tmp) = () ;

  foreach my $l ( @{$list} )
  {
    my $i = 1 ;
    foreach my $t (@tmp)
    {
      if ( $t eq $l )
      {
        $i = 0 ;
        last ;
      }
    }
    push @tmp,$l if ($i) ;
  }

  @{$list} = @tmp ;
}

#
# Break the right hand side of a variable assignment into separate chunks 
#
sub split_vars($)
{
  my $line = $_[0] ;
  my (@buf) = split(//,"$line") ;

  my $begin = 0 ;
  my @res = () ;

  my $depth = 0 ;
  my $state = 0 ;

  my $len = $#buf + 1 ;
  for ( my $i = 0 ; $i < $len ; $i++ )
  {
    my $c = @buf[$i] ;
    if ( $state == 0 )
    {
      if ( "$c" ne " " )
      { # token
        $begin = $i ;
        $state++ ;
      }
      if ( "$c" eq "\$" )
      { # variable 
        $depth++ ;
      }
    }
    elsif ( $state == 1 )
    {
      if ( ( "$c" eq "\)" ) or ( "$c" eq "\}" ) )
      { # variable 
        $depth-- ;
      }
      elsif ( ("$c" eq " " ) and ( $depth == 0 ) )
      {
        push @res, substr($line,$begin,$i-$begin);
        $state-- ;
      }
      elsif ( "$c" eq "\$" )
      { # variable 
        $depth++ ;
      }
    }
    else
    {
      die "split_vars: unknown mode\n" ;
    }
  }

  if ( $state > 0 )
  {
    push @res, substr($line,$begin,$len-$begin);
    $state = 0
  }
  return @res ;
}

sub print_var($$$)
{
  my ($ibuf,$line,$l) = @_ ; # $l .. reference to list

  foreach (@{$l}) {
    if ( ( length($line) + length($_) ) < 76 )
    {
          $line .= " $_";
    }
    else
    {
           push @{$ibuf}, "$line \\\n";
           $line = "    $_" ;
    }
  }
  push @{$ibuf}, "$line\n" ;
}

sub print_line($$)
{
  my ($ibuf,$input) = @_ ; 
  my @l = split( / /, $input );
  my $line = shift @l ;

  foreach my $i (@l) {
    if ( ( length($line) + length($i) ) < 76 )
    {
          $line .= " $i";
    }
    else
    {
           push @{$ibuf}, "$line \\\n";
           $line = "    $i" ;
    }
  }
  push @{$ibuf}, "$line" ;
}

sub print_script($$)
{
  my ($ibuf,$input) = @_ ;
  $input =~ s%§%\\\n%g ;
  push @{$ibuf}, $input ;
}