Author: sparky                       Date: Mon Mar 12 22:24:22 2007 GMT
Module: admin                         Tag: DEVEL
---- Log message:
- brute-force macros expansion: finds all possibilities;
  useful for [EMAIL PROTECTED], but it may be distfiles killer in
  case of opera.spec (918 possibilities)

---- Files affected:
admin/distfiles:
   specparser.pl (1.13.2.1 -> 1.13.2.2) 

---- Diffs:

================================================================
Index: admin/distfiles/specparser.pl
diff -u admin/distfiles/specparser.pl:1.13.2.1 
admin/distfiles/specparser.pl:1.13.2.2
--- admin/distfiles/specparser.pl:1.13.2.1      Mon Mar 12 23:21:33 2007
+++ admin/distfiles/specparser.pl       Mon Mar 12 23:24:17 2007
@@ -25,7 +25,7 @@
        $spec = shift;
        $base_spec = $spec;
        $base_spec =~ s|.*/||;
-       %macro = ( "nil" => "" );
+       %macro = ( "nil" => [""] );
        #$err_cnt = 0;
 }
 
@@ -50,25 +50,11 @@
        return $v;
 }
 
-# expand macros in string
-sub expand($)
+sub expand_tr($)
 {
-       my $v = trim_spaces(shift);
-       my $cnt = 20;
-
-       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)
-       }
+       my $v = shift;
 
+       my $cnt = 20;
        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, "");
@@ -90,17 +76,60 @@
                return $v if (length $v > 1000 or $cnt-- <= 0)
        }
 
-       error("unexpanded macros in $v")
-               if ($v =~ /\%[^0-9]/);
-       
        return $v;
 }
 
+# recursive expansion
+sub expand_r($$);
+sub expand_r($$)
+{
+       my ($to_expand, $level) = @_;
+       return $to_expand if $level < 0;
+       $level--;
+
+       if ($to_expand =~ /\%\{([^\}]+)\}/) {
+               my $key = quotemeta $1;
+               my $values;
+               if (defined $macro{$1}) {
+                       $values = $macro{$1};
+               } else {
+                       error("undefined macro $1");
+                       $values = ["UNDEFINED"];
+               }
+               my @vs;
+               foreach my $value (@{$values}) {
+                       (my $vs = $to_expand) =~ s/\%\{($key)\}/$value/;
+                       push @vs, expand_r($vs, $level);
+               }
+
+               return @vs;
+       } else {
+               return $to_expand;
+       }
+}
+
+# expand macros in string
+sub expand($)
+{
+       my $v = trim_spaces(shift);
+       my $done = [];
+
+       foreach my $e ( expand_r($v, 20) ) {
+               $e = expand_tr($e);
+               push @{$done}, $e;
+               error("unexpanded macros in $e")
+                       if ($e =~ /\%[^0-9]/);
+       }
+
+       return $done;
+}
+
 # define given macro
 sub define($$)
 {
        my ($n, $v) = @_;
-       $macro{$n} = trim_spaces($v);
+       $macro{$n} = [] unless exists $macro{$n};
+       push @{$macro{$n}}, trim_spaces($v);
 }
 
 # sets hash of macros defined with %define or %global
@@ -116,8 +145,6 @@
                        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) {
@@ -127,6 +154,16 @@
        close(F);
 }
 
+my %printed;
+sub print_once($)
+{
+       my $l = shift;
+       unless (exists $printed{$l}) {
+               print $l . "\n";
+               $printed{$l} = 1;
+       }
+}
+
 sub print_source($$$) {
        my ($no, $md5, $s) = @_;
        if ($s =~ /^([a-z0-9A-Z:[EMAIL PROTECTED]/_]|\%[0-9])+$/) {
@@ -136,14 +173,14 @@
                        } else {
                                if ($s =~ 
/:\/\/distfiles\.pld-linux\.org\/src/) {
                                        $s =~ s|.*/||;
-                                       print "$md5 no-url-copy://$s\n";
+                                       print_once( "$md5 no-url-copy://$s" );
                                } else {
-                                                               print "$md5 
$s\n";
-                                                       }
+                                       print_once( "$md5 $s" );
+                               }
                        }
                } else {
                        $s =~ s|.*/||;
-                       print "$md5 no-url://$s\n";
+                       print_once( "$md5 no-url://$s");
                }
        } else {
                error("source $no url $s is ill-formatted");
@@ -167,7 +204,9 @@
                        if (defined $macro{"no_source_$no"}) {
                                error("both NoSource: $no and md5 given");
                        } elsif (defined $sourceno and ($sourceno == $no)) {
-                               print_source($no, $md5, $source);
+                               foreach my $s (@{$source}) {
+                                       print_source($no, $md5, $s);
+                               }
                        } elsif (defined $sourceno) {
                                error("found md5 for source $no, but last 
defined source is $sourceno");
                        } else {
================================================================

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

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

Reply via email to