Update the address of the Free Software Foundation.
[wine] / tools / winapi / make_parser.pm
1 #
2 # Copyright 1999, 2000, 2001 Patrik Stridvall
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 #
18
19 package make_parser;
20
21 use strict;
22
23 use setup qw($current_dir $wine_dir $winapi_dir);
24
25 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
26 require Exporter;
27
28 @ISA = qw(Exporter);
29 @EXPORT = qw();
30 @EXPORT_OK = qw($directory $tool $file $line $message);
31
32 use vars qw($directory $tool $file $line $message);
33
34 use output qw($output);
35 use options qw($options);
36
37
38 #sub command($);
39 #sub gcc_output($$);
40 #sub ld_output($$);
41 #sub make_output($$);
42 #sub winebuild_output($$);
43 #sub wmc_output($$);
44 #sub wrc_output($$);
45
46
47 ########################################################################
48 # global
49 ########################################################################
50
51 my $current;
52 my $function;
53
54 ########################################################################
55 # error
56 ########################################################################
57
58 sub error($) {
59     my $where = shift;
60
61     if(!defined($where)) {
62         $where = "";
63     }
64
65     my $context;
66     if($tool) {
67         $context = "$tool";
68         if($where) {
69             $context .= "<$where>";
70         }
71     } else {
72         if($where) {
73             $context = "<$where>";
74         } else {
75             $context = "<>";
76         }
77     }
78
79     if(defined($tool)) {
80         $output->write("$directory: $context: can't parse output: '$current'\n");
81     } else {
82         $output->write("$directory: $context: can't parse output: '$current'\n");
83     }
84     exit 1;
85 }
86
87 ########################################################################
88 # make_output
89 ########################################################################
90
91 sub make_output($$) {
92     my $level = shift;
93     local $_ = shift;
94
95     $file = "";
96     $message = "";
97
98     if(0) {
99         # Nothing
100     } elsif(/^\*\*\* \[(.*?)\] Error (\d+)$/) {
101         # Nothing
102     } elsif(/^\*\*\* Error code (\d+)$/) {
103         # Nothing
104     } elsif(/^\*\*\* Warning:\s+/) { #
105         if(/^File \`(.+?)\' has modification time in the future \((.+?) > \(.+?\)\)$/) {
106             # Nothing
107         } else {
108             error("make_output");
109         }
110     } elsif(/^\`(.*?)\' is up to date.$/) {
111         # Nothing
112     } elsif(/^\[(.*?)\] Error (\d+) \(ignored\)$/) {
113         # Nothing
114     } elsif(/^don\'t know how to make (.*?)\. Stop$/) {
115         $message = "$_";
116     } elsif(/^(Entering|Leaving) directory \`(.*?)\'$/) {
117         if($1 eq "Entering") {
118             $directory = $2;
119         } else {
120             $directory = "";
121         }
122
123         my @components;
124         foreach my $component (split(/\//, $directory)) {
125             if($component eq "wine") {
126                 @components = ();
127             } else {
128                 push @components, $component;
129             }
130         }
131         $directory = join("/", @components);
132     } elsif(/^(.*?) is older than (.*?), please rerun (.*?)\$/) {
133         # Nothing
134     } elsif(/^Nothing to be done for \`(.*?)\'\.$/) {
135         # Nothing
136     } elsif(s/^warning:\s+//) {
137         if(/^Clock skew detected.  Your build may be incomplete.$/) {
138             # Nothing
139         } else {
140             error("make_output");
141         }
142     } elsif(/^Stop in (.*?)\.$/) {
143         # Nothing
144     } elsif(/^\s*$/) {
145         # Nothing
146     } else {
147         error("make_output");
148     }
149
150 }
151
152 ########################################################################
153 # ar_command
154 ########################################################################
155
156 sub ar_command($) {
157     local $_ = shift;
158
159     my $read_files;
160     my $write_files;
161
162     if(/rc\s+(\S+)(\s+\S+)+$/) {
163         $write_files = [$1];
164         $read_files = $2;
165         $read_files =~ s/^\s*//;
166         $read_files = [split(/\s+/, $read_files)];
167     } else {
168         error("ar_command");
169     }
170
171     return ($read_files, $write_files);
172 }
173
174 ########################################################################
175 # as_command
176 ########################################################################
177
178 sub as_command($) {
179     local $_ = shift;
180
181     my $read_files;
182     my $write_files;
183
184     if(/-o\s+(\S+)\s+(\S+)$/) {
185         $write_files = [$1];
186         $read_files = [$2];
187     } else {
188         error("as_command");
189     }
190
191     return ($read_files, $write_files);
192 }
193
194 ########################################################################
195 # bision_command
196 ########################################################################
197
198 sub bison_command($) {
199     local $_ = shift;
200
201     return ([], []);
202 }
203
204 ########################################################################
205 # cd_command
206 ########################################################################
207
208 sub cd_command($) {
209     local $_ = shift;
210
211     return ([], []);
212 }
213
214 ########################################################################
215 # cd_output
216 ########################################################################
217
218 sub cd_output($) {
219     local $_ = shift;
220
221     if(/^(.*?): No such file or directory/) {
222         $message = "directory '$1' doesn't exist";
223     }
224 }
225
226 ########################################################################
227 # flex_command
228 ########################################################################
229
230 sub flex_command($) {
231     local $_ = shift;
232
233     return ([], []);
234 }
235
236 ########################################################################
237 # for_command
238 ########################################################################
239
240 sub for_command($) {
241     local $_ = shift;
242
243     return ([], []);
244 }
245
246 ########################################################################
247 # gcc_command
248 ########################################################################
249
250 sub gcc_command($) {
251     my $read_files;
252     my $write_files;
253
254     if(/-o\s+(\S+)\s+(\S+)$/) {
255         my $write_file = $1;
256         my $read_file = $2;
257
258         $write_file =~ s%^\./%%;
259         $read_file =~ s%^\./%%;
260
261         $write_files = [$write_file];
262         $read_files = [$read_file];
263     } elsif(/-o\s+(\S+)/) {
264         my $write_file = $1;
265
266         $write_file =~ s%^\./%%;
267
268         $write_files = [$write_file];
269         $read_files = ["<???>"];
270     } elsif(/^-shared.*?-o\s+(\S+)/) {
271         my $write_file = $1;
272
273         $write_file =~ s%^\./%%;
274
275         $write_files = [$write_file];
276         $read_files = ["<???>"];
277     } else {
278         error("gcc_command");
279     }
280
281     return ($read_files, $write_files);
282 }
283
284 ########################################################################
285 # gcc_output
286 ########################################################################
287
288 sub gcc_output($$) {
289     $file = shift;
290     local $_ = shift;
291
292     if(s/^(\d+):\s+//) {
293         $line = $1;
294         if(s/^warning:\s+//) {
295             my $suppress = 0;
296
297             if(0) {
298                 # Nothing
299             } elsif(/^((?:signed |unsigned )?(?:int|long)) format, (different type|\S+) arg \(arg (\d+)\)$/) {
300                 my $type = $2;
301                 if($type =~ /^(?:
302                    HACCEL|HACMDRIVER|HANDLE|HBITMAP|HBRUSH|HCALL|HCURSOR|HDC|HDRVR|HDESK|HDRAWDIB
303                    HGDIOBJ|HKL|HGLOBAL|HIMC|HINSTANCE|HKEY|HLOCAL|
304                    HMENU|HMIDISTRM|HMIDIIN|HMIDIOUT|HMIXER|HMIXEROBJ|HMMIO|HMODULE|
305                    HLINE|HPEN|HPHONE|HPHONEAPP|
306                    HRASCONN|HRGN|HRSRC|HWAVEIN|HWAVEOUT|HWINSTA|HWND|
307                    SC_HANDLE|WSAEVENT|handle_t|pointer)$/x)
308                 {
309                     $suppress = 1;
310                 } else {
311                     $suppress = 0;
312                 }
313             } elsif(/^\(near initialization for \`(.*?)\'\)$/) {
314                 $suppress = 0;
315             } elsif(/^\`(.*?)\' defined but not used$/) {
316                 $suppress = 0;
317             } elsif(/^\`(.*?)\' is not at beginning of declaration$/) {
318                 $suppress = 0;
319             } elsif(/^\`%x\' yields only last 2 digits of year in some locales$/) {
320                 $suppress = 1;
321             } elsif(/^assignment makes integer from pointer without a cast$/) {
322                 $suppress = 0;
323             } elsif(/^assignment makes pointer from integer without a cast$/) {
324                 $suppress = 0;
325             } elsif(/^assignment from incompatible pointer type$/) {
326                 $suppress = 0;
327             } elsif(/^cast from pointer to integer of different size$/) {
328                 $suppress = 0;
329             } elsif(/^comparison between pointer and integer$/) {
330                 $suppress = 0;
331             } elsif(/^comparison between signed and unsigned$/) {
332                 $suppress = 0;
333             } elsif(/^comparison of unsigned expression < 0 is always false$/) {
334                 $suppress = 0;
335             } elsif(/^comparison of unsigned expression >= 0 is always true$/) {
336                 $suppress = 0;
337             } elsif(/^conflicting types for built-in function \`(.*?)\'$/) {
338                 $suppress = 0;
339             } elsif(/^empty body in an if-statement$/) {
340                 $suppress = 0;
341             } elsif(/^empty body in an else-statement$/) {
342                 $suppress = 0;
343             } elsif(/^implicit declaration of function \`(.*?)\'$/) {
344                 $suppress = 0;
345             } elsif(/^initialization from incompatible pointer type$/) {
346                 $suppress = 0;
347             } elsif(/^initialization makes pointer from integer without a cast$/) {
348                 $suppress = 0;
349             } elsif(/^missing initializer$/) {
350                 $suppress = 0;
351             } elsif(/^ordered comparison of pointer with integer zero$/) {
352                 $suppress = 0;
353             } elsif(/^passing arg (\d+) of (?:pointer to function|\`(\S+)\') from incompatible pointer type$/) {
354                 my $arg = $1;
355                 my $name = $2;
356                 if(defined($name) && $name =~ /^GDI_AllocObject$/) {
357                     $suppress = 1;
358                 } else {
359                     $suppress = 0;
360                 }
361             } elsif(/^passing arg (\d+) of (?:pointer to function|\`(\S+)\') makes integer from pointer without a cast$/) {
362                 $suppress = 0;
363             } elsif(/^passing arg (\d+) of (?:pointer to function|\`(\S+)\') makes pointer from integer without a cast$/) {
364                 $suppress = 0;
365             } elsif(/^return makes integer from pointer without a cast$/) {
366                 $suppress = 0;
367             } elsif(/^return makes pointer from integer without a cast$/) {
368                 $suppress = 0;
369             } elsif(/^type of \`(.*?)\' defaults to \`(.*?)\'$/) {
370                 $suppress = 0;
371             } elsif(/^unused variable \`(.*?)\'$/) {
372                 $suppress = 0;
373             } elsif(!$options->pedantic) {
374                 $suppress = 0;
375             } else {
376                 error("gcc_output");
377             }
378
379             if(!$suppress) {
380                 if($function) {
381                     $message = "function $function: warning: $_";
382                 } else {
383                     $message = "warning: $_";
384                 }
385             } else {
386                 $message = "";
387             }
388         } elsif(/^\`(.*?)\' undeclared \(first use in this function\)$/) {
389             $message = "$_";
390         } elsif(/^\(Each undeclared identifier is reported only once$/) {
391             $message = "$_";
392         } elsif(/^conflicting types for \`(.*?)\'$/) {
393             $message = "$_";
394         } elsif(/^for each function it appears in.\)$/) {
395             $message = "$_";
396         } elsif(/^too many arguments to function$/) {
397             $message = "$_";
398         } elsif(/^previous declaration of \`(.*?)\'$/) {
399             $message = "$_";
400         } elsif(/^parse error before `(.*?)'$/) {
401             $message = "$_";
402         } elsif(!$options->pedantic) {
403             $message = "$_";
404         } else {
405             error("gcc_output");
406         }
407     } elsif(/^In function \`(.*?)\':$/) {
408         $function = $1;
409     } elsif(/^At top level:$/) {
410         $function = "";
411     } else {
412         error("gcc_output");
413     }
414 }
415
416 ########################################################################
417 # install_command
418 ########################################################################
419
420 sub install_command($) {
421     local $_ = shift;
422
423     return ([], []);
424 }
425
426 ########################################################################
427 # ld_command
428 ########################################################################
429
430 sub ld_command($) {
431     local $_ = shift;
432
433     my $read_files;
434     my $write_files;
435
436     if(/-r\s+(.*?)\s+-o\s+(\S+)$/) {
437         $write_files = [$2];
438         $read_files = [split(/\s+/, $1)];
439     } else {
440         error("ld_command");
441     }
442
443     return ($read_files, $write_files);
444 }
445
446 ########################################################################
447 # ld_output
448 ########################################################################
449
450 sub ld_output($$) {
451     $file = shift;
452     local $_ = shift;
453
454     if(0) {
455         # Nothing
456     } elsif(/^In function \`(.*?)\':$/) {
457         $function = $1;
458     } elsif(/^more undefined references to \`(.*?)\' follow$/) {
459         # Nothing
460     } elsif(/^the use of \`(.+?)\' is dangerous, better use \`(.+?)\'$/) {
461         # Nothing
462     } elsif(/^undefined reference to \`(.*?)\'$/) {
463         # Nothing
464     } elsif(/^warning: (.*?)\(\) possibly used unsafely; consider using (.*?)\(\)$/) {
465         # Nothing
466     } elsif(/^warning: type and size of dynamic symbol \`(.*?)\' are not defined$/) {
467         $message = "$_";
468     } else {
469         $message = "$_";
470     }
471 }
472
473 ########################################################################
474 # ldconfig_command
475 ########################################################################
476
477 sub ldconfig_command($) {
478     local $_ = shift;
479
480     return ([], []);
481 }
482
483 ########################################################################
484 # makedep_command
485 ########################################################################
486
487 sub makedep_command($) {
488     local $_ = shift;
489
490     return ([], []);
491 }
492
493 ########################################################################
494 # mkdir_command
495 ########################################################################
496
497 sub mkdir_command($) {
498     local $_ = shift;
499
500     return ([], []);
501 }
502
503 ########################################################################
504 # ranlib_command
505 ########################################################################
506
507 sub ranlib_command($) {
508     local $_ = shift;
509
510     my $read_files;
511     my $write_files;
512
513     $read_files = [split(/\s+/)];
514     $write_files = [];
515
516     return ($read_files, $write_files);
517 }
518
519 ########################################################################
520 # rm_command
521 ########################################################################
522
523 sub rm_command($) {
524     local $_ = shift;
525     s/^-f\s*//;
526     return ([], [], [split(/\s+/, $_)]);
527 }
528
529 ########################################################################
530 # sed_command
531 ########################################################################
532
533 sub sed_command($) {
534     local $_ = shift;
535
536     return ([], []);
537 }
538
539 ########################################################################
540 # strip_command
541 ########################################################################
542
543 sub strip_command($) {
544     local $_ = shift;
545
546     return ([], []);
547 }
548
549 ########################################################################
550 # winebuild_command
551 ########################################################################
552
553 sub winebuild_command($) {
554     local $_ = shift;
555
556     return ([], []);
557 }
558
559 ########################################################################
560 # winebuild_output
561 ########################################################################
562
563 sub winebuild_output($$) {
564     $file = shift;
565     local $_ = shift;
566
567     $message = $_;
568 }
569
570 ########################################################################
571 # wmc_command
572 ########################################################################
573
574 sub wmc_command($) {
575     local $_ = shift;
576
577     my $read_files;
578     my $write_files;
579
580     if(/\s+(\S+)$/) {
581         my $mc_file = $1;
582
583         my $rc_file = $mc_file;
584         $rc_file =~ s/\.mc$/.rc/;
585
586         $write_files = [$rc_file];
587         $read_files = [$mc_file];
588     } else {
589         error("wmc_command");
590     }
591
592     return ($read_files, $write_files);
593 }
594
595 ########################################################################
596 # wmc_output
597 ########################################################################
598
599 sub wmc_output($$) {
600     $file = shift;
601     local $_ = shift;
602 }
603
604 ########################################################################
605 # wrc_command
606 ########################################################################
607
608 sub wrc_command($) {
609     local $_ = shift;
610
611     my $read_files;
612     my $write_files;
613
614     if(/\s+(\S+)$/) {
615         my $rc_file = $1;
616
617         my $o_file = $rc_file;
618         $o_file =~ s/\.rc$/.o/;
619
620         $write_files = [$o_file];
621         $read_files = [$rc_file];
622     } else {
623         error("wrc_command");
624     }
625
626     return ($read_files, $write_files);
627 }
628
629 ########################################################################
630 # wrc_output
631 ########################################################################
632
633 sub wrc_output($$) {
634     $file = shift;
635     local $_ = shift;
636 }
637
638 ########################################################################
639 # command
640 ########################################################################
641
642 sub command($) {
643     local $_ = shift;
644
645     my $tool;
646     my $file;
647     my $read_files = ["<???>"];
648     my $write_files = ["<???>"];
649     my $remove_files = [];
650
651     s/^\s*(.*?)\s*$/$1/;
652
653     if(s/^\[\s+-d\s+(.*?)\s+\]\s+\|\|\s+//) {
654         # Nothing
655     }
656
657     if(s/^ar\s+//) {
658         $tool = "ar";
659         ($read_files, $write_files) = ar_command($_);
660     } elsif(s/^as\s+//) {
661         $tool = "as";
662         ($read_files, $write_files) = as_command($_);
663     } elsif(s/^bison\s+//) {
664         $tool = "bison";
665         ($read_files, $write_files) = bison_command($_);
666     } elsif(s/^cd\s+//) {
667         $tool = "cd";
668         ($read_files, $write_files) = cd_command($_);
669     } elsif(s/^flex\s+//) {
670         $tool = "flex";
671         ($read_files, $write_files) = flex_command($_);
672     } elsif(s/^for\s+//) {
673         $tool = "for";
674         ($read_files, $write_files) = for_command($_);
675     } elsif(s/^\/usr\/bin\/install\s+//) {
676         $tool = "install";
677         ($read_files, $write_files) = install_command($_);
678     } elsif(s/^ld\s+//) {
679         $tool = "ld";
680         ($read_files, $write_files) = ld_command($_);
681     } elsif(s/^\/sbin\/ldconfig\s+//) {
682         $tool = "ldconfig";
683         ($read_files, $write_files) = ldconfig_command();
684     } elsif(s/^gcc\s+//) {
685         $tool = "gcc";
686         ($read_files, $write_files) = gcc_command($_);
687     } elsif(s/^(?:(?:\.\.\/)+|\.\/)tools\/makedep\s+//) {
688         $tool = "makedep";
689         ($read_files, $write_files) = makedep_command($_);
690     } elsif(s/^mkdir\s+//) {
691         $tool = "mkdir";
692         ($read_files, $write_files) = mkdir_command($_);
693     } elsif(s/^ranlib\s+//) {
694         $tool = "ranlib";
695         ($read_files, $write_files) = ranlib_command($_);
696     } elsif(s/^rm\s+//) {
697         $tool = "rm";
698         ($read_files, $write_files, $remove_files) = rm_command($_);
699     } elsif(s/^sed\s+//) {
700         $tool = "sed";
701         ($read_files, $write_files) = sed_command($_);
702     } elsif(s/^strip\s+//) {
703         $tool = "sed";
704         ($read_files, $write_files) = strip_command($_);
705     } elsif(s/^LD_LIBRARY_PATH="(?:(?:\.\.\/)*unicode)?:\$LD_LIBRARY_PATH"\s+(?:\.\.\/)*tools\/winebuild\/winebuild\s+//) {
706         $tool = "winebuild";
707         ($read_files, $write_files) = winebuild_command($_);
708     } elsif(s/^LD_LIBRARY_PATH="(?:(?:\.\.\/)*unicode)?:\$LD_LIBRARY_PATH"\s+(?:\.\.\/)*tools\/wmc\/wmc\s+//) {
709         $tool = "wmc";
710         ($read_files, $write_files) = wmc_command($_);
711     } elsif(s/^LD_LIBRARY_PATH="(?:(?:\.\.\/)*unicode)?:\$LD_LIBRARY_PATH"\s+(?:\.\.\/)*tools\/wrc\/wrc\s+//) {
712         $tool = "wrc";
713         ($read_files, $write_files) = wrc_command($_);
714     }
715
716     return ($tool, $read_files, $write_files, $remove_files);
717 }
718
719 ########################################################################
720 # line
721 ########################################################################
722
723 sub line($) {
724     local $_ = shift;
725
726     $file = "";
727     $line = "";
728     $message = "";
729
730     $current = $_;
731
732     my ($new_tool, $read_files, $write_files, $remove_files) = command($_);
733     if(defined($new_tool)) {
734         $tool = $new_tool;
735
736         $function = "";
737
738         my $progress = "";
739         if($directory && $directory ne ".") {
740             $progress .= "$directory: ";
741         }
742         if($tool) {
743             $progress .= "$tool: ";
744         }
745
746         if($tool =~ /^(?:cd|make)$/) {
747             # Nothing
748         } elsif($tool eq "ld"/) {
749             foreach my $file (@{$read_files}) {
750                 $output->lazy_progress("${progress}reading '$file'");
751             }
752             my $file = $$write_files[0];
753             $output->progress("$progress: writing '$file'");
754         } elsif($tool eq "rm") {
755             foreach my $file (@{$remove_files}) {
756                 $output->lazy_progress("${progress}removing '$file'");
757             }
758         } else {
759             if($#$read_files >= 0) {
760                 $progress .= "read[" . join(" ", @{$read_files}) . "]";
761             }
762             if($#$write_files >= 0) {
763                 if($#$read_files >= 0) {
764                     $progress .= ", ";
765                 }
766                 $progress .= "write[" . join(" ", @{$write_files}) . "]";
767             }
768             if($#$remove_files >= 0) {
769                 if($#$read_files >= 0 || $#$write_files >= 0) {
770                     $progress .= ", ";
771                 }
772                 $progress .= "remove[" . join(" ", @{$remove_files}) . "]";
773             }
774
775             $output->progress($progress);
776         }
777
778         return 0;
779     }
780
781     my $make = $options->make;
782
783     if(/^Wine build complete\.$/) {
784         # Nothing
785     } elsif(/^(.*?) is newer than (.*?), please rerun (.*?)\!$/) {
786         $message = "$_";
787     } elsif(/^(.*?) is older than (.*?), please rerun (.*?)$/) {
788         $message = "$_";
789     } elsif(/^\`(.*?)\' is up to date.$/) {
790         $tool = "make";
791         make_output($1, $_);
792     } elsif(s/^$make(?:\[(\d+)\])?:\s*//) {
793         $tool = "make";
794         make_output($1, $_);
795     } elsif(!defined($tool)) {
796         error("line");
797     } elsif($tool eq "make") {
798         make_output($1, $_);
799     } elsif($tool eq "bison" && /^conflicts:\s+\d+\s+shift\/reduce$/) {
800         # Nothing
801     } elsif($tool eq "gcc" && /^(?:In file included |\s*)from (.+?):(\d+)[,:]$/) {
802         # Nothing
803     } elsif($tool =~ /^(?:gcc|ld)$/ && s/^(.+?\.s?o)(?:\(.*?\))?:\s*//) {
804         $tool = "ld";
805         ld_output($1, $_)
806     } elsif($tool =~ /^(?:gcc|ld)$/ && s/^(.*?)ld:\s*//) {
807         $tool = "ld";
808         ld_output("", $_)
809     } elsif($tool =~ /^(?:gcc|ld)$/ && s/^collect2:\s*//) {
810         $tool = "ld";
811         ld_output("collect2", $_);
812     } elsif($tool eq "gcc" && s/^(.+?\.[chly]):\s*//) {
813         gcc_output($1, $_);
814     } elsif($tool eq "ld" && s/^(.+?\.c):(?:\d+:)?\s*//) {
815         ld_output($1, $_);
816     } elsif($tool eq "winebuild" && s/^(.+?\.spec):\s*//) {
817         winebuild_output($1, $_);
818     } elsif($tool eq "wmc" && s/^(.+?\.mc):\s*//) {
819         wmc_output($1, $_);
820     } elsif($tool eq "wrc" && s/^(.+?\.rc):\s*//) {
821         wrc_output($1, $_);
822     } elsif($tool eq "cd" && s/^\/bin\/sh:\s*cd:\s*//) {
823         parse_cd_output($_);
824     } elsif(/^\s*$/) {
825         # Nothing
826     } else {
827         error("line");
828     }
829
830     $file =~ s/^\.\///;
831
832     return 1;
833 }
834
835 1;