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., 59 Temple Place - Suite 330, 29# Boston, MA 02111-1307, 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>; 56close(CF); 57chomp @subs; 58@comp_match=(); 59@comp_subs=(); 60 61if ($bad_perl) { 62 print "Using perl older than version 5.005\n"; 63 foreach my $pat (@subs) { 64 if ( ($pat =~ m/s%([^%]*)%([^%]*)%g/ ) 65 || ($pat =~ m/s%([^%]*)%([^%]*)%;t/ ) 66 || ($pat =~ m/s,([^,]*),(.*),;t/) 67 || ($pat =~ m%s/([^/]*)/([^/]*)/g% ) 68 || ($pat =~ m%s/([^/]*)/([^/]*)/;t% ) 69 ) { 70 # form : s%bla%blubb%g 71 # or s%bla%blubb%;t t (autoconf > 2.13 and < 2.52 ?) 72 # or s,bla,blubb,;t t (autoconf 2.52) 73 my $srch = $1; 74 my $repl = $2; 75 $repl =~ s/\\(.)/$1/g; 76 push @comp_subs, make_closure($srch, $repl); 77 78 } elsif ( ($pat =~ /%([^%]*)%d/ ) 79 || ($pat =~ m%/([^/]*)/d% ) 80 ) { 81 push @comp_subs, make_closure($1, ""); 82 } else { 83 die "Uhh. Malformed pattern in $ac_subs ($pat)" 84 unless ( $pat =~ /^\s*$/ ); # ignore white lines 85 } 86 } 87} else { 88 foreach my $pat (@subs) { 89 if ( ($pat =~ /s%([^%]*)%([^%]*)%g/ ) || 90 ($pat =~ /s%([^%]*)%([^%]*)%;t/ ) || 91 ($pat =~ /s,([^,]*),(.*),;t/) ) { 92 # form : s%bla%blubb%g 93 # or s%bla%blubb%;t t (autoconf > 2.13 and < 2.52 ?) 94 # or s,bla,blubb,;t t (autoconf 2.52) 95 my $srch = $1; 96 my $repl = $2; 97 push @comp_match, eval "qr/\Q$srch\E/"; # compile match pattern 98 $repl =~ s/\\(.)/$1/g; 99 push @comp_subs, $repl; 100 } elsif ( ($pat =~ /%([^%]*)%d/ ) 101 || ($pat =~ m%/([^/]*)/d% ) 102 ) { 103 push @comp_match, eval "qr/\Q$1\E/"; 104 push @comp_subs, ""; 105 } else { 106 die "Uhh. Malformed pattern in $ac_subs ($pat)" 107 unless ( $pat =~ /^\s*$/ ); # ignore white lines 108 } 109 } 110} 111undef @subs; 112 113# read the list of files to be patched, form: 114# ./Makefile arts/Makefile arts/examples/Makefile arts/flow/Makefile 115 116open(CF, "< $ac_sacfiles") || die "can't open $ac_sacfiles: $!"; 117my @ac_files = <CF>; 118close(CF); 119chomp @ac_files; 120 121 122my $ac_file; 123foreach $ac_file (@ac_files) { 124 next if $ac_file =~ /\.\./; 125 next if $ac_file =~ /^\s*$/; 126 my $ac_file_in; 127 my ($ac_dir, $ac_dots, $ac_dir_suffix); 128 129 if ($ac_file =~ /.*:.*/ ) { 130 ($ac_file_in = $ac_file) =~ s%[^:]*:%%; 131 $ac_file =~ s%:.*%%; 132 } else { 133 $ac_file_in = $ac_file.".in"; 134 } 135 136# Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. 137 138# Remove last slash and all that follows it. Not all systems have dirname. 139 ($ac_dir = $ac_file) =~ s%/[^/][^/]*$%%; 140 if ( ($ac_dir ne $ac_file) && ($ac_dir ne ".")) { 141# The file is in a subdirectory. 142 if (! -d "$ac_dir") { mkpath "$ac_dir", 0, 0777; } 143 ($ac_dir_suffix = $ac_dir) =~ s%^./%%; 144 $ac_dir_suffix="/".$ac_dir_suffix; 145# A "../" for each directory in $ac_dir_suffix. 146 ($ac_dots = $ac_dir_suffix) =~ s%/[^/]*%../%g; 147 } else { 148 $ac_dir_suffix=""; 149 $ac_dots=""; 150 } 151 152 if ($ac_given_srcdir eq ".") { 153 $srcdir="."; 154 if ($ac_dots) { 155 ( $top_srcdir = $ac_dots) =~ s%/$%%; 156 } else { $top_srcdir="."; } 157 } elsif ($ac_given_srcdir =~ m%^/%) { 158 $srcdir=$ac_given_srcdir.$ac_dir_suffix; 159 $top_srcdir = $ac_given_srcdir; 160 } else { 161 $srcdir = $ac_dots.$ac_given_srcdir.$ac_dir_suffix; 162 $top_srcdir = $ac_dots.$ac_given_srcdir; 163 } 164 165 if ($ac_given_INSTALL) { 166 if ($ac_given_INSTALL =~ m%^/% ) { 167 $INSTALL = $ac_given_INSTALL; 168 } else { 169 $INSTALL = $ac_dots.$ac_given_INSTALL; 170 } 171 } 172 173 print "fast creating $ac_file\n"; 174 unlink $ac_file; 175 my $ac_comsub=""; 176 my $fname=$ac_file_in; 177 $fname =~ s%.*/%%; 178 $configure_input="$ac_file. Generated from $fname by config.pl."; 179 180 my $ac_file_inputs; 181 ($ac_file_inputs = $ac_file_in) =~ s%^%$ac_given_srcdir/%; 182 $ac_file_inputs =~ s%:% $ac_given_srcdir/%g; 183 184 patch_file($ac_file, $ac_file_inputs); 185 ++$created_file_count; 186} 187 188print "config.pl: fast created $created_file_count file(s).\n"; 189 190sub patch_file { 191 my ($outf, $infiles) = @_; 192 my $filedata; 193 my @infiles=split(' ', $infiles); 194 my $i=0; 195 196 foreach my $name (@infiles) { 197 if (open(CF, "< $name")) { 198 while (<CF>) { 199 $filedata .= $_; 200 } 201 close(CF); 202 } else { 203 print STDERR "can't open $name: $!"."\n"; 204 } 205 } 206 207 $filedata =~ s%\@configure_input\@%$configure_input%g; 208 $filedata =~ s%\@srcdir\@%$srcdir%g; 209 $filedata =~ s%\@top_srcdir\@%$top_srcdir%g; 210 $filedata =~ s%\@INSTALL\@%$INSTALL%g; 211 212 if ($bad_perl) { 213 while ($i <= $#comp_subs) { 214 my $ref = $comp_subs[$i]; 215 &$ref(\$filedata); 216 $i++; 217 } 218 } else { 219 while ($i <= $#comp_match) { 220 $filedata =~ s/$comp_match[$i]/$comp_subs[$i]/g; 221 $i++; 222 } 223 } 224 open(CF, "> $outf") || die "can't create $outf: $!"; 225 print CF $filedata; 226 close(CF); 227} 228 229sub make_closure { 230 my ($pat, $sub) = @_; 231 my $ret = eval "return sub { my \$ref=shift; \$\$ref =~ s%\Q$pat\E%\Q$sub\E%g; }"; 232 if ($@) { 233 print "can't create CODE: $@\n"; 234 } 235 return $ret; 236} 237