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