Author: sparky                       Date: Tue Mar 13 09:55:57 2007 GMT
Module: admin                         Tag: HEAD
---- Log message:
- version from DEVEL seems to be functional: merged

---- Files affected:
admin/distfiles:
   specparser.pl (1.13 -> 1.14) 

---- Diffs:

================================================================
Index: admin/distfiles/specparser.pl
diff -u admin/distfiles/specparser.pl:1.13 admin/distfiles/specparser.pl:1.14
--- admin/distfiles/specparser.pl:1.13  Mon Mar 12 21:47:30 2007
+++ admin/distfiles/specparser.pl       Tue Mar 13 10:55:52 2007
@@ -13,164 +13,268 @@
 #     0 - normal
 #     2 - cannot open spec file
 #
+use strict;
+use warnings;
+
+my %no_source;
+my $spec;
+my $base_spec;
+my @spec;
+my @sources;
 
 sub next_spec($)
 {
-  $spec = shift;
-  $base_spec = $spec;
-  $base_spec =~ s|.*/||;
-  %macro = ( "nil" => "" );
-  $err_cnt = 0;
+       $spec = shift;
+       @spec = ();
+       $base_spec = $spec;
+       $base_spec =~ s|.*/||;
 }
 
 sub error($)
 {
-  $err_cnt++;
-  print "ERROR: $base_spec: $_[0]\n";
+       print_once( "ERROR: $base_spec: $_[0]" );
 }
 
 sub warning($)
 {
-  print "ERROR: $base_spec: $_[0]\n";
+       print "ERROR: $base_spec: $_[0]\n";
 }
 
 sub trim_spaces($)
 {
-  my $v = shift;
-  
-  $v =~ s/\s+$//;
-  $v =~ s/^\s+//;
-  
-  return $v;
+       my $v = shift;
+       
+       $v =~ s/\s+$//;
+       $v =~ s/^\s+//;
+       
+       return $v;
 }
 
 # expand macros in string
-sub expand($)
+sub expand($$) # {{{
 {
-  my $v = trim_spaces(shift);
-  my $cnt = 20;
+       my $v = trim_spaces(shift);
+       my $macrotree = shift;
+       my $cnt = 20;
+
+       while ($v =~ /\%\{([^\}]+)\}/) {
+               my $value;
+               if (defined $macrotree->{$1}) {
+                       $value = $macrotree->{$1};
+               } else {
+                       error("undefined macro $1");
+                       $value = "UNDEFINED";
+                       return undef;
+               }
+               $v =~ s/\%\{([^\}]+)\}/$value/;
 
-  while ($v =~ /\%\{([^\}]+)\}/) {
-    my $value;
-    if (defined $macro{$1}) {
-      $value = $macro{$1};
-    } else {
-      error("undefined macro $1");
-      $value = "UNDEFINED";
-    }
-    $v =~ s/\%\{([^\}]+)\}/$value/;
-
-    return $v if (length $v > 1000 or $cnt-- <= 0)
-  }
-
-  while ($v =~ 
s/\%\(\s*echo\s+([^\|]+?)\s*\|\s*tr\s*(-d|)\s+([^\)]+?)\s*\)/[EMAIL 
PROTECTED]@[EMAIL PROTECTED]@/) {
-    my ($what, $d_opt, $how) = ($1, $2, $3);
-    my ($from, $to) = ($how, "");
-    ($from, $to) = ($1, $2) 
-      if $how =~ /^([^\s]+)\s+([^\s]+)$/;
-    if ($d_opt and $to ne "") {
-      error("tr -d with second string)");
-    } elsif (($from . $to) =~ /^[a-zA-Z0-9\+_\-\.]+$/) {
-      if ($d_opt) {
-        eval "\$what =~ tr/$from//d;";
-      } else {
-        eval "\$what =~ tr/$from/$to/;";
-      }
-    } else {
-      error("illegal characters in tr string(s) '$from' '$to'");
-    }
-    $v =~ s/[EMAIL PROTECTED]@[EMAIL PROTECTED]@/$what/;
-    
-    return $v if (length $v > 1000 or $cnt-- <= 0)
-  }
-
-  error("unexpanded macros in $v")
-    if ($v =~ /\%[^0-9]/);
-  
-  return $v;
-}
+               return $v if (length $v > 1000 or $cnt-- <= 0)
+       }
 
