2006-12-05 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
+ * lib/autoconf/status.m4 (_AC_OUTPUT_FILES_PREPARE): When
+ creating the awk substitution script, handle one input line at a
+ time, so that the maximum length of a substituted (multi-line)
+ value is not limited by the size of the sed pattern space.
+ The trade-off is a slightly repetitive sed script.
+ * doc/autoconf.texi (Limitations of Usual Tools): Branch labels
+ can only have up to 7 characters, due to Solaris 10 /bin/sed.
+ * tests/torture.at (Substitute a 2000-byte string): Increase the
+ test with several long lines, they should not be caught by sed
+ limits any more.
+
* tests/tools.at (autom4te preselections): New test, to flag
entries missing from autom4te.cfg.
Report by David Byron <dbyron@hheld.com>.
Unicos 9 @command{sed} loops endlessly on patterns like @samp{.*\n.*}.
-Sed scripts should not use branch labels longer than 8 characters and
+Sed scripts should not use branch labels longer than 7 characters and
should not contain comments. @acronym{HP-UX} sed has a limit of 99 commands
(not counting @samp{:} commands) and
48 labels, which can not be circumvented by using more than one script
fi
dnl Initialize an awk array of substitutions, keyed by variable name.
dnl
-dnl First read a whole (potentially multi-line) substitution,
-dnl and construct `S["VAR"]='. Then, split it into pieces that fit
-dnl in an awk literal. Each piece then gets active characters escaped
-dnl (if we escape earlier we risk splitting inside an escape sequence).
+dnl The initial line contains the variable name VAR, then a `!'.
+dnl Construct `S["VAR"]=' from it.
+dnl The rest of the line, and potentially further lines, contain the
+dnl substituted value; the last of those ends with $ac_delim. We split
+dnl the output both along those substituted newlines and at intervals of
+dnl length _AC_AWK_LITERAL_LIMIT. The latter is done to comply with awk
+dnl string literal limitations, the former for simplicity in doing so.
+dnl
+dnl We deal with one input line at a time to avoid sed pattern space
+dnl limitations. We kill the delimiter $ac_delim before splitting the
+dnl string (otherwise we risk splitting the delimiter). And we do the
+dnl splitting before the quoting of awk special characters (otherwise we
+dnl risk splitting an escape sequence).
+dnl
dnl Output as separate string literals, joined with backslash-newline.
dnl Eliminate the newline after `=' in a second script, for readability.
dnl
[cat >>$CONFIG_STATUS <<_ACEOF
cat >>"\$tmp/subs.awk" <<\CEOF$ac_eof
_ACEOF
-sed '
-t line
-:line
-s/'"$ac_delim"'$//; t gotline
-N; b line
-:gotline
+sed -n '
h
-s/^/S["/; s/!.*/"]=/; p
+s/^/S["/; s/!.*/"]=/
+p
g
s/^[^!]*!//
-:more
-t more
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{]_AC_AWK_LITERAL_LIMIT[\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{]_AC_AWK_LITERAL_LIMIT[\}//
+t nl
+:delim
h
s/\(.\{]_AC_AWK_LITERAL_LIMIT[\}\).*/\1/
-t notlast
-s/["\\]/\\&/g; s/\n/\\n/g
-s/^/"/; s/$/"/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
b
-:notlast
-s/["\\]/\\&/g; s/\n/\\n/g
-s/^/"/; s/$/"\\/
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
p
g
s/.\{]_AC_AWK_LITERAL_LIMIT[\}//
-b more
+t delim
' <conf$$subs.awk | sed '
/^[^"]/{
N
# sed dumps core around 8 KiB. However, POSIX says that sed need not
# handle lines longer than 2048 bytes (including the trailing newline).
# So we'll just test a 2000-byte value, and for awk, we test a line with
-# almost 1000 words, and one variable with 4 lines of 500 bytes each.
+# almost 1000 words, and one variable with 5 lines of 2000 bytes each:
+# multi-line values should allow to get around the limitations.
AT_SETUP([Substitute a 2000-byte string])
AC_CONFIG_AUX_DIR($top_srcdir/build-aux)
AC_SUBST([foo], ]m4_for([n], 1, 100,, ....................)[)
AC_SUBST([bar], "]m4_for([n], 1, 100,, @ @ @ @ @ @ @ @ @ @@)[")
-AC_SUBST([baz], "]m4_for([n], 1, 4,, m4_for([m], 1, 25,, ... ... ... ... ....)
+AC_SUBST([baz], "]m4_for([n], 1, 5,, m4_for([m], 1, 100,, ... ... ... ... ....)
)[")
AC_PROG_AWK
AC_CONFIG_FILES([Foo Bar Baz])
)
AT_CHECK([cat Bar], 0, m4_for([n], 1, 100,, @ @ @ @ @ @ @ @ @ @@)
)
- AT_CHECK([cat Baz], 0, m4_for([n], 1, 4,, m4_for([m], 1, 25,, ... ... ... ... ....)
+ AT_CHECK([cat Baz], 0, m4_for([n], 1, 5,, m4_for([m], 1, 100,, ... ... ... ... ....)
)
)
done