#!/usr/bin/perl -w


# Helper script to strip unused parts out of crossrpms's rpm.specs
#
# Usage: specstrip < infile > outfile


# Copyright (C) 2005,2006	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 @condstack ;
my @actionstack ;

push @condstack,'<>';

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 ;
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 $i->{state}, $i->{line}, "\n";
  if ( $i->{state} =~ m/($ppat)/ ) {
  } else {
    push @buffer3, $i->{line}, "\n"
  }
}

print STDOUT @buffer3;
