- A few more bug fixes
[wine] / tools / winapi / make_parser.pm
1 package make_parser;
2
3 use strict;
4
5 use output qw($output);
6
7 ########################################################################
8 # global
9 ########################################################################
10
11 my $current; 
12 my $tool;
13 my $directory;
14 my $file;
15 my $line;
16 my $function;
17 my $message;
18
19 sub directory { return $directory; }
20 sub tool { return $tool; }
21 sub file_name { return $file; }
22 sub file_line { return $line; }
23 sub message { return $message; }
24
25 ########################################################################
26 # error
27 ########################################################################
28
29 sub error {
30     $output->write("make_filter: $tool: can't parse output: '$current'\n");
31     exit 1;
32 }
33
34 ########################################################################
35 # line
36 ########################################################################
37
38 sub line {
39     local $_ = shift;
40
41     $file = "";
42     $line = "";
43     $message = "";
44
45     $current = $_;
46
47     my ($new_tool, $read_files, $write_files, $remove_files) = command($_);
48     if(defined($new_tool)) {
49         $tool = $new_tool;
50
51         $function = "";
52
53         my $progress = "$directory: $tool: ";
54         if($#$read_files >= 0) {
55             $progress .= "read[" . join(" ", @{$read_files}) . "]";
56         }
57         if($#$write_files >= 0) {
58             if($#$read_files >= 0) {
59                 $progress .= ", ";
60             }          
61             $progress .= "write[" . join(" ", @{$write_files}) . "]";
62         }
63         if($#$remove_files >= 0) {
64             if($#$read_files >= 0 || $#$write_files >= 0) {
65                 $progress .= ", ";
66             }          
67             $progress .= "remove[" . join(" ", @{$remove_files}) . "]";
68         }
69
70         if($tool =~ /^cd|make$/) {
71             # Nothing
72         } elsif($tool =~ /^ld$/) {
73             $progress =~ s/read\[.*?\]/read[*.o]/; # FIXME: Kludge
74             $output->progress($progress)
75         } else {
76             $output->progress($progress)
77         }
78
79         return 0;
80     }
81
82     if(/^Wine build complete\.$/) {
83         # Nothing
84     } elsif(s/^make\[(\d+)\]:\s*//) {
85         $tool = "make";
86         make_output($1, $_);
87     } elsif($tool eq "bison" && /^conflicts:\s+\d+\s+shift\/reduce$/) {
88         # Nothing
89     } elsif($tool eq "gcc" && /^In file included from (.+?):(\d+):$/) {
90         # Nothing
91     } elsif($tool =~ /^gcc|ld$/ && s/^(.+?\.o(?:\(.*?\))?):\s*//) {
92         ld_output($1, $_)
93     } elsif($tool eq "gcc" && s/^(.+?\.[chly]):\s*//) {
94         gcc_output($1, $_);
95     } elsif($tool eq "winebuild" && s/^(.+?\.spec):\s*//) {
96         winebuild_output($1, $_);
97     } elsif($tool eq "wmc" && s/^(.+?\.mc):\s*//) {
98         wmc_output($1, $_);
99     } elsif($tool eq "wrc" && s/^(.+?\.rc):\s*//) {
100         wrc_output($1, $_);
101     } elsif($tool eq "cd" && s/^\/bin\/sh:\s*cd:\s*//) {
102         parse_cd_output($_);
103     } else {
104         error($_)
105     }
106     
107     $file =~ s/^\.\///;
108
109     return 1;
110 }
111
112 ########################################################################
113 # make_output
114 ########################################################################
115
116 sub make_output {
117     my $level = shift;
118     local $_ = shift;
119
120     $file = "";
121     $message = "";
122
123     if(0) {
124         # Nothing
125     } elsif(/^\*\*\* \[(.*?)\] Error (\d+)$/) {
126         # Nothing
127     } elsif(/^\*\*\* Warning:\s+/) { # 
128         if(/^File \`(.+?)\' has modification time in the future \((.+?) > \(.+?\)\)$/) {
129             # Nothing
130         } else {
131             error();
132         }
133     } elsif(/^\`(.*?)\' is up to date.$/) {
134         # Nothing
135     } elsif(/^\[(.*?)\] Error (\d+) \(ignored\)$/) {
136         # Nothing
137     } elsif(/^(Entering|Leaving) directory \`(.*?)\'$/) {
138         if($1 eq "Entering") {
139             $directory = $2;
140         } else {
141             $directory = "";
142         }
143
144         my @components;
145         foreach my $component (split(/\//, $directory)) {
146             if($component eq "wine") {
147                 @components = ();
148             } else {
149                 push @components, $component;
150             }
151         }
152         $directory = join("/", @components);
153     } elsif(/^Nothing to be done for \`(.*?)\'.$/) {
154         # Nothing
155     } elsif(s/^warning:\s+//) {
156         if(/^Clock skew detected.  Your build may be incomplete.$/) {
157             # Nothing
158         } else {
159             error();
160         }
161     } else {
162         error();
163     }
164
165 }
166
167 ########################################################################
168 # command
169 ########################################################################
170
171 sub command {
172     local $_ = shift;
173
174     my $tool;
175     my $file;
176     my $read_files = ["<???>"];
177     my $write_files = ["<???>"];
178     my $remove_files = [];
179
180     s/^\s*(.*?)\s*$/$1/;
181
182     if(s/^\[\s+-d\s+(.*?)\s+\]\s+\|\|\s+//) {
183         # Nothing
184     }
185
186     if(s/^ar\s*//) {
187         $tool = "ar";
188         ($read_files, $write_files) = ar_command($_);
189     } elsif(s/^as\s*//) {
190         $tool = "as";
191         ($read_files, $write_files) = as_command($_);
192     } elsif(s/^bison\s*//) {
193         $tool = "bison";
194         ($read_files, $write_files) = bison_command($_);
195     } elsif(s/^cd\s*//) {
196         $tool = "cd";
197         ($read_files, $write_files) = cd_command($_);
198     } elsif(s/^flex\s*//) {
199         $tool = "flex";
200         ($read_files, $write_files) = flex_command($_);
201     } elsif(s/^for\s*//) {
202         $tool = "for";
203         ($read_files, $write_files) = for_command($_);
204     } elsif(s/^\/usr\/bin\/install\s*//) {
205         $tool = "install";
206         ($read_files, $write_files) = install_command($_);
207     } elsif(s/^ld\s*//) {
208         $tool = "ld";
209         ($read_files, $write_files) = ld_command($_);
210     } elsif(s/^\/sbin\/ldconfig\s*//) {
211         $tool = "ldconfig";
212         ($read_files, $write_files) = ldconfig_command();
213     } elsif(s/^gcc\s*//) {
214         $tool = "gcc";
215         ($read_files, $write_files) = gcc_command($_);
216     } elsif(s/^(?:(?:\.\.\/)+|\.\/)tools\/makedep\s*//) {
217         $tool = "makedep";
218         ($read_files, $write_files) = makedep_command($_);
219     } elsif(s/^mkdir\s*//) {
220         $tool = "mkdir";
221         ($read_files, $write_files) = mkdir_command($_);
222     } elsif(s/^ranlib\s*//) {
223         $tool = "ranlib";
224         ($read_files, $write_files) = ranlib_command($_);
225     } elsif(s/^rm\s*//) {
226         $tool = "rm";
227         ($read_files, $write_files, $remove_files) = rm_command($_);
228     } elsif(s/^sed\s*//) {
229         $tool = "sed";
230         ($read_files, $write_files) = sed_command($_);
231     } elsif(s/^strip\s*//) {
232         $tool = "sed";
233         ($read_files, $write_files) = strip_command($_);
234     } elsif(s/^LD_LIBRARY_PATH="(?:(?:\.\.\/)*unicode)?:\$LD_LIBRARY_PATH"\s+(?:\.\.\/)*tools\/winebuild\/winebuild\s*//) {
235         $tool = "winebuild";
236         ($read_files, $write_files) = winebuild_command($_);
237     } elsif(s/^LD_LIBRARY_PATH="(?:(?:\.\.\/)*unicode)?:\$LD_LIBRARY_PATH"\s+(?:\.\.\/)*tools\/wmc\/wmc\s*//) {
238         $tool = "wmc";
239         ($read_files, $write_files) = wmc_command($_);
240     } elsif(s/^LD_LIBRARY_PATH="(?:(?:\.\.\/)*unicode)?:\$LD_LIBRARY_PATH"\s+(?:\.\.\/)*tools\/wrc\/wrc\s*//) {
241         $tool = "wrc";
242         ($read_files, $write_files) = wrc_command($_);
243     }
244
245     return ($tool, $read_files, $write_files, $remove_files);
246 }
247
248 ########################################################################
249 # ar_command
250 ########################################################################
251
252 sub ar_command {
253     local $_ = shift;
254
255     my $read_files;
256     my $write_files;
257
258     if(/rc\s+(\S+)(\s+\S+)+$/) {
259         $write_files = [$1];
260         $read_files = $2;
261         $read_files =~ s/^\s*//;
262         $read_files = [split(/\s+/, $read_files)];
263     } else {
264         error();
265     }
266
267     return ($read_files, $write_files);
268 }
269
270 ########################################################################
271 # as_command
272 ########################################################################
273
274 sub as_command {
275     local $_ = shift;
276
277     my $read_files;
278     my $write_files;
279
280     if(/-o\s+(\S+)\s+(\S+)$/) {
281         $write_files = [$1];
282         $read_files = [$2];
283     } else {
284         error();
285     }
286
287     return ($read_files, $write_files);
288 }
289
290 ########################################################################
291 # bision_command
292 ########################################################################
293
294 sub bison_command {
295     local $_ = shift;
296
297     return ([], []);
298 }
299
300 ########################################################################
301 # cd_command
302 ########################################################################
303
304 sub cd_command {
305     local $_ = shift;
306
307     return ([], []);
308 }
309
310 ########################################################################
311 # cd_output
312 ########################################################################
313
314 sub cd_output {
315     local $_ = shift;
316
317     if(/^(.*?): No such file or directory/) {
318         $message = "directory '$1' doesn't exist";
319     }
320 }
321
322 ########################################################################
323 # flex_command
324 ########################################################################
325
326 sub flex_command {
327     local $_ = shift;
328
329     return ([], []);
330 }
331
332 ########################################################################
333 # for_command
334 ########################################################################
335
336 sub for_command {
337     local $_ = shift;
338
339     return ([], []);
340 }
341
342 ########################################################################
343 # gcc_command
344 ########################################################################
345
346 sub gcc_command {
347     my $read_files;
348     my $write_files;
349
350     if(/-o\s+(\S+)\s+(\S+)$/) {
351         $write_files = [$1];
352         $read_files = [$2];
353     } elsif(/-o\s+(\S+)/) {
354         $write_files = [$1];
355         $read_files = ["<???>"];
356     } elsif(/^-shared.*?-o\s+(\S+)/) {
357         $write_files = [$1];
358         $read_files = ["<???>"];
359     } else {
360         error();
361     }
362
363     return ($read_files, $write_files);
364 }
365
366 ########################################################################
367 # gcc_output
368 ########################################################################
369
370 sub gcc_output {
371     $file = shift;
372     local $_ = shift;
373
374     if(s/^(\d+):\s+//) {
375         $line = $1;
376         if(s/^warning:\s+//) {
377             my $supress = 0;
378
379             if(0) {
380                 # Nothing
381             } elsif(/^\(near initialization for \`(.*?)\'\)$/) {
382                 $supress = 0;
383             } elsif(/^\`(.*?)\' defined but not used$/) {
384                 $supress = 0;
385             } elsif(/^\`(.*?)\' is not at beginning of declaration$/) {
386                 $supress = 0;
387             } elsif(/^\`%x\' yields only last 2 digits of year in some locales$/) {
388                 $supress = 1;
389             } elsif(/^(.*?) format, different type arg \(arg (\d+)\)$/) {
390                 $supress = 0;
391             } elsif(/^assignment from incompatible pointer type$/) {
392                 $supress = 0;
393             } elsif(/^comparison between signed and unsigned$/) {
394                 $supress = 0;
395             } elsif(/^comparison of unsigned expression < 0 is always false$/) {
396                 $supress = 0;
397             } elsif(/^comparison of unsigned expression >= 0 is always true$/) {
398                 $supress = 0;
399             } elsif(/^conflicting types for built-in function \`(.*?)\'$/) {
400                 $supress = 0;
401             } elsif(/^empty body in an if-statement$/) {
402                 $supress = 0;
403             } elsif(/^empty body in an else-statement$/) {
404                 $supress = 0;
405             } elsif(/^implicit declaration of function \`(.*?)\'$/) {
406                 $supress = 0;
407             } elsif(/^initialization from incompatible pointer type$/) {
408                 $supress = 0;
409             } elsif(/^missing initializer$/) {
410                 $supress = 0;
411             } elsif(/^ordered comparison of pointer with integer zero$/) {
412                 $supress = 0;
413             } elsif(/^passing arg (\d+) of pointer to function from incompatible pointer type$/) {
414                 $supress = 0;
415             } elsif(/^passing arg (\d+) of \`(\S+)\' from incompatible pointer type$/) {
416                 $supress = 0;
417             } elsif(/^passing arg (\d+) of \`(\S+)\' makes integer from pointer without a cast$/) {
418                 $supress = 0;
419             } elsif(/^type of \`(.*?)\' defaults to \`(.*?)\'$/) {
420                 $supress = 0;
421             } else {
422                 error();
423             }
424
425             if(!$supress) {
426                 if($function) {
427                     $message = "function $function: $_";
428                 } else {
429                     $message = "$_";
430                 }
431             } else {
432                 $message = "";
433             }
434         } elsif(/^\`(.*?)\' undeclared \(first use in this function\)$/) {
435             $message = "$_";
436         } elsif(/^\(Each undeclared identifier is reported only once$/) {
437             $message = "$_";
438         } elsif(/^for each function it appears in.\)$/) {
439             $message = "$_";
440         } elsif(/^parse error before `(.*?)'$/) {
441             $message = "$_";
442         } elsif(/^$/) {
443             $message = "$_";
444         } else {
445             error();
446         }
447     } elsif(/^In function \`(.*?)\':$/) {
448         $function = $1;
449     } elsif(/^At top level:$/) {
450         $function = "";
451     } else {
452         error();
453     }
454 }
455
456 ########################################################################
457 # install_command
458 ########################################################################
459
460 sub install_command {
461     local $_ = shift;
462
463     return ([], []);
464 }
465
466 ########################################################################
467 # ld_command
468 ########################################################################
469
470 sub ld_command {
471     local $_ = shift;
472
473     my $read_files;
474     my $write_files;
475
476     if(/-r\s+(.*?)\s+-o\s+(\S+)$/) {
477         $write_files = [$2];
478         $read_files = [split(/\s+/, $1)];
479     } else {
480         error();
481     }
482
483     return ($read_files, $write_files);
484 }
485
486 ########################################################################
487 # ld_output
488 ########################################################################
489
490 sub ld_output {
491     $file = shift;
492     local $_ = shift;
493
494     if(/^the use of \`(.+?)\' is dangerous, better use \`(.+?)\'$/) {
495         # nothing
496     }
497 }
498
499 ########################################################################
500 # ldconfig_command
501 ########################################################################
502
503 sub ldconfig_command {
504     local $_ = shift;
505
506     return ([], []);
507 }
508
509 ########################################################################
510 # makedep_command
511 ########################################################################
512
513 sub makedep_command {
514     local $_ = shift;
515
516     return ([], []);
517 }
518
519 ########################################################################
520 # mkdir_command
521 ########################################################################
522
523 sub mkdir_command {
524     local $_ = shift;
525
526     return ([], []);
527 }
528
529 ########################################################################
530 # ranlib_command
531 ########################################################################
532
533 sub ranlib_command {
534     local $_ = shift;
535
536     my $read_files;
537     my $write_files;
538
539     $read_files = [split(/\s+/)];
540     $write_files = [];
541
542     return ($read_files, $write_files);
543 }
544
545 ########################################################################
546 # rm_command
547 ########################################################################
548
549 sub rm_command {
550     local $_ = shift;
551     s/^-f\s*//;
552     return ([], [], [split(/\s+/, $_)]);
553 }
554
555 ########################################################################
556 # sed_command
557 ########################################################################
558
559 sub sed_command {
560     local $_ = shift;
561
562     return ([], []);
563 }
564
565 ########################################################################
566 # strip_command
567 ########################################################################
568
569 sub strip_command {
570     local $_ = shift;
571
572     return ([], []);
573 }
574
575 ########################################################################
576 # winebuild_command
577 ########################################################################
578
579 sub winebuild_command {
580     local $_ = shift;
581
582     return ([], []);
583 }
584
585 ########################################################################
586 # winebuild_output
587 ########################################################################
588
589 sub winebuild_output {
590     $file = shift;
591     local $_ = shift;
592
593     $message = $_;
594 }
595
596 ########################################################################
597 # wmc_command
598 ########################################################################
599
600 sub wmc_command {
601     local $_ = shift;
602
603     my $read_files;
604     my $write_files;
605
606     if(/\s+(\S+)$/) {
607         my $mc_file = $1;
608
609         my $rc_file = $mc_file;
610         $rc_file =~ s/\.mc$/.rc/;
611
612         $write_files = [$rc_file];
613         $read_files = [$mc_file];
614     } else {
615         error();
616     }
617
618     return ($read_files, $write_files);
619 }
620
621 ########################################################################
622 # wmc_output
623 ########################################################################
624
625 sub wmc_output {
626     $file = shift;
627     local $_ = shift;
628 }
629
630 ########################################################################
631 # wrc_command
632 ########################################################################
633
634 sub wrc_command {
635     local $_ = shift;
636
637     my $read_files;
638     my $write_files;
639
640     if(/\s+(\S+)$/) {
641         my $rc_file = $1;
642
643         my $o_file = $rc_file;
644         $o_file =~ s/\.rc$/.o/;
645
646         $write_files = [$o_file];
647         $read_files = [$rc_file];
648     } else {
649         error();
650     }
651
652     return ($read_files, $write_files);
653 }
654
655 ########################################################################
656 # wrc_output
657 ########################################################################
658
659 sub wrc_output {
660     $file = shift;
661     local $_ = shift;
662 }
663
664 1;