+2000-06-16 Akim Demaille <akim@epita.fr>
+
+ The test suite reveals AC_OUTPUT_MAKE_DEFS fails on RISC/OS.
+
+ * acgeneral.m4 (AC_OUTPUT_MAKE_DEFS) <confdef2opt.sed>: Reset the
+ t flag between each cycle.
+ * doc/autoconf.texi (Limitations of Usual Tools): Some about the t
+ flag in sed.
+
2000-06-16 Akim Demaille <akim@epita.fr>
* acspecific.m4 (AC_EXEEXT, AC_OBJEXT): Don't obsolete them, let
# take arguments), then we branch to the cleanup section. Otherwise,
# look for a macro that doesn't take arguments.
cat >confdef2opt.sed <<\EOF
+t clear
+: clear
s%^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)%-D\1=\2%g
t cleanup
s%^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)%-D\1=\2%g
# config.status. Protect against being in an unquoted here document
# in config.status.
rm -f conftest.defines conftest.undefs
-dnl Using a here document instead of a string reduces the quoting nightmare.
-dnl Putting comments in sed scripts is not portable.
-dnl
-dnl There are two labels in the following scripts, `cleanup' and `clear'.
-dnl
-dnl `cleanup' is used to avoid that the second main sed command (meant for
-dnl 0-ary CPP macros) applies to n-ary macro definitions. So we use
-dnl `t cleanup' to jump over the second main sed command when it succeeded.
-dnl
-dnl But because in sed the `t' flag is set when there is a substitution
-dnl that succeeded before, and not *right* before (i.e., included the
-dnl first two small commands), we need to clear the `t' flag. This is the
-dnl purpose of `t clear; : clear'.
-dnl
-dnl Additionally, this works around a bug of IRIX' sed which does not
-dnl clear the `t' flag between two cycles.
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `cleanup' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions. So we use
+# `t cleanup' to jump over the second main sed command when it succeeded.
+# See the Autoconf documentation for `clear'.
cat >confdef2sed.sed <<\EOF
dnl Double quote for `[ ]' and `define'.
[s/[\\&%]/\\&/g
@item @command{sed}
@cindex @command{sed}
-@code{sed} scripts should not use branch labels longer than 8 characters
-and should not contain comments.
+@command{sed} scripts should not use branch labels longer than 8
+characters and should not contain comments.
-@code{sed} input should have reasonably long lines, since some
-@code{sed} have an input buffer limited to 4000 bytes.
+@command{sed} input should have reasonably long lines, since some
+@command{sed} have an input buffer limited to 4000 bytes.
Alternation, @samp{\|}, is common but not portable.
-Nested groups are extremely portable, but there is at least one sed
-(System V/68 Base Operating System R3V7.1) which does not support it.
+Nested groups are extremely portable, but there is at least one
+@command{sed} (System V/68 Base Operating System R3V7.1) which does not
+support it.
+
+@item @command{sed} (@samp{t})
+@cindex @command{sed} (@samp{t})
+Some old systems have @command{sed} which ``forget'' to reset their
+@samp{t} flag when starting a new cycle. For instance on @sc{mips
+risc/os}, and on @sc{irix} 5.3, if you run the following @command{sed}
+script (the line numbers are not actual part of the texts):
+
+@example
+s/keep me/kept/g # a
+t end # b
+s/.*/deleted/g # c
+: end # d
+@end example
+
+@noindent
+on
+
+@example
+delete me # 1
+delete me # 2
+keep me # 3
+delete me # 4
+@end example
+
+@noindent
+you get
+
+@example
+deleted
+delete me
+kept
+deleted
+@end example
+
+@noindent
+instead of
+
+@example
+deleted
+deleted
+kept
+deleted
+@end example
+
+Why? When processing 1, a matches, therefore sets the t flag, b jumps to
+d, and the output is produced. When processing line 2, the t flag is
+still set (this is the bug). Line a fails to match, but @command{sed}
+is not supposed to clear the t flag when a substitution fails. Line b
+sees that the flag is set, therefore it clears it, and jumps to d, hence
+you get @samp{delete me} instead of @samp{deleted}. When processing 3 t
+is clear, a matches, so the flag is set, hence b clears the flags and
+jumps. Finally, since the flag is clear, 4 is processed properly.
+
+There are two things one should remind about @samp{t} in @command{sed}.
+Firstly, always remember that @samp{t} jumps if @emph{some} substitution
+succeeded, not only the immediately preceding substitution, therefore,
+always use a fake @samp{t clear; : clear} to reset the t flag where
+indeed.
+
+Secondly, you cannot rely on @command{sed} to clear the flag at each new
+cycle.
+
+One portable implementation of the script above is:
+
+@example
+t clear
+: clear
+s/keep me/kept/g
+t end
+s/.*/deleted/g
+: end
+@end example
@end table
# take arguments), then we branch to the cleanup section. Otherwise,
# look for a macro that doesn't take arguments.
cat >confdef2opt.sed <<\EOF
+t clear
+: clear
s%^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)%-D\1=\2%g
t cleanup
s%^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)%-D\1=\2%g
# config.status. Protect against being in an unquoted here document
# in config.status.
rm -f conftest.defines conftest.undefs
-dnl Using a here document instead of a string reduces the quoting nightmare.
-dnl Putting comments in sed scripts is not portable.
-dnl
-dnl There are two labels in the following scripts, `cleanup' and `clear'.
-dnl
-dnl `cleanup' is used to avoid that the second main sed command (meant for
-dnl 0-ary CPP macros) applies to n-ary macro definitions. So we use
-dnl `t cleanup' to jump over the second main sed command when it succeeded.
-dnl
-dnl But because in sed the `t' flag is set when there is a substitution
-dnl that succeeded before, and not *right* before (i.e., included the
-dnl first two small commands), we need to clear the `t' flag. This is the
-dnl purpose of `t clear; : clear'.
-dnl
-dnl Additionally, this works around a bug of IRIX' sed which does not
-dnl clear the `t' flag between two cycles.
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `cleanup' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions. So we use
+# `t cleanup' to jump over the second main sed command when it succeeded.
+# See the Autoconf documentation for `clear'.
cat >confdef2sed.sed <<\EOF
dnl Double quote for `[ ]' and `define'.
[s/[\\&%]/\\&/g