1eval '(exit $?0)' && eval 'exec perl -wS "$0" ${1+"$@"}' 2 & eval 'exec perl -wS "$0" $argv:q' 3 if 0; 4 5use strict; 6use IO::File; 7use Getopt::Long; 8use File::Basename; # for dirname 9 10my $VERSION = '2012-01-21 17:13'; # UTC 11(my $ME = $0) =~ s|.*/||; 12 13my $prefix; 14my $lib_name; 15 16sub usage ($) 17{ 18 my ($exit_code) = @_; 19 my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR); 20 if ($exit_code != 0) 21 { 22 print $STREAM "Try '$ME --help' for more information.\n"; 23 } 24 else 25 { 26 print $STREAM <<EOF; 27Usage: $ME --lib-name=NAME FILE 28 or: $ME [--help|--version] 29Rewrite a gnulib-tool-generated FILE like lib/gnulib.mk to work with 30automake's subdir-objects. 31 32OPTIONS: 33 34This option must be specified: 35 36 --lib-name=NAME library name, often "lib\$project" 37 38The following are optional: 39 40 --help display this help and exit 41 --version output version information and exit 42 43EOF 44 } 45 exit $exit_code; 46} 47 48# contents ($FILE_NAME) 49# --------------------- 50sub contents ($) 51{ 52 my ($file) = @_; 53 local $/; # Turn on slurp-mode. 54 my $f = new IO::File "< $file" or die "$file"; 55 my $contents = $f->getline or die "$file"; 56 $f->close; 57 return $contents; 58} 59 60# prefix_word ($WORD) 61# ------------------- 62# Do not prefix special words such as variable dereferences. Also, 63# "Makefile" is really "Makefile", since precisely there is no 64# lib/Makefile. 65sub prefix_word ($) 66{ 67 local ($_) = @_; 68 $_ = $prefix . $_ 69 unless (/^-/ || m{^\$\(\w+\)} || $_ eq "Makefile" || $_ eq '\\' 70 || $_ eq '@ALLOCA@'); 71 return $_; 72} 73 74 75# prefix_words ($TEXT) 76# -------------------- 77sub prefix_words ($) 78{ 79 local ($_) = @_; 80 s{(\S+)}{prefix_word($1)}gem; 81 return $_; 82} 83 84 85# prefix_assignment ($LHS-AND-ASSIGN-OP, $RHS) 86# -------------------------------------------- 87sub prefix_assignment ($$) 88{ 89 my ($lhs_and_assign_op, $rhs) = @_; 90 my $res; 91 92 # Some variables are initialized by gnulib.mk, and we don't want 93 # that. Change '=' to '+='. 94 if ($lhs_and_assign_op =~ /^GPERF =$/) 95 { 96 # Do not change the RHS, which specifies the GPERF program. 97 } 98 elsif ($lhs_and_assign_op =~ 99 /^(SUBDIRS|EXTRA_DIST|BUILT_SOURCES|SUFFIXES|MOSTLYCLEANFILES 100 |CLEANFILES|DISTCLEANFILES|MAINTAINERCLEANFILES|AM_CFLAGS 101 |AM_CPPFLAGS|AM_GNU_GETTEXT)\ =/x) 102 { 103 $lhs_and_assign_op =~ s/=/+=/; 104 } 105 # We don't want to inherit gnulib's AUTOMAKE_OPTIONS, comment them. 106 elsif ($lhs_and_assign_op =~ /^AUTOMAKE_OPTIONS =/) 107 { 108 $lhs_and_assign_op =~ s/^/# /; 109 } 110 elsif ($lhs_and_assign_op =~ /^SUFFIXES /) 111 { 112 # Elide any SUFFIXES assignment or concatenation. 113 $lhs_and_assign_op =~ s/^/# /; 114 } 115 # The words are (probably) paths to files in lib/: prefix them. 116 else 117 { 118 $rhs = prefix_words($rhs) 119 } 120 121 # Variables which name depend on the location: libbison_a_SOURCES => 122 # lib_libbison_a_SOURCES. 123 $lhs_and_assign_op =~ s/($lib_name)/lib_$1/g; 124 125 return $lhs_and_assign_op . $rhs; 126} 127 128# prefix $CONTENTS 129# ---------------- 130# $CONTENTS is a Makefile content. Post-process it so that each file-name 131# is prefixed with $prefix (e.g., "lib/"). 132# 133# Relies heavily on the regularity of the file generated by gnulib-tool. 134sub prefix ($) 135{ 136 # Work on $_. 137 local ($_) = @_; 138 139 # Prefix all the occurrence of files in rules. If there is nothing 140 # after in the :, it's probably a phony target, or a suffix rule. 141 # Don't touch it. 142 s{^([-\w+/]+\.[-\w.]+ *: *\S.*)$} 143 {prefix_words($1)}gem; 144 145 # Prefix files in variables. 146 s{^([\w.]+\s*\+?=)(.*)$} 147 {prefix_assignment($1, $2)}gem; 148 149 # These three guys escape all the other regular rules. 150 # Require the leading white space to avoid inserting the prefix 151 # on a line like this: 152 # charset_alias = $(DESTDIR)$(libdir)/charset.alias 153 # With $(libdir), it would be erroneous. 154 s{(\s)(charset\.alias|ref-add\.sed|ref-del\.sed)}{$1$prefix$2}g; 155 # Unfortunately, as a result we sometimes have lib/lib. 156 s{($prefix){2}}{$1}g; 157 158 # lib_libcoreutils_a_SOURCES += \ 159 # imaxtostr.c \ 160 # inttostr.c \ 161 # offtostr.c \ 162 # uinttostr.c \ 163 # umaxtostr.c 164 # The above are not handled since they're on continued lines, so 165 # deal with them manually: 166 s{^(\s*)((?:[ui]max|u?int|off)tostr\.c(:? \\)?)$}{$1$prefix$2}gm; 167 168 # $(srcdir)/ is actually $(top_srcdir)/$prefix/. 169 # The trailing slash is required to avoid matching this rule: 170 # test '$(srcdir)' = . || rm -f $(top_builddir)/GNUmakefile 171 s{\$\(srcdir\)/}{\$(top_srcdir)/$prefix}g; 172 173 # Sometimes, t-$@ is used instead of $@-t, which, of course, does 174 # not work when we have a $@ with a directory in it. 175 s{t-\$\@}{\$\@-t}g; 176 177 # Some AC_SUBST patterns remain and would better be Make macros. 178 s{\@(MKDIR_P)\@}{\$($1)}g; 179 180 # Adjust paths in mkdir. 181 s{(\$\(MKDIR_P\))\s*(\w+)}{$1 $prefix$2}g; 182 183 return $_; 184} 185 186# process ($IN) 187# ------------- 188sub process ($) 189{ 190 my ($file) = @_; 191 my ($bak) = "$file.bak"; 192 rename ($file, $bak) or die "$ME: rename $file $bak failed: $!\n"; 193 my $contents = contents ($bak); 194 $contents = prefix ($contents); 195 my $out = new IO::File(">$file") 196 or die "$ME: $file: failed to open for writing: $!\n"; 197 print $out $contents; 198} 199 200{ 201 GetOptions 202 ( 203 'lib-name=s' => \$lib_name, 204 help => sub { usage 0 }, 205 version => sub { print "$ME version $VERSION\n"; exit }, 206 ) or usage 1; 207 208 my $fail = 0; 209 defined $lib_name 210 or (warn "$ME: no library name; use --lib-name=NAME\n"), $fail = 1; 211 212 # There must be exactly one argument. 213 @ARGV == 0 214 and (warn "$ME: missing FILE argument\n"), $fail = 1; 215 1 < @ARGV 216 and (warn "$ME: too many arguments:\n", join ("\n", @ARGV), "\n"), 217 $fail = 1; 218 $fail 219 and usage 1; 220 221 my $file = $ARGV[0]; 222 $prefix = (dirname $file) . '/'; 223 warn "prefix=$prefix\n"; 224 225 process $file; 226} 227 228### Setup "GNU" style for perl-mode and cperl-mode. 229## Local Variables: 230## perl-indent-level: 2 231## perl-continued-statement-offset: 2 232## perl-continued-brace-offset: 0 233## perl-brace-offset: 0 234## perl-brace-imaginary-offset: 0 235## perl-label-offset: -2 236## cperl-indent-level: 2 237## cperl-brace-offset: 0 238## cperl-continued-brace-offset: 0 239## cperl-label-offset: -2 240## cperl-extra-newline-before-brace: t 241## cperl-merge-trailing-else: nil 242## cperl-continued-statement-offset: 2 243## eval: (add-hook 'write-file-hooks 'time-stamp) 244## time-stamp-start: "my $VERSION = '" 245## time-stamp-format: "%:y-%02m-%02d %02H:%02M" 246## time-stamp-time-zone: "UTC" 247## time-stamp-end: "'; # UTC" 248## End: 249