Index: ChangeLog
from Akim Demaille <[EMAIL PROTECTED]>
* automake.in (file_contents): Rewrite: instead of trying to parse
it line by line, first swallow it completely into $CONTENTS,
*then*, parse it *paragraph* by paragraph.
Index: automake.in
--- automake.in Wed, 31 Jan 2001 00:08:51 +0100 akim (am/f/39_automake.i 1.20 755)
+++ automake.in Wed, 31 Jan 2001 01:41:47 +0100 akim (am/f/39_automake.i 1.20 755)
@@ -40,7 +40,8 @@
$IGNORE_PATTERN = "^##([^#].*)?\$";
$WHITE_PATTERN = "^[ \t]*\$";
$COMMENT_PATTERN = "^#";
-$RULE_PATTERN = "^([\$a-zA-Z_.][-.a-zA-Z0-9_(){}/\$]*) *:([^=].*|)\$";
+$TARGET_PATTERN="[\$a-zA-Z_.][-.a-zA-Z0-9_(){}/\$]*";
+$RULE_PATTERN = "^($TARGET_PATTERN) *:([^=].*|)\$";
$SUFFIX_RULE_PATTERN = "^\\.([a-zA-Z0-9]+)\\.([a-zA-Z0-9]+)\$";
# Only recognize leading spaces, not leading tabs. If we recognize
# leading tabs here then we need to make the reader smarter, because
@@ -6991,13 +6992,9 @@ sub file_contents
# Looks stupid?
# print "automake: reading $file\n" if $verbose;
- local ($was_rule) = 0;
- local ($result_vars) = '';
- local ($result_rules) = '';
- local ($comment) = '';
- local ($spacing) = "\n";
- local ($skipping) = 0;
- local ($had_chars);
+ # Swallow into $CONTENTS the whole content of the file, after
+ # having performed the $COMMAND, and removed Automake comments.
+ local ($contents) = '';
while (<FC_FILE>)
{
@@ -7005,7 +7002,7 @@ sub file_contents
unless $seen_maint_mode;
$had_chars = length ($_) && $_ ne "\n";
- eval $command;
+ eval $command;
# If the transform caused all the characters to go away, then
# ignore the line. Why do this? Because in Perl 4, a "next"
# inside of an eval doesn't affect a loop outside the eval.
@@ -7014,76 +7011,83 @@ sub file_contents
# newline.
next if $had_chars && ($_ eq '' || $_ eq "\n");
- if (/$IGNORE_PATTERN/o)
- {
- # Merely delete comments beginning with two hashes.
- }
- elsif (/$WHITE_PATTERN/o)
- {
- # Stick a single white line before the incoming macro or rule.
- $spacing = "\n";
- &am_line_error ($., "blank line following trailing backslash")
- if $saw_bk;
- }
- elsif (/$COMMENT_PATTERN/o)
- {
- # Stick comments before the incoming macro or rule.
- $comment .= $spacing . $_;
- $spacing = '';
- &am_line_error ($., "comment following trailing backslash")
- if $saw_bk;
- }
- elsif ($saw_bk)
- {
- if ($was_rule)
- {
- $result_rules .= $_ if ! $skipping;
- }
- else
- {
- $result_vars .= $_ if ! $skipping;
- }
- $saw_bk = /\\$/;
- }
- elsif (/^.PHONY: (.*)$/)
- {
- # Having a special case for PHONY upstream seems much easier than
- # trying to have it fit in RULE_PATTERN and extract it later.
- push (@phony, split (/\s+/, $1));
- }
- elsif (/$RULE_PATTERN/o)
- {
- # Found a rule.
- $was_rule = 1;
- $skipping = defined $contents{$1};
- $result_rules .= $comment . $spacing . $_ if ! $skipping;
- $comment = $spacing = '';
- $saw_bk = /\\$/;
- }
- elsif (/$MACRO_PATTERN/o)
- {
- # Found a variable reference.
- $was_rule = 0;
- $skipping = defined $contents{$1};
- $result_vars .= $comment . $spacing . $_ if ! $skipping;
- $comment = $spacing = '';
- $saw_bk = /\\$/;
- &prog_error (".am macro \`$1' with trailing backslash at $file:$.")
- if $saw_bk;
- $am_var_defs{$1} = $3;
- }
- else
- {
- # This isn't an error; it is probably a continued rule.
- # In fact, this is what we assume.
- $was_rule = 1;
- $result_rules .= $comment . $spacing . $_ if ! $skipping;
- $comment = $spacing = '';
- $saw_bk = /\\$/;
- }
+ # Merely delete comments beginning with two hashes.
+ next if /$IGNORE_PATTERN/o;
+
+ $contents .= $_;
}
close (FC_FILE);
+
+ # We don't need more than two consecutive new-lines.
+ $contents =~ s/\n{3,}/\n\n/g;
+
+ # Process each Make `paragraph'.
+ #
+ # A Make `paragraph' is delimited by a new line which is not
+ # escaped, and not followed by a tab or a comment.
+ #
+ # Frankly, unless you like fighting with Perl (you're a freak!),
+ # if I were you I would not try some other implementation, it's
+ # very easy falling either into extremely low RE matching
+ # (backtracking...), or worse yet: infloop... For instance, (my)
+ # perl goes loopy if you try to
+ #
+ # $result_rules =~ /^($TARGET_PATTERN *)+: ($TARGET_PATTERN *)+\n\n/sm
+ local ($result_vars) = '';
+ local ($result_rules) = '';
+ local ($comment) = '';
+ foreach (split (/(?<!\\)\n(?![\t#])/, $contents))
+ {
+ &am_file_error ("$basename.am",
+ "blank line following trailing backslash:\n$_")
+ if /\\$/;
+ &am_file_error ("$basename.am",
+ "comment following trailing backslash:\n$_")
+ if /\\#/;
+
+ if (/^$/)
+ {
+ # Stick empty line before the incoming macro or rule.
+ $separator = "\n";
+ }
+ elsif (/$COMMENT_PATTERN/mso)
+ {
+ # Stick comments before the incoming macro or rule.
+ $comment = $_;
+ }
+ elsif (/^\.PHONY: (.*)$/mso)
+ {
+ # Having a special case for PHONY upstream seems much easier than
+ # trying to have it fit in RULE_PATTERN and extract it later.
+ push (@phony, split (/\s/, $1));
+ }
+ elsif (/$RULE_PATTERN/mso)
+ {
+ $result_rules .= "$comment$separator$_\n"
+ unless defined $contents{$1};
+ $comment = $separator = '';
+ }
+ elsif (/$MACRO_PATTERN/mso)
+ {
+ $result_vars .= "$comment$separator$_\n"
+ unless defined $contents{$1};
+ $comment = $separator = '';
+ &prog_error (".am macro \`$1' with trailing backslash at $file:$.")
+ if /\\$/;;
+ $am_var_defs{$1} = $3;
+ }
+ else
+ {
+ # This isn't an error; it is probably some tokens which
+ # configure is supposed to replace, such as `@SET_MAKE@'.
+ $result_rules .= "$comment$separator$_\n";
+ $comment = $separator = '';
+ }
+ }
+
+# print STDERR "result_vars: $result_vars\n";
+# print STDERR "result_rules: $result_rules\n";
return $result_vars . $result_rules . $comment;
}
@@ -7833,6 +7837,17 @@ sub my_glob
sub am_error
{
warn "automake: ${am_file}.am: @_\n";
+ $exit_status = 1;
+}
+
+
+# am_file_error ($FILE, @ARGS)
+# ----------------------------
+sub am_file_error
+{
+ my ($file, @args) = @_;
+
+ warn "$file: @args\n";
$exit_status = 1;
}
Index: tests/Makefile.in
--- tests/Makefile.in Wed, 31 Jan 2001 00:08:51 +0100 akim (am/h/14_Makefile.i 1.1 644)
+++ tests/Makefile.in Wed, 31 Jan 2001 01:39:39 +0100 akim (am/h/14_Makefile.i 1.1 644)
@@ -492,7 +492,7 @@
info-am install install-am install-data install-data-am install-exec \
install-exec-am install-strip installcheck installcheck-am installdirs \
maintainer-clean maintainer-clean-generic mostlyclean \
-mostlyclean-generic tags uninstall uninstall-am
+mostlyclean-generic uninstall uninstall-am
distclean-local:
Index: m4/Makefile.in
--- m4/Makefile.in Wed, 31 Jan 2001 00:08:51 +0100 akim (am/h/15_Makefile.i 1.1 644)
+++ m4/Makefile.in Wed, 31 Jan 2001 01:39:38 +0100 akim (am/h/15_Makefile.i 1.1 644)
@@ -197,7 +197,7 @@
install-am install-data install-data-am install-exec install-exec-am \
install-m4dataDATA install-strip installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic mostlyclean \
-mostlyclean-generic tags uninstall uninstall-am uninstall-m4dataDATA
+mostlyclean-generic uninstall uninstall-am uninstall-m4dataDATA
# Tell versions [3.59,3.63) of GNU make to not export all variables.
Index: Makefile.in
--- Makefile.in Wed, 31 Jan 2001 00:08:51 +0100 akim (am/h/16_Makefile.i 1.1 644)
+++ Makefile.in Wed, 31 Jan 2001 01:39:38 +0100 akim (am/h/16_Makefile.i 1.1 644)
@@ -360,7 +360,6 @@
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
-
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
@@ -602,7 +601,7 @@
maintainer-clean: maintainer-clean-recursive
-rm -f config.status
-.PHONY: all all-am all-recursive all-redirect check check-am \
+.PHONY: all all-am all-recursive all-redirect check check-am \
check-recursive clean clean-aminfo clean-generic clean-recursive \
clean-tags clean-vti distclean distclean-aminfo distclean-generic \
distclean-recursive distclean-tags distclean-vti distdir dvi dvi-am \
@@ -617,10 +616,8 @@
maintainer-clean-tags maintainer-clean-vti mostlyclean \
mostlyclean-aminfo mostlyclean-generic mostlyclean-recursive \
mostlyclean-tags mostlyclean-vti tags tags-recursive uninstall \
-uninstall-am uninstall-binSCRIPTS uninstall-data-recursive \
-uninstall-dist_pkgdataDATA uninstall-dist_scriptDATA \
-uninstall-exec-recursive uninstall-info uninstall-recursive \
-uninstalldirs-recursive
+uninstall-am uninstall-binSCRIPTS uninstall-dist_pkgdataDATA \
+uninstall-dist_scriptDATA uninstall-info uninstall-recursive
install-data-hook: