273 lines
7.6 KiB
Perl
Executable File
273 lines
7.6 KiB
Perl
Executable File
#!/bin/sh
|
|
#! -*-perl-*-
|
|
|
|
# Rewrite a gnulib.mk, adding prefixes to work with automake's subdir-objects.
|
|
|
|
# Copyright (C) 2012-2021 Free Software Foundation, Inc.
|
|
#
|
|
# This file is free software; the Free Software Foundation
|
|
# gives unlimited permission to copy and/or distribute it,
|
|
# with or without modifications, as long as this notice is preserved.
|
|
#
|
|
# Written by Jim Meyering
|
|
|
|
# This is a prologue that allows to run a perl script as an executable
|
|
# on systems that are compliant to a POSIX version before POSIX:2017.
|
|
# On such systems, the usual invocation of an executable through execlp()
|
|
# or execvp() fails with ENOEXEC if it is a script that does not start
|
|
# with a #! line. The script interpreter mentioned in the #! line has
|
|
# to be /bin/sh, because on GuixSD systems that is the only program that
|
|
# has a fixed file name. The second line is essential for perl and is
|
|
# also useful for editing this file in Emacs. The next two lines below
|
|
# are valid code in both sh and perl. When executed by sh, they re-execute
|
|
# the script through the perl program found in $PATH. The '-x' option
|
|
# is essential as well; without it, perl would re-execute the script
|
|
# through /bin/sh. When executed by perl, the next two lines are a no-op.
|
|
eval 'exec perl -wSx "$0" "$@"'
|
|
if 0;
|
|
|
|
my $VERSION = '2020-04-04 15:07'; # UTC
|
|
# The definition above must lie within the first 8 lines in order
|
|
# for the Emacs time-stamp write hook (at end) to update it.
|
|
# If you change this file with Emacs, please let the write hook
|
|
# do its job. Otherwise, update this string manually.
|
|
|
|
use strict;
|
|
use IO::File;
|
|
use Getopt::Long;
|
|
use File::Basename; # for dirname
|
|
|
|
(my $ME = $0) =~ s|.*/||;
|
|
|
|
my $prefix;
|
|
my $lib_name;
|
|
|
|
sub usage ($)
|
|
{
|
|
my ($exit_code) = @_;
|
|
my $STREAM = ($exit_code == 0 ? *STDOUT : *STDERR);
|
|
if ($exit_code != 0)
|
|
{
|
|
print $STREAM "Try '$ME --help' for more information.\n";
|
|
}
|
|
else
|
|
{
|
|
print $STREAM <<EOF;
|
|
Usage: $ME --lib-name=NAME FILE
|
|
or: $ME [--help|--version]
|
|
Rewrite a gnulib-tool-generated FILE like lib/gnulib.mk to work with
|
|
automake's subdir-objects.
|
|
|
|
OPTIONS:
|
|
|
|
This option must be specified:
|
|
|
|
--lib-name=NAME library name, often "lib\$project"
|
|
|
|
The following are optional:
|
|
|
|
--help display this help and exit
|
|
--version output version information and exit
|
|
|
|
EOF
|
|
}
|
|
exit $exit_code;
|
|
}
|
|
|
|
# contents ($FILE_NAME)
|
|
# ---------------------
|
|
sub contents ($)
|
|
{
|
|
my ($file) = @_;
|
|
local $/; # Turn on slurp-mode.
|
|
my $f = new IO::File "< $file" or die "$file";
|
|
my $contents = $f->getline or die "$file";
|
|
$f->close;
|
|
return $contents;
|
|
}
|
|
|
|
# prefix_word ($WORD)
|
|
# -------------------
|
|
# Do not prefix special words such as variable dereferences. Also,
|
|
# "Makefile" is really "Makefile", since precisely there is no
|
|
# lib/Makefile.
|
|
sub prefix_word ($)
|
|
{
|
|
local ($_) = @_;
|
|
$_ = $prefix . $_
|
|
unless (/^-/ || m{^\$\(\w+\)} || $_ eq "Makefile" || $_ eq '\\'
|
|
|| $_ eq '@ALLOCA@');
|
|
return $_;
|
|
}
|
|
|
|
|
|
# prefix_words ($TEXT)
|
|
# --------------------
|
|
sub prefix_words ($)
|
|
{
|
|
local ($_) = @_;
|
|
s{(\S+)}{prefix_word($1)}gem;
|
|
return $_;
|
|
}
|
|
|
|
|
|
# prefix_assignment ($LHS-AND-ASSIGN-OP, $RHS)
|
|
# --------------------------------------------
|
|
sub prefix_assignment ($$)
|
|
{
|
|
my ($lhs_and_assign_op, $rhs) = @_;
|
|
|
|
# Some variables are initialized by gnulib.mk, and we don't want
|
|
# that. Change '=' to '+='.
|
|
if ($lhs_and_assign_op =~ /^(GPERF|V_GPERF.*) =$/)
|
|
{
|
|
# Do not change the RHS, which specifies the GPERF program.
|
|
}
|
|
# Don't change variables such as HAVE_INCLUDE_NEXT.
|
|
elsif ($lhs_and_assign_op =~ /^HAVE_/)
|
|
{
|
|
}
|
|
elsif ($lhs_and_assign_op =~
|
|
/^(SUBDIRS|EXTRA_DIST|BUILT_SOURCES|SUFFIXES|MOSTLYCLEANFILES
|
|
|CLEANFILES|DISTCLEANFILES|MAINTAINERCLEANFILES
|
|
|AM_GNU_GETTEXT)\ =/x)
|
|
{
|
|
$lhs_and_assign_op =~ s/=/+=/;
|
|
}
|
|
# We don't want things such as AM_CPPFLAGS +=
|
|
# -DDEFAULT_TEXT_DOMAIN=\"bison-gnulib\" to apply to the whole
|
|
# Makefile.in: scope it to the library: libbison_a_CPPFLAGS =
|
|
# $(AM_CPPFLAGS) -DDEFAULT_TEXT_DOMAIN=\"bison-gnulib\".
|
|
elsif ($lhs_and_assign_op =~
|
|
/^(AM_CFLAGS|AM_CPPFLAGS)\ \+?=/x)
|
|
{
|
|
$lhs_and_assign_op =~ s/^AM_(\w+)\ \+?=/${lib_name}_a_$1 =/;
|
|
$rhs = " \$(AM_$1)$rhs";
|
|
}
|
|
# We don't want to inherit gnulib's AUTOMAKE_OPTIONS, comment them.
|
|
elsif ($lhs_and_assign_op =~ /^AUTOMAKE_OPTIONS =/)
|
|
{
|
|
$lhs_and_assign_op =~ s/^/# /;
|
|
}
|
|
# Elide any SUFFIXES assignment or concatenation.
|
|
elsif ($lhs_and_assign_op =~ /^SUFFIXES /)
|
|
{
|
|
$lhs_and_assign_op =~ s/^/# /;
|
|
}
|
|
# The words are (probably) paths to files in lib/: prefix them.
|
|
else
|
|
{
|
|
$rhs = prefix_words($rhs)
|
|
}
|
|
|
|
# Variables whose name depend on the location: libbison_a_SOURCES =>
|
|
# lib_libbison_a_SOURCES.
|
|
$lhs_and_assign_op =~ s/($lib_name)/lib_$1/g;
|
|
|
|
$lhs_and_assign_op . $rhs;
|
|
}
|
|
|
|
# prefix $CONTENTS
|
|
# ----------------
|
|
# $CONTENTS is a Makefile content. Post-process it so that each file-name
|
|
# is prefixed with $prefix (e.g., "lib/").
|
|
#
|
|
# Relies heavily on the regularity of the file generated by gnulib-tool.
|
|
sub prefix ($)
|
|
{
|
|
# Work on $_.
|
|
local ($_) = @_;
|
|
|
|
# Prefix all the occurrence of files in rules. If there is nothing
|
|
# after in the :, it's probably a phony target, or a suffix rule.
|
|
# Don't touch it.
|
|
s{^([-\w+/]+\.[-\w.]+ *: *\S.*)$}
|
|
{prefix_words($1)}gem;
|
|
|
|
# Prefix files in variables.
|
|
s{^([\w.]+\s*\+?=)(.*)$}
|
|
{prefix_assignment($1, $2)}gem;
|
|
|
|
# $(srcdir)/ is actually $(top_srcdir)/$prefix/.
|
|
# The trailing slash is required to avoid matching this rule:
|
|
# test '$(srcdir)' = . || rm -f $(top_builddir)/GNUmakefile
|
|
s{\$\(srcdir\)/}{\$(top_srcdir)/$prefix}g;
|
|
|
|
# Sometimes, t-$@ is used instead of $@-t, which, of course, does
|
|
# not work when we have a $@ with a directory in it.
|
|
s{t-\$\@}{\$\@-t}g;
|
|
|
|
# Some AC_SUBST patterns remain and would better be Make macros.
|
|
s{\@(MKDIR_P)\@}{\$($1)}g;
|
|
|
|
# Adjust paths in mkdir.
|
|
s{(\$\(MKDIR_P\))\s*(\w+)}{$1 $prefix$2}g;
|
|
|
|
return $_;
|
|
}
|
|
|
|
# process ($IN)
|
|
# -------------
|
|
sub process ($)
|
|
{
|
|
my ($file) = @_;
|
|
my ($bak) = "$file.bak";
|
|
rename ($file, $bak) or die "$ME: rename $file $bak failed: $!\n";
|
|
my $contents = contents ($bak);
|
|
$contents = prefix ($contents);
|
|
my $out = new IO::File(">$file")
|
|
or die "$ME: $file: failed to open for writing: $!\n";
|
|
print $out $contents;
|
|
}
|
|
|
|
{
|
|
GetOptions
|
|
(
|
|
'lib-name=s' => \$lib_name,
|
|
help => sub { usage 0 },
|
|
version => sub { print "$ME version $VERSION\n"; exit },
|
|
) or usage 1;
|
|
|
|
my $fail = 0;
|
|
defined $lib_name
|
|
or (warn "$ME: no library name; use --lib-name=NAME\n"), $fail = 1;
|
|
|
|
# There must be exactly one argument.
|
|
@ARGV == 0
|
|
and (warn "$ME: missing FILE argument\n"), $fail = 1;
|
|
1 < @ARGV
|
|
and (warn "$ME: too many arguments:\n", join ("\n", @ARGV), "\n"),
|
|
$fail = 1;
|
|
$fail
|
|
and usage 1;
|
|
|
|
my $file = $ARGV[0];
|
|
$prefix = (dirname $file) . '/';
|
|
warn "prefix=$prefix\n";
|
|
|
|
process $file;
|
|
}
|
|
|
|
### Setup "GNU" style for perl-mode and cperl-mode.
|
|
## Local Variables:
|
|
## perl-indent-level: 2
|
|
## perl-continued-statement-offset: 2
|
|
## perl-continued-brace-offset: 0
|
|
## perl-brace-offset: 0
|
|
## perl-brace-imaginary-offset: 0
|
|
## perl-label-offset: -2
|
|
## cperl-indent-level: 2
|
|
## cperl-brace-offset: 0
|
|
## cperl-continued-brace-offset: 0
|
|
## cperl-label-offset: -2
|
|
## cperl-extra-newline-before-brace: t
|
|
## cperl-merge-trailing-else: nil
|
|
## cperl-continued-statement-offset: 2
|
|
## eval: (add-hook 'before-save-hook 'time-stamp)
|
|
## time-stamp-line-limit: 50
|
|
## time-stamp-start: "my $VERSION = '"
|
|
## time-stamp-format: "%:y-%02m-%02d %02H:%02M"
|
|
## time-stamp-time-zone: "UTC0"
|
|
## time-stamp-end: "'; # UTC"
|
|
## End:
|