1#!/usr/bin/env perl 2# a script for use by autoconf to make the Makefiles 3# from the Makefile.in's 4# 5# the original autoconf mechanism first splits all substitutions into groups 6# of ca. 90, and than invokes sed for _every_ Makefile.in and every group 7# (so around 2-3 times per Makefile.in). So this takes forever, as sed 8# has to recompile the regexps every time. 9# 10# this script does better. It changes all Makefile.ins in one process. 11# in kdelibs the time for building Makefile went down from 2:59 min to 13 sec! 12# 13# written by Michael Matz <matz@kde.org> 14# adapted by Dirk Mueller <mueller@kde.org> 15 16# This file is free software; you can redistribute it and/or 17# modify it under the terms of the GNU Library General Public 18# License as published by the Free Software Foundation; either 19# version 2 of the License, or (at your option) any later version. 20 21# This library is distributed in the hope that it will be useful, 22# but WITHOUT ANY WARRANTY; without even the implied warranty of 23# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 24# Library General Public License for more details. 25 26# You should have received a copy of the GNU Library General Public License 27# along with this library; see the file COPYING.LIB. If not, write to 28# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 29# Boston, MA 02110-1301, USA. 30 31use strict; 32 33use File::Path; 34 35my $ac_subs=$ARGV[0]; 36my $ac_sacfiles = $ARGV[1]; 37my $ac_given_srcdir=$ARGV[2]; 38my $ac_given_INSTALL=$ARGV[3]; 39 40my @comp_match; 41my @comp_subs; 42 43#print "ac_subs=$ac_subs\n"; 44#print "ac_sacfiles=$ac_sacfiles\n"; 45#print "ac_given_srcdir=$ac_given_srcdir\n"; 46#print "ac_given_INSTALL=$ac_given_INSTALL\n"; 47 48my $configure_input; 49my ($srcdir, $top_srcdir); 50my $INSTALL; 51my $bad_perl = ($] < 5.005); 52my $created_file_count = 0; 53 54open(CF, "< $ac_subs") || die "can't open $ac_subs: $!"; 55my @subs = <CF>; 56my $pat; 57close(CF); 58chomp @subs; 59@comp_match=(); 60@comp_subs=(); 61 62if ($bad_perl) { 63 print "Using perl older than version 5.005\n"; 64 foreach $pat (@subs) { 65 if ( ($pat =~ m/s%([^%]*)%([^%]*)%g/ ) 66 || ($pat =~ m/s%([^%]*)%([^%]*)%;t/ ) 67 || ($pat =~ m/s,([^,]*),(.*),;t/) 68 || ($pat =~ m%s/([^/]*)/([^/]*)/g% ) 69 || ($pat =~ m%s/([^/]*)/([^/]*)/;t% ) 70 ) { 71 # form : s%bla%blubb%g 72 # or s%bla%blubb%;t t (autoconf > 2.13 and < 2.52 ?) 73 # or s,bla,blubb,;t t (autoconf 2.52) 74 my $srch = $1; 75 my $repl = $2; 76 $repl =~ s/\\(.)/$1/g; 77 push @comp_subs, make_closure($srch, $repl); 78 79 } elsif ( ($pat =~ /%([^%]*)%d/ ) 80 || ($pat =~ m%/([^/]*)/d% ) 81 ) { 82 push @comp_subs, make_closure($1, ""); 83 } else { 84 die "Uhh. Malformed pattern in $ac_subs ($pat)" 85 unless ( $pat =~ /^\s*$/ ); # ignore white lines 86 } 87 } 88} else { 89 foreach $pat (@subs) { 90 if ( ($pat =~ /s%([^%]*)%([^%]*)%g/ ) || 91 ($pat =~ /s%([^%]*)%([^%]*)%;t/ ) || 92 ($pat =~ /s,([^,]*),(.*),;t/) ) { 93 # form : s%bla%blubb%g 94 # or s%bla%blubb%;t t (autoconf > 2.13 and < 2.52 ?) 95 # or s,bla,blubb,;t t (autoconf 2.52) 96 my $srch = $1; 97 my $repl = $2; 98 push @comp_match, eval "qr/\Q$srch\E/"; # compile match pattern 99 $repl =~ s/\\(.)/$1/g; 100 push @comp_subs, $repl; 101 } elsif ( ($pat =~ /%([^%]*)%d/ ) 102 || ($pat =~ m%/([^/]*)/d% ) 103 ) { 104 push @comp_match, eval "qr/\Q$1\E/"; 105 push @comp_subs, ""; 106 } else { 107 die "Uhh. Malformed pattern in $ac_subs ($pat)" 108 unless ( $pat =~ /^\s*$/ ); # ignore white lines 109 } 110 } 111} 112undef @subs; 113 114# read the list of files to be patched, form: 115# ./Makefile arts/Makefile arts/examples/Makefile arts/flow/Makefile 116 117open(CF, "< $ac_sacfiles") || die "can't open $ac_sacfiles: $!"; 118my @ac_files = <CF>; 119close(CF); 120chomp @ac_files; 121 122 123my $ac_file; 124foreach $ac_file (@ac_files) { 125 next if $ac_file =~ /\.\./; 126 next if $ac_file =~ /^\s*$/; 127 my $ac_file_in; 128 my ($ac_dir, $ac_dots, $ac_dir_suffix); 129 130 if ($ac_file =~ /.*:.*/ ) { 131 ($ac_file_in = $ac_file) =~ s%[^:]*:%%; 132 $ac_file =~ s%:.*%%; 133 } else { 134 $ac_file_in = $ac_file.".in"; 135 } 136 137# Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. 138 139# Remove last slash and all that follows it. Not all systems have dirname. 140 ($ac_dir = $ac_file) =~ s%/[^/][^/]*$%%; 141 if ( ($ac_dir ne $ac_file) && ($ac_dir ne ".")) { 142# The file is in a subdirectory. 143 if (! -d "$ac_dir") { mkpath "$ac_dir", 0, 0777; } 144 ($ac_dir_suffix = $ac_dir) =~ s%^./%%; 145 $ac_dir_suffix="/".$ac_dir_suffix; 146# A "../" for each directory in $ac_dir_suffix. 147 ($ac_dots = $ac_dir_suffix) =~ s%/[^/]*%../%g; 148 } else { 149 $ac_dir_suffix=""; 150 $ac_dots=""; 151 } 152 153 if ($ac_given_srcdir eq ".") { 154 $srcdir="."; 155 if ($ac_dots) { 156 ( $top_srcdir = $ac_dots) =~ s%/$%%; 157 } else { $top_srcdir="."; } 158 } elsif ($ac_given_srcdir =~ m%^/%) { 159 $srcdir=$ac_given_srcdir.$ac_dir_suffix; 160 $top_srcdir = $ac_given_srcdir; 161 } else { 162 $srcdir = $ac_dots.$ac_given_srcdir.$ac_dir_suffix; 163 $top_srcdir = $ac_dots.$ac_given_srcdir; 164 } 165 166 if ($ac_given_INSTALL) { 167 if ($ac_given_INSTALL =~ m%^/% ) { 168 $INSTALL = $ac_given_INSTALL; 169 } else { 170 $INSTALL = $ac_dots.$ac_given_INSTALL; 171 } 172 } 173 174 print "fast creating $ac_file\n"; 175 unlink $ac_file; 176 my $ac_comsub=""; 177 my $fname=$ac_file_in; 178 $fname =~ s%.*/%%; 179 $configure_input="$ac_file. Generated from $fname by config.pl."; 180 181 my $ac_file_inputs; 182 ($ac_file_inputs = $ac_file_in) =~ s%^%$ac_given_srcdir/%; 183 $ac_file_inputs =~ s%:% $ac_given_srcdir/%g; 184 185 patch_file($ac_file, $ac_file_inputs); 186 ++$created_file_count; 187} 188 189print "config.pl: fast created $created_file_count file(s).\n"; 190 191sub patch_file { 192 my ($outf, $infiles) = @_; 193 my $filedata; 194 my @infiles=split(' ', $infiles); 195 my $i=0; 196 my $name; 197 198 foreach $name (@infiles) { 199 if (open(CF, "< $name")) { 200 while (<CF>) { 201 $filedata .= $_; 202 } 203 close(CF); 204 } else { 205 print STDERR "can't open $name: $!"."\n"; 206 } 207 } 208 209 $filedata =~ s%\@configure_input\@%$configure_input%g; 210 $filedata =~ s%\@srcdir\@%$srcdir%g; 211 $filedata =~ s%\@top_srcdir\@%$top_srcdir%g; 212 $filedata =~ s%\@INSTALL\@%$INSTALL%g; 213 214 if ($bad_perl) { 215 while ($i <= $#comp_subs) { 216 my $ref = $comp_subs[$i]; 217 &$ref(\$filedata); 218 $i++; 219 } 220 } else { 221 while ($i <= $#comp_match) { 222 $filedata =~ s/$comp_match[$i]/$comp_subs[$i]/g; 223 $i++; 224 } 225 } 226 open(CF, "> $outf") || die "can't create $outf: $!"; 227 print CF $filedata; 228 close(CF); 229} 230 231sub make_closure { 232 my ($pat, $sub) = @_; 233 my $ret = eval "return sub { my \$ref=shift; \$\$ref =~ s%\Q$pat\E%\Q$sub\E%g; }"; 234 if ($@) { 235 print "can't create CODE: $@\n"; 236 } 237 return $ret; 238} 239