#!/usr/bin/perl -w # Helper script to strip unused parts out of crossrpms's rpm.specs # # Usage: specstrip < infile > outfile # Copyright (C) 2005,2006,2010 Ralf Corsépius, Ulm, Germany, # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # For a copy of the GNU General Public License, visit # http://www.gnu.org or write to the Free Software Foundation, Inc., # 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # $Id$ use Getopt::Long; use strict; my $newlib = 0; my $infos = 0; my $prefix = '/usr'; my $verbose = 0; my @languages = (); my %options = (); GetOptions( \%options, 'prefix=s' => \$prefix, 'enable-infos' => sub { $options{infos} = 1 }, 'disable-infos' => sub { $options{infos} = 0 }, 'newlib!', 'languages=s' => \@languages, 'verbose+' => \$verbose ) or die( "failed to GetOptions" ); if ( !defined($options{infos}) ) { # User did not override, use defaults if ( $prefix =~ m/^\/usr$/ ) { $infos = 0; } elsif ( $prefix =~ m/^\/usr\/local$/ ) { $infos = 0; } else { $infos = 1; } } else { $infos = int($options{infos}); } if ( defined($options{newlib}) ) { $newlib = $options{newlib}; } else { $newlib = 0; } if ( $verbose ) { print STDERR "INFOS : $infos\n"; print STDERR "PREFIX : $prefix\n"; } my %langs; foreach ( split(/,/,join(',',@languages)) ){ $langs{$_} = 1; } my @npatterns = ( "(\"%\{_prefix\}\" (!=|==) \"/usr\")", "(%build_cxx)", "(%build_gnat)", "(%build_objc)", "(%build_gcj)", "(%build_libgcj)", "(%build_fortran)", "(%build_newlib)", "(%build_infos)" ); my @ppatterns = ( ); push @ppatterns, "(\"%\{_prefix\}\" " . (("$prefix" eq '/usr') ? '!=' : '==' ) . " \"/usr\")"; push @ppatterns, "(%build_gnat " . ( ($langs{gnat}) ? "==" : "!=" ) . " 0)"; push @ppatterns, "(%build_cxx " . ( ($langs{cxx}) ? "==" : "!=" ) . " 0)"; push @ppatterns, "(%build_objc " . ( ($langs{objc}) ? "==" : "!=" ) . " 0)"; push @ppatterns, "(%build_gcj " . ( ($langs{gcj}) ? "==" : "!=" ) . " 0)"; push @ppatterns, "(%build_libgcj " . ( ($langs{libgcj}) ? "==" : "!=" ) . " 0)"; push @ppatterns, "(%build_fortran " . ( ($langs{fortran}) ? "==" : "!=" ) . " 0)"; push @ppatterns, "(%build_newlib " . ( ($newlib) ? "==" : "!=" ) . " 0)"; push @ppatterns, "(%build_infos " . ( ($infos) ? "==" : "!=" ) . " 0)"; my $npat = join('|',@npatterns); my $ppat = join('|',@ppatterns); if ( $verbose > 1 ) { print STDERR "PPAT: ", $ppat, "\n"; print STDERR "NPAT: ", $npat, "\n"; } my @buffer0 = <> ; my @buffer2 ; my @condstack ; @condstack = (); push @condstack,'<>'; foreach (@buffer0) { chomp $_; if ( /^%if(os|)\s+(.*)$/ ) { push @condstack,"<$2>"; if ( $condstack[$#condstack] =~ m/$npat/ ) { # transform unary conditionals into binary conditionals if ( $condstack[$#condstack] =~/.*<(%[a-zA-Z_0-9]+)>.*/ ) { $condstack[$#condstack] = "<$1 != 0>"; } } else { push @buffer2, { state => join('',@condstack), line => "$_" }; } } elsif ( /^%else.*$/ ) { my %ops = ( "!=" => "==", "==" => "!=" ); if ( $condstack[$#condstack] =~/.*<(.*) (!=|==) (.*)>.*/ ) { $condstack[$#condstack] = "<$1 " . $ops{$2} . " $3>"; if ( $condstack[$#condstack] =~ m/$npat/ ) { } else { push @buffer2, { state => join('',@condstack), line => "$_" }; } } else { push @buffer2, { state => join('',@condstack), line => "$_" }; } } elsif ( /^%endif.*$/ ) { if ( $condstack[$#condstack] =~ m/$npat/ ) { } else { push @buffer2, { state => join('',@condstack), line => "$_" }; } pop @condstack; } else { push @buffer2, { state => join('',@condstack), line => "$_" }; } } my @buffer3; foreach my $i ( @buffer2 ) { print STDERR "STATE:", $i->{state}, " LINE:", $i->{line}, "\n" if $verbose > 1; if ( $i->{state} =~ m/($ppat)/ ) { } else { push @buffer3, $i->{line}; } } #foreach my $line ( @buffer3 ) #{ # print STDERR "L:<$line>\n"; #} my @buffer4; @condstack = (); push @condstack, "<>"; foreach my $line ( @buffer3 ) { # print STDERR "READ:{", $line, "}\n"; if ( $line =~/^%if\s+"([a-zA-Z_0-9\.\-]+)"\s+==\s+"([a-zA-Z_0-9\.\-]+)"\s*$/ ) { if ( "$1" eq "$2" ) { push @condstack,""; } else { push @condstack,""; } } elsif ( $line =~/^%if\s+"([a-zA-Z_0-9\.\-]+)"\s+!=\s+"([a-zA-Z_0-9\.\-]+)"\s*$/ ) { if ( "$1" ne "$2" ) { push @condstack,""; } else { push @condstack,""; } } elsif ( $line =~/^%if\s+(.*)\s*$/ ) { my $exp = $1; if ( $condstack[$#condstack] =~ m/$/ ) { push @condstack,""; } else { push @condstack,""; push @buffer4, "$line\n"; } } elsif ( $line =~/^%if((os|narch)\s+.*)\s*$/ ) { my $exp = $1; if ( $condstack[$#condstack] =~ m/$/ ) { push @condstack,""; } else { push @condstack,""; push @buffer4, "$line\n"; } } elsif ( $line =~ /^%else\s*$/ ) { if ( $condstack[$#condstack] =~ m/$/ ) { $condstack[$#condstack] = ""; } elsif ( $condstack[$#condstack] =~ m/$/ ) { $condstack[$#condstack] = ""; } else { push @buffer4, "$line\n"; } } elsif ( $line =~ /^%endif\s*$/ ) { if ( $condstack[$#condstack] =~ m/$/ ) { # print STDERR "ENDIF: TRUE\n"; } elsif ( $condstack[$#condstack] =~ m/$/ ) { # print STDERR "ENDIF: FALSE\n"; } else { push @buffer4, "%endif\n"; } # print STDERR "POP: $line\n"; pop @condstack; } else { # print STDERR "CATCH $condstack[$#condstack]:$line\n"; if ( $condstack[$#condstack] =~ m/$/ ) { push @buffer4, "$line\n"; } elsif ( $condstack[$#condstack] =~ m/$/ ) { } else { push @buffer4, "$line\n"; } } # print STDERR @condstack, "LINE: $line\n"; } print STDOUT @buffer4;