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