]> git.pld-linux.org Git - projects/distfiles.git/blob - specparser.pl
- add alternative passive-ftp; untested
[projects/distfiles.git] / specparser.pl
1 #!/usr/bin/perl
2 #
3 # USAGE: specparser.pl file.spec
4 #
5 # Output:
6 #   stdout:
7 #     list of:
8 #       <md5><space><url>\n
9 #     for given specfile.
10 #     except for lines prefixed with: ERROR:
11 #   exit status:
12 #     0 - normal
13 #     2 - cannot open spec file
14 #
15
16 sub next_spec($)
17 {
18   $spec = shift;
19   $base_spec = $spec;
20   $base_spec =~ s|.*/||;
21   %macro = ();
22   $err_cnt = 0;
23 }
24
25 sub error($)
26 {
27   $err_cnt++;
28   print "ERROR: $base_spec: $_[0]\n";
29 }
30
31 sub warning($)
32 {
33   print "ERROR: $base_spec: $_[0]\n";
34 }
35
36 sub trim_spaces($)
37 {
38   my $v = shift;
39   
40   $v =~ s/\s+$//;
41   $v =~ s/^\s+//;
42   
43   return $v;
44 }
45
46 # expand macros in string
47 sub expand($)
48 {
49   my $v = trim_spaces(shift);
50   my $cnt = 20;
51
52   while ($v =~ /\%\{([^\{]+)\}/) {
53     my $value;
54     if (defined $macro{$1}) {
55       $value = $macro{$1};
56     } else {
57       error("undefined macro $1");
58       $value = "UNDEFINED";
59     }
60     $v =~ s/\%\{([^\{]+)\}/$value/;
61
62     return $v if (length $v > 1000 or $cnt-- <= 0)
63   }
64
65   while ($v =~ s/\%\(\s*echo\s+([^\|]+?)\s*\|\s*tr\s*(-d|)\s+([^\)]+?)\s*\)/\@\@tr-me\@\@/) {
66     my ($what, $d_opt, $how) = ($1, $2, $3);
67     my ($from, $to) = ($how, "");
68     ($from, $to) = ($1, $2) 
69       if $how =~ /^([^\s]+)\s+([^\s]+)$/;
70     if ($d_opt and $to ne "") {
71       error("tr -d with second string)");
72     } elsif (($from . $to) =~ /^[a-zA-Z0-9\+_\-\.]+$/) {
73       if ($d_opt) {
74         eval "\$what =~ tr/$from//d;";
75       } else {
76         eval "\$what =~ tr/$from/$to/;";
77       }
78     } else {
79       error("illegal characters in tr string(s) '$from' '$to'");
80     }
81     $v =~ s/\@\@tr-me\@\@/$what/;
82     
83     return $v if (length $v > 1000 or $cnt-- <= 0)
84   }
85
86   error("unexpanded macros in $v")
87     if ($v =~ /\%[^0-9]/);
88   
89   return $v;
90 }
91
92 # define given macro
93 sub define($$)
94 {
95   my ($n, $v) = @_;
96   $macro{$n} = trim_spaces($v);
97 }
98
99 # sets hash of macros defined with %define or %global
100 # also define %{name}, %{version} and %{source_N}
101 sub parse_defines($)
102 {
103   open(F, "< $_[0]") or die;
104   while (<F>) {
105     chomp;
106     if (/^\s*\%(define|global)\s+([^\s]+)\s+([^\s].*)$/) {
107      define($2, $3);
108     } elsif (/^Version\s*:\s*(.*)/i) {
109       define("version", $1);
110     } elsif (/^Name\s*:\s*(.*)/i) {
111       define("name", $1);
112     } elsif (/^Source(\d+)\s*:\s*(.*)/i) {
113       define("source_$1", expand($2));
114     } elsif (/^Patch(\d+)\s*:\s*(.*)/i) {
115       define("patch_$1", expand($2));
116     } elsif (/^NoSource\s*:\s*(\d+)\s*$/i) {
117       define("no_source_$1", "1");
118     }
119   }
120   close(F);
121 }
122
123 sub print_md5($)
124 {
125   open(F, "< $_[0]") or die;
126   while (<F>) {
127     chomp;
128     if (/^\s*#\s*source(\d+)-md5\s*:\s*([a-f0-9]{32})/i) {
129       my $no = $1;
130       my $md5 = $2;
131       if (defined $macro{"no_source_$no"}) {
132         error("both NoSource: $no and md5 given");
133       } elsif (defined $macro{"source_$no"}) {
134         my $s = $macro{"source_$no"};
135         if ($s =~ /^([a-z0-9A-Z:\=\?\@\+\~\.\-\/_]|\%[0-9])+$/) {
136           if ($s =~ /^(ftp|http):\/\//) {
137             if ($s =~ /\/$/) {
138               error("source $no ($s) is directory");
139             } else {
140               if ($s =~ /:\/\/distfiles\.pld-linux\.org\/src/) {
141                 $s =~ s|.*/||;
142                 print "$md5 no-url-copy://$s\n";
143               } else {
144                 print "$md5 $s\n";
145               }
146             }
147           } else {
148             $s =~ s|.*/||;
149             print "$md5 no-url://$s\n";
150           }
151         } else {
152           error("source $no url $s is ill-formatted");
153         }
154       } else {
155         error("source $no not defined");
156       }
157     }
158   }
159   close(F);
160 }
161
162 next_spec(shift);
163 parse_defines($spec);
164 print_md5($spec);
165
166 exit(0);
This page took 0.104593 seconds and 3 git commands to generate.