|
Packit |
47b4ca |
#! @PERL@ -w
|
|
Packit |
47b4ca |
# -*- perl -*-
|
|
Packit |
47b4ca |
# @configure_input@
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
eval 'case $# in 0) exec @PERL@ -S "$0";; *) exec @PERL@ -S "$0" "$@";; esac'
|
|
Packit |
47b4ca |
if 0;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# autom4te - Wrapper around M4 libraries.
|
|
Packit |
47b4ca |
# Copyright (C) 2001-2003, 2005-2012 Free Software Foundation, Inc.
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# This program is free software: you can redistribute it and/or modify
|
|
Packit |
47b4ca |
# it under the terms of the GNU General Public License as published by
|
|
Packit |
47b4ca |
# the Free Software Foundation, either version 3 of the License, or
|
|
Packit |
47b4ca |
# (at your option) any later version.
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# This program is distributed in the hope that it will be useful,
|
|
Packit |
47b4ca |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
47b4ca |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
47b4ca |
# GNU General Public License for more details.
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# You should have received a copy of the GNU General Public License
|
|
Packit |
47b4ca |
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
BEGIN
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my $pkgdatadir = $ENV{'autom4te_perllibdir'} || '@pkgdatadir@';
|
|
Packit |
47b4ca |
unshift @INC, $pkgdatadir;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Override SHELL. On DJGPP SHELL may not be set to a shell
|
|
Packit |
47b4ca |
# that can handle redirection and quote arguments correctly,
|
|
Packit |
47b4ca |
# e.g.: COMMAND.COM. For DJGPP always use the shell that configure
|
|
Packit |
47b4ca |
# has detected.
|
|
Packit |
47b4ca |
$ENV{'SHELL'} = '@SHELL@' if ($^O eq 'dos');
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
use Autom4te::C4che;
|
|
Packit |
47b4ca |
use Autom4te::ChannelDefs;
|
|
Packit |
47b4ca |
use Autom4te::Channels;
|
|
Packit |
47b4ca |
use Autom4te::FileUtils;
|
|
Packit |
47b4ca |
use Autom4te::General;
|
|
Packit |
47b4ca |
use Autom4te::XFile;
|
|
Packit |
47b4ca |
use File::Basename;
|
|
Packit |
47b4ca |
use strict;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Data directory.
|
|
Packit |
47b4ca |
my $pkgdatadir = $ENV{'AC_MACRODIR'} || '@pkgdatadir@';
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# $LANGUAGE{LANGUAGE} -- Automatic options for LANGUAGE.
|
|
Packit |
47b4ca |
my %language;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
my $output = '-';
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Mode of the output file except for traces.
|
|
Packit |
47b4ca |
my $mode = "0666";
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# If melt, don't use frozen files.
|
|
Packit |
47b4ca |
my $melt = 0;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Names of the cache directory, cache directory index, trace cache
|
|
Packit |
47b4ca |
# prefix, and output cache prefix. And the IO object for the index.
|
|
Packit |
47b4ca |
my $cache;
|
|
Packit |
47b4ca |
my $icache;
|
|
Packit |
47b4ca |
my $tcache;
|
|
Packit |
47b4ca |
my $ocache;
|
|
Packit |
47b4ca |
my $icache_file;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
my $flock_implemented = '@PERL_FLOCK@';
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# The macros to trace mapped to their format, as specified by the
|
|
Packit |
47b4ca |
# user.
|
|
Packit |
47b4ca |
my %trace;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# The macros the user will want to trace in the future.
|
|
Packit |
47b4ca |
# We need `include' to get the included file, `m4_pattern_forbid' and
|
|
Packit |
47b4ca |
# `m4_pattern_allow' to check the output.
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# FIXME: What about `sinclude'?
|
|
Packit |
47b4ca |
my @preselect = ('include',
|
|
Packit |
47b4ca |
'm4_pattern_allow', 'm4_pattern_forbid',
|
|
Packit |
47b4ca |
'_m4_warn');
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# M4 include path.
|
|
Packit |
47b4ca |
my @include;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Do we freeze?
|
|
Packit |
47b4ca |
my $freeze = 0;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# $M4.
|
|
Packit |
47b4ca |
my $m4 = $ENV{"M4"} || '@M4@';
|
|
Packit |
47b4ca |
# Some non-GNU m4's don't reject the --help option, so give them /dev/null.
|
|
Packit |
47b4ca |
fatal "need GNU m4 1.4 or later: $m4"
|
|
Packit |
47b4ca |
if system "$m4 --help </dev/null 2>&1 | grep reload-state >/dev/null";
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Set some high recursion limit as the default limit, 250, has already
|
|
Packit |
47b4ca |
# been hit with AC_OUTPUT. Don't override the user's choice.
|
|
Packit |
47b4ca |
$m4 .= ' --nesting-limit=1024'
|
|
Packit |
47b4ca |
if " $m4 " !~ / (--nesting-limit(=[0-9]+)?|-L[0-9]*) /;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# @M4_BUILTIN -- M4 builtins and a useful comment.
|
|
Packit |
47b4ca |
my @m4_builtin = `echo dumpdef | $m4 2>&1 >/dev/null`;
|
|
Packit |
47b4ca |
map { s/:.*//;s/\W// } @m4_builtin;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# %M4_BUILTIN_ALTERNATE_NAME
|
|
Packit |
47b4ca |
# --------------------------
|
|
Packit |
47b4ca |
# The builtins are renamed, e.g., `define' is renamed `m4_define'.
|
|
Packit |
47b4ca |
# So map `define' to `m4_define' and conversely.
|
|
Packit |
47b4ca |
# Some macros don't follow this scheme: be sure to properly map to their
|
|
Packit |
47b4ca |
# alternate name too.
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# FIXME: Trace status of renamed builtins was fixed in M4 1.4.5, which
|
|
Packit |
47b4ca |
# we now depend on; do we still need to do this mapping?
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# So we will merge them, i.e., tracing `BUILTIN' or tracing
|
|
Packit |
47b4ca |
# `m4_BUILTIN' will be the same: tracing both, but honoring the
|
|
Packit |
47b4ca |
# *last* trace specification.
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# FIXME: This is not enough: in the output `$0' will be `BUILTIN'
|
|
Packit |
47b4ca |
# sometimes and `m4_BUILTIN' at others. We should return a unique name,
|
|
Packit |
47b4ca |
# the one specified by the user.
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# FIXME: To be absolutely rigorous, I would say that given that we
|
|
Packit |
47b4ca |
# _redefine_ divert (instead of _copying_ it), divert and the like
|
|
Packit |
47b4ca |
# should not be part of this list.
|
|
Packit |
47b4ca |
my %m4_builtin_alternate_name;
|
|
Packit |
47b4ca |
@m4_builtin_alternate_name{"$_", "m4_$_"} = ("m4_$_", "$_")
|
|
Packit |
47b4ca |
foreach (grep { !/m4wrap|m4exit|dnl|ifelse|__.*__/ } @m4_builtin);
|
|
Packit |
47b4ca |
@m4_builtin_alternate_name{"ifelse", "m4_if"} = ("m4_if", "ifelse");
|
|
Packit |
47b4ca |
@m4_builtin_alternate_name{"m4exit", "m4_exit"} = ("m4_exit", "m4exit");
|
|
Packit |
47b4ca |
@m4_builtin_alternate_name{"m4wrap", "m4_wrap"} = ("m4_wrap", "m4wrap");
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# $HELP
|
|
Packit |
47b4ca |
# -----
|
|
Packit |
47b4ca |
$help = "Usage: $0 [OPTION]... [FILES]
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
Run GNU M4 on the FILES, avoiding useless runs. Output the traces if tracing,
|
|
Packit |
47b4ca |
the frozen file if freezing, otherwise the expansion of the FILES.
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
If some of the FILES are named \`FILE.m4f\' they are considered to be M4
|
|
Packit |
47b4ca |
frozen files of all the previous files (which are therefore not loaded).
|
|
Packit |
47b4ca |
If \`FILE.m4f\' is not found, then \`FILE.m4\' will be used, together with
|
|
Packit |
47b4ca |
all the previous files.
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
Some files may be optional, i.e., will only be processed if found in the
|
|
Packit |
47b4ca |
include path, but then must end in \`.m4?\'; the question mark is not part of
|
|
Packit |
47b4ca |
the actual file name.
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
Operation modes:
|
|
Packit |
47b4ca |
-h, --help print this help, then exit
|
|
Packit |
47b4ca |
-V, --version print version number, then exit
|
|
Packit |
47b4ca |
-v, --verbose verbosely report processing
|
|
Packit |
47b4ca |
-d, --debug don\'t remove temporary files
|
|
Packit |
47b4ca |
-o, --output=FILE save output in FILE (defaults to \`-\', stdout)
|
|
Packit |
47b4ca |
-f, --force don\'t rely on cached values
|
|
Packit |
47b4ca |
-W, --warnings=CATEGORY report the warnings falling in CATEGORY
|
|
Packit |
47b4ca |
-l, --language=LANG specify the set of M4 macros to use
|
|
Packit |
47b4ca |
-C, --cache=DIRECTORY preserve results for future runs in DIRECTORY
|
|
Packit |
47b4ca |
--no-cache disable the cache
|
|
Packit |
47b4ca |
-m, --mode=OCTAL change the non trace output file mode (0666)
|
|
Packit |
47b4ca |
-M, --melt don\'t use M4 frozen files
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
Languages include:
|
|
Packit |
47b4ca |
\`Autoconf\' create Autoconf configure scripts
|
|
Packit |
47b4ca |
\`Autotest\' create Autotest test suites
|
|
Packit |
47b4ca |
\`M4sh\' create M4sh shell scripts
|
|
Packit |
47b4ca |
\`M4sugar\' create M4sugar output
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
" . Autom4te::ChannelDefs::usage . "
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
The environment variables \`M4\' and \`WARNINGS\' are honored.
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
Library directories:
|
|
Packit |
47b4ca |
-B, --prepend-include=DIR prepend directory DIR to search path
|
|
Packit |
47b4ca |
-I, --include=DIR append directory DIR to search path
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
Tracing:
|
|
Packit |
47b4ca |
-t, --trace=MACRO[:FORMAT] report the MACRO invocations
|
|
Packit |
47b4ca |
-p, --preselect=MACRO prepare to trace MACRO in a future run
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
Freezing:
|
|
Packit |
47b4ca |
-F, --freeze produce an M4 frozen state file for FILES
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
FORMAT defaults to \`\$f:\$l:\$n:\$%\', and can use the following escapes:
|
|
Packit |
47b4ca |
\$\$ literal \$
|
|
Packit |
47b4ca |
\$f file where macro was called
|
|
Packit |
47b4ca |
\$l line where macro was called
|
|
Packit |
47b4ca |
\$d nesting depth of macro call
|
|
Packit |
47b4ca |
\$n name of the macro
|
|
Packit |
47b4ca |
\$NUM argument NUM, unquoted and with newlines
|
|
Packit |
47b4ca |
\$SEP\@ all arguments, with newlines, quoted, and separated by SEP
|
|
Packit |
47b4ca |
\$SEP* all arguments, with newlines, unquoted, and separated by SEP
|
|
Packit |
47b4ca |
\$SEP% all arguments, without newlines, unquoted, and separated by SEP
|
|
Packit |
47b4ca |
SEP can be empty for the default (comma for \@ and *, colon for %),
|
|
Packit |
47b4ca |
a single character for that character, or {STRING} to use a string.
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
Report bugs to <bug-autoconf\@gnu.org>.
|
|
Packit |
47b4ca |
GNU Autoconf home page: <http://www.gnu.org/software/autoconf/>.
|
|
Packit |
47b4ca |
General help using GNU software: <http://www.gnu.org/gethelp/>.
|
|
Packit |
47b4ca |
";
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# $VERSION
|
|
Packit |
47b4ca |
# --------
|
|
Packit |
47b4ca |
$version = <<"EOF";
|
|
Packit |
47b4ca |
autom4te (@PACKAGE_NAME@) @VERSION@
|
|
Packit |
47b4ca |
Copyright (C) @RELEASE_YEAR@ Free Software Foundation, Inc.
|
|
Packit |
47b4ca |
License GPLv3+/Autoconf: GNU GPL version 3 or later
|
|
Packit |
47b4ca |
<http://gnu.org/licenses/gpl.html>, <http://gnu.org/licenses/exceptions.html>
|
|
Packit |
47b4ca |
This is free software: you are free to change and redistribute it.
|
|
Packit |
47b4ca |
There is NO WARRANTY, to the extent permitted by law.
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
Written by Akim Demaille.
|
|
Packit |
47b4ca |
EOF
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
## ---------- ##
|
|
Packit |
47b4ca |
## Routines. ##
|
|
Packit |
47b4ca |
## ---------- ##
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# $OPTION
|
|
Packit |
47b4ca |
# files_to_options (@FILE)
|
|
Packit |
47b4ca |
# ------------------------
|
|
Packit |
47b4ca |
# Transform Autom4te conventions (e.g., using foo.m4f to designate a frozen
|
|
Packit |
47b4ca |
# file) into a suitable command line for M4 (e.g., using --reload-state).
|
|
Packit |
47b4ca |
# parse_args guarantees that we will see at most one frozen file, and that
|
|
Packit |
47b4ca |
# if a frozen file is present, it is the first argument.
|
|
Packit |
47b4ca |
sub files_to_options (@)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my (@file) = @_;
|
|
Packit |
47b4ca |
my @res;
|
|
Packit |
47b4ca |
foreach my $file (@file)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my $arg = shell_quote ($file);
|
|
Packit |
47b4ca |
if ($file =~ /\.m4f$/)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
$arg = "--reload-state=$arg";
|
|
Packit |
47b4ca |
# If the user downgraded M4 from 1.6 to 1.4.x after freezing
|
|
Packit |
47b4ca |
# the file, then we ensure the frozen __m4_version__ will
|
|
Packit |
47b4ca |
# not cause m4_init to make the wrong decision about the
|
|
Packit |
47b4ca |
# current M4 version.
|
|
Packit |
47b4ca |
$arg .= " --undefine=__m4_version__"
|
|
Packit |
47b4ca |
unless grep {/__m4_version__/} @m4_builtin;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
push @res, $arg;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
return join ' ', @res;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# load_configuration ($FILE)
|
|
Packit |
47b4ca |
# --------------------------
|
|
Packit |
47b4ca |
# Load the configuration $FILE.
|
|
Packit |
47b4ca |
sub load_configuration ($)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my ($file) = @_;
|
|
Packit |
47b4ca |
use Text::ParseWords;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
my $cfg = new Autom4te::XFile ("< " . open_quote ($file));
|
|
Packit |
47b4ca |
my $lang;
|
|
Packit |
47b4ca |
while ($_ = $cfg->getline)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
chomp;
|
|
Packit |
47b4ca |
# Comments.
|
|
Packit |
47b4ca |
next
|
|
Packit |
47b4ca |
if /^\s*(\#.*)?$/;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
my @words = shellwords ($_);
|
|
Packit |
47b4ca |
my $type = shift @words;
|
|
Packit |
47b4ca |
if ($type eq 'begin-language:')
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
fatal "$file:$.: end-language missing for: $lang"
|
|
Packit |
47b4ca |
if defined $lang;
|
|
Packit |
47b4ca |
$lang = lc $words[0];
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
elsif ($type eq 'end-language:')
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
error "$file:$.: end-language mismatch: $lang"
|
|
Packit |
47b4ca |
if $lang ne lc $words[0];
|
|
Packit |
47b4ca |
$lang = undef;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
elsif ($type eq 'args:')
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
fatal "$file:$.: no current language"
|
|
Packit |
47b4ca |
unless defined $lang;
|
|
Packit |
47b4ca |
push @{$language{$lang}}, @words;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
else
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
error "$file:$.: unknown directive: $type";
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# parse_args ()
|
|
Packit |
47b4ca |
# -------------
|
|
Packit |
47b4ca |
# Process any command line arguments.
|
|
Packit |
47b4ca |
sub parse_args ()
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
# We want to look for the early options, which should not be found
|
|
Packit |
47b4ca |
# in the configuration file. Prepend to the user arguments.
|
|
Packit |
47b4ca |
# Perform this repeatedly so that we can use --language in language
|
|
Packit |
47b4ca |
# definitions. Beware that there can be several --language
|
|
Packit |
47b4ca |
# invocations.
|
|
Packit |
47b4ca |
my @language;
|
|
Packit |
47b4ca |
do {
|
|
Packit |
47b4ca |
@language = ();
|
|
Packit |
47b4ca |
use Getopt::Long;
|
|
Packit |
47b4ca |
Getopt::Long::Configure ("pass_through", "permute");
|
|
Packit |
47b4ca |
GetOptions ("l|language=s" => \@language);
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
foreach (@language)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
error "unknown language: $_"
|
|
Packit |
47b4ca |
unless exists $language{lc $_};
|
|
Packit |
47b4ca |
unshift @ARGV, @{$language{lc $_}};
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
} while @language;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# --debug is useless: it is parsed below.
|
|
Packit |
47b4ca |
if (exists $ENV{'AUTOM4TE_DEBUG'})
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
print STDERR "$me: concrete arguments:\n";
|
|
Packit |
47b4ca |
foreach my $arg (@ARGV)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
print STDERR "| $arg\n";
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Process the arguments for real this time.
|
|
Packit |
47b4ca |
my @trace;
|
|
Packit |
47b4ca |
my @prepend_include;
|
|
Packit |
47b4ca |
parse_WARNINGS;
|
|
Packit |
47b4ca |
getopt
|
|
Packit |
47b4ca |
(
|
|
Packit |
47b4ca |
# Operation modes:
|
|
Packit |
47b4ca |
"o|output=s" => \$output,
|
|
Packit |
47b4ca |
"W|warnings=s" => \&parse_warnings,
|
|
Packit |
47b4ca |
"m|mode=s" => \$mode,
|
|
Packit |
47b4ca |
"M|melt" => \$melt,
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Library directories:
|
|
Packit |
47b4ca |
"B|prepend-include=s" => \@prepend_include,
|
|
Packit |
47b4ca |
"I|include=s" => \@include,
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Tracing:
|
|
Packit |
47b4ca |
# Using a hash for traces is seducing. Unfortunately, upon `-t FOO',
|
|
Packit |
47b4ca |
# instead of mapping `FOO' to undef, Getopt maps it to `1', preventing
|
|
Packit |
47b4ca |
# us from distinguishing `-t FOO' from `-t FOO=1'. So let's do it
|
|
Packit |
47b4ca |
# by hand.
|
|
Packit |
47b4ca |
"t|trace=s" => \@trace,
|
|
Packit |
47b4ca |
"p|preselect=s" => \@preselect,
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Freezing.
|
|
Packit |
47b4ca |
"F|freeze" => \$freeze,
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Caching.
|
|
Packit |
47b4ca |
"C|cache=s" => \$cache,
|
|
Packit |
47b4ca |
"no-cache" => sub { $cache = undef; },
|
|
Packit |
47b4ca |
);
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
fatal "too few arguments
|
|
Packit |
47b4ca |
Try `$me --help' for more information."
|
|
Packit |
47b4ca |
unless @ARGV;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Freezing:
|
|
Packit |
47b4ca |
# We cannot trace at the same time (well, we can, but it sounds insane).
|
|
Packit |
47b4ca |
# And it implies melting: there is risk not to update properly using
|
|
Packit |
47b4ca |
# old frozen files, and worse yet: we could load a frozen file and
|
|
Packit |
47b4ca |
# refreeze it! A sort of caching :)
|
|
Packit |
47b4ca |
fatal "cannot freeze and trace"
|
|
Packit |
47b4ca |
if $freeze && @trace;
|
|
Packit |
47b4ca |
$melt = 1
|
|
Packit |
47b4ca |
if $freeze;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Names of the cache directory, cache directory index, trace cache
|
|
Packit |
47b4ca |
# prefix, and output cache prefix. If the cache is not to be
|
|
Packit |
47b4ca |
# preserved, default to a temporary directory (automatically removed
|
|
Packit |
47b4ca |
# on exit).
|
|
Packit |
47b4ca |
$cache = $tmp
|
|
Packit |
47b4ca |
unless $cache;
|
|
Packit |
47b4ca |
$icache = "$cache/requests";
|
|
Packit |
47b4ca |
$tcache = "$cache/traces.";
|
|
Packit |
47b4ca |
$ocache = "$cache/output.";
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Normalize the includes: the first occurrence is enough, several is
|
|
Packit |
47b4ca |
# a pain since it introduces a useless difference in the path which
|
|
Packit |
47b4ca |
# invalidates the cache. And strip `.' which is implicit and always
|
|
Packit |
47b4ca |
# first.
|
|
Packit |
47b4ca |
@include = grep { !/^\.$/ } uniq (reverse(@prepend_include), @include);
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Convert @trace to %trace, and work around the M4 builtins tracing
|
|
Packit |
47b4ca |
# problem.
|
|
Packit |
47b4ca |
# The default format is `$f:$l:$n:$%'.
|
|
Packit |
47b4ca |
foreach (@trace)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
/^([^:]+)(?::(.*))?$/ms;
|
|
Packit |
47b4ca |
$trace{$1} = defined $2 ? $2 : '$f:$l:$n:$%';
|
|
Packit |
47b4ca |
$trace{$m4_builtin_alternate_name{$1}} = $trace{$1}
|
|
Packit |
47b4ca |
if exists $m4_builtin_alternate_name{$1};
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Work around the M4 builtins tracing problem for @PRESELECT.
|
|
Packit |
47b4ca |
# FIXME: Is this still needed, now that we rely on M4 1.4.5?
|
|
Packit |
47b4ca |
push (@preselect,
|
|
Packit |
47b4ca |
map { $m4_builtin_alternate_name{$_} }
|
|
Packit |
47b4ca |
grep { exists $m4_builtin_alternate_name{$_} } @preselect);
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# If we find frozen files, then all the files before it are
|
|
Packit |
47b4ca |
# discarded: the frozen file is supposed to include them all.
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# We don't want to depend upon m4's --include to find the top level
|
|
Packit |
47b4ca |
# files, so we use `find_file' here. Try to get a canonical name,
|
|
Packit |
47b4ca |
# as it's part of the key for caching. And some files are optional
|
|
Packit |
47b4ca |
# (also handled by `find_file').
|
|
Packit |
47b4ca |
my @argv;
|
|
Packit |
47b4ca |
foreach (@ARGV)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
if ($_ eq '-')
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
push @argv, $_;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
elsif (/\.m4f$/)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
# Frozen files are optional => pass a `?' to `find_file'.
|
|
Packit |
47b4ca |
my $file = find_file ("$_?", @include);
|
|
Packit |
47b4ca |
if (!$melt && $file)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
@argv = ($file);
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
else
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
s/\.m4f$/.m4/;
|
|
Packit |
47b4ca |
push @argv, find_file ($_, @include);
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
else
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my $file = find_file ($_, @include);
|
|
Packit |
47b4ca |
push @argv, $file
|
|
Packit |
47b4ca |
if $file;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
@ARGV = @argv;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# handle_m4 ($REQ, @MACRO)
|
|
Packit |
47b4ca |
# ------------------------
|
|
Packit |
47b4ca |
# Run m4 on the input files, and save the traces on the @MACRO.
|
|
Packit |
47b4ca |
sub handle_m4 ($@)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my ($req, @macro) = @_;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# GNU m4 appends when using --debugfile/--error-output.
|
|
Packit |
47b4ca |
unlink ($tcache . $req->id . "t");
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Run m4.
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# We don't output directly to the cache files, to avoid problems
|
|
Packit |
47b4ca |
# when we are interrupted (that leaves corrupted files).
|
|
Packit |
47b4ca |
xsystem ("$m4 @M4_GNU@"
|
|
Packit |
47b4ca |
. join (' --include=', '', map { shell_quote ($_) } @include)
|
|
Packit |
47b4ca |
. ' --debug=aflq'
|
|
Packit |
47b4ca |
. (!exists $ENV{'AUTOM4TE_NO_FATAL'} ? ' --fatal-warning' : '')
|
|
Packit |
47b4ca |
. " @M4_DEBUGFILE@=" . shell_quote ("$tcache" . $req->id . "t")
|
|
Packit |
47b4ca |
. join (' --trace=', '', map { shell_quote ($_) } sort @macro)
|
|
Packit |
47b4ca |
. " " . files_to_options (@ARGV)
|
|
Packit |
47b4ca |
. " > " . shell_quote ("$ocache" . $req->id . "t"));
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Everything went ok: preserve the outputs.
|
|
Packit |
47b4ca |
foreach my $file (map { $_ . $req->id } ($tcache, $ocache))
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
use File::Copy;
|
|
Packit |
47b4ca |
move ("${file}t", "$file")
|
|
Packit |
47b4ca |
or fatal "cannot rename ${file}t as $file: $!";
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# warn_forbidden ($WHERE, $WORD, %FORBIDDEN)
|
|
Packit |
47b4ca |
# ------------------------------------------
|
|
Packit |
47b4ca |
# $WORD is forbidden. Warn with a dedicated error message if in
|
|
Packit |
47b4ca |
# %FORBIDDEN, otherwise a simple `error: possibly undefined macro'
|
|
Packit |
47b4ca |
# will do.
|
|
Packit |
47b4ca |
my $first_warn_forbidden = 1;
|
|
Packit |
47b4ca |
sub warn_forbidden ($$%)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my ($where, $word, %forbidden) = @_;
|
|
Packit |
47b4ca |
my $message;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
for my $re (sort keys %forbidden)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
if ($word =~ $re)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
$message = $forbidden{$re};
|
|
Packit |
47b4ca |
last;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
$message ||= "possibly undefined macro: $word";
|
|
Packit |
47b4ca |
warn "$where: error: $message\n";
|
|
Packit |
47b4ca |
if ($first_warn_forbidden)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
warn <
|
|
Packit |
47b4ca |
If this token and others are legitimate, please use m4_pattern_allow.
|
|
Packit |
47b4ca |
See the Autoconf documentation.
|
|
Packit |
47b4ca |
EOF
|
|
Packit |
47b4ca |
$first_warn_forbidden = 0;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# handle_output ($REQ, $OUTPUT)
|
|
Packit |
47b4ca |
# -----------------------------
|
|
Packit |
47b4ca |
# Run m4 on the input files, perform quadrigraphs substitution, check for
|
|
Packit |
47b4ca |
# forbidden tokens, and save into $OUTPUT.
|
|
Packit |
47b4ca |
sub handle_output ($$)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my ($req, $output) = @_;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
verb "creating $output";
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Load the forbidden/allowed patterns.
|
|
Packit |
47b4ca |
handle_traces ($req, "$tmp/patterns",
|
|
Packit |
47b4ca |
('m4_pattern_forbid' => 'forbid:$1:$2',
|
|
Packit |
47b4ca |
'm4_pattern_allow' => 'allow:$1'));
|
|
Packit |
47b4ca |
my @patterns = new Autom4te::XFile ("< " . open_quote ("$tmp/patterns"))->getlines;
|
|
Packit |
47b4ca |
chomp @patterns;
|
|
Packit |
47b4ca |
my %forbidden =
|
|
Packit |
47b4ca |
map { /^forbid:([^:]+):.+$/ => /^forbid:[^:]+:(.+)$/ } @patterns;
|
|
Packit |
47b4ca |
my $forbidden = join ('|', map { /^forbid:([^:]+)/ } @patterns) || "^\$";
|
|
Packit |
47b4ca |
my $allowed = join ('|', map { /^allow:([^:]+)/ } @patterns) || "^\$";
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
verb "forbidden tokens: $forbidden";
|
|
Packit |
47b4ca |
verb "forbidden token : $_ => $forbidden{$_}"
|
|
Packit |
47b4ca |
foreach (sort keys %forbidden);
|
|
Packit |
47b4ca |
verb "allowed tokens: $allowed";
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Read the (cached) raw M4 output, produce the actual result. We
|
|
Packit |
47b4ca |
# have to use the 2nd arg to have Autom4te::XFile honor the third, but then
|
|
Packit |
47b4ca |
# stdout is to be handled by hand :(. Don't use fdopen as it means
|
|
Packit |
47b4ca |
# we will close STDOUT, which we already do in END.
|
|
Packit |
47b4ca |
my $out = new Autom4te::XFile;
|
|
Packit |
47b4ca |
if ($output eq '-')
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
$out->open (">$output");
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
else
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
$out->open($output, O_CREAT | O_WRONLY | O_TRUNC, oct ($mode));
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
fatal "cannot create $output: $!"
|
|
Packit |
47b4ca |
unless $out;
|
|
Packit |
47b4ca |
my $in = new Autom4te::XFile ("< " . open_quote ($ocache . $req->id));
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
my %prohibited;
|
|
Packit |
47b4ca |
my $res;
|
|
Packit |
47b4ca |
while ($_ = $in->getline)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
s/\s+$//;
|
|
Packit |
47b4ca |
s/__oline__/$./g;
|
|
Packit |
47b4ca |
s/\@<:\@/[/g;
|
|
Packit |
47b4ca |
s/\@:>\@/]/g;
|
|
Packit |
47b4ca |
s/\@\{:\@/(/g;
|
|
Packit |
47b4ca |
s/\@:\}\@/)/g;
|
|
Packit |
47b4ca |
s/\@S\|\@/\$/g;
|
|
Packit |
47b4ca |
s/\@%:\@/#/g;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
$res = $_;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Don't complain in comments. Well, until we have something
|
|
Packit |
47b4ca |
# better, don't consider `#include' etc. are comments.
|
|
Packit |
47b4ca |
s/\#.*//
|
|
Packit |
47b4ca |
unless /^\#\s*(if|include|endif|ifdef|ifndef|define)\b/;
|
|
Packit |
47b4ca |
foreach (split (/\W+/))
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
$prohibited{$_} = $.
|
|
Packit |
47b4ca |
if !/^$/ && /$forbidden/o && !/$allowed/o && ! exists $prohibited{$_};
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Performed *last*: the empty quadrigraph.
|
|
Packit |
47b4ca |
$res =~ s/\@&t\@//g;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
print $out "$res\n";
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
$out->close();
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# If no forbidden words, we're done.
|
|
Packit |
47b4ca |
return
|
|
Packit |
47b4ca |
if ! %prohibited;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Locate the forbidden words in the last input file.
|
|
Packit |
47b4ca |
# This is unsatisfying but...
|
|
Packit |
47b4ca |
$exit_code = 1;
|
|
Packit |
47b4ca |
if ($ARGV[$#ARGV] ne '-')
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my $prohibited = '\b(' . join ('|', keys %prohibited) . ')\b';
|
|
Packit |
47b4ca |
my $file = new Autom4te::XFile ("< " . open_quote ($ARGV[$#ARGV]));
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
while ($_ = $file->getline)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
# Don't complain in comments. Well, until we have something
|
|
Packit |
47b4ca |
# better, don't consider `#include' etc. to be comments.
|
|
Packit |
47b4ca |
s/\#.*//
|
|
Packit |
47b4ca |
unless /^\#(if|include|endif|ifdef|ifndef|define)\b/;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Complain once per word, but possibly several times per line.
|
|
Packit |
47b4ca |
while (/$prohibited/)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my $word = $1;
|
|
Packit |
47b4ca |
warn_forbidden ("$ARGV[$#ARGV]:$.", $word, %forbidden);
|
|
Packit |
47b4ca |
delete $prohibited{$word};
|
|
Packit |
47b4ca |
# If we're done, exit.
|
|
Packit |
47b4ca |
return
|
|
Packit |
47b4ca |
if ! %prohibited;
|
|
Packit |
47b4ca |
$prohibited = '\b(' . join ('|', keys %prohibited) . ')\b';
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
warn_forbidden ("$output:$prohibited{$_}", $_, %forbidden)
|
|
Packit |
47b4ca |
foreach (sort { $prohibited{$a} <=> $prohibited{$b} } keys %prohibited);
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
## --------------------- ##
|
|
Packit |
47b4ca |
## Handling the traces. ##
|
|
Packit |
47b4ca |
## --------------------- ##
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# $M4_MACRO
|
|
Packit |
47b4ca |
# trace_format_to_m4 ($FORMAT)
|
|
Packit |
47b4ca |
# ----------------------------
|
|
Packit |
47b4ca |
# Convert a trace $FORMAT into a M4 trace processing macro's body.
|
|
Packit |
47b4ca |
sub trace_format_to_m4 ($)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my ($format) = @_;
|
|
Packit |
47b4ca |
my $underscore = $_;
|
|
Packit |
47b4ca |
my %escape = (# File name.
|
|
Packit |
47b4ca |
'f' => '$1',
|
|
Packit |
47b4ca |
# Line number.
|
|
Packit |
47b4ca |
'l' => '$2',
|
|
Packit |
47b4ca |
# Depth.
|
|
Packit |
47b4ca |
'd' => '$3',
|
|
Packit |
47b4ca |
# Name (also available as $0).
|
|
Packit |
47b4ca |
'n' => '$4',
|
|
Packit |
47b4ca |
# Escaped dollar.
|
|
Packit |
47b4ca |
'$' => '$');
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
my $res = '';
|
|
Packit |
47b4ca |
$_ = $format;
|
|
Packit |
47b4ca |
while ($_)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
# $n -> $(n + 4)
|
|
Packit |
47b4ca |
if (s/^\$(\d+)//)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
$res .= "\$" . ($1 + 4);
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
# $x, no separator given.
|
|
Packit |
47b4ca |
elsif (s/^\$([fldn\$])//)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
$res .= $escape{$1};
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
# $.x or ${sep}x.
|
|
Packit |
47b4ca |
elsif (s/^\$\{([^}]*)\}([@*%])//
|
|
Packit |
47b4ca |
|| s/^\$(.?)([@*%])//)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
# $@, list of quoted effective arguments.
|
|
Packit |
47b4ca |
if ($2 eq '@')
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
$res .= ']at_at([' . ($1 ? $1 : ',') . '], $@)[';
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
# $*, list of unquoted effective arguments.
|
|
Packit |
47b4ca |
elsif ($2 eq '*')
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
$res .= ']at_star([' . ($1 ? $1 : ',') . '], $@)[';
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
# $%, list of flattened unquoted effective arguments.
|
|
Packit |
47b4ca |
elsif ($2 eq '%')
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
$res .= ']at_percent([' . ($1 ? $1 : ':') . '], $@)[';
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
elsif (/^(\$.)/)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
error "invalid escape: $1";
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
else
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
s/^([^\$]+)//;
|
|
Packit |
47b4ca |
$res .= $1;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
$_ = $underscore;
|
|
Packit |
47b4ca |
return '[[' . $res . ']]';
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# handle_traces($REQ, $OUTPUT, %TRACE)
|
|
Packit |
47b4ca |
# ------------------------------------
|
|
Packit |
47b4ca |
# We use M4 itself to process the traces. But to avoid name clashes when
|
|
Packit |
47b4ca |
# processing the traces, the builtins are disabled, and moved into `at_'.
|
|
Packit |
47b4ca |
# Actually, all the low level processing macros are in `at_' (and `_at_').
|
|
Packit |
47b4ca |
# To avoid clashes between user macros and `at_' macros, the macros which
|
|
Packit |
47b4ca |
# implement tracing are in `AT_'.
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# Having $REQ is needed to neutralize the macros which have been traced,
|
|
Packit |
47b4ca |
# but are not wanted now.
|
|
Packit |
47b4ca |
sub handle_traces ($$%)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my ($req, $output, %trace) = @_;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
verb "formatting traces for `$output': " . join (', ', sort keys %trace);
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Processing the traces.
|
|
Packit |
47b4ca |
my $trace_m4 = new Autom4te::XFile ("> " . open_quote ("$tmp/traces.m4"));
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
$_ = <<'EOF';
|
|
Packit |
47b4ca |
divert(-1)
|
|
Packit |
47b4ca |
changequote([, ])
|
|
Packit |
47b4ca |
# _at_MODE(SEPARATOR, ELT1, ELT2...)
|
|
Packit |
47b4ca |
# ----------------------------------
|
|
Packit |
47b4ca |
# List the elements, separating then with SEPARATOR.
|
|
Packit |
47b4ca |
# MODE can be:
|
|
Packit |
47b4ca |
# `at' -- the elements are enclosed in brackets.
|
|
Packit |
47b4ca |
# `star' -- the elements are listed as are.
|
|
Packit |
47b4ca |
# `percent' -- the elements are `flattened': spaces are singled out,
|
|
Packit |
47b4ca |
# and no new line remains.
|
|
Packit |
47b4ca |
define([_at_at],
|
|
Packit |
47b4ca |
[at_ifelse([$#], [1], [],
|
|
Packit |
47b4ca |
[$#], [2], [[[$2]]],
|
|
Packit |
47b4ca |
[[[$2]][$1]$0([$1], at_shift(at_shift($@)))])])
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
define([_at_percent],
|
|
Packit |
47b4ca |
[at_ifelse([$#], [1], [],
|
|
Packit |
47b4ca |
[$#], [2], [at_flatten([$2])],
|
|
Packit |
47b4ca |
[at_flatten([$2])[$1]$0([$1], at_shift(at_shift($@)))])])
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
define([_at_star],
|
|
Packit |
47b4ca |
[at_ifelse([$#], [1], [],
|
|
Packit |
47b4ca |
[$#], [2], [[$2]],
|
|
Packit |
47b4ca |
[[$2][$1]$0([$1], at_shift(at_shift($@)))])])
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# FLATTEN quotes its result.
|
|
Packit |
47b4ca |
# Note that the second pattern is `newline, tab or space'. Don't lose
|
|
Packit |
47b4ca |
# the tab!
|
|
Packit |
47b4ca |
define([at_flatten],
|
|
Packit |
47b4ca |
[at_patsubst(at_patsubst([[[$1]]], [\\\n]), [[\n\t ]+], [ ])])
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
define([at_args], [at_shift(at_shift(at_shift(at_shift(at_shift($@)))))])
|
|
Packit |
47b4ca |
define([at_at], [_$0([$1], at_args($@))])
|
|
Packit |
47b4ca |
define([at_percent], [_$0([$1], at_args($@))])
|
|
Packit |
47b4ca |
define([at_star], [_$0([$1], at_args($@))])
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
EOF
|
|
Packit |
47b4ca |
s/^ //mg;s/\\t/\t/mg;s/\\n/\n/mg;
|
|
Packit |
47b4ca |
print $trace_m4 $_;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# If you trace `define', then on `define([m4_exit], defn([m4exit])' you
|
|
Packit |
47b4ca |
# will produce
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# AT_define([m4sugar.m4], [115], [1], [define], [m4_exit], <m4exit>)
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# Since `<m4exit>' is not quoted, the outer m4, when processing
|
|
Packit |
47b4ca |
# `trace.m4' will exit prematurely. Hence, move all the builtins to
|
|
Packit |
47b4ca |
# the `at_' name space.
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
print $trace_m4 "# Copy the builtins.\n";
|
|
Packit |
47b4ca |
map { print $trace_m4 "define([at_$_], defn([$_]))\n" } @m4_builtin;
|
|
Packit |
47b4ca |
print $trace_m4 "\n";
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
print $trace_m4 "# Disable them.\n";
|
|
Packit |
47b4ca |
map { print $trace_m4 "at_undefine([$_])\n" } @m4_builtin;
|
|
Packit |
47b4ca |
print $trace_m4 "\n";
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Neutralize traces: we don't want traces of cached requests (%REQUEST).
|
|
Packit |
47b4ca |
print $trace_m4
|
|
Packit |
47b4ca |
"## -------------------------------------- ##\n",
|
|
Packit |
47b4ca |
"## By default neutralize all the traces. ##\n",
|
|
Packit |
47b4ca |
"## -------------------------------------- ##\n",
|
|
Packit |
47b4ca |
"\n";
|
|
Packit |
47b4ca |
print $trace_m4 "at_define([AT_$_], [at_dnl])\n"
|
|
Packit |
47b4ca |
foreach (sort keys %{$req->macro});
|
|
Packit |
47b4ca |
print $trace_m4 "\n";
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Implement traces for current requests (%TRACE).
|
|
Packit |
47b4ca |
print $trace_m4
|
|
Packit |
47b4ca |
"## ------------------------- ##\n",
|
|
Packit |
47b4ca |
"## Trace processing macros. ##\n",
|
|
Packit |
47b4ca |
"## ------------------------- ##\n",
|
|
Packit |
47b4ca |
"\n";
|
|
Packit |
47b4ca |
foreach (sort keys %trace)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
# Trace request can be embed \n.
|
|
Packit |
47b4ca |
(my $comment = "Trace $_:$trace{$_}") =~ s/^/\# /;
|
|
Packit |
47b4ca |
print $trace_m4 "$comment\n";
|
|
Packit |
47b4ca |
print $trace_m4 "at_define([AT_$_],\n";
|
|
Packit |
47b4ca |
print $trace_m4 trace_format_to_m4 ($trace{$_}) . ")\n\n";
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
print $trace_m4 "\n";
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Reenable output.
|
|
Packit |
47b4ca |
print $trace_m4 "at_divert(0)at_dnl\n";
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Transform the traces from m4 into an m4 input file.
|
|
Packit |
47b4ca |
# Typically, transform:
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# | m4trace:configure.ac:3: -1- AC_SUBST([exec_prefix], [NONE])
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# into
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# | AT_AC_SUBST([configure.ac], [3], [1], [AC_SUBST], [exec_prefix], [NONE])
|
|
Packit |
47b4ca |
#
|
|
Packit |
47b4ca |
# Pay attention that the file name might include colons, if under DOS
|
|
Packit |
47b4ca |
# for instance, so we don't use `[^:]+'.
|
|
Packit |
47b4ca |
my $traces = new Autom4te::XFile ("< " . open_quote ($tcache . $req->id));
|
|
Packit |
47b4ca |
while ($_ = $traces->getline)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
# Trace with arguments, as the example above. We don't try
|
|
Packit |
47b4ca |
# to match the trailing parenthesis as it might be on a
|
|
Packit |
47b4ca |
# separate line.
|
|
Packit |
47b4ca |
s{^m4trace:(.+):(\d+): -(\d+)- ([^(]+)\((.*)$}
|
|
Packit |
47b4ca |
{AT_$4([$1], [$2], [$3], [$4], $5};
|
|
Packit |
47b4ca |
# Traces without arguments, always on a single line.
|
|
Packit |
47b4ca |
s{^m4trace:(.+):(\d+): -(\d+)- ([^)]*)\n$}
|
|
Packit |
47b4ca |
{AT_$4([$1], [$2], [$3], [$4])\n};
|
|
Packit |
47b4ca |
print $trace_m4 "$_";
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
$trace_m4->close;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
my $in = new Autom4te::XFile ("$m4 " . shell_quote ("$tmp/traces.m4") . " |");
|
|
Packit |
47b4ca |
my $out = new Autom4te::XFile ("> " . open_quote ($output));
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# This is dubious: should we really transform the quadrigraphs in
|
|
Packit |
47b4ca |
# traces? It might break balanced [ ] etc. in the output. The
|
|
Packit |
47b4ca |
# consensus seems to be that traces are more useful this way.
|
|
Packit |
47b4ca |
while ($_ = $in->getline)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
# It makes no sense to try to transform __oline__.
|
|
Packit |
47b4ca |
s/\@<:\@/[/g;
|
|
Packit |
47b4ca |
s/\@:>\@/]/g;
|
|
Packit |
47b4ca |
s/\@\{:\@/(/g;
|
|
Packit |
47b4ca |
s/\@:\}\@/)/g;
|
|
Packit |
47b4ca |
s/\@S\|\@/\$/g;
|
|
Packit |
47b4ca |
s/\@%:\@/#/g;
|
|
Packit |
47b4ca |
s/\@&t\@//g;
|
|
Packit |
47b4ca |
print $out $_;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# $BOOL
|
|
Packit |
47b4ca |
# up_to_date ($REQ)
|
|
Packit |
47b4ca |
# -----------------
|
|
Packit |
47b4ca |
# Are the cache files of $REQ up to date?
|
|
Packit |
47b4ca |
# $REQ is `valid' if it corresponds to the request and exists, which
|
|
Packit |
47b4ca |
# does not mean it is up to date. It is up to date if, in addition,
|
|
Packit |
47b4ca |
# its files are younger than its dependencies.
|
|
Packit |
47b4ca |
sub up_to_date ($)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my ($req) = @_;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
return 0
|
|
Packit |
47b4ca |
if ! $req->valid;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
my $tfile = $tcache . $req->id;
|
|
Packit |
47b4ca |
my $ofile = $ocache . $req->id;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# We can't answer properly if the traces are not computed since we
|
|
Packit |
47b4ca |
# need to know what other files were included. Actually, if any of
|
|
Packit |
47b4ca |
# the cache files is missing, we are not up to date.
|
|
Packit |
47b4ca |
return 0
|
|
Packit |
47b4ca |
if ! -f $tfile || ! -f $ofile;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# The youngest of the cache files must be older than the oldest of
|
|
Packit |
47b4ca |
# the dependencies.
|
|
Packit |
47b4ca |
my $tmtime = mtime ($tfile);
|
|
Packit |
47b4ca |
my $omtime = mtime ($ofile);
|
|
Packit |
47b4ca |
my ($file, $mtime) = ($tmtime < $omtime
|
|
Packit |
47b4ca |
? ($ofile, $omtime) : ($tfile, $tmtime));
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# We depend at least upon the arguments.
|
|
Packit |
47b4ca |
my @dep = @ARGV;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# stdin is always out of date.
|
|
Packit |
47b4ca |
if (grep { $_ eq '-' } @dep)
|
|
Packit |
47b4ca |
{ return 0 }
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Files may include others. We can use traces since we just checked
|
|
Packit |
47b4ca |
# if they are available.
|
|
Packit |
47b4ca |
handle_traces ($req, "$tmp/dependencies",
|
|
Packit |
47b4ca |
('include' => '$1',
|
|
Packit |
47b4ca |
'm4_include' => '$1'));
|
|
Packit |
47b4ca |
my $deps = new Autom4te::XFile ("< " . open_quote ("$tmp/dependencies"));
|
|
Packit |
47b4ca |
while ($_ = $deps->getline)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
chomp;
|
|
Packit |
47b4ca |
my $file = find_file ("$_?", @include);
|
|
Packit |
47b4ca |
# If a file which used to be included is no longer there, then
|
|
Packit |
47b4ca |
# don't say it's missing (it might no longer be included). But
|
|
Packit |
47b4ca |
# of course, that causes the output to be outdated (as if the
|
|
Packit |
47b4ca |
# time stamp of that missing file was newer).
|
|
Packit |
47b4ca |
return 0
|
|
Packit |
47b4ca |
if ! $file;
|
|
Packit |
47b4ca |
push @dep, $file;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# If $FILE is younger than one of its dependencies, it is outdated.
|
|
Packit |
47b4ca |
return up_to_date_p ($file, @dep);
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
## ---------- ##
|
|
Packit |
47b4ca |
## Freezing. ##
|
|
Packit |
47b4ca |
## ---------- ##
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# freeze ($OUTPUT)
|
|
Packit |
47b4ca |
# ----------------
|
|
Packit |
47b4ca |
sub freeze ($)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my ($output) = @_;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# When processing the file with diversion disabled, there must be no
|
|
Packit |
47b4ca |
# output but comments and empty lines.
|
|
Packit |
47b4ca |
my $result = xqx ("$m4"
|
|
Packit |
47b4ca |
. ' --fatal-warning'
|
|
Packit |
47b4ca |
. join (' --include=', '', map { shell_quote ($_) } @include)
|
|
Packit |
47b4ca |
. ' --define=divert'
|
|
Packit |
47b4ca |
. " " . files_to_options (@ARGV)
|
|
Packit |
47b4ca |
. '
|
|
Packit |
47b4ca |
$result =~ s/#.*\n//g;
|
|
Packit |
47b4ca |
$result =~ s/^\n//mg;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
fatal "freezing produced output:\n$result"
|
|
Packit |
47b4ca |
if $result;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# If freezing produces output, something went wrong: a bad `divert',
|
|
Packit |
47b4ca |
# or an improper paren etc.
|
|
Packit |
47b4ca |
xsystem ("$m4"
|
|
Packit |
47b4ca |
. ' --fatal-warning'
|
|
Packit |
47b4ca |
. join (' --include=', '', map { shell_quote ($_) } @include)
|
|
Packit |
47b4ca |
. " --freeze-state=" . shell_quote ($output)
|
|
Packit |
47b4ca |
. " " . files_to_options (@ARGV)
|
|
Packit |
47b4ca |
. '
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
## -------------- ##
|
|
Packit |
47b4ca |
## Main program. ##
|
|
Packit |
47b4ca |
## -------------- ##
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
mktmpdir ('am4t');
|
|
Packit |
47b4ca |
load_configuration ($ENV{'AUTOM4TE_CFG'} || "$pkgdatadir/autom4te.cfg");
|
|
Packit |
47b4ca |
load_configuration ("$ENV{'HOME'}/.autom4te.cfg")
|
|
Packit |
47b4ca |
if exists $ENV{'HOME'} && -f "$ENV{'HOME'}/.autom4te.cfg";
|
|
Packit |
47b4ca |
load_configuration (".autom4te.cfg")
|
|
Packit |
47b4ca |
if -f ".autom4te.cfg";
|
|
Packit |
47b4ca |
parse_args;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Freezing does not involve the cache.
|
|
Packit |
47b4ca |
if ($freeze)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
freeze ($output);
|
|
Packit |
47b4ca |
exit $exit_code;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# We need our cache directory. Don't fail with parallel creation.
|
|
Packit |
47b4ca |
if (! -d "$cache")
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
mkdir "$cache", 0755
|
|
Packit |
47b4ca |
or -d "$cache"
|
|
Packit |
47b4ca |
or fatal "cannot create $cache: $!";
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Open the index for update, and lock it. autom4te handles several
|
|
Packit |
47b4ca |
# files, but the index is the first and last file to be updated, so
|
|
Packit |
47b4ca |
# locking it is sufficient.
|
|
Packit |
47b4ca |
$icache_file = new Autom4te::XFile $icache, O_RDWR|O_CREAT;
|
|
Packit |
47b4ca |
$icache_file->lock (LOCK_EX)
|
|
Packit |
47b4ca |
if ($flock_implemented eq "yes");
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Read the cache index if available and older than autom4te itself.
|
|
Packit |
47b4ca |
# If autom4te is younger, then some structures such as C4che might
|
|
Packit |
47b4ca |
# have changed, which would corrupt its processing.
|
|
Packit |
47b4ca |
Autom4te::C4che->load ($icache_file)
|
|
Packit |
47b4ca |
if -f $icache && mtime ($icache) > mtime ($0);
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Add the new trace requests.
|
|
Packit |
47b4ca |
my $req = Autom4te::C4che->request ('input' => \@ARGV,
|
|
Packit |
47b4ca |
'path' => \@include,
|
|
Packit |
47b4ca |
'macro' => [keys %trace, @preselect]);
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# If $REQ's cache files are not up to date, or simply if the user
|
|
Packit |
47b4ca |
# discarded them (-f), declare it invalid.
|
|
Packit |
47b4ca |
$req->valid (0)
|
|
Packit |
47b4ca |
if $force || ! up_to_date ($req);
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# We now know whether we can trust the Request object. Say it.
|
|
Packit |
47b4ca |
verb "the trace request object is:\n" . $req->marshall;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# We need to run M4 if (i) the user wants it (--force), (ii) $REQ is
|
|
Packit |
47b4ca |
# invalid.
|
|
Packit |
47b4ca |
handle_m4 ($req, keys %{$req->macro})
|
|
Packit |
47b4ca |
if $force || ! $req->valid;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Issue the warnings each time autom4te was run.
|
|
Packit |
47b4ca |
my $separator = "\n" . ('-' x 25) . " END OF WARNING " . ('-' x 25) . "\n\n";
|
|
Packit |
47b4ca |
handle_traces ($req, "$tmp/warnings",
|
|
Packit |
47b4ca |
('_m4_warn' => "\$1::\$f:\$l::\$2::\$3$separator"));
|
|
Packit |
47b4ca |
# Swallow excessive newlines.
|
|
Packit |
47b4ca |
for (split (/\n*$separator\n*/o, contents ("$tmp/warnings")))
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
# The message looks like:
|
|
Packit |
47b4ca |
# | syntax::input.as:5::ouch
|
|
Packit |
47b4ca |
# | ::input.as:4: baz is expanded from...
|
|
Packit |
47b4ca |
# | input.as:2: bar is expanded from...
|
|
Packit |
47b4ca |
# | input.as:3: foo is expanded from...
|
|
Packit |
47b4ca |
# | input.as:5: the top level
|
|
Packit |
47b4ca |
# In particular, m4_warn guarantees that either $stackdump is empty, or
|
|
Packit |
47b4ca |
# it consists of lines where only the last line ends in "top level".
|
|
Packit |
47b4ca |
my ($cat, $loc, $msg, $stacktrace) = split ('::', $_, 4);
|
|
Packit |
47b4ca |
msg $cat, $loc, "warning: $msg",
|
|
Packit |
47b4ca |
partial => ($stacktrace =~ /top level$/) + 0;
|
|
Packit |
47b4ca |
for (split /\n/, $stacktrace)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
my ($loc, $trace) = split (': ', $_, 2);
|
|
Packit |
47b4ca |
msg $cat, $loc, $trace, partial => ($trace !~ /top level$/) + 0;
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# Now output...
|
|
Packit |
47b4ca |
if (%trace)
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
# Always produce traces, since even if the output is young enough,
|
|
Packit |
47b4ca |
# there is no guarantee that the traces use the same *format*
|
|
Packit |
47b4ca |
# (e.g., `-t FOO:foo' and `-t FOO:bar' are both using the same M4
|
|
Packit |
47b4ca |
# traces, hence the M4 traces cache is usable, but its formatting
|
|
Packit |
47b4ca |
# will yield different results).
|
|
Packit |
47b4ca |
handle_traces ($req, $output, %trace);
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
else
|
|
Packit |
47b4ca |
{
|
|
Packit |
47b4ca |
# Actual M4 expansion, if the user wants it, or if $output is old
|
|
Packit |
47b4ca |
# (STDOUT is pretty old).
|
|
Packit |
47b4ca |
handle_output ($req, $output)
|
|
Packit |
47b4ca |
if $force || mtime ($output) < mtime ($ocache . $req->id);
|
|
Packit |
47b4ca |
}
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
# If we ran up to here, the cache is valid.
|
|
Packit |
47b4ca |
$req->valid (1);
|
|
Packit |
47b4ca |
Autom4te::C4che->save ($icache_file);
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
exit $exit_code;
|
|
Packit |
47b4ca |
|
|
Packit |
47b4ca |
### Setup "GNU" style for perl-mode and cperl-mode.
|
|
Packit |
47b4ca |
## Local Variables:
|
|
Packit |
47b4ca |
## perl-indent-level: 2
|
|
Packit |
47b4ca |
## perl-continued-statement-offset: 2
|
|
Packit |
47b4ca |
## perl-continued-brace-offset: 0
|
|
Packit |
47b4ca |
## perl-brace-offset: 0
|
|
Packit |
47b4ca |
## perl-brace-imaginary-offset: 0
|
|
Packit |
47b4ca |
## perl-label-offset: -2
|
|
Packit |
47b4ca |
## cperl-indent-level: 2
|
|
Packit |
47b4ca |
## cperl-brace-offset: 0
|
|
Packit |
47b4ca |
## cperl-continued-brace-offset: 0
|
|
Packit |
47b4ca |
## cperl-label-offset: -2
|
|
Packit |
47b4ca |
## cperl-extra-newline-before-brace: t
|
|
Packit |
47b4ca |
## cperl-merge-trailing-else: nil
|
|
Packit |
47b4ca |
## cperl-continued-statement-offset: 2
|
|
Packit |
47b4ca |
## End:
|