This is the mail archive of the automake@gnu.org mailing list for the automake project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

15-file-contents-paragraph.patch


Index: ChangeLog
from  Akim Demaille  <akim@epita.fr>
	
	* 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:


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]