Tizen 2.0 Release
[framework/uifw/ise-engine-hangul.git] / skim / admin / am_edit
1 #!/usr/bin/perl -w
2
3 # Expands the specialised KDE tags in Makefile.in to (hopefully) valid
4 # make syntax.
5 # When called without file parameters, we work recursively on all Makefile.in
6 # in and below the current subdirectory. When called with file parameters,
7 # only those Makefile.in are changed.
8 # The currently supported tags are
9 #
10 # {program}_METASOURCES
11 # where you have a choice of two styles
12 #   {program}_METASOURCES = name1.moc name2.moc ... [\]
13 #   {program}_METASOURCES = AUTO
14 #       The second style requires other tags as well.
15 #
16 # To install icons :
17 #    KDE_ICON = iconname iconname2 ...
18 #    KDE_ICON = AUTO
19 #
20 # For documentation :
21 #    http://developer.kde.org/documentation/other/developer-faq.html
22 #
23 # and more new tags TBD!
24 #
25 # The concept (and base code) for this program came from automoc,
26 # supplied by the following
27 #
28 # Matthias Ettrich <ettrich@kde.org>      (The originator)
29 # Kalle Dalheimer <kalle@kde.org>      (The original implementator)
30 # Harri Porten  <porten@tu-harburg.de>
31 # Alex Zepeda  <jazepeda@pacbell.net>
32 # David Faure <faure@kde.org>
33 # Stephan Kulow <coolo@kde.org>
34 # Dirk Mueller <mueller@kde.org>
35
36 use Cwd;
37 use File::Find;
38 use File::Basename;
39
40 # Prototype the functions
41 sub initialise ();
42 sub processMakefile ($);
43 sub updateMakefile ();
44 sub restoreMakefile ();
45
46 sub removeLine ($$);
47 sub appendLines ($);
48 sub substituteLine ($$);
49
50 sub findMocCandidates ();
51 sub pruneMocCandidates ($);
52 sub checkMocCandidates ();
53 sub addMocRules ();
54 sub findKcfgFile($);
55
56 sub tag_AUTOMAKE ();
57 sub tag_META_INCLUDES ();
58 sub tag_METASOURCES ();
59 sub tag_POFILES ();
60 sub tag_DOCFILES ();
61 sub tag_LOCALINSTALL();
62 sub tag_IDLFILES();
63 sub tag_UIFILES();
64 sub tag_KCFGFILES();
65 sub tag_SUBDIRS();
66 sub tag_ICON();
67 sub tag_CLOSURE();
68 sub tag_NO_UNDEFINED();
69 sub tag_NMCHECK();
70 sub tag_DIST();
71 sub tag_KDEINIT();
72
73 # Some global globals...
74 $verbose    = 0;        # a debug flag
75 $thisProg   = "$0";     # This programs name
76 $topdir     = cwd();    # The current directory
77 @makefiles  = ();       # Contains all the files we'll process
78 @foreignfiles = ();
79 $start      = (times)[0]; # some stats for testing - comment out for release
80 $version    = "v0.2";
81 $errorflag  = 0;
82 $cppExt     = "(cpp|cc|cxx|C|c\\+\\+)";
83 $hExt       = "(h|H|hh|hxx|hpp|h\\+\\+)";
84 $progId     = "KDE tags expanded automatically by " . basename($thisProg);
85 $automkCall = "\n";
86 $printname  = "";  # used to display the directory the Makefile is in
87 $use_final  = 1;        # create code for --enable-final
88 $cleantarget = "clean";
89 $dryrun     = 0;
90 $pathoption = 0;
91 $foreign_libtool = 0;
92
93 while (defined ($ARGV[0]))
94 {
95     $_ = shift;
96     if (/^--version$/)
97     {
98         print STDOUT "\n";
99         print STDOUT basename($thisProg), " $version\n",
100                 "This is really free software, unencumbered by the GPL.\n",
101                 "You can do anything you like with it except sueing me.\n",
102                 "Copyright 1998 Kalle Dalheimer <kalle\@kde.org>\n",
103                 "Concept, design and unnecessary questions about perl\n",
104                 "       by Matthias Ettrich <ettrich\@kde.org>\n\n",
105                 "Making it useful by Stephan Kulow <coolo\@kde.org> and\n",
106                 "Harri Porten <porten\@kde.org>\n",
107                 "Updated (Feb-1999), John Birch <jb.nz\@writeme.com>\n",
108                 "Fixes and Improvements by Dirk Mueller <mueller\@kde.org>\n",
109                 "Current Maintainer Stephan Kulow\n\n";
110         exit 0;
111     }
112     elsif (/^--verbose$|^-v$/)
113     {
114         $verbose = 1;       # Oh is there a problem...?
115     }
116     elsif (/^(?:-p|--path=)(.+)$/)
117     {
118         my $p = $1;
119         $thisProg = $p . "/". basename($thisProg);
120         warn ("$thisProg doesn't exist\n")      if (!(-f $thisProg));
121         $thisProg .= " -p".$p;
122         $pathoption=1;
123     }
124     elsif (/^--help$|^-h$/)
125     {
126         print STDOUT "Usage $thisProg [OPTION] ... [dir/Makefile.in]...\n",
127                 "\n",
128                 "Patches dir/Makefile.in generated by automake\n",
129                 "(where dir can be an absolute or relative directory name)\n",
130                 "\n",
131                 "  -v, --verbose      verbosely list files processed\n",
132                 "  -h, --help         print this help, then exit\n",
133                 "  --version          print version number, then exit\n",
134                 "  -p, --path=        use the path to am_edit if the path\n",
135                 "                     called from is not the one to be used\n",
136                 "  --no-final         don't patch for --enable-final\n";
137         
138         exit 0;
139     }
140     elsif (/^--no-final$/)
141     {
142         $use_final = 0;
143         $thisProg .= " --no-final";
144     }
145     elsif (/^--foreign-libtool$/)
146     {
147         $foreign_libtool = 1;
148         $thisProg .= " --foreign-libtool";
149     }
150     elsif (/^-n$/)
151     {
152         $dryrun = 1;
153     }
154     else
155     {
156         # user selects what input files to check
157         # add full path if relative path is given
158         $_ = cwd()."/".$_   if (! /^\//);
159         print "User wants $_\n" if ($verbose);
160         push (@makefiles, $_);
161     }
162 }
163
164 if ($thisProg =~ /^\// && !$pathoption )
165 {
166   print STDERR "Illegal full pathname call performed...\n",
167       "The call to \"$thisProg\"\nwould be inserted in some Makefile.in.\n",
168       "Please use option --path.\n";
169   exit 1;
170 }
171
172 # Only scan for files when the user hasn't entered data
173 if (!@makefiles)
174 {
175     print STDOUT "Scanning for Makefile.in\n"       if ($verbose);
176     find (\&add_makefile, cwd());
177     #chdir('$topdir');
178 } else {
179     print STDOUT "Using input files specified by user\n"   if ($verbose);
180 }
181
182 foreach $makefile (sort(@makefiles))
183 {
184     processMakefile ($makefile);
185     last            if ($errorflag);
186 }
187
188 # Just some debug statistics - comment out for release as it uses printf.
189 printf STDOUT "Time %.2f CPU sec\n", (times)[0] - $start     if ($verbose);
190
191 exit $errorflag;        # causes make to fail if erroflag is set
192
193 #-----------------------------------------------------------------------------
194
195 # In conjunction with the "find" call, this builds the list of input files
196 sub add_makefile ()
197 {
198   push (@makefiles, $File::Find::name) if (/Makefile.in$/);
199 }
200
201 #-----------------------------------------------------------------------------
202
203 # Processes a single make file
204 # The parameter contains the full path name of the Makefile.in to use
205 sub processMakefile ($)
206 {
207     # some useful globals for the subroutines called here
208     local ($makefile)       = @_;
209     local @headerdirs       = ('.');
210     local $haveAutomocTag   = 0;
211     local $MakefileData     = "";
212
213     local $cxxsuffix  = "KKK";
214
215     local @programs = ();  # lists the names of programs and libraries
216     local $program = "";
217
218     local @kdeinits = (); # lists the kdeinit targets
219
220     local %realObjs = ();  # lists the objects compiled into $program
221     local %sources = ();   # lists the sources used for $program
222     local %finalObjs = (); # lists the objects compiled when final
223     local %realname = ();  # the binary name of program variable
224     local %idlfiles = ();  # lists the idl files used for $program
225     local %globalmocs = ();# list of all mocfiles (in %mocFiles format)
226     local %important = (); # list of files to be generated asap
227     local %uiFiles = ();
228     local %kcfgFiles = ();
229
230     local $allidls = "";
231     local $idl_output = "";# lists all idl generated files for cleantarget
232     local $ui_output = "";# lists all uic generated files for cleantarget
233     local $kcfg_output = "";# lists all kcfg generated files for cleantarget
234
235     local %dependmocs = ();
236     
237     local $metasourceTags = 0;
238     local $dep_files      = "";
239     local $dep_finals     = "";
240     local %target_adds    = (); # the targets to add
241     local %rule_adds      = ();
242     local $kdelang        = "";
243     local @cleanfiles     = ();
244     local $cleanMoc       = "";
245     local $closure_output = "";
246
247     local %varcontent     = ();
248
249     $makefileDir = dirname($makefile);
250     chdir ($makefileDir);
251     $printname = $makefile;
252     $printname =~ s/^\Q$topdir\E\///;
253     $makefile = basename($makefile);
254
255     print STDOUT "Processing makefile $printname\n"   if ($verbose);
256
257     # Setup and see if we need to do this.
258     return      if (!initialise());
259
260     tag_AUTOMAKE ();            # Allows a "make" to redo the Makefile.in
261     tag_META_INCLUDES ();       # Supplies directories for src locations
262
263     foreach $program (@programs) {
264         $sources_changed{$program} = 0;
265         $dependmocs{$program} = "";
266         $important{$program} = "";
267         tag_IDLFILES();             # Sorts out idl rules
268         tag_NO_UNDEFINED();
269         tag_CLOSURE();
270         tag_NMCHECK();
271         tag_UIFILES();              # Sorts out ui rules
272         tag_KCFGFILES();            # Sorts out kcfg rules
273         tag_METASOURCES ();         # Sorts out the moc rules
274         if ($sources_changed{$program}) {
275             my $lookup = $program . '_SOURCES\s*=[ \t]*(.*)';
276
277             if($program =~ /libkdeinit_(.*)/) {
278                 my $prog = $1;
279                 substituteLine($prog . '_SOURCES\s*=[ \t]*(.*)', 
280                     "${prog}_SOURCES = ${prog}_dummy.$cxxsuffix\n" .
281                     "libkdeinit_${prog}_SOURCES = " . $sources{$program});
282                 $sources{$prog} = "${prog}_dummy.$cxxsuffix";
283             }
284             else {
285                 substituteLine($lookup, "$program\_SOURCES=" . $sources{$program});
286             }
287         }
288         if ($important{$program}) {
289             local %source_dict = ();
290             for $source (split(/[\034\s]+/, $sources{$program})) {
291                 $source_dict{$source} = 1;
292             }
293             for $source (@cleanfiles) {
294                 $source_dict{$source} = 0;
295             }
296             for $source (keys %source_dict) {
297                 next if (!$source);
298                 if ($source_dict{$source}) {
299                     # sanity check
300                     if (! -f $source) {
301                         print STDERR "Error: $source is listed in a _SOURCE line in $printname, but doesn't exist yet. Put it in DISTCLEANFILES!\n";
302                     } else {
303                         $target_adds{"\$(srcdir)/$source"} .= $important{$program};
304                     }
305                 }
306             }
307         }
308     }
309     if ($cleanMoc) {
310         # Always add dist clean tag
311         # Add extra *.moc.cpp files created for USE_AUTOMOC because they
312         # aren't included in the normal *.moc clean rules.
313         appendLines ("$cleantarget-metasources:\n\t-rm -f $cleanMoc\n");
314         $target_adds{"$cleantarget-am"} .= "$cleantarget-metasources ";
315     }
316     
317     tag_DIST() unless ($kdeopts{"noautodist"});
318
319     if ($idl_output) {
320         appendLines ("$cleantarget-idl:\n\t-rm -f $idl_output\n");
321         $target_adds{"$cleantarget-am"} .= "$cleantarget-idl ";
322     }
323
324     if ($ui_output) {
325         appendLines ("$cleantarget-ui:\n\t-rm -f $ui_output\n");
326         $target_adds{"$cleantarget-am"} .= "$cleantarget-ui ";
327     }
328
329     if ($kcfg_output) {
330         appendLines ("$cleantarget-kcfg:\n\t-rm -f $kcfg_output\n");
331         $target_adds{"$cleantarget-am"} .= "$cleantarget-kcfg ";
332     }
333
334     if ($closure_output) {
335         appendLines ("$cleantarget-closures:\n\t-rm -f $closure_output\n");
336         $target_adds{"$cleantarget-am"} .= "$cleantarget-closures ";
337     }
338
339     if ($MakefileData =~ /\nKDE_LANG\s*=\s*(\S*)\s*\n/) {
340         $kdelang = '$(KDE_LANG)'
341     } else {
342         $kdelang = '';
343     }
344
345     tag_POFILES ();             # language rules for po directory
346     tag_DOCFILES ();            # language rules for doc directories
347     tag_LOCALINSTALL();         # add $(DESTDIR) before all kde_ dirs
348     tag_ICON();
349     tag_SUBDIRS();
350
351     my $tmp = "force-reedit:\n";
352     $tmp   .= "\t$automkCall\n\tcd \$(top_srcdir) && perl $thisProg $printname\n\n";
353     appendLines($tmp);
354     
355     make_bcheck_target();
356     make_meta_classes();
357     tag_COMPILE_FIRST();
358     tag_FINAL() if (!$kdeopts{"nofinal"});
359
360     my $final_lines = "final:\n\t\$(MAKE) ";
361     my $final_install_lines = "final-install:\n\t\$(MAKE) ";
362     my $nofinal_lines = "no-final:\n\t\$(MAKE) ";
363     my $nofinal_install_lines = "no-final-install:\n\t\$(MAKE) ";
364
365     foreach $program (@programs) {
366         my $lookup = $program . '_OBJECTS\s*=[ \t]*.*';
367         my $new = "";
368         my @list = split(/[\034\s]+/, $realObjs{$program});
369         if (!$kdeopts{"nofinal"} && @list > 1 && $finalObjs{$program}) {
370             $new .= "$program\_final\_OBJECTS = " . $finalObjs{$program};
371             $new .= "\n$program\_nofinal\_OBJECTS = " . $realObjs{$program};
372             $new .= "\n\@KDE_USE_FINAL_FALSE\@$program\_OBJECTS = \$($program\_nofinal\_OBJECTS)";
373             $new .= "\n\@KDE_USE_FINAL_TRUE\@$program\_OBJECTS = \$($program\_final\_OBJECTS)";
374
375             $final_lines .= "$program\_OBJECTS=\"\$($program\_final_OBJECTS)\" ";
376             $final_install_lines .= "$program\_OBJECTS=\"\$($program\_final_OBJECTS)\" ";
377             $nofinal_lines .= "$program\_OBJECTS=\"\$($program\_nofinal\_OBJECTS)\" ";
378             $nofinal_install_lines .= "$program\_OBJECTS=\"\$($program\_nofinal_OBJECTS)\" ";
379         } else {
380             $new = "$program\_OBJECTS = " . $realObjs{$program};
381         }
382         if($MakefileData =~ m/\n$lookup/) {
383             substituteLine ($lookup, $new);
384         }
385         else {
386             appendLines("$new\n");
387         }
388     }
389     appendLines($final_lines . "all-am\n");
390     appendLines($final_install_lines . "install-am\n");
391     appendLines($nofinal_lines . "all-am\n");
392     appendLines($nofinal_install_lines . "install-am\n");
393
394     my $lookup = '(\@\S+\@)?DEP_FILES\s*=[ \t]*(.*)';
395     if ($MakefileData =~ /\n$lookup/) {
396         my $condition = $1;
397         my $depfiles = $2;
398         my $workfiles;
399
400         if ($dep_finals) {
401             # Add the conditions on every line, since
402             # there may be line continuations in the list.
403             $workfiles = "$dep_files $dep_finals $depfiles";
404             $workfiles =~ s/\034/\034$condition\@KDE_USE_FINAL_TRUE\@\t/g;
405             $lines  = "$condition\@KDE_USE_FINAL_TRUE\@DEP_FILES = $workfiles\n";
406             $workfiles = "$dep_files $depfiles";
407             $workfiles =~ s/\034/\034$condition\@KDE_USE_FINAL_FALSE\@\t/g;
408             $lines .= "$condition\@KDE_USE_FINAL_FALSE\@DEP_FILES = $workfiles";
409         } else {
410             $workfiles = "$dep_files $depfiles";
411             $workfiles =~ s/\034/\034$condition\t/g;
412             $lines = $condition . "DEP_FILES = $workfiles";
413         }
414         substituteLine($lookup, $lines);
415     }
416
417     # new recursive targets
418     $target_adds{ "nmcheck" } .= ""; # always create nmcheck target
419     $target_adds{ "nmcheck-am" } .= "nmcheck";
420     $lookup = 'RECURSIVE_TARGETS\s*=[ \t]*(.*)';
421     if ($MakefileData =~ /\n$lookup/) {
422       substituteLine($lookup, "RECURSIVE_TARGETS = $1 nmcheck-recursive bcheck-recursive");
423     }
424
425     my $cvs_lines = "cvs-clean:\n";
426     $cvs_lines .= "\t\$(MAKE) admindir=\$(top_srcdir)/admin -f \$(top_srcdir)/admin/Makefile.common cvs-clean\n";
427     appendLines($cvs_lines);
428
429     $cvs_lines  = "kde-rpo-clean:\n";
430     $cvs_lines .= "\t-rm -f *.rpo\n";
431     appendLines($cvs_lines);
432     $target_adds{"clean"} .= "kde-rpo-clean ";
433
434     my %target_dels = ("install-data-am" => "");
435
436     # some strange people like to do a install-exec, and expect that also
437     # all modules are installed.  automake doesn't know this, so we need to move
438     # this here from install-data to install-exec.
439     if ($MakefileData =~ m/\nkde_module_LTLIBRARIES\s*=/) {
440 #      $target_adds{"install-exec-am"} .= "install-kde_moduleLTLIBRARIES ";
441 #      don't use $target_adds here because we need to append the dependency, not
442 #      prepend it. Fixes #44342 , when a module depends on a lib in the same dir
443 #      and libtool needs it during relinking upon install (Simon)
444       my $lookup = "install-exec-am:([^\n]*)";
445       if($MakefileData =~ /\n$lookup\n/) {
446         substituteLine("$lookup", "install-exec-am: $1 install-kde_moduleLTLIBRARIES");
447       }
448       $target_dels{"install-data-am"} .= "install-kde_moduleLTLIBRARIES ";
449       $target_adds{"install-data-am"} .= " ";
450     }
451
452     my $lines = "";
453
454     foreach $add (keys %target_adds) {
455         my $lookup = quotemeta($add) . ':([^\n]*)';
456         if ($MakefileData =~ /\n$lookup\n/) {
457           my $newlines = $1;
458           my $oldlines = $lookup;
459           if (defined $target_dels{$add}) {
460             foreach $del (split(' ', $target_dels{$add})) {
461               $newlines =~ s/\s*$del\s*/ /g;
462             }
463           }
464           substituteLine($oldlines, "$add: " . $target_adds{$add} . $newlines);
465         } else {
466           $lines .= "$add: " . $target_adds{$add} . "\n";
467         }
468     }
469
470     appendLines($lines) if ($lines);
471
472     $lines = join("\n", values %rule_adds);
473     appendLines($lines) if ($lines);
474
475     my $found = 1;
476
477     while ($found) {
478         if ($MakefileData =~ m/\n(.*)\$\(CXXFLAGS\)(.*)\n/) {
479             my $stuff_before = $1;
480             my $stuff_after = $2;
481             my $lookup = quotemeta("$1\$(CXXFLAGS)$2");
482             my $replacement = "$1\$(KCXXFLAGS)$2";
483             $MakefileData =~ s/$lookup/$replacement/;
484             $lookup =~ s/\\\$\\\(CXXFLAGS\\\)/\\\$\\\(KCXXFLAGS\\\)/;
485             $replacement = "$stuff_before\$(KCXXFLAGS) \$(KDE_CXXFLAGS)$stuff_after";
486             substituteLine($lookup, $replacement);
487         } else {
488             $found = 0;
489         }
490     }
491
492     if($foreign_libtool == 0) {
493         $lookup = '(\n[^#].*\$\(LIBTOOL\) --mode=link) (\$\(CXXLD\).*\$\(KCXXFLAGS\))';
494
495         if ($MakefileData =~ m/$lookup/ ) {
496             $MakefileData =~ s/$lookup/$1 --tag=CXX $2/;
497         }
498
499         $lookup = '(\n[^#].*\$\(LIBTOOL\) --mode=compile)\s+(\$\(CXX\)\s+)';
500         if ($MakefileData =~ m/$lookup/ ) {
501             $MakefileData =~ s/$lookup/$1 --tag=CXX $2/;
502         }
503     }
504
505     $MakefileData =~ s/\$\(KCXXFLAGS\)/\$\(CXXFLAGS\)/g;
506
507     $lookup = '(.*)cp -pr \$\$/\$\$file \$\(distdir\)/\$\$file(.*)';
508     if ($MakefileData =~ m/\n$lookup\n/) {
509         substituteLine($lookup, "$1cp -pr \$\$d/\$\$file \$(distdir)/\$\$file$2");
510     }
511
512     # Always update the Makefile.in
513     updateMakefile ();
514     return;
515 }
516
517 #-----------------------------------------------------------------------------
518
519 # Beware: This procedure is not complete.  E.g. it also parses lines
520 # containing a '=' in rules (for instance setting shell vars).  For our
521 # usage this us enough, though.
522 sub read_variables ()
523 {
524     while ($MakefileData =~ /\n\s*(\S+)\s*=([^\n]*)/g) {
525         $varcontent{$1} = $2;
526     }
527 }
528
529 # Check to see whether we should process this make file.
530 # This is where we look for tags that we need to process.
531 # A small amount of initialising on the tags is also done here.
532 # And of course we open and/or create the needed make files.
533 sub initialise ()
534 {
535     if (! -r "Makefile.am") {
536         print STDOUT "found Makefile.in without Makefile.am\n" if ($verbose);
537         return 0;
538     }
539
540     # Checking for files to process...
541
542     open (FILEIN, $makefile) || die "Can't open $makefileDir/$makefile: $!\n";
543     # perl bug in 5.8.0: in utf8 mode it badly screws up
544     binmode(FILEIN, ":bytes") if ($] >= 5.008);
545     # Read the file
546     # stat(FILEIN)[7] might look more elegant, but is slower as it 
547     # requires stat'ing the file
548     seek(FILEIN, 0, 2);
549     my $fsize = tell(FILEIN);
550     seek(FILEIN, 0, 0);
551     read FILEIN, $MakefileData, $fsize;
552     close FILEIN;
553     print "DOS CRLF within $makefileDir/$makefile!\n" if($MakefileData =~ y/\r//d);
554
555     # Remove the line continuations, but keep them marked
556     # Note: we lose the trailing spaces but that's ok.
557     # Don't mangle line-leading spaces (usually tabs)
558     # since they're important.
559     $MakefileData =~ s/\\\s*\n/\034/g;
560
561     # If we've processed the file before...
562     restoreMakefile ()      if ($MakefileData =~ /$progId/);
563
564     foreach $dir (@foreignfiles) {
565       if (substr($makefileDir,0,length($dir)) eq $dir) {
566         return 0;
567       }
568     }
569
570     %kdeopts = ();
571     $kdeopts{"foreign"} = 0;
572     $kdeopts{"qtonly"} = 0;
573     $kdeopts{"noautodist"} = 0;
574     $kdeopts{"foreign-libtool"} = $foreign_libtool;
575     $kdeopts{"nofinal"} = !$use_final; # default
576
577     read_variables();
578
579     if ($MakefileData =~ /\nKDE_OPTIONS\s*=[ \t]*([^\n]*)\n/) {
580         my $kde_options_str = $1;
581         local @kde_options = split(/[\034\s]+/, $kde_options_str);
582         if (grep(/^foreign$/, @kde_options)) {
583             push(@foreignfiles, $makefileDir . "/");
584             return 0; # don't touch me
585         }
586         for $opt (@kde_options) {
587             if (!defined $kdeopts{$opt}) {
588                 print STDERR "Warning: unknown option $opt in $printname\n";
589             } else {
590                 $kdeopts{$opt} = 1;
591             }
592         }
593     }
594
595     # Look for the tags that mean we should process this file.
596     $metasourceTags = 0;
597     $metasourceTags++    while ($MakefileData =~ /\n[^=\#]*METASOURCES\s*=/g);
598
599     my $pofileTag = 0;
600     $pofileTag++    while ($MakefileData =~ /\nPOFILES\s*=/g);
601     if ($pofileTag > 1)
602       {
603           print STDERR "Error: Only one POFILES tag allowed\n";
604           $errorflag = 1;
605       }
606
607     while ($MakefileData =~ /\n\.SUFFIXES:([^\n]+)\n/g) {
608         my $suffixes_str = $1;
609         my @list=split(' ', $suffixes_str);
610         foreach $ext (@list) {
611             if ($ext =~ /^\.$cppExt$/) {
612                 $cxxsuffix = $ext;
613                 $cxxsuffix =~ s/\.//g;
614                 print STDOUT "will use suffix $cxxsuffix\n" if ($verbose);
615                 last;
616             }
617         }
618     }
619
620     tag_KDEINIT();
621
622     while ($MakefileData =~ /\n(\S*)_OBJECTS\s*=[\034 \t]*([^\n]*)\n/g) {
623
624         my $program = $1;
625         my $objs = $2; # safe them
626
627         my $ocv = 0;
628
629         my @objlist = split(/[\034\s]+/, $objs);
630         foreach $obj (@objlist) {
631             if ($obj =~ /(\S*)\$\((\S+)\)/ ) {
632                 my $pre = $1;
633                 my $variable = $2;
634                 if ($pre eq '' && exists($varcontent{$variable})) {
635                     my @addlist = split(/[\034\s]+/, $varcontent{$variable});
636                     push(@objlist, @addlist);
637                 } elsif ($variable !~ 'OBJEXT') {
638                     $ocv = 1;
639                 }
640             }
641         }
642
643         next if ($ocv);
644         next if ($program =~ /^am_libkdeinit_/);
645
646         $program =~ s/^am_// if ($program =~ /^am_/);
647
648         my $sourceprogram = $program;
649         $sourceprogram =~ s/\@am_/\@/ if($sourceprogram =~ /^.*\@am_.+/);
650
651         print STDOUT "found program $program\n" if ($verbose);
652         push(@programs, $program);
653
654         $realObjs{$program} = $objs;
655
656         if ($MakefileData =~ /\n$sourceprogram\_SOURCES\s*=[ \t]*(.*)\n/) {
657             $sources{$program} = $1;
658         } 
659         else {
660             $sources{$program} = "";
661             print STDERR "found program with no _SOURCES: $program\n";
662         }
663         
664         my $realprogram = $program;
665         $realprogram =~ s/_/./g; # unmask to regexp
666         if ($MakefileData =~ /\n($realprogram)(\$\(EXEEXT\)?)?:.*\$\($program\_OBJECTS\)/) {
667             $realname{$program} = $1;
668         } else {
669             # not standard Makefile - nothing to worry about
670             $realname{$program} = "";
671         }
672     }
673
674     my $lookup = 'DEPDIR\s*=.*';
675     if ($MakefileData !~ /\n$lookup/) {
676         $lookup = 'bindir\s*=[ \t]*.*';
677         substituteLine($lookup, "DEPDIR = .deps\n$1") if ($MakefileData =~ /\n($lookup)/);
678     }
679
680     my @marks = ('MAINTAINERCLEANFILES', 'CLEANFILES', 'DISTCLEANFILES');
681     foreach $mark (@marks) {
682         while ($MakefileData =~ /\n($mark)\s*=[ \t]*([^\n]*)/g) {
683             my $clean_str = $2; 
684             foreach $file (split('[\034\s]+', $clean_str)) {
685                 $file =~ s/\.\///;
686                 push(@cleanfiles, $file);
687             }
688         }
689     }
690
691     my $localTag = 0;
692     $localTag++ if ($MakefileData =~ /\ninstall-\S+-local:/);
693     
694     return (!$errorflag);
695 }
696
697 #-----------------------------------------------------------------------------
698
699 # Gets the list of user defined directories - relative to $srcdir - where
700 # header files could be located.
701 sub tag_META_INCLUDES ()
702 {
703     my $lookup = '[^=\n]*META_INCLUDES\s*=[ \t]*(.*)';
704     return 1    if ($MakefileData !~ /($lookup)\n/);
705     print STDOUT "META_INCLUDE processing <$1>\n"       if ($verbose);
706
707     my $headerStr = $2;
708     removeLine ($lookup, $1);
709
710     my @headerlist = split(/[\034\s]+/, $headerStr);
711
712     foreach $dir (@headerlist)
713     {
714         $dir =~ s#\$\(srcdir\)#.#;
715         if (! -d $dir)
716         {
717             print STDERR "Warning: $dir can't be found. ",
718                             "Must be a relative path to \$(srcdir)\n";
719         }
720         else
721         {
722             push (@headerdirs, $dir);
723         }
724     }
725
726     return 0;
727 }
728
729 #-----------------------------------------------------------------------------
730
731 sub tag_FINAL()
732 {
733     my @final_names = ();
734     
735     foreach $program (@programs) {
736         
737         if ($sources{$program} =~ /\(/) {
738             print STDOUT "found ( in $program\_SOURCES. skipping\n" if ($verbose);
739             next;
740         }
741
742         my $mocs = "";       # Moc files (in this program)
743         my $moc_cpp_added = 0;  # If we added some .moc.cpp files, due to
744                                 # no other .cpp file including the .moc one.
745         
746         my @progsources = split(/[\034\s]+/, $sources{$program});
747         my %shash = ();
748         @shash{@progsources} = 1;  # we are only interested in the existence
749         my %sourcelist = ();
750         my %extradeps = ();
751         
752         foreach $source (@progsources) {
753             my $suffix = $source;
754             $suffix =~ s/^.*\.([^\.]+)$/$1/;
755             
756             $sourcelist{$suffix} .= "$source ";
757         }
758         foreach my $mocFile (keys (%globalmocs))
759         {
760             my ($dir, $hFile, $cppFile) = split ("\035", $globalmocs{$mocFile}, 3);
761             if (defined ($cppFile)) {
762                 $mocs .= " $mocFile.moc" if exists $shash{$cppFile};
763             } else {
764                 $sourcelist{$cxxsuffix} .= "$mocFile.moc.$cxxsuffix ";
765                 $moc_cpp_added = 1;
766             }
767         }
768
769         # scan for extra given dependencies and add them to our target
770         while ($MakefileData =~ /\n\s*(\S+)\.(?:lo|o)\s*:([^\n]*)/g) {
771             $extradeps{$1} = $2;
772         }
773
774         foreach $suffix (keys %sourcelist) {
775             # See if this file contains c++ code. (i.e., just check the file's suffix against c++ extensions)
776             my $suffix_is_cxx = 0;
777             if($suffix =~ /($cppExt)$/) {
778               $cxxsuffix = $1;
779               $suffix_is_cxx = 1;
780             }
781             
782             my $mocfiles_in = ($suffix eq $cxxsuffix) && $moc_cpp_added;
783             
784             my @sourcelist = split(/[\034\s]+/, $sourcelist{$suffix});
785             
786             if ((@sourcelist == 1 && !$mocfiles_in) || $suffix_is_cxx != 1 ) {
787                 
788                 # we support IDL on our own
789                 if ($suffix eq "skel" || $suffix =~ /^stub/
790                     || $suffix =~ /^signals/ # obsolete, remove in KDE-4
791                     || $suffix eq "h" || $suffix eq "ui" 
792                     || $suffix eq "kcfgc" ) {
793                     next;
794                 }
795                 
796                 foreach $file (@sourcelist) {
797                     $file =~ s/\Q$suffix\E$//;
798                     
799                     $finalObjs{$program} .= $file;
800                     if ($program =~ /_la$/) {
801                         $finalObjs{$program} .= "lo ";
802                     } else {
803                         $finalObjs{$program} .= "o ";
804                     }
805                 }
806                 next; # suffix
807             }
808             
809             my $source_deps = "";
810             foreach $source (@sourcelist) {
811                 if (-f $source) {
812                     $source_deps .= " \$(srcdir)/$source";
813                 } else {
814                     $source_deps .= " $source";
815                 }
816                 my $plainsource = $source;
817                 $plainsource =~ s/\.$cppExt$//;
818                 $source_deps .= " " . $extradeps{$plainsource} if (exists($extradeps{$plainsource}));
819             }
820
821             $handling = "$program.all_$suffix.$suffix: \$(srcdir)/Makefile.in" . $source_deps . " " . join(' ', $mocs)  . "\n";
822             $handling .= "\t\@echo 'creating $program.all_$suffix.$suffix ...'; \\\n";
823             $handling .= "\trm -f $program.all_$suffix.files $program.all_$suffix.final; \\\n";
824             $handling .= "\techo \"#define KDE_USE_FINAL 1\" >> $program.all_$suffix.final; \\\n";
825             $handling .= "\tfor file in " . $sourcelist{$suffix} . "; do \\\n";
826             $handling .= "\t  echo \"#include \\\"\$\$file\\\"\" >> $program.all_$suffix.files; \\\n";
827             $handling .= "\t  test ! -f \$\(srcdir\)/\$\$file || egrep '^#pragma +implementation' \$\(srcdir\)/\$\$file >> $program.all_$suffix.final; \\\n";
828             $handling .= "\tdone; \\\n";
829             $handling .= "\tcat $program.all_$suffix.final $program.all_$suffix.files > $program.all_$suffix.$suffix; \\\n";
830             $handling .= "\trm -f $program.all_$suffix.final $program.all_$suffix.files\n";
831
832             appendLines($handling);
833
834             push(@final_names, "$program.all_$suffix.$suffix");
835             my $finalObj = "$program.all_$suffix.";
836             if ($program =~ /_la$/) {
837                 $finalObj .= "lo";
838             } else {
839                 $finalObj .= "o";
840             }
841             $finalObjs{$program} .= $finalObj . " ";
842         }
843     }
844     
845     if (!$kdeopts{"nofinal"} && @final_names >= 1) {
846         # add clean-final target
847         my $lines = "$cleantarget-final:\n";
848         $lines .= "\t-rm -f " . join(' ', @final_names) . "\n" if (@final_names);
849         appendLines($lines);
850         $target_adds{"$cleantarget-am"} .= "$cleantarget-final ";
851         
852         foreach $finalfile (@final_names) {
853             $finalfile =~ s/\.[^.]*$/.P/;
854             $dep_finals .= " \$(DEPDIR)/$finalfile";
855         }
856     }
857 }
858
859 sub tag_KDEINIT()
860 {
861     my @progs = ();
862     my $ltlibs = "";
863     my $lookup = 'kdeinit_LTLIBRARIES\s*=[ \t]*(.*)';
864
865     if ($MakefileData =~ m/\n$lookup/) {
866         @kdeinits = split(/[\034\s]+/, $1);
867         my $lines = "";
868         foreach my $kdeinit (@kdeinits) {
869             if ($kdeinit =~ m/\.la$/) {
870                 $kdeinit =~ s/\.la$//;
871                 push(@progs, $kdeinit);
872
873                 $lines .= "\n${kdeinit}.la.$cxxsuffix:\n";
874                 $lines .= "\techo 'extern \"C\" int kdemain(int argc, char* argv[]);' > ${kdeinit}.la.$cxxsuffix; \\\n";
875                 $lines .= "\techo 'int main(int argc, char* argv[]) { return kdemain(argc,argv); }' >> ${kdeinit}.la.$cxxsuffix\n";
876
877                 $lines .= "\n${kdeinit}_dummy.$cxxsuffix:\n";
878                 $lines .= "\techo 'extern \"C\" int kdemain(int argc, char* argv[]);' > ${kdeinit}_dummy.$cxxsuffix; \\\n";
879                 $lines .= "\techo 'extern \"C\" int kdeinitmain(int argc, char* argv[]) { return kdemain(argc,argv); }' >> ${kdeinit}_dummy.$cxxsuffix\n";
880
881                 push(@cleanfiles, "${kdeinit}.la.$cxxsuffix");
882                 push(@cleanfiles, "${kdeinit}_dummy.$cxxsuffix");
883
884                 # add dependency
885                 $dep_files .= " \$(DEPDIR)/${kdeinit}.la.Po" if($dep_files !~/${kdeinit}.la.Po/ );
886                 $dep_files .= " \$(DEPDIR)/${kdeinit}_dummy.Plo" if($dep_files !~/${kdeinit}_dummy.Plo/ );
887
888                 # make library
889                 $lookup = $kdeinit . '_la_LIBADD\s*=[ \t]*(.*)';
890                 if($MakefileData =~ m/\n$lookup/) {
891                     my $libadd = $1;
892                     substituteLine($lookup, "${kdeinit}_la_LIBADD = libkdeinit_${kdeinit}.la");
893                     appendLines("libkdeinit_${kdeinit}_la_LIBADD = $libadd\n");
894                 }
895                 appendLines("libkdeinit_${kdeinit}_la_LDFLAGS = -no-undefined -avoid-version \$(all_libraries)\n");
896
897                 # add library dependencies
898                 $lookup = $kdeinit . '_la_DEPENDENCIES\s*=[ \t]*(.*)';
899                 if($MakefileData =~ m/\n$lookup/) {
900                     my $libdeps = $1;
901                     substituteLine($lookup, "${kdeinit}_la_DEPENDENCIES = libkdeinit_${kdeinit}.la");
902                     appendLines("libkdeinit_${kdeinit}_la_DEPENDENCIES = $libdeps\n");
903                 }
904
905                 # make library objects
906                 $lookup = "am_${kdeinit}_la_OBJECTS" . '\s*=[ \t]*(.*)';
907                 if($MakefileData =~ m/\n$lookup/) {
908                     my $libobjects = $1;
909                     substituteLine($lookup, "am_${kdeinit}_la_OBJECTS = ${kdeinit}_dummy.lo");
910                     appendLines("am_libkdeinit_${kdeinit}_la_OBJECTS = $libobjects\n");
911                     my $prog = "libkdeinit_${kdeinit}_la";
912                     push(@programs, $prog);
913                     $realObjs{$prog} = $libobjects;
914                     $realname{$prog} = "libkdeinit_${kdeinit}.la";
915                 }
916                 $target_adds{"libkdeinit_${kdeinit}.la"} = "\$(libkdeinit_${kdeinit}_la_OBJECTS) \$(libkdeinit_${kdeinit}_la_DEPENDENCIES)\n" .
917                         "\t\$(CXXLINK) -rpath \$(libdir) \$(libkdeinit_${kdeinit}_la_LDFLAGS) ".
918                            "\$(libkdeinit_${kdeinit}_la_OBJECTS) " .
919                            "\$(libkdeinit_${kdeinit}_la_LIBADD) " .
920                            "\$(LIBS)\n";
921
922                 # make libkdeinit sources
923                 $lookup = $kdeinit . '_la_SOURCES\s*=[ \t]*(.*)';
924                 if($MakefileData =~ m/\n$lookup/) {
925                     my $srces = $1;
926                     $sources_changed{"libkdeinit_${kdeinit}_la"} = 1;
927                     $sources{"libkdeinit_${kdeinit}_la"} = $srces;
928                 }
929
930                 # make libkdeinit metasources
931                 $lookup = $kdeinit . '_la_METASOURCES\s*=[ \t]*(.*)';
932                 substituteLine($lookup, "libkdeinit_${kdeinit}_la_METASOURCES = $1")
933                     if($MakefileData =~ m/\n$lookup/);
934
935 =cut
936                 # make binary sources
937                 $lookup = $kdeinit. '_SOURCES\s*=[ \t]*(.*)';
938                 if($MakefileData =~ m/\n$lookup/) {
939                     substituteLine($lookup, "${kdeinit}_SOURCES = ${kdeinit}.la.$cxxsuffix");
940                     $lookup = 'SOURCES\s*=[ \t]*(.*)';
941                     if($MakefileData =~ m/\n$lookup/) {
942                         my $srces = $1;
943                         $srces =~ s/\b$kdeinit\.c\b/\$(${kdeinit}_SOURCES)/;
944                         $srces =~ s/\$\(${kdeinit}_la_SOURCES\)/\$(libkdeinit_${kdeinit}_la_SOURCES)/;
945                         substituteLine($lookup, "SOURCES = $srces");
946                     }
947                     $lookup = 'DIST_SOURCES\s*=[ \t](.*)';
948                     if($MakefileData =~ m/\n$lookup/) {
949                         my $srces = $1;
950                         $srces =~ s/\b$kdeinit\.c\b/\$(${kdeinit}_SOURCES)/;
951                         $srces =~ s/\$\(${kdeinit}_la_SOURCES\)/\$(libkdeinit_${kdeinit}_la_SOURCES)/;
952                         substituteLine($lookup, "DIST_SOURCES = $srces");
953                     }
954                 }
955
956                 # make binary objects / libs
957                 $lookup = $kdeinit . '_OBJECTS\s*=[ \t]*.*';
958                 if($MakefileData =~ m/\n$lookup/) {
959                     $realObjs{$kdeinit} = "${kdeinit}.la.\$(OBJEXT)";
960                     substituteLine("${kdeinit}_LDFLAGS\\s*=.*", "${kdeinit}_LDFLAGS = \$(all_libraries)");
961                     substituteLine("${kdeinit}_LDADD\\s*=.*", "${kdeinit}_LDADD = libkdeinit_${kdeinit}.la");
962                     substituteLine("${kdeinit}_DEPENDENCIES\\s*=.*", "${kdeinit}_DEPENDENCIES = libkdeinit_${kdeinit}.la");
963                 }
964 =cut
965                 # add binary
966                 push(@programs, $kdeinit);
967                 $realObjs{$kdeinit} = "${kdeinit}.la.\$(OBJEXT)";
968                 $realname{$kdeinit} = $kdeinit;
969                 $sources{$kdeinit} = "${kdeinit}.la.$cxxsuffix";
970
971                 $lines .= "${kdeinit}_LDFLAGS = \$(KDE_RPATH) -no-undefined \$(all_libraries)\n";
972                 $lines .= "${kdeinit}_LDADD = libkdeinit_${kdeinit}.la\n";
973                 $lines .= "${kdeinit}_DEPENDENCIES = libkdeinit_${kdeinit}.la\n";
974
975                 $target_adds{"${kdeinit}\$(EXEEXT)"} =
976                           "\$(${kdeinit}_OBJECTS) \$(${kdeinit}_DEPENDENCIES)\n" .
977                           "\t\@rm -f ${kdeinit}\$(EXEEXT)\n" .
978                           "\t\$(CXXLINK) \$(${kdeinit}_LDFLAGS) \$(${kdeinit}_OBJECTS) \$(${kdeinit}_LDADD) \$(LIBS)\n";
979
980                 $ltlibs .= " libkdeinit_${kdeinit}.la";
981             }
982         }
983         appendLines($lines);
984
985         # add libkdeinit target
986         $lookup = 'lib_LTLIBRARIES\s*=[ \t]*(.*)';
987         if($MakefileData =~ m/\n$lookup/) {
988             substituteLine($lookup, "lib_LTLIBRARIES = $1 $ltlibs");
989         }
990         else {
991             print STDERR
992                 "Error: lib_LTLIBRARIES missing in $printname (required for kdeinit_LTLIBRARIES).\n";
993             $errorflag = 1;
994         }
995     }
996
997     if($#progs >= 0) {
998         if($MakefileData !~ m/\nbin_PROGRAMS\s*=/) {
999             print STDERR "Error: bin_PROGRAMS missing in $printname (required for kdeinit_LTLIBRARIES).\n";
1000             $errorflag = 1;
1001         }
1002         else {
1003             # add our new progs to SOURCES, DIST_SOURCES and bin_PROGRAMS
1004             my $progsources = "";
1005             my $progexes = "";
1006             foreach my $p (@progs) {
1007                 $progsources .= "\$(${p}_SOURCES) ";
1008                 $progexes .= "${p}\$(EXEEXT) ";
1009             }
1010             $lookup = 'SOURCES\s*=[ \t]*(.*)';
1011             if($MakefileData =~ /\n$lookup/) {
1012                 substituteLine($lookup, "SOURCES = $1 $progsources");
1013             }
1014             $lookup = 'DIST_SOURCES\s*=[ \t]*(.*)';
1015             if($MakefileData =~ /\n$lookup/) {
1016                 substituteLine($lookup, "DIST_SOURCES = $1 $progsources");
1017             }
1018             # bin_PROGRAMS is complicated, as it exists twice, so we do a little
1019             # magic trick here
1020             $lookup = 'PROGRAMS\s*=[ \t]*(.*)';
1021             if ($MakefileData =~ /\n$lookup/) {
1022                 substituteLine($lookup, "bin_PROGRAMS += $progexes\nPROGRAMS = $1");
1023             }
1024         }
1025     }
1026 }
1027
1028 #-----------------------------------------------------------------------------
1029
1030 sub tag_COMPILE_FIRST()
1031 {
1032   foreach $program (@programs) {
1033     my $lookup = "$program" . '_COMPILE_FIRST\s*=[ \t]*(.*)';
1034     if ($MakefileData =~ m/\n$lookup\n/) {
1035       my $compilefirst_str = $1;
1036       my @compilefirst = split(/[\034\s]+/, $compilefirst_str);
1037       my @progsources = split(/[\034\s]+/, $sources{$program});
1038       my %donesources = ();
1039       foreach $source (@progsources) {
1040         my @deps  = ();
1041         my $sdeps = "";
1042         if (-f $source) {
1043           $sdeps = "\$(srcdir)/$source";
1044         } else {
1045           $sdeps = "$source";
1046         }
1047         foreach $depend (@compilefirst) {
1048           next if ($source eq $depend);
1049           # avoid cyclic dependencies
1050           next if defined($donesources{$depend});
1051           push @deps, $depend;
1052         }
1053         $target_adds{$sdeps} .= join(' ', @deps) . ' ' if (@deps);
1054         $donesources{$source} = 1;
1055       }
1056     }
1057   }
1058 }
1059
1060 #-----------------------------------------------------------------------------
1061
1062
1063 # Organises the list of headers that we'll use to produce moc files
1064 # from.
1065 sub tag_METASOURCES ()
1066 {
1067     local @newObs           = ();  # here we add to create object files
1068     local @depend           = ();  # here we add to create moc files
1069     local $mocExt           = ".moc";
1070     local %mocFiles         = ();
1071
1072     my $line = "";
1073     my $postEqual = "";
1074
1075     my $lookup;
1076     my $found = "";
1077     if ($metasourceTags > 1) {
1078         $lookup = $program . '_METASOURCES\s*=\s*(.*)';
1079         return 1    if ($MakefileData !~ /\n($lookup)\n/);
1080         $found = $1;
1081     } else {
1082         $lookup = $program . '_METASOURCES\s*=\s*(.*)';
1083         if ($MakefileData !~ /\n($lookup)\n/) {
1084             $lookup = 'METASOURCES\s*=\s*(.*)';
1085             return 1    if ($MakefileData !~ /\n($lookup)\n/);
1086             $found = $1;
1087             $metasourceTags = 0; # we can use the general target only once
1088         } else {
1089             $found = $1;
1090         }
1091     }
1092     print STDOUT "METASOURCE processing <$found>)\n"      if ($verbose);
1093     
1094     $postEqual = $found;
1095     $postEqual =~ s/[^=]*=//;
1096     
1097     removeLine ($lookup, $found);
1098     
1099     # Always find the header files that could be used to "moc"
1100     return 1    if (findMocCandidates ());
1101     
1102     if ($postEqual =~ /AUTO\s*(\S*)|USE_AUTOMOC\s*(\S*)/)
1103     {
1104         print STDERR "$printname: the argument for AUTO|USE_AUTOMOC is obsolete" if ($+);
1105         $mocExt = ".moc.$cxxsuffix";
1106         $haveAutomocTag = 1;
1107     }
1108     else
1109     {
1110         # Not automoc so read the list of files supplied which
1111         # should be .moc files.
1112
1113         $postEqual =~ tr/\034/ /;
1114
1115         # prune out extra headers - This also checks to make sure that
1116         # the list is valid.
1117         pruneMocCandidates ($postEqual);
1118     }
1119
1120     checkMocCandidates ();
1121     
1122     if (@newObs) {
1123         my $ext =  ($program =~ /_la$/) ? ".moc.lo " : ".moc.o ";
1124         $realObjs{$program} .= "\034" . join ($ext, @newObs) . $ext;
1125         $dependmocs{$program} = join (".moc.$cxxsuffix " , @newObs) . ".moc.$cxxsuffix";
1126         foreach $file (@newObs) {
1127             $dep_files .= " \$(DEPDIR)/$file.moc.P" if($dep_files !~/$file.moc.P/);
1128         }
1129     }
1130     if (@depend) {
1131         $dependmocs{$program} .= " ";
1132         $dependmocs{$program} .= join('.moc ', @depend) . ".moc";
1133         $dependmocs{$program} .= " ";
1134     }
1135     addMocRules ();
1136     @globalmocs{keys %mocFiles}=values %mocFiles;
1137 }
1138
1139 #-----------------------------------------------------------------------------
1140
1141 # Returns 0 if the line was processed - 1 otherwise.
1142 # Errors are logged in the global $errorflags
1143 sub tag_AUTOMAKE ()
1144 {
1145     my $lookup = '.*cd \$\(top_srcdir\)\s+&&[\034\s]+\$\(AUTOMAKE\)(.*)';
1146     return 1    if ($MakefileData !~ /\n($lookup)\n/);
1147     print STDOUT "AUTOMAKE processing <$1>\n"        if ($verbose);
1148
1149     my $newLine = $1."\n\tcd \$(top_srcdir) && perl $thisProg $printname";
1150
1151     # automake 1.8.x adds another automake call. *sigh*
1152     $newLine =~ s/;([\034\s]+cd\s+\$\(srcdir\)\s+&&[\034\s]+\$\(AUTOMAKE\).*)[\034\s]+\&\&[\034\s]+exit[\034\s]+0;([\034\s]+exit\s+1)/; \034 ( $1 ) || exit 1; echo \' cd \$(top_srcdir) && perl $thisProg \'; cd \$(top_srcdir) && perl $thisProg && exit 0; $2/;
1153     substituteLine ($lookup, $newLine);
1154     $automkCall = $1;
1155
1156     $lookup = '.*cd \$\(srcdir\)\s+&&[\034\s]+\$\(AUTOCONF\)(.*)';
1157     if ($MakefileData =~ /\n($lookup)\n/) {
1158       $newLine  = "\tcd \$(srcdir) && rm -f configure\n";
1159       $newLine .= "\tcd \$(top_srcdir) && \$(MAKE) -f admin/Makefile.common configure";
1160       substituteLine ($lookup, $newLine);
1161     }
1162
1163     return 0;
1164 }
1165
1166 #-----------------------------------------------------------------------------
1167
1168 sub handle_TOPLEVEL()
1169 {
1170     my $pofiles = "";
1171     my @restfiles = ();
1172     opendir (THISDIR, ".");
1173     foreach $entry (readdir(THISDIR)) {
1174         next if (-d $entry);
1175         
1176         next if ($entry eq "CVS" || $entry =~ /^\./  || $entry =~ /^Makefile/ || $entry =~ /~$/ || $entry =~ /^\#.*\#$/ || $entry =~ /.gmo$/);
1177                  
1178         if ($entry =~ /\.po$/) {
1179              next;
1180         }
1181         push(@restfiles, $entry);
1182     }
1183     closedir (THISDIR);
1184             
1185     if (@restfiles) {
1186         $target_adds{"install-data-am"} .= "install-nls-files ";
1187         $lines = "install-nls-files:\n";
1188         $lines .= "\t\$(mkinstalldirs) \$(DESTDIR)\$(kde_locale)/$kdelang\n";
1189         for $file (@restfiles) {
1190             $lines .= "\t\$(INSTALL_DATA) \$\(srcdir\)/$file \$(DESTDIR)\$(kde_locale)/$kdelang/$file\n";
1191         }
1192         $target_adds{"uninstall"} .= "uninstall-nls-files ";
1193         $lines .= "uninstall-nls-files:\n";
1194         for $file (@restfiles) {
1195             $lines .= "\t-rm -f \$(DESTDIR)\$(kde_locale)/$kdelang/$file\n";
1196         }
1197         appendLines($lines);
1198     }
1199     
1200     return 0;
1201 }
1202
1203 #-----------------------------------------------------------------------------
1204
1205 sub tag_SUBDIRS ()
1206 {
1207   if ($MakefileData !~ /\nSUBDIRS\s*=\s*\$\(AUTODIRS\)\s*\n/) {
1208     return 1;
1209   }
1210
1211   my $subdirs = ".";
1212
1213   opendir (THISDIR, ".");
1214   foreach $entry (readdir(THISDIR)) {
1215     next if ($entry eq "CVS" || $entry =~ /^\./);
1216     if (-d $entry && -f $entry . "/Makefile.am") {
1217       $subdirs .= " $entry";
1218       next;
1219     }
1220   }
1221   closedir (THISDIR);
1222
1223   substituteLine('SUBDIRS\s*=.*', "SUBDIRS =$subdirs");
1224   return 0;
1225 }
1226
1227 sub tag_IDLFILES ()
1228 {
1229     my @psources = split(/[\034\s]+/, $sources{$program});
1230     my $dep_lines = "";
1231     my @cppFiles = ();
1232     
1233     foreach $source (@psources) {
1234         my $skel = ($source =~ m/\.skel$/);
1235         my $stub = ($source =~ m/\.stub$/);
1236         my $signals = ($source =~ m/\.signals$/); # obsolete, remove in KDE-4
1237         
1238         if ($stub || $skel || $signals) {
1239
1240             my $qs = quotemeta($source);
1241             $sources{$program} =~ s/$qs//;
1242             $sources_changed{$program} = 1;
1243
1244             $source =~ s/\.(stub|skel|signals)$//;
1245             my $sourcename;
1246
1247             if ($skel) {
1248                 $sourcename = "$source\_skel";
1249             } elsif ($stub) {
1250                 $sourcename = "$source\_stub";
1251             } else {
1252                 $sourcename = "$source\_signals";
1253             }
1254             
1255             my $sourcedir = '';
1256             if (-f "$makefileDir/$source.h") {
1257                 $sourcedir = '$(srcdir)/';
1258             } else {
1259                 if ($MakefileData =~ /\n$source\_DIR\s*=\s*(\S+)\n/) {
1260                     $sourcedir = $1;
1261                     $sourcedir .= "/" if ($sourcedir !~ /\/$/);
1262                 }
1263             }
1264             
1265             if ($allidls !~ /$source\_kidl/) {
1266                 
1267                 $use_ng = ($MakefileData =~ /\n$source\_DCOPIDLNG\s*=\s*(\S+)\n/);
1268                 $dcopidl =  $use_ng ? "KDECONFIG=\"\$(KDECONFIG)\" \$(DCOPIDLNG)" : "\$(DCOPIDL)";
1269
1270                 $dep_lines .= "$source.kidl: $sourcedir$source.h \$(DCOP_DEPENDENCIES)\n";
1271                 $dep_lines .= "\t$dcopidl $sourcedir$source.h > $source.kidl || ( rm -f $source.kidl ; false )\n";
1272                 
1273                 $allidls .= $source . "_kidl ";
1274             }
1275             
1276             if ($allidls !~ /$sourcename/) {
1277                 
1278                 $dep_lines_tmp = "";
1279
1280                 if ($skel) {
1281                     $dep_lines .= "$sourcename.$cxxsuffix: $source.kidl\n";
1282                     $dep_lines .= "\t\$(DCOPIDL2CPP) --c++-suffix $cxxsuffix --no-signals --no-stub $source.kidl\n";
1283                 } elsif ($stub) {
1284                     $dep_lines_tmp = "\t\$(DCOPIDL2CPP) --c++-suffix $cxxsuffix --no-signals --no-skel $source.kidl\n";
1285                 } else { # signals - obsolete, remove in KDE 4
1286                     $dep_lines_tmp = "\t\$(DCOPIDL2CPP) --c++-suffix $cxxsuffix --no-stub --no-skel $source.kidl\n";
1287                 }
1288
1289                 if ($stub || $signals) {
1290                     $target_adds{"$sourcename.$cxxsuffix"} .= "$sourcename.h ";
1291                     $dep_lines .= "$sourcename.h: $source.kidl\n";
1292                     $dep_lines .= $dep_lines_tmp;
1293                 }
1294                 
1295                 $allidls .= $sourcename . " ";
1296             }
1297             
1298             $idlfiles{$program} .= $sourcename . " ";
1299             
1300             if ($program =~ /_la$/) {
1301                 $realObjs{$program} .= " $sourcename.lo";
1302             } else {
1303                 $realObjs{$program} .= " $sourcename.\$(OBJEXT)";
1304             }
1305             $sources{$program} .= " $sourcename.$cxxsuffix";
1306             $sources_changed{$program} = 1;
1307             $important{$program} .= "$sourcename.h " if (!$skel);
1308             $idl_output .= "\\\n\t$sourcename.$cxxsuffix $sourcename.h $source.kidl ";
1309             push(@cleanfiles, "$sourcename.$cxxsuffix");
1310             push(@cleanfiles, "$sourcename.h");
1311             push(@cleanfiles, "$sourcename.kidl");
1312             $dep_files .= " \$(DEPDIR)/$sourcename.P" if ($dep_files !~/$sourcename.P/);
1313         }
1314     }
1315     if ($dep_lines) {
1316         appendLines($dep_lines);
1317     }
1318     
1319     if (0) {
1320         my $lookup = "($program)";
1321         $lookup .= '(|\$\(EXEEXT\))';
1322         $lookup =~ s/\_/./g;
1323         $lookup .= ":(.*..$program\_OBJECTS..*)";
1324         #    $lookup = quotemeta($lookup);
1325         if ($MakefileData =~ /\n$lookup\n/) {
1326             
1327             my $line = "$1$2: ";
1328             foreach $file (split(' ', $idlfiles{$program})) {
1329                 $line .= "$file.$cxxsuffix ";
1330             }
1331             $line .= $3;
1332             substituteLine($lookup, $line);
1333         } else {
1334             print STDERR "no built dependency found $lookup\n";
1335         }
1336     }
1337 }
1338
1339 sub tag_UIFILES ()
1340 {
1341     my @psources = split(/[\034\s]+/, $sources{$program});
1342     my @depFiles = ();
1343     
1344     foreach $source (@psources) {
1345
1346         if ($source =~ m/\.ui$/) {
1347
1348             print STDERR "adding UI file $source\n" if ($verbose);
1349
1350             my $qs = quotemeta($source);
1351             $sources{$program} =~ s/$qs//;
1352             $sources_changed{$program} = 1;
1353       
1354             $source =~ s/\.ui$//;
1355
1356             my $sourcedir = '';
1357             if (-f "$makefileDir/$source.ui") {
1358                 $sourcedir = '$(srcdir)/';
1359             }
1360
1361             if (!$uiFiles{$source}) {
1362
1363                 my $dep_lines = "$source.$cxxsuffix: $sourcedir$source.ui $source.h $source.moc\n";
1364                 $dep_lines .= "\trm -f $source.$cxxsuffix\n";
1365                 if (!$kdeopts{"qtonly"}) {
1366                     $dep_lines .= "\techo '#include <kdialog.h>' > $source.$cxxsuffix\n";
1367                     $dep_lines .= "\techo '#include <klocale.h>' >> $source.$cxxsuffix\n";
1368                     my ($mangled_source) = $source;
1369                     $mangled_source =~ s/[^A-Za-z0-9]/_/g;  # get rid of garbage
1370                     $dep_lines .= "\t\$(UIC) -tr \${UIC_TR} -i $source.h $sourcedir$source.ui > $source.$cxxsuffix.temp ; ret=\$\$?; \\\n";
1371                     $dep_lines .= "\t\$(PERL) -pe \"s,\${UIC_TR}( \\\"\\\" ),QString::null,g\" $source.$cxxsuffix.temp | \$(PERL) -pe \"s,\${UIC_TR}( \\\"\\\"\\, \\\"\\\" ),QString::null,g\" | \$(PERL) -pe \"s,image([0-9][0-9]*)_data,img\\\$\$1_" . $mangled_source . ",g\" | \$(PERL) -pe \"s,: QWizard\\(,: KWizard(,g\" >> $source.$cxxsuffix ;\\\n";
1372                     $dep_lines .= "\trm -f $source.$cxxsuffix.temp ;\\\n";
1373                 } else {
1374                     $dep_lines .= "\t\$(UIC) -i $source.h $sourcedir$source.ui > $source.$cxxsuffix; ret=\$\$?; \\\n";
1375                 }
1376                 $dep_lines .= "\tif test \"\$\$ret\" = 0; then echo '#include \"$source.moc\"' >> $source.$cxxsuffix; else rm -f $source.$cxxsuffix ; exit \$\$ret ; fi\n\n";
1377                 $dep_lines .= "$source.h: $sourcedir$source.ui\n";
1378                 $dep_lines .= "\trm -rf $source.h;\n";
1379                 $dep_lines .= "\t\$(UIC) $sourcedir$source.ui | \$(PERL) -pi -e \"s,public QWizard,public KWizard,g; s,#include <qwizard.h>,#include <kwizard.h>,g\" >> $source.h ;\n";
1380
1381                 $dep_lines .= "$source.moc: $source.h\n";
1382                 $dep_lines .= "\t\$(MOC) $source.h -o $source.moc\n";
1383
1384                 $rule_adds{"$source.$cxxsuffix"} = $dep_lines;
1385
1386                 $uiFiles{$source} = 1;
1387                 $dependmocs{$program} .= " $source.moc";
1388                 $globalmocs{$source} = "\035$source.h\035$source.cpp";
1389             }
1390             
1391             if ($program =~ /_la$/) {
1392                 $realObjs{$program} .= " $source.lo";
1393             } else {
1394                 $realObjs{$program} .= " $source.\$(OBJEXT)";
1395             }
1396             $sources{$program} .= " $source.$cxxsuffix";
1397             $sources_changed{$program} = 1;
1398             $important{$program} .= "$source.h ";
1399             $ui_output .= "\\\n\t$source.$cxxsuffix $source.h $source.moc ";
1400             push(@cleanfiles, "$source.$cxxsuffix");
1401             push(@cleanfiles, "$source.h");
1402             push(@cleanfiles, "$source.moc");
1403             $dep_files .= " \$(DEPDIR)/$source.P" if($dep_files !~/$source.P/ );
1404         }
1405     }
1406 }
1407
1408 sub tag_KCFGFILES ()
1409 {
1410     my @psources = split(/[\034\s]+/, $sources{$program});
1411     my @depFiles = ();
1412     
1413     foreach $source (@psources) {
1414
1415         if ($source =~ m/\.kcfgc$/) {
1416
1417             print STDERR "adding KCFG file $source\n" if ($verbose);
1418
1419             my $qs = quotemeta($source);
1420             $sources{$program} =~ s/$qs//;
1421             $sources_changed{$program} = 1;
1422       
1423             $source =~ s/\.kcfgc$//;
1424
1425             my $sourcedir = '';
1426             if (-f "$makefileDir/$source.kcfgc") {
1427                 $sourcedir = '$(srcdir)/';
1428             }
1429
1430             if (!$kcfgFiles{$source}) {
1431                 $kcfg = "$program.kcfg";
1432                 findKcfgFile("$source.kcfgc");
1433
1434                 my $fixsuffix = "";
1435                 $fixsuffix = "else mv $source.cpp $source.$cxxsuffix ; " 
1436                     unless "cpp" eq $cxxsuffix;
1437
1438                 my $dep_lines = "$source.$cxxsuffix: $source.h\n";
1439                 $dep_lines .= "$source.h: $sourcedir$kcfg $sourcedir$source.kcfgc \$(KCFG_DEPENDENCIES)\n";
1440                 $dep_lines .= "\t\$(KCONFIG_COMPILER) $sourcedir$kcfg $sourcedir$source.kcfgc; ret=\$\$?; \\\n";
1441                 $dep_lines .= "\tif test \"\$\$ret\" != 0; then rm -f $source.h ; exit \$\$ret ; $fixsuffix fi\n\n";
1442
1443                 $rule_adds{"$source.$cxxsuffix"} = $dep_lines;
1444
1445                 $kcfgFiles{$source} = 1;
1446             }
1447             
1448             if ($program =~ /_la$/) {
1449                 $realObjs{$program} .= " $source.lo";
1450             } else {
1451                 $realObjs{$program} .= " $source.\$(OBJEXT)";
1452             }
1453             $sources{$program} .= " $source.$cxxsuffix";
1454             $sources_changed{$program} = 1;
1455             $important{$program} .= "$source.h ";
1456             $kcfg_output .= "\\\n\t$source.$cxxsuffix $source.h ";
1457             push(@cleanfiles, "$source.$cxxsuffix");
1458             push(@cleanfiles, "$source.h");
1459             $dep_files .= " \$(DEPDIR)/$source.P" if($dep_files !~/$source.P/ );
1460         }
1461     }
1462 }
1463
1464 sub tag_ICON()
1465 {
1466     my $lookup = '([^\s]*)_ICON\s*=[ \t]*(.*)';
1467     my $install = "";
1468     my $uninstall = "";
1469
1470     while ($MakefileData =~ /\n$lookup/g) {
1471         my $destdir;
1472         if ($1 eq "KDE") {
1473             $destdir = "kde_icondir";
1474         } else {
1475             $destdir = $1 . "dir";
1476         }
1477         my $iconauto = ($2 =~ /AUTO\s*$/);
1478         my @appnames = ();
1479         if ( ! $iconauto ) {
1480             my $appicon_str = $2;
1481             my @_appnames = split(" ", $appicon_str);
1482             print STDOUT "KDE_ICON processing <@_appnames>\n"   if ($verbose);
1483             foreach $appname (@_appnames) {
1484                 push(@appnames, quotemeta($appname));
1485             }
1486         } else {
1487             print STDOUT "KDE_ICON processing <AUTO>\n"   if ($verbose);
1488         }
1489
1490         my @files = ();
1491         opendir (THISDIR, ".");
1492         foreach $entry (readdir(THISDIR)) {
1493             next if ($entry eq "CVS" || $entry =~ /^\./  || $entry =~ /^Makefile/ || $entry =~ /~$/ || $entry =~ /^\#.*\#$/);
1494             next if (! -f $entry);
1495             if ( $iconauto )
1496               {
1497                   push(@files, $entry)
1498                     if ($entry =~ /\.xpm/ || $entry =~ /\.png/ || $entry =~ /\.mng/ || $entry =~ /\.svg/);
1499               } else {
1500                   foreach $appname (@appnames) {
1501                       push(@files, $entry)
1502                         if ($entry =~ /-$appname\.xpm/ || $entry =~ /-$appname\.png/ || $entry =~ /-$appname\.mng/ || $entry =~ /-$appname\.svg/);
1503                   }
1504               }
1505         }
1506         closedir (THISDIR);
1507         
1508         my %directories = ();
1509         
1510         foreach $file (@files) {
1511             my $newfile = $file;
1512             my $prefix = $file;
1513             $prefix =~ s/\.(png|xpm|mng|svg|svgz)$//;
1514             my $appname = $prefix;
1515             $appname =~ s/^[^-]+-// if ($appname =~ /-/) ;
1516             $appname =~ s/^[^-]+-// if ($appname =~ /-/) ;
1517             $appname = quotemeta($appname);
1518             $prefix =~ s/$appname$//;
1519             $prefix =~ s/-$//;
1520             
1521             $prefix = 'lo16-app' if ($prefix eq 'mini');
1522             $prefix = 'lo32-app' if ($prefix eq 'lo');
1523             $prefix = 'hi48-app' if ($prefix eq 'large');
1524             $prefix .= '-app' if ($prefix =~ m/^...$/);
1525             
1526             my $type = $prefix;
1527             $type =~ s/^.*-([^-]+)$/$1/;
1528             $prefix =~ s/^(.*)-[^-]+$/$1/;
1529             
1530             my %type_hash =
1531               (
1532                'action' => 'actions',
1533                'app' => 'apps',
1534                'device' => 'devices',
1535                'filesys' => 'filesystems',
1536                'mime' => 'mimetypes'
1537               );
1538
1539             if (! defined $type_hash{$type} ) {
1540                 print STDERR "unknown icon type $type in $printname ($file)\n";
1541                 next;
1542             }
1543
1544             my %dir_hash =
1545               (
1546                'los' => 'locolor/16x16',
1547                'lom' => 'locolor/32x32',
1548                'him' => 'hicolor/32x32',
1549                'hil' => 'hicolor/48x48',
1550                'lo16' => 'locolor/16x16',
1551                'lo22' => 'locolor/22x22',
1552                'lo32' => 'locolor/32x32',
1553                'hi16' => 'hicolor/16x16',
1554                'hi22' => 'hicolor/22x22',
1555                'hi32' => 'hicolor/32x32',
1556                'hi48' => 'hicolor/48x48',
1557                'hi64' => 'hicolor/64x64',
1558                'hi128' => 'hicolor/128x128',
1559                'hisc' => 'hicolor/scalable',
1560                'cr16' => 'crystalsvg/16x16',
1561                'cr22' => 'crystalsvg/22x22',
1562                'cr32' => 'crystalsvg/32x32',
1563                'cr48' => 'crystalsvg/48x48',
1564                'cr64' => 'crystalsvg/64x64',
1565                'cr128' => 'crystalsvg/128x128',
1566                'crsc' => 'crystalsvg/scalable'
1567               );
1568             
1569             $newfile =~ s@.*-($appname\.(png|xpm|mng|svgz|svg?))@$1@;
1570             
1571             if (! defined $dir_hash{$prefix}) {
1572                 print STDERR "unknown icon prefix $prefix in $printname\n";
1573                 next;
1574             }
1575             
1576             my $dir = $dir_hash{$prefix} . "/" . $type_hash{$type};
1577             if ($newfile =~ /-[^\.]/) {
1578                 my $tmp = $newfile;
1579                 $tmp =~ s/^([^-]+)-.*$/$1/;
1580                 $dir = $dir . "/" . $tmp;
1581                 $newfile =~ s/^[^-]+-//;
1582             }
1583             
1584             if (!defined $directories{$dir}) {
1585                 $install .= "\t\$(mkinstalldirs) \$(DESTDIR)\$($destdir)/$dir\n";
1586                 $directories{$dir} = 1;
1587             }
1588             
1589             $install .= "\t\$(INSTALL_DATA) \$(srcdir)/$file \$(DESTDIR)\$($destdir)/$dir/$newfile\n";
1590             $uninstall .= "\t-rm -f \$(DESTDIR)\$($destdir)/$dir/$newfile\n";
1591             
1592         }
1593     }
1594
1595     if (length($install)) {
1596         $target_adds{"install-data-am"} .= "install-kde-icons ";
1597         $target_adds{"uninstall-am"} .= "uninstall-kde-icons ";
1598         appendLines("install-kde-icons:\n" . $install . "\nuninstall-kde-icons:\n" . $uninstall);
1599     }
1600 }
1601
1602 sub handle_POFILES($$)
1603 {
1604   my @pofiles = split(" ", $_[0]);
1605   my $lang = $_[1];
1606
1607   # Build rules for creating the gmo files
1608   my $tmp = "";
1609   my $allgmofiles     = "";
1610   my $pofileLine   = "POFILES =";
1611   foreach $pofile (@pofiles)
1612     {
1613         $pofile =~ /(.*)\.[^\.]*$/;          # Find name minus extension
1614         $tmp .= "$1.gmo: $pofile\n";
1615         $tmp .= "\t\@echo \"Generating GMO file for language $1\"\n";
1616         $tmp .= "\t\@rm -f $1.gmo; \$(GMSGFMT) --statistics -o $1.gmo \$(srcdir)/$pofile\n";
1617         $tmp .= "\t\@test ! -f $1.gmo || touch $1.gmo\n";
1618         $allgmofiles .= " $1.gmo";
1619         $pofileLine  .= " $1.po";
1620     }
1621   appendLines ($tmp);
1622   my $lookup = 'POFILES\s*=([^\n]*)';
1623   if ($MakefileData !~ /\n$lookup/) {
1624     appendLines("$pofileLine\nGMOFILES =$allgmofiles");
1625   } else {
1626     substituteLine ($lookup, "$pofileLine\nGMOFILES =$allgmofiles");
1627   }
1628
1629     if ($allgmofiles) {
1630
1631         # Add the "clean" rule so that the maintainer-clean does something
1632         appendLines ("clean-nls:\n\t-rm -f $allgmofiles\n");
1633
1634         $target_adds{"maintainer-clean"} .= "clean-nls ";
1635
1636         $lookup = 'DISTFILES\s*=[ \t]*(.*)';
1637         if ($MakefileData =~ /\n$lookup/) {
1638           $tmp = "DISTFILES = \$(GMOFILES) \$(POFILES) $1";
1639           substituteLine ($lookup, $tmp);
1640         }
1641     }
1642
1643   $target_adds{"install-data-am"} .= "install-nls ";
1644
1645   $tmp = "install-nls:\n";
1646   if ($lang) {
1647     $tmp  .= "\t\$(mkinstalldirs) \$(DESTDIR)\$(kde_locale)/$lang/LC_MESSAGES\n";
1648   }
1649   $tmp .= "\t\@for base in ";
1650   foreach $pofile (@pofiles)
1651     {
1652       my $lookup = '(desktop)[^\n]*';
1653       if ($pofile !~ /$lookup/) {
1654         $pofile =~ /(.*)\.[^\.]*$/;          # Find name minus extension
1655         $tmp .= "$1 ";
1656       }
1657     }
1658
1659   $tmp .= "; do \\\n";
1660   if ($lang) {
1661     $tmp .= "\t  echo \$(INSTALL_DATA) \$\$base.gmo \$(DESTDIR)\$(kde_locale)/$lang/LC_MESSAGES/\$\$base.mo ;\\\n";
1662     $tmp .= "\t  if test -f \$\$base.gmo; then \$(INSTALL_DATA) \$\$base.gmo \$(DESTDIR)\$(kde_locale)/$lang/LC_MESSAGES/\$\$base.mo ;\\\n";
1663     $tmp .= "\t  elif test -f \$(srcdir)/\$\$base.gmo; then \$(INSTALL_DATA) \$(srcdir)/\$\$base.gmo \$(DESTDIR)\$(kde_locale)/$lang/LC_MESSAGES/\$\$base.mo ;\\\n";
1664     $tmp .= "\t  fi ;\\\n";
1665   } else {
1666     $tmp .= "\t  echo \$(INSTALL_DATA) \$\$base.gmo \$(DESTDIR)\$(kde_locale)/\$\$base/LC_MESSAGES/\$(PACKAGE).mo ;\\\n";
1667     $tmp .= "\t  \$(mkinstalldirs) \$(DESTDIR)\$(kde_locale)/\$\$base/LC_MESSAGES ; \\\n";
1668     $tmp .= "\t  if test -f \$\$base.gmo; then \$(INSTALL_DATA) \$\$base.gmo \$(DESTDIR)\$(kde_locale)/\$\$base/LC_MESSAGES/\$(PACKAGE).mo ;\\\n";
1669     $tmp .= "\t  elif test -f \$(srcdir)/\$\$base.gmo; then \$(INSTALL_DATA) \$(srcdir)/\$\$base.gmo \$(DESTDIR)\$(kde_locale)/\$\$base/LC_MESSAGES/\$(PACKAGE).mo ;\\\n";
1670     $tmp .= "\t  fi ;\\\n";
1671   }
1672   $tmp .= "\tdone\n\n";
1673   appendLines ($tmp);
1674
1675   $target_adds{"uninstall"} .= "uninstall-nls ";
1676
1677   $tmp = "uninstall-nls:\n";
1678   foreach $pofile (@pofiles)
1679     {
1680       my $lookup = '(desktop)[^\n]*';
1681       if ($pofile !~ /$lookup/) {
1682       $pofile =~ /(.*)\.[^\.]*$/;          # Find name minus extension
1683       if ($lang) {
1684         $tmp .= "\trm -f \$(DESTDIR)\$(kde_locale)/$lang/LC_MESSAGES/$1.mo\n";
1685       } else {
1686         $tmp .= "\trm -f \$(DESTDIR)\$(kde_locale)/$1/LC_MESSAGES/\$(PACKAGE).mo\n";
1687       }
1688       }
1689     }
1690   appendLines($tmp);
1691
1692   $target_adds{"all"} .= "all-nls ";
1693
1694   $tmp = "all-nls: \$(GMOFILES)\n";
1695
1696   appendLines($tmp);
1697
1698   $target_adds{"distdir"} .= "distdir-nls ";
1699
1700   $tmp = "distdir-nls:\$(GMOFILES)\n";
1701   $tmp .= "\tfor file in \$(POFILES); do \\\n";
1702   $tmp .= "\t  cp \$(srcdir)/\$\$file \$(distdir); \\\n";
1703   $tmp .= "\tdone\n";
1704   $tmp .= "\tfor file in \$(GMOFILES); do \\\n";
1705   $tmp .= "\t  cp \$(srcdir)/\$\$file \$(distdir); \\\n";
1706   $tmp .= "\tdone\n";
1707
1708   appendLines ($tmp);
1709
1710   if (!$lang) {
1711     appendLines("merge:\n\t\$(MAKE) -f \$(top_srcdir)/admin/Makefile.common package-merge POFILES=\"\${POFILES}\" PACKAGE=\${PACKAGE}\n\n");
1712   }
1713  
1714 }
1715
1716 #-----------------------------------------------------------------------------
1717
1718 # Returns 0 if the line was processed - 1 otherwise.
1719 # Errors are logged in the global $errorflags
1720 sub tag_POFILES ()
1721 {
1722     my $lookup = 'POFILES\s*=([^\n]*)';
1723     return 1    if ($MakefileData !~ /\n$lookup/);
1724     print STDOUT "POFILES processing <$1>\n"   if ($verbose);
1725
1726     my $tmp = $1;
1727
1728     # make sure these are all gone.
1729     if ($MakefileData =~ /\n\.po\.gmo:\n/)
1730     {
1731         print STDERR "Warning: Found old .po.gmo rules in $printname. New po rules not added\n";
1732         return 1;
1733     }
1734
1735     # Either find the pofiles in the directory (AUTO) or use
1736     # only the specified po files.
1737     my $pofiles = "";
1738     if ($tmp =~ /^\s*AUTO\s*$/)
1739     {
1740         opendir (THISDIR, ".");
1741         $pofiles =  join(" ", grep(/\.po$/, readdir(THISDIR)));
1742         closedir (THISDIR);
1743         print STDOUT "pofiles found = $pofiles\n"   if ($verbose);
1744         if (-f "charset" && -f "kdelibs/kdelibs.po") {
1745             handle_TOPLEVEL();
1746         }
1747     }
1748     else
1749     {
1750         $tmp =~ s/\034/ /g;
1751         $pofiles = $tmp;
1752     }
1753     return 1    if (!$pofiles);        # Nothing to do
1754
1755     handle_POFILES($pofiles, $kdelang);
1756
1757     return 0;
1758 }
1759
1760 sub helper_LOCALINSTALL($)
1761 {
1762   my $lookup = "\035" . $_[0] . " *:[^\035]*\035\t";
1763   my $copy = $MakefileData;
1764   $copy =~ s/\n/\035/g;
1765   if ($copy =~ /($lookup.*)$/) {
1766
1767     $install = $1;
1768     $install =~ s/\035$_[0] *:[^\035]*\035//;
1769     my $emptyline = 0;
1770     while (! $emptyline ) {
1771       if ($install =~ /([^\035]*)\035(.*)/) {
1772         local $line = $1;
1773         $install = $2;
1774         if ($line !~ /^\s*$/ && $line !~ /^(\@.*\@)*\t/) {
1775           $emptyline = 1;
1776         } else {
1777           replaceDestDir($line);
1778         }
1779       } else {
1780         $emptyline = 1;
1781       }
1782     }
1783   }
1784
1785 }
1786
1787 sub tag_LOCALINSTALL ()
1788 {
1789   helper_LOCALINSTALL('install-exec-local');
1790   helper_LOCALINSTALL('install-data-local');
1791   helper_LOCALINSTALL('uninstall-local');
1792
1793   return 0;
1794 }
1795
1796 sub replaceDestDir($) {
1797   local $line = $_[0];
1798
1799   if (   $line =~ /^\s*(\@.*\@)*\s*\$\(mkinstalldirs\)/
1800       || $line =~ /^\s*(\@.*\@)*\s*\$\(INSTALL\S*\)/
1801       || $line =~ /^\s*(\@.*\@)*\s*(-?rm.*) \S*$/)
1802   {
1803     $line =~ s/^(.*) ([^\s]+)\s*$/$1 \$(DESTDIR)$2/ if ($line !~ /\$\(DESTDIR\)/);
1804   }
1805
1806   if ($line ne $_[0]) {
1807     $_[0] = quotemeta $_[0];
1808     substituteLine($_[0], $line);
1809   }
1810 }
1811
1812 #---------------------------------------------------------------------------
1813 # libtool is very hard to persuade it could use -Wl,--no-undefined for making
1814 # -no-undefined actually work
1815 # append $(KDE_NO_UNFINED) after every -no-undefined in LDFLAGS
1816 # this may go away if libtool ever does this on its own
1817 sub tag_NO_UNDEFINED () {
1818     return if ($program !~ /_la$/);
1819
1820     my $lookup = quotemeta($realname{$program}) . ":.*?\n\t.*?\\((.*?)\\) .*\n";
1821     $MakefileData =~ m/$lookup/;
1822     return if (!defined($1));
1823     return if ($1 !~ /CXXLINK/);
1824
1825     if ($MakefileData !~ /\n$program\_LDFLAGS\s*=.*-no-undefined/ ) {
1826         return;
1827     }
1828
1829     $lookup = $program . '\_LDFLAGS(\s*)=(.*)-no-undefined(.*)';
1830     if ($MakefileData =~ /\n$lookup\n/) {
1831         my $replace = $program . "\_LDFLAGS$1=$2-no-undefined \$(KDE_NO_UNDEFINED)$3";
1832         substituteLine($lookup, $replace);
1833     }
1834 }
1835
1836 sub tag_CLOSURE () {
1837     return if ($program !~ /_la$/);
1838
1839     my $lookup = quotemeta($realname{$program}) . ":.*?\n\t.*?\\((.*?)\\) .*\n";
1840     $MakefileData =~ m/$lookup/;
1841     return if (!defined($1));
1842     return if ($1 !~ /CXXLINK/);
1843
1844     if ($MakefileData !~ /\n$program\_LDFLAGS\s*=.*-no-undefined/ &&
1845         $MakefileData !~ /\n$program\_LDFLAGS\s*=.*KDE_PLUGIN/ ) {
1846         print STDERR "Report: $program contains undefined in $printname\n" if ($program =~ /^lib/ && $dryrun);
1847         return;
1848     }
1849
1850     my $closure = $realname{$program} . ".closure";
1851     my $lines = "$closure: \$($program\_OBJECTS) \$($program\_DEPENDENCIES)\n";
1852     $lines .= "\t\@echo \"int main() {return 0;}\" > $program\_closure.$cxxsuffix\n";
1853     $lines .= "\t\@\$\(LTCXXCOMPILE\) -c $program\_closure.$cxxsuffix\n";
1854     $lines .= "\t\$\(CXXLINK\) $program\_closure.lo \$($program\_LDFLAGS) \$($program\_OBJECTS) \$($program\_LIBADD) \$(LIBS)\n";
1855     $lines .= "\t\@rm -f $program\_closure.* $closure\n";
1856     $lines .= "\t\@echo \"timestamp\" > $closure\n";
1857     $lines .= "\n";
1858     appendLines($lines);
1859     $lookup = $realname{$program} . ": (.*)";
1860     if ($MakefileData =~ /\n$lookup\n/) {
1861         $lines  = "\@KDE_USE_CLOSURE_TRUE@". $realname{$program} . ": $closure $1";
1862         $lines .= "\n\@KDE_USE_CLOSURE_FALSE@" . $realname{$program} . ": $1";
1863         substituteLine($lookup, $lines);
1864     }
1865     $closure_output .= " $closure";
1866 }
1867
1868 sub tag_NMCHECK () {
1869     return if ($program !~ /_la$/);
1870     my $lookup = quotemeta($realname{$program}) . ":.*?\n\t.*?\\((.*?)\\) .*\n";
1871     $MakefileData =~ m/$lookup/;
1872     my $linkcmd = $1;
1873     return if (!defined($1));
1874     return if ($linkcmd !~ /CXXLINK/ && $linkcmd !~ /LINK/);
1875
1876     $lookup = $program . '_NMCHECK\s*=([^\n]*)';
1877     if( $MakefileData !~ m/\n$lookup\n/ ) {
1878         return;
1879     }
1880     my $allowed = $1;
1881     $allowed =~ s/^ *//;
1882     $lookup = $program . '_NMCHECKWEAK\s*=([^\n]*)';
1883     my $weak = "";
1884     my $is_weak = 0;
1885     if( $MakefileData =~ m/\n$lookup\n/ ) {
1886         $weak = $1;
1887         $is_weak = 1;
1888     }
1889     $weak =~ s/^ *//;
1890
1891     if( $is_weak )
1892     {
1893         $weak = '--allowweak=\'' . $weak . '\' ';
1894     }
1895     my $nmline = "\@KDE_USE_NMCHECK_TRUE@\t\@\$(MAKE) \$(AM_MAKEFLAGS) nmcheck_$realname{$program} || ( rm -f $realname{$program}; exit 1 )";
1896     $lookup = '(\t\$\(CXXLINK\)[^\n]*' . $program . '_OBJECTS[^\n]*)';
1897     if( $MakefileData =~ /\n$lookup\n/ ) {
1898         my $oldstuff = $1;
1899         substituteLine( $lookup, $oldstuff . "\n" . $nmline );
1900     }
1901     $lookup = '(\t\$\(LINK\)[^\n]*' . $program . '_OBJECTS[^\n]*)';
1902     if( $MakefileData =~ /\n$lookup\n/ ) {
1903         my $oldstuff = $1;
1904         substituteLine( $lookup, $oldstuff . "\n" . $nmline );
1905     }
1906     $nmline = "\@\$(top_srcdir)/admin/nmcheck $realname{$program} \'$allowed\' $weak";
1907     appendLines( "\nnmcheck_$realname{$program}: $realname{$program} \n\t$nmline\n" );
1908     $target_adds{ "nmcheck" } .= "nmcheck_$realname{$program} ";
1909 }
1910
1911 sub tag_DIST () {
1912     my %foundfiles = ();
1913     opendir (THISDIR, ".");
1914     foreach $entry (readdir(THISDIR)) {
1915         next if ($entry eq "CVS" || $entry =~ /^\./  || $entry eq "Makefile" || $entry =~ /~$/ || $entry =~ /^\#.*\#$/);
1916         next if (! -f $entry);
1917         next if ($entry =~ /\.moc/ || $entry =~ /\.moc.$cppExt$/ || $entry =~ /\.lo$/ || $entry =~ /\.la$/ || $entry =~ /\.o/);
1918         next if ($entry =~ /\.all_$cppExt\.$cppExt$/);
1919         $foundfiles{$entry} = 1;
1920     }
1921     closedir (THISDIR);
1922
1923     # doing this for MAINTAINERCLEANFILES would be wrong
1924     my @marks = ("EXTRA_DIST", "DIST_COMMON", '\S*_SOURCES', '\S*_HEADERS', 'CLEANFILES', 'DISTCLEANFILES', '\S*_OBJECTS');
1925     foreach $mark (@marks) {
1926         while ($MakefileData =~ /\n($mark)\s*=[ \t]*([^\n]*)/g) {
1927             my $cleanfiles_str = $2;
1928             foreach $file (split('[\034\s]+', $cleanfiles_str)) {
1929                 $file =~ s/\.\///;
1930                 $foundfiles{$file} = 0 if (defined $foundfiles{$file});
1931             }
1932         }
1933     }
1934     my @files = ("Makefile", "config.cache", "config.log", "stamp-h",
1935                  "stamp-h1", "stamp-h1", "config.h", "Makefile", 
1936                  "config.status", "config.h", "libtool", "core" );
1937     foreach $file (@files) {
1938         $foundfiles{$file} = 0 if (defined $foundfiles{$file});
1939     }
1940
1941     my $KDE_DIST = "";
1942     foreach $file (keys %foundfiles) {
1943         if ($foundfiles{$file} == 1) {
1944             $KDE_DIST .= "$file ";
1945         }
1946     }
1947     if ($KDE_DIST) {
1948         print "KDE_DIST $printname $KDE_DIST\n" if ($verbose);
1949
1950         my $lookup = 'DISTFILES\s*=[ \t]*(.*)';
1951         if ($MakefileData =~ /\n$lookup/) {
1952             substituteLine($lookup, "DISTFILES = $1 \$(KDE_DIST)");
1953             appendLines("KDE_DIST=$KDE_DIST\n");
1954         }
1955     }
1956 }
1957
1958 #-----------------------------------------------------------------------------
1959 # Returns 0 if the line was processed - 1 otherwise.
1960 # Errors are logged in the global $errorflags
1961 sub tag_DOCFILES ()
1962 {
1963     $target_adds{"all"} .= "docs-am ";
1964
1965     my $lookup = 'KDE_DOCS\s*=[ \t]*([^\n]*)';
1966     goto nodocs    if ($MakefileData !~ /\n$lookup/);
1967     print STDOUT "KDE_DOCS processing <$1>\n"   if ($verbose);
1968
1969     my $tmp = $1;
1970
1971     # Either find the files in the directory (AUTO) or use
1972     # only the specified po files.
1973     my $files = "";
1974     my $appname = $tmp;
1975     $appname =~ s/^(\S*)\s*.*$/$1/;
1976     if ($appname =~ /AUTO/) {
1977       $appname = basename($makefileDir);
1978       if ("$appname" eq "en") {
1979           print STDERR "Error: KDE_DOCS = AUTO relies on the directory name. Yours is 'en' - you most likely want something else, e.g. KDE_DOCS = myapp\n";
1980           exit(1);
1981       }
1982     }
1983
1984     if ($tmp !~ / - /)
1985     {
1986         opendir (THISDIR, ".");
1987         foreach $entry (readdir(THISDIR)) {
1988           next if ($entry eq "CVS" || $entry =~ /^\./  || $entry =~ /^Makefile/ || $entry =~ /~$/ || $entry =~ /^\#.*\#$/ || $entry eq "core" || $entry eq "index.cache.bz2");
1989           next if (! -f $entry);
1990           $files .= "$entry ";
1991         }
1992         closedir (THISDIR);
1993         print STDOUT "docfiles found = $files\n"   if ($verbose);
1994     }
1995     else
1996     {
1997         $tmp =~ s/\034/ /g;
1998         $tmp =~ s/^\S*\s*-\s*//;
1999         $files = $tmp;
2000     }
2001     goto nodocs if (!$files);        # Nothing to do
2002
2003     if ($files =~ /(^| )index\.docbook($| )/) {
2004
2005       my $lines = "";
2006       my $lookup = 'MEINPROC\s*=';
2007       if ($MakefileData !~ /\n($lookup)/) {
2008         $lines = "MEINPROC=/\$(kde_bindir)/meinproc\n";
2009       }
2010       $lookup = 'KDE_XSL_STYLESHEET\s*=';
2011       if ($MakefileData !~ /\n($lookup)/) {
2012         $lines .= "KDE_XSL_STYLESHEET=/\$(kde_datadir)/ksgmltools2/customization/kde-chunk.xsl\n";
2013       }
2014       $lookup = '\nindex.cache.bz2:';
2015       if ($MakefileData !~ /\n($lookup)/) {
2016          $lines .= "index.cache.bz2: \$(srcdir)/index.docbook \$(KDE_XSL_STYLESHEET) $files\n";
2017          $lines .= "\t\@if test -n \"\$(MEINPROC)\"; then echo \$(MEINPROC) --check --cache index.cache.bz2 \$(srcdir)/index.docbook; \$(MEINPROC) --check --cache index.cache.bz2 \$(srcdir)/index.docbook; fi\n";
2018          $lines .= "\n";
2019       }
2020
2021       $lines .= "docs-am: index.cache.bz2\n";
2022       $lines .= "\n";
2023       $lines .= "install-docs: docs-am install-nls\n";
2024       $lines .= "\t\$(mkinstalldirs) \$(DESTDIR)\$(kde_htmldir)/$kdelang/$appname\n";
2025       $lines .= "\t\@if test -f index.cache.bz2; then \\\n";
2026       $lines .= "\techo \$(INSTALL_DATA) index.cache.bz2 \$(DESTDIR)\$(kde_htmldir)/$kdelang/$appname/; \\\n";
2027       $lines .= "\t\$(INSTALL_DATA) index.cache.bz2 \$(DESTDIR)\$(kde_htmldir)/$kdelang/$appname/; \\\n";
2028       $lines .= "\telif test -f  \$(srcdir)/index.cache.bz2; then \\\n";
2029       $lines .= "\techo \$(INSTALL_DATA) \$(srcdir)/index.cache.bz2 \$(DESTDIR)\$(kde_htmldir)/$kdelang/$appname/; \\\n";
2030       $lines .= "\t\$(INSTALL_DATA) \$(srcdir)/index.cache.bz2 \$(DESTDIR)\$(kde_htmldir)/$kdelang/$appname/; \\\n";
2031       $lines .= "\tfi\n";
2032       $lines .= "\t-rm -f \$(DESTDIR)\$(kde_htmldir)/$kdelang/$appname/common\n";
2033       $lines .= "\t\$(LN_S) \$(kde_libs_htmldir)/$kdelang/common \$(DESTDIR)\$(kde_htmldir)/$kdelang/$appname/common\n";
2034
2035       $lines .= "\n";
2036       $lines .= "uninstall-docs:\n";
2037       $lines .= "\t-rm -rf \$(kde_htmldir)/$kdelang/$appname\n";
2038       $lines .= "\n";
2039       $lines .= "clean-docs:\n";
2040       $lines .= "\t-rm -f index.cache.bz2\n";
2041       $lines .= "\n";
2042       $target_adds{"install-data-am"} .= "install-docs ";
2043       $target_adds{"uninstall"} .= "uninstall-docs ";
2044       $target_adds{"clean-am"} .= "clean-docs ";
2045       appendLines ($lines);
2046     } else {
2047       appendLines("docs-am: $files\n");
2048     }
2049
2050     $target_adds{"install-data-am"} .= "install-nls ";
2051     $target_adds{"uninstall"} .= "uninstall-nls ";
2052
2053     $tmp = "install-nls:\n";
2054     $tmp .= "\t\$(mkinstalldirs) \$(DESTDIR)\$(kde_htmldir)/$kdelang/$appname\n";
2055     $tmp .= "\t\@for base in $files; do \\\n";
2056     $tmp .= "\t  echo \$(INSTALL_DATA) \$\$base \$(DESTDIR)\$(kde_htmldir)/$kdelang/$appname/\$\$base ;\\\n";
2057     $tmp .= "\t  \$(INSTALL_DATA) \$(srcdir)/\$\$base \$(DESTDIR)\$(kde_htmldir)/$kdelang/$appname/\$\$base ;\\\n";
2058     $tmp .= "\tdone\n";
2059     if ($appname eq 'common') {
2060       $tmp .= "\t\@echo \"merging common and language specific dir\" ;\\\n";
2061       $tmp .= "\tif test ! -f \$(kde_htmldir)/en/common/kde-common.css; then echo 'no english docs found in \$(kde_htmldir)/en/common/'; exit 1; fi \n";
2062       $tmp .= "\t\@com_files=`cd \$(kde_htmldir)/en/common && echo *` ;\\\n";
2063       $tmp .= "\tcd \$(DESTDIR)\$(kde_htmldir)/$kdelang/common ;\\\n";
2064       $tmp .= "\tif test -n \"\$\$com_files\"; then for p in \$\$com_files ; do \\\n";
2065       $tmp .= "\t  case \" $files \" in \\\n";
2066       $tmp .= "\t    *\" \$\$p \"*) ;; \\\n";
2067       $tmp .= "\t    *) test ! -f \$\$p && echo \$(LN_S) ../../en/common/\$\$p \$(DESTDIR)\$(kde_htmldir)/$kdelang/common/\$\$p && \$(LN_S) ../../en/common/\$\$p \$\$p ;; \\\n";
2068       $tmp .= "\t  esac ; \\\n";
2069       $tmp .= "\tdone ; fi ; true\n";
2070     }
2071     $tmp .= "\n";
2072     $tmp .= "uninstall-nls:\n";
2073     $tmp .= "\tfor base in $files; do \\\n";
2074     $tmp .= "\t  rm -f \$(DESTDIR)\$(kde_htmldir)/$kdelang/$appname/\$\$base ;\\\n";
2075     $tmp .= "\tdone\n\n";
2076     appendLines ($tmp);
2077
2078     $target_adds{"distdir"} .= "distdir-nls ";
2079
2080     $tmp = "distdir-nls:\n";
2081     $tmp .= "\tfor file in $files; do \\\n";
2082     $tmp .= "\t  cp \$(srcdir)/\$\$file \$(distdir); \\\n";
2083     $tmp .= "\tdone\n";
2084
2085     appendLines ($tmp);
2086
2087     return 0;
2088
2089   nodocs:
2090     appendLines("docs-am:\n");
2091     return 1;
2092 }
2093
2094 #-----------------------------------------------------------------------------
2095 # Find headers in any of the source directories specified previously, that
2096 # are candidates for "moc-ing".
2097 sub findMocCandidates ()
2098 {
2099     foreach $dir (@headerdirs)
2100     {
2101         my @list = ();
2102         opendir (SRCDIR, "$dir");
2103         @hFiles = grep { /.+\.$hExt$/o && !/^\./ } readdir(SRCDIR);
2104         closedir SRCDIR;
2105         foreach $hf (@hFiles)
2106         {
2107             next if ($hf =~ /^\.\#/);
2108             $hf =~ /(.*)\.[^\.]*$/;          # Find name minus extension
2109             next if ($uiFiles{$1});
2110             open (HFIN, "$dir/$hf") || die "Could not open $dir/$hf: $!\n";
2111             my $hfsize = 0;
2112             seek(HFIN, 0, 2);
2113             $hfsize = tell(HFIN);
2114             seek(HFIN, 0, 0);
2115             read HFIN, $hfData, $hfsize;
2116             close HFIN;
2117             # push (@list, $hf) if(index($hfData, "Q_OBJECT") >= 0); ### fast but doesn't handle //Q_OBJECT
2118             # handle " { friend class blah; Q_OBJECT ", but don't match antlarr_Q_OBJECT (\b).
2119             if ( $hfData =~ /{([^}]*)\bQ_OBJECT/s ) {
2120                 push (@list, $hf) unless $1 =~ m://[^\n]*Q_OBJECT[^\n]*$:s;  ## reject "// Q_OBJECT"
2121             }
2122         }
2123         # The assoc array of root of headerfile and header filename
2124         foreach $hFile (@list)
2125         {
2126             $hFile =~ /(.*)\.[^\.]*$/;          # Find name minus extension
2127             if ($mocFiles{$1})
2128             {
2129               print STDERR "Warning: Multiple header files found for $1\n";
2130               next;                           # Use the first one
2131             }
2132             $mocFiles{$1} = "$dir\035$hFile";   # Add relative dir
2133         }
2134     }
2135
2136     return 0;
2137 }
2138
2139 #-----------------------------------------------------------------------------
2140
2141 # The programmer has specified a moc list. Prune out the moc candidates
2142 # list that we found based on looking at the header files. This generates
2143 # a warning if the programmer gets the list wrong, but this doesn't have
2144 # to be fatal here.
2145 sub pruneMocCandidates ($)
2146 {
2147     my %prunedMoc = ();
2148     local @mocList = split(' ', $_[0]);
2149
2150     foreach $mocname (@mocList)
2151     {
2152         $mocname =~ s/\.moc$//;
2153         if ($mocFiles{$mocname})
2154         {
2155             $prunedMoc{$mocname} = $mocFiles{$mocname};
2156         }
2157         else
2158         {
2159             my $print = $makefileDir;
2160             $print =~ s/^\Q$topdir\E\\//;
2161             # They specified a moc file but we can't find a header that
2162             # will generate this moc file. That's possible fatal!
2163             print STDERR "Warning: No moc-able header file for $print/$mocname\n";
2164         }
2165     }
2166
2167     undef %mocFiles;
2168     %mocFiles = %prunedMoc;
2169 }
2170
2171 #-----------------------------------------------------------------------------
2172
2173 # Finds the cpp files (If they exist).
2174 # The cpp files get appended to the header file separated by \035
2175 sub checkMocCandidates ()
2176 {
2177     my @cppFiles;
2178     my $cpp2moc;  # which c++ file includes which .moc files
2179     my $moc2cpp;  # which moc file is included by which c++ files
2180
2181     return unless (keys %mocFiles);
2182     opendir(THISDIR, ".") || return;
2183     @cppFiles = grep { /.+\.$cppExt$/o  && !/.+\.moc\.$cppExt$/o
2184                          && !/.+\.all_$cppExt\.$cppExt$/o
2185                          && !/^\./  } readdir(THISDIR);
2186     closedir THISDIR;
2187     return unless (@cppFiles);
2188     my $files = join (" ", @cppFiles);
2189     $cpp2moc = {};
2190     $moc2cpp = {};
2191     foreach $cxxf (@cppFiles)
2192     {
2193       open (CXXFIN, $cxxf) || die "Could not open $cxxf: $!\n";
2194       seek(CXXFIN, 0, 2);
2195       my $cxxfsize = tell(CXXFIN);
2196       seek(CXXFIN, 0, 0);
2197       read CXXFIN, $cxxfData, $cxxfsize;
2198       close CXXFIN;
2199       while(($cxxfData =~ m/^[ \t]*\#include\s*[<\"](.*\.moc)[>\"]/gm)) {
2200         $cpp2moc->{$cxxf}->{$1} = 1;
2201         $moc2cpp->{$1}->{$cxxf} = 1;
2202       }
2203     }
2204     foreach my $mocFile (keys (%mocFiles))
2205     {
2206         @cppFiles = keys %{$moc2cpp->{"$mocFile.moc"}};
2207         if (@cppFiles == 1) {
2208             $mocFiles{$mocFile} .= "\035" . $cppFiles[0];
2209             push(@depend, $mocFile);
2210         } elsif (@cppFiles == 0) {
2211             push (@newObs, $mocFile);           # Produce new object file
2212             next    if ($haveAutomocTag);       # This is expected...
2213             # But this is an error we can deal with - let them know
2214             print STDERR
2215                 "Warning: No c++ file that includes $mocFile.moc\n";
2216         } else {
2217             # We can't decide which file to use, so it's fatal. Although as a
2218             # guess we could use the mocFile.cpp file if it's in the list???
2219             print STDERR
2220                 "Error: Multiple c++ files that include $mocFile.moc\n";
2221             print STDERR "\t",join ("\t", @cppFiles),"\n";
2222             $errorflag = 1;
2223             delete $mocFiles{$mocFile};
2224             # Let's continue and see what happens - They have been told!
2225         }
2226     }
2227 }
2228
2229 #-----------------------------------------------------------------------------
2230
2231 # Add the rules for generating moc source from header files
2232 # For Automoc output *.moc.cpp but normally we'll output *.moc
2233 # (We must compile *.moc.cpp separately. *.moc files are included
2234 # in the appropriate *.cpp file by the programmer)
2235 sub addMocRules ()
2236 {
2237     my $cppFile;
2238     my $hFile;
2239
2240     foreach $mocFile (keys (%mocFiles))
2241     {
2242         undef $cppFile;
2243         ($dir, $hFile, $cppFile) =  split ("\035", $mocFiles{$mocFile}, 3);
2244         $dir =~ s#^\.#\$(srcdir)#;
2245         if (defined ($cppFile))
2246         {
2247           $cppFile =~ s,\.[^.]*$,,;
2248           $target_adds{"$cppFile.o"} .= "$mocFile.moc ";
2249           $target_adds{"$cppFile.lo"} .= "$mocFile.moc ";
2250           appendLines ("$mocFile.moc: $dir/$hFile\n\t\$(MOC) $dir/$hFile -o $mocFile.moc\n");
2251           $cleanMoc .= " $mocFile.moc";
2252           appendLines ("mocs: $mocFile.moc\n");
2253         }
2254         else
2255         {
2256             appendLines ("$mocFile$mocExt: $dir/$hFile\n\t\$(MOC) $dir/$hFile -o $mocFile$mocExt\n");
2257             $cleanMoc .= " $mocFile$mocExt";
2258             appendLines ("mocs: $mocFile$mocExt\n");
2259         }
2260     }
2261 }
2262
2263 sub make_bcheck_target()
2264 {
2265     my $lookup = 'RECURSIVE_TARGETS\s*=[ \t]*(.*)';
2266     my $bcheckdep = "bcheck-am";
2267     $bcheckdep = "bcheck-recursive" if ($MakefileData =~ /\n$lookup/);
2268
2269     my $headers= "";
2270     $headers = $1 if($MakefileData =~ /\nHEADERS\s*=[ \t]*(.+)/);
2271     $headers =~ s/\$\((?:noinst|EXTRA)_HEADERS\)//g;
2272
2273     $target_adds{"clean-am"} .= "clean-bcheck ";
2274
2275     my $t = "clean-bcheck: \n" .
2276             "\trm -f *.bchecktest.cc *.bchecktest.cc.class a.out\n\n" .
2277             "bcheck: $bcheckdep\n\n" .
2278             "bcheck-am:\n" .
2279            "\t\@for i in $headers; do \\\n" .
2280            "\t    if test \$(srcdir)/\$\$i -nt \$\$i.bchecktest.cc; then \\\n" . 
2281            "\t        echo \"int main() {return 0;}\" > \$\$i.bchecktest.cc ; \\\n" .
2282            "\t        echo \"#include \\\"\$\$i\\\"\" >> \$\$i.bchecktest.cc ; \\\n" .
2283            "\t        echo \"\$\$i\"; \\\n" . 
2284            "\t        if ! ";
2285     $t .=  $cxxsuffix eq "KKK" ?
2286            "\$(CXX) \$(DEFS) -I. -I\$(srcdir) -I\$(top_builddir) \$(INCLUDES) \$(AM_CPPFLAGS) \$(CPPFLAGS) \$(KDE_CXXFLAGS) " :
2287            "\$(CXXCOMPILE) ";
2288     $t .=  " --dump-class-hierarchy -c \$\$i.bchecktest.cc; then \\\n" .
2289            "\t            rm -f \$\$i.bchecktest.cc; exit 1; \\\n" .
2290            "\t        fi ; \\\n" .
2291            "\t        echo \"\" >> \$\$i.bchecktest.cc.class; \\\n" .
2292            "\t        perl \$(top_srcdir)/admin/bcheck.pl \$\$i.bchecktest.cc.class || { rm -f \$\$i.bchecktest.cc; exit 1; }; \\\n" .
2293            "\t        rm -f a.out; \\\n" .
2294            "\t    fi ; \\\n" .
2295            "\tdone\n";
2296     appendLines("$t\n");
2297 }
2298
2299 sub make_meta_classes ()
2300 {
2301     return if ($kdeopts{"qtonly"});
2302
2303     my $cppFile;
2304     my $hFile;
2305     my $moc_class_headers = "";
2306     foreach $program (@programs) {
2307         my $mocs = "";
2308         my @progsources = split(/[\034\s]+/, $sources{$program});
2309         my @depmocs = split(' ', $dependmocs{$program});
2310         my %shash = (), %mhash = ();
2311         @shash{@progsources} = 1;  # we are only interested in the existence
2312         @mhash{@depmocs} = 1;
2313
2314         print STDOUT "program=$program\n" if ($verbose);
2315         print STDOUT "psources=[".join(' ', keys %shash)."]\n" if ($verbose);
2316         print STDOUT "depmocs=[".join(' ', keys %mhash)."]\n" if ($verbose);
2317         print STDOUT "globalmocs=[".join(' ', keys(%globalmocs))."]\n" if ($verbose);
2318         foreach my $mocFile (keys (%globalmocs))
2319         {
2320             my ($dir, $hFile, $cppFile) = split ("\035", $globalmocs{$mocFile}, 3);
2321             if (defined ($cppFile))
2322             {
2323                 $mocs .= " $mocFile.moc" if exists $shash{$cppFile};
2324             }
2325             else
2326             {
2327                 # Bah. This is the case, if no C++ file includes the .moc
2328                 # file. We make a .moc.cpp file for that. Unfortunately this
2329                 # is not included in the %sources hash, but rather is mentioned
2330                 # in %dependmocs. If the user wants to use AUTO he can't just
2331                 # use an unspecific METAINCLUDES. Instead he must use
2332                 # program_METAINCLUDES. Anyway, it's not working real nicely.
2333                 # E.g. Its not clear what happens if user specifies two
2334                 # METAINCLUDES=AUTO in the same Makefile.am.
2335                 $mocs .= " $mocFile.moc.$cxxsuffix"
2336                     if exists $mhash{$mocFile.".moc.$cxxsuffix"};
2337             }
2338         }
2339         if ($mocs) {
2340             print STDOUT "==> mocs=[".$mocs."]\n" if ($verbose);
2341         }
2342         print STDOUT "\n" if $verbose;
2343     }
2344     if ($moc_class_headers) {
2345         appendLines ("$cleantarget-moc-classes:\n\t-rm -f $moc_class_headers\n");
2346         $target_adds{"$cleantarget-am"} .= "$cleantarget-moc-classes ";
2347     }
2348 }
2349
2350 #-----------------------------------------------------------------------------
2351
2352 sub updateMakefile ()
2353 {
2354     return if ($dryrun);
2355
2356     open (FILEOUT, "> $makefile")
2357                         || die "Could not create $makefile: $!\n";
2358
2359     $MakefileData =~ s/\034/\\\n/g;    # Restore continuation lines
2360     # Append our $progId line, _below_ the "generated by automake" line
2361     # because automake-1.6 relies on the first line to be his own.
2362     my $progIdLine = "\# $progId - " . '$Revision: 1.7 $ '."\n";
2363     if ( !( $MakefileData =~ s/^(.*generated .*by automake.*\n)/$1$progIdLine/ ) ) {
2364         warn "automake line not found in $makefile\n";
2365         # Fallback: first line
2366         print FILEOUT $progIdLine;
2367     };
2368     print FILEOUT $MakefileData;
2369     close FILEOUT;
2370 }
2371
2372 #-----------------------------------------------------------------------------
2373
2374 # The given line needs to be removed from the makefile
2375 # Do this by adding the special "removed line" comment at the line start.
2376 sub removeLine ($$)
2377 {
2378     my ($lookup, $old) = @_;
2379
2380     $old =~ s/\034/\\\n#>- /g;          # Fix continuation lines
2381     $MakefileData =~ s/\n$lookup/\n#>\- $old/;
2382 }
2383
2384 #-----------------------------------------------------------------------------
2385
2386 # Replaces the old line with the new line
2387 # old line(s) are retained but tagged as removed. The new line(s) have the
2388 # "added" tag placed before it.
2389 sub substituteLine ($$)
2390 {
2391     my ($lookup, $new) = @_;
2392
2393     if ($MakefileData =~ /\n($lookup)/) {
2394       $old = $1;
2395       $old =~ s/\034/\\\n#>\- /g;         # Fix continuation lines
2396       my $newCount = ($new =~ tr/\034//) + ($new =~ tr/\n//) + 1;
2397       $new =~ s/\\\n/\034/g;
2398       $MakefileData =~ s/\n$lookup/\n#>- $old\n#>\+ $newCount\n$new/;
2399     } else {
2400         warn "Warning: substitution of \"$lookup\" in $printname failed\n";
2401     }
2402 }
2403
2404 #-----------------------------------------------------------------------------
2405
2406 # Slap new lines on the back of the file.
2407 sub appendLines ($)
2408 {
2409   my ($new) = @_;
2410   my $copynew = $new;
2411   my $newCount = ($new =~ tr/\034//) + ($new =~ tr/\n//) + 1;
2412   $new =~ s/\\\n/\034/g;        # Fix continuation lines
2413   $MakefileData .= "\n#>\+ $newCount\n$new";
2414 }
2415
2416 #-----------------------------------------------------------------------------
2417
2418 # Restore the Makefile.in to the state it was before we fiddled with it
2419 sub restoreMakefile ()
2420 {
2421     $MakefileData =~ s/# $progId[^\n\034]*[\n\034]*//g;
2422     # Restore removed lines
2423     $MakefileData =~ s/([\n\034])#>\- /$1/g;
2424     # Remove added lines
2425     while ($MakefileData =~ /[\n\034]#>\+ ([^\n\034]*)/)
2426     {
2427         my $newCount = $1;
2428         my $removeLines = "";
2429         while ($newCount--) {
2430             $removeLines .= "[^\n\034]*([\n\034]|)";
2431         }
2432         $MakefileData =~ s/[\n\034]#>\+.*[\n\034]$removeLines/\n/;
2433     }
2434 }
2435
2436 #-----------------------------------------------------------------------------
2437
2438 # find the .kcfg file listed in the .kcfgc file
2439 sub findKcfgFile($)
2440 {
2441   my ($kcfgf) = @_;
2442   open (KCFGFIN, $kcfgf) || die "Could not open $kcfgf: $!\n";
2443   seek(KCFGFIN, 0, 2);
2444   my $kcfgfsize = tell(KCFGFIN);
2445   seek(KCFGFIN, 0, 0);
2446   read KCFGFIN, $kcfgfData, $kcfgfsize;
2447   close KCFGFIN;
2448   if(($kcfgfData =~ m/^File=(.*\.kcfg)/gm)) {
2449     $kcfg = $1;
2450   }
2451 }