-# define given macro
-sub define($$)
+       while ($v =~ 
s/\%\(\s*echo\s+([^\|]+?)\s*\|\s*tr\s*(-d|)\s+([^\)]+?)\s*\)/[EMAIL 
PROTECTED]@[EMAIL PROTECTED]@/) {
+               my ($what, $d_opt, $how) = ($1, $2, $3);
+               my ($from, $to) = ($how, "");
+               ($from, $to) = ($1, $2) 
+                       if $how =~ /^([^\s]+)\s+([^\s]+)$/;
+               if ($d_opt and $to ne "") {
+                       error("tr -d with second string)");
+               } elsif (($from . $to) =~ /^[a-zA-Z0-9\+_\-\.]+$/) {
+                       if ($d_opt) {
+                               eval "\$what =~ tr/$from//d;";
+                       } else {
+                               eval "\$what =~ tr/$from/$to/;";
+                       }
+               } else {
+                       error("illegal characters in tr string(s) '$from' 
'$to'");
+               }
+               $v =~ s/[EMAIL PROTECTED]@[EMAIL PROTECTED]@/$what/;
+               
+               return $v if (length $v > 1000 or $cnt-- <= 0)
+       }
+
+       error("unexpanded macros in $v")
+               if ($v =~ /\%[^0-9]/);
+       
+       return $v;
+} # }}}
+
+sub preparse_spec($) # {{{
 {
-  my ($n, $v) = @_;
-  $macro{$n} = trim_spaces($v);
-}
+       @spec = ("");
+
+       open(F, "< $_[0]") or die;
+       while (<F>) {
+               chomp;
+               if 
(/^\s*(\%(description|package|prep|install|pre|post|files)|BuildRoot|URL)/) {
+                       last;
+               } elsif 
(/^\s*(\%if.*|\%else|\%endif|\%define\s+.*|Version.*|Name.*)\s*$/) {
+                       $_ = $1;
+                       if ($spec[$#spec] =~ /\%if/) {
+                               if (/\%else/) {
+                                       next; # don't include empty %if-%else
+                               } elsif (/\%endif/) {
+                                       # remove empty %if-%endif
+                                       pop @spec;
+                                       next;
+                               }
+                       }
+                       push @spec, $_;
+               } elsif (/^NoSource\s*:\s*(\d+)\s*$/i) {
+                       $no_source{$1} = 1;
+               }
+       }
+       close(F);
+
+       shift @spec;
+} # }}}
+
+
+my $total = 0;
+
+sub cont($$);
+sub cont($$) # {{{
+{
+       my ($spec, $macros) = @_;
+       local $_;
+       while ($_ = shift @{$spec}) {
+               if (0 <= index $_, '%if') { # if, ifarch, ifos
+
+                       # split spec parsing
+                       my @speccopy = @{$spec};
+                       my %macroscopy = %{$macros};
+                       cont([EMAIL PROTECTED], \%macroscopy);
+
+                       my $level = 0;
+                       while ($_ = shift @{$spec}) {
+                               if ($level <= 0 and ($_ eq '%else' or $_ eq 
'%endif')) {
+                                       last;
+                               } elsif (0 <= index $_, '%if') {
+                                       $level++;
+                               } elsif ($_ eq '%endif') {
+                                       $level--;
+                               }
+                       }
+
+                       # continue parsing
+                       
+               } elsif ($_ eq '%else') {
+
+                       # %else happens only when %if was interpreted
+                       # so skip until %endif
+                       
+                       my $level = 0;
+                       while ($_ = shift @{$spec}) {
+                               if ($level <= 0 and $_ eq '%endif') {
+                                       last;
+                               } elsif (0 <= index $_, '%if') {
+                                       $level++;
+                               } elsif ($_ eq '%endif') {
+                                       $level--;
+                               }
+                       }
+
+               } elsif (/^\s*\%(define|global)\s+([^\s]+)\s+([^\s].*?)\s*$/) {
+                       $macros->{$2} = $3;
+
+               } elsif (/^Version\s*:\s*(.*?)\s*$/i) {
+                       $macros->{"version"} = $1;
+               } elsif (/^Name\s*:\s*(.*?)\s*$/i) {
+                       $macros->{"name"} = $1;
+               } elsif (!/\%endif/) {
+                       warn "unrecognised line: $_\n";
+               }
+       }
 
-# sets hash of macros defined with %define or %global
-# also define %{name}, %{version} and %{source_N}
-sub parse_defines($)
-{
-  open(F, "< $_[0]") or die;
-  while (<F>) {
-    chomp;
-    if (/^\s*\%(define|global)\s+([^\s]+)\s+([^\s].*)$/) {
-      define($2, $3);
-    } elsif (/^Version\s*:\s*(.*)/i) {
-      define("version", $1);
-    } elsif (/^Name\s*:\s*(.*)/i) {
-      define("name", $1);
-    #} elsif (/^Source(\d+)\s*:\s*(.*)/i) {
-    #  define("source_$1", expand($2));
-    } elsif (/^Patch(\d+)\s*:\s*(.*)/i) {
-      define("patch_$1", expand($2));
-    } elsif (/^NoSource\s*:\s*(\d+)\s*$/i) {
-      define("no_source_$1", "1");
-    }
-  }
-  close(F);
+       # the end, yuppie !
+       foreach my $s (@sources) {
+               my $src = expand( $s->[2], $macros );
+               if (defined $src) {
+                       our %tried;
+                       unless (exists $tried{$src}) {
+                               print_source( $s->[0], $s->[1], $src );
+                               $tried{$src} = 1;
+                       }
+               }
+       }
+       
+       if (++$total > 10000) {
+               error("maximum number of bcond posibilities exceeded");
+               exit 0;
+       }
+} # }}}
+
+sub print_once($)
+{
+       our %printed;
+       my $l = shift;
+       unless (exists $printed{$l}) {
+               print $l . "\n";
+               $printed{$l} = 1;
+       }
 }
 
-sub print_md5($)
+sub print_source($$$) # {{{
 {
-  open(F, "< $_[0]") or die;
-  my $sourceno = undef;
-  my $source = undef;
-  while (<F>) {
-    chomp;
-    if (/^Source(\d+)\s*:\s*(.*)/i) {
-      $sourceno = $1;
-      $source = expand($2);
-    } elsif (/^\s*#\s*source(\d+)-md5\s*:\s*([a-f0-9]{32})/i) {
-      my $no = $1;
-      my $md5 = $2;
-      if (defined $macro{"no_source_$no"}) {
-        error("both NoSource: $no and md5 given");
-      } elsif (defined $sourceno and ($sourceno == $no)) {
-        my $s = $source;
+       my ($no, $md5, $s) = @_;
+
        if ($s =~ /^([a-z0-9A-Z:[EMAIL PROTECTED]/_]|\%[0-9])+$/) {
-         if ($s =~ /^(ftp|http|https):\/\//) {
-           if ($s =~ /\/$/) {
-             error("source $no ($s) is directory");
-           } else {
-             if ($s =~ /:\/\/distfiles\.pld-linux\.org\/src/) {
-               $s =~ s|.*/||;
-               print "$md5 no-url-copy://$s\n";
-             } else {
-                print "$md5 $s\n";
-              }
-           }
-         } else {
-           $s =~ s|.*/||;
-           print "$md5 no-url://$s\n";
-         }
+               if ($s =~ /^(ftp|http|https):\/\//) {
+                       if ($s =~ /\/$/) {
+                               error("source $no ($s) is directory");
+                       } else {
+                               if ($s =~ 
/:\/\/distfiles\.pld-linux\.org\/src/) {
+                                       $s =~ s|.*/||;
+                                       print_once( "$md5 no-url-copy://$s" );
+                               } else {
+                                       print_once( "$md5 $s" );
+                               }
+                       }
+               } else {
+                       $s =~ s|.*/||;
+                       print_once( "$md5 no-url://$s");
+               }
        } else {
-         error("source $no url $s is ill-formatted");
+               error("source $no url $s is ill-formatted");
        }
-      } elsif (defined $sourceno) {
-        error("found md5 for source $no, but last defined source is 
$sourceno");
-      } else {
-        error("source $no not defined");
-      }
-      $sourceno = undef;
-      $source = undef;
-    }
-  }
-  close(F);
-}
+} # }}}
+
+sub add_md5_to_print($) # {{{
+{
+       open(F, "< $_[0]") or die;
+       my $sourceno = undef;
+       my $source = undef;
+       while (<F>) {
+               chomp;
+               if (/^Source(\d+)\s*:\s*(.*)/i) {
+                       $sourceno = $1;
+                       $source = $2;
+               } elsif (/^\s*#\s*source(\d+)-md5\s*:\s*([a-f0-9]{32})/i) {
+                       my $no = $1;
+                       my $md5 = $2;
+                       if (defined $no_source{$no}) {
+                               error("both NoSource: $no and md5 given");
+                       } if (defined $sourceno) {
+                               if ($sourceno == $no) {
+                                       push @sources, [$no, $md5, $source];
+                               } else {
+                                       error("found md5 for source $no, but 
last defined source is $sourceno (# SourceN-md5: has to be placed just after 
SourceN:)");
+                               }
+                       } else {
+                               error("source $no not defined (# SourceN-md5: 
has to be placed just after SourceN:)");
+                       }
+
+                       $sourceno = undef;
+                       $source = undef;
+               }
+       }
+       close(F);
+} # }}}
 
 next_spec(shift);
-parse_defines($spec);
-print_md5($spec);
+preparse_spec($spec);
+add_md5_to_print($spec);
+cont( [EMAIL PROTECTED], { "nil" => "" } );
 
 exit(0);
+
+# vim: ts=4:sw=4:fdm=marker
================================================================

---- CVS-web:
    http://cvs.pld-linux.org/admin/distfiles/specparser.pl?r1=1.13&r2=1.14&f=u

_______________________________________________
pld-cvs-commit mailing list
[email protected]
http://lists.pld-linux.org/mailman/listinfo/pld-cvs-commit

Reply via email to