]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Honor properly the `#define' config.h.in templates.
authorAkim Demaille <akim@epita.fr>
Thu, 10 Feb 2000 10:38:59 +0000 (10:38 +0000)
committerAkim Demaille <akim@epita.fr>
Thu, 10 Feb 2000 10:38:59 +0000 (10:38 +0000)
Test it.

* acgeneral.m4 (AC_OUTPUT_HEADERS): Renamed as...
(_AC_OUTPUT_HEADERS): this.  All callers changed.
Don't mess with changequote, just quote properly.
Bug 1.  Because of the `#' in `ac_dA', the quotes <<>> were not
removed, and therefore the sed script contained `<<define>>'
instead of `define'.  Now that the block is properly quoted, there
is no need to quote `define'.
Bug 2.  Once a `#define' substitution performed, we were branching
to the top of the sed script (`t top').  This resulted in an
endless substitution of `#define foo 1' to `#define foo 1'.
Branching is not enough: you also have to fetch the next input
line, i.e., use `t' instead of `t t' in ac_dD, and don't output
`: top' in `config.defines'.
Though it was correct for `#undef' templates, just apply the same
transformation to `ac_uD' and `config.undefs'.
Bug 3.  Don't try to preserve what was behind the value in the
template, since on
#define NAME "bar baz"
it leads to
#define NAME 1 baz"
Now `ac_dB' catches everything behind the NAME (making sure there
is at least a space) and `ac_dC' only outputs a space.
* tests/torture.m4: Check that various forms of `#define' header
templates are properly handled.

ChangeLog
acgeneral.m4
lib/autoconf/general.m4
tests/torture.m4

index af33e84c34d2bc90afcb952d9b8fc5f94f0893d3..ac7cceb7014e7ca2652c12a6989d184077a4f890 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+2000-02-10  Akim Demaille  <akim@epita.fr>
+
+       Honor properly the `#define' config.h.in templates.
+       Test it.
+
+       * acgeneral.m4 (AC_OUTPUT_HEADERS): Renamed as...
+       (_AC_OUTPUT_HEADERS): this.  All callers changed.
+       Don't mess with changequote, just quote properly.
+       Bug 1.  Because of the `#' in `ac_dA', the quotes <<>> were not
+       removed, and therefore the sed script contained `<<define>>'
+       instead of `define'.  Now that the block is properly quoted, there
+       is no need to quote `define'.
+       Bug 2.  Once a `#define' substitution performed, we were branching
+       to the top of the sed script (`t top').  This resulted in an
+       endless substitution of `#define foo 1' to `#define foo 1'.
+       Branching is not enough: you also have to fetch the next input
+       line, i.e., use `t' instead of `t t' in ac_dD, and don't output
+       `: top' in `config.defines'.
+       Though it was correct for `#undef' templates, just apply the same
+       transformation to `ac_uD' and `config.undefs'.
+       Bug 3.  Don't try to preserve what was behind the value in the
+       template, since on
+               #define NAME "bar baz"
+       it leads to
+               #define NAME 1 baz"
+       Now `ac_dB' catches everything behind the NAME (making sure there
+       is at least a space) and `ac_dC' only outputs a space.
+       * tests/torture.m4: Check that various forms of `#define' header
+       templates are properly handled.
+
 2000-02-10  Akim Demaille  <akim@epita.fr>
 
        Avoid calling `rm' without arguments.
index d5744122ff98ef119896b894f399950722d0163a..4d698e503ff5ef0f4e7368e28e49bcbb4dc704c8 100644 (file)
@@ -3585,7 +3585,7 @@ ifset([AC_LIST_FILES],
        AC_OUTPUT_FILES()dnl
        AC_DIVERT_POP()])dnl
 ifset([AC_LIST_HEADERS],
-      [AC_OUTPUT_HEADERS()])dnl
+      [_AC_OUTPUT_HEADERS()])dnl
 ifset([AC_LIST_LINKS],
       [AC_OUTPUT_LINKS()])dnl
 ifset([AC_LIST_COMMANDS],
@@ -3609,7 +3609,7 @@ chmod +x $CONFIG_STATUS
 # Set the DEFS variable to the -D options determined earlier.
 # This is a subroutine of AC_OUTPUT.
 # It is called inside configure, outside of config.status.
-# FIXME: This has to be fixed the same way as in AC_OUTPUT_HEADERS.
+# FIXME: This has to be fixed the same way as in _AC_OUTPUT_HEADERS.
 define(AC_OUTPUT_MAKE_DEFS,
 [# Transform confdefs.h into DEFS.
 dnl Using a here document instead of a string reduces the quoting nightmare.
@@ -3827,16 +3827,52 @@ EOF
 ])# AC_OUTPUT_FILES
 
 
-# AC_OUTPUT_HEADERS
-# -----------------
-# Create the config.h files from the config.h.in files.
-# This is a subroutine of AC_OUTPUT.
+# _AC_OUTPUT_HEADERS
+# ------------------
 #
-# It has to send itself into $CONFIG_STATUS (eg, via here documents).
-# Upon exit, no here document shall be opened.
-define(AC_OUTPUT_HEADERS,
+# Output the code which instantiates the `config.h' files from their
+# `config.h.in'.
+#
+# This is a subroutine of _AC_OUTPUT_CONFIG_STATUS.  It has to send
+# itself into $CONFIG_STATUS (eg, via here documents).  Upon exit, no
+# here document shall be opened.
+#
+#
+# The code produced used to be extremely costly: there are was a
+# single sed script (n lines) handling both `#define' templates,
+# `#undef' templates with trailing space, and `#undef' templates
+# without trailing spaces.  The full script was run on each of the m
+# lines of `config.h.in', i.e., about n x m.
+#
+# Now there are two scripts: `conftest.defines' for the `#define'
+# templates, and `conftest.undef' for the `#undef' templates.
+#
+# Optimization 1.  It is incredibly costly to run two `#undef'
+# scripts, so just remove trailing spaces first.  Removes about a
+# third of the cost.
+#
+# Optimization 2.  Since `#define' are rare and obsoleted,
+# `conftest.defines' is built and run only if grep says there are
+# `#define'.  Improves by at least a factor 2, since in addition we
+# avoid the cost of *producing* the sed script.
+#
+# Optimization 3.  In each script, first check that the current input
+# line is a template.  This avoids running the full sed script on
+# empty lines and comments (divides the cost by about 3 since each
+# template chunk is typically a comment, a template, an empty line).
+#
+# Optimization 4.  Once a substitution performed, since there can be
+# only one per line, immediately restart the script on the next input
+# line (using the `t' sed instruction).  Divides by about 2.
+# *Note:* In the case of the AC_SUBST sed script (AC_OUTPUT_FILES)
+# this optimization cannot be applied as is, because there can be
+# several substitutions per line.
+#
+#
+# The result is about, hm, ... times blah... plus....  Ahem.  The
+# result is about much faster.
+define(_AC_OUTPUT_HEADERS,
 [cat >>$CONFIG_STATUS <<\EOF
-changequote(<<, >>)dnl
 
 #
 # CONFIG_HEADER section.
@@ -3846,16 +3882,16 @@ changequote(<<, >>)dnl
 # NAME is the cpp macro being defined and VALUE is the value it is being given.
 #
 # ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s%^\([  ]*\)#\([        ]*<<define>>[   ][      ]*\)'
-ac_dB='\([     ][      ]*\)[^  ]*%\1#\2'
-ac_dC='\3'
-ac_dD='%;t t'
+dnl Double quote for the `[ ]' and `define'.
+[ac_dA='s%^\([         ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='[       ].*$%\1#\2'
+ac_dC=' '
+ac_dD='%;t'
 # ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
 ac_uA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
-ac_uB='<<$>>%\1#\2define\3'
+ac_uB='$%\1#\2define\3'
 ac_uC=' '
-ac_uD='%;t t'
-changequote([, ])dnl
+ac_uD='%;t']
 
 for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
 changequote(, )dnl
@@ -3946,7 +3982,6 @@ do
   # Write a limited-size here document to $ac_cs_root.frag.
   echo '  cat >$ac_cs_root.frag <<CEOF' >>$CONFIG_STATUS
 dnl Speed up: don't consider the non `#define' lines.
-  echo ': t' >>$CONFIG_STATUS
   echo '/^@BKL@        @BKR@*#@BKL@    @BKR@*define/!b' >>$CONFIG_STATUS
   sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
   echo 'CEOF
@@ -3971,7 +4006,6 @@ do
   # Write a limited-size here document to $ac_cs_root.frag.
   echo '  cat >$ac_cs_root.frag <<CEOF' >>$CONFIG_STATUS
 dnl Speed up: don't consider the non `#undef'
-  echo ': t' >>$CONFIG_STATUS
   echo '/^@BKL@        @BKR@*#@BKL@    @BKR@*undef/!b' >>$CONFIG_STATUS
   sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
   echo 'CEOF
@@ -4016,7 +4050,7 @@ AC_LIST_HEADERS_COMMANDS()dnl
 ])dnl
 fi; done
 EOF
-])# AC_OUTPUT_HEADERS
+])# _AC_OUTPUT_HEADERS
 
 
 # AC_OUTPUT_LINKS
index d5744122ff98ef119896b894f399950722d0163a..4d698e503ff5ef0f4e7368e28e49bcbb4dc704c8 100644 (file)
@@ -3585,7 +3585,7 @@ ifset([AC_LIST_FILES],
        AC_OUTPUT_FILES()dnl
        AC_DIVERT_POP()])dnl
 ifset([AC_LIST_HEADERS],
-      [AC_OUTPUT_HEADERS()])dnl
+      [_AC_OUTPUT_HEADERS()])dnl
 ifset([AC_LIST_LINKS],
       [AC_OUTPUT_LINKS()])dnl
 ifset([AC_LIST_COMMANDS],
@@ -3609,7 +3609,7 @@ chmod +x $CONFIG_STATUS
 # Set the DEFS variable to the -D options determined earlier.
 # This is a subroutine of AC_OUTPUT.
 # It is called inside configure, outside of config.status.
-# FIXME: This has to be fixed the same way as in AC_OUTPUT_HEADERS.
+# FIXME: This has to be fixed the same way as in _AC_OUTPUT_HEADERS.
 define(AC_OUTPUT_MAKE_DEFS,
 [# Transform confdefs.h into DEFS.
 dnl Using a here document instead of a string reduces the quoting nightmare.
@@ -3827,16 +3827,52 @@ EOF
 ])# AC_OUTPUT_FILES
 
 
-# AC_OUTPUT_HEADERS
-# -----------------
-# Create the config.h files from the config.h.in files.
-# This is a subroutine of AC_OUTPUT.
+# _AC_OUTPUT_HEADERS
+# ------------------
 #
-# It has to send itself into $CONFIG_STATUS (eg, via here documents).
-# Upon exit, no here document shall be opened.
-define(AC_OUTPUT_HEADERS,
+# Output the code which instantiates the `config.h' files from their
+# `config.h.in'.
+#
+# This is a subroutine of _AC_OUTPUT_CONFIG_STATUS.  It has to send
+# itself into $CONFIG_STATUS (eg, via here documents).  Upon exit, no
+# here document shall be opened.
+#
+#
+# The code produced used to be extremely costly: there are was a
+# single sed script (n lines) handling both `#define' templates,
+# `#undef' templates with trailing space, and `#undef' templates
+# without trailing spaces.  The full script was run on each of the m
+# lines of `config.h.in', i.e., about n x m.
+#
+# Now there are two scripts: `conftest.defines' for the `#define'
+# templates, and `conftest.undef' for the `#undef' templates.
+#
+# Optimization 1.  It is incredibly costly to run two `#undef'
+# scripts, so just remove trailing spaces first.  Removes about a
+# third of the cost.
+#
+# Optimization 2.  Since `#define' are rare and obsoleted,
+# `conftest.defines' is built and run only if grep says there are
+# `#define'.  Improves by at least a factor 2, since in addition we
+# avoid the cost of *producing* the sed script.
+#
+# Optimization 3.  In each script, first check that the current input
+# line is a template.  This avoids running the full sed script on
+# empty lines and comments (divides the cost by about 3 since each
+# template chunk is typically a comment, a template, an empty line).
+#
+# Optimization 4.  Once a substitution performed, since there can be
+# only one per line, immediately restart the script on the next input
+# line (using the `t' sed instruction).  Divides by about 2.
+# *Note:* In the case of the AC_SUBST sed script (AC_OUTPUT_FILES)
+# this optimization cannot be applied as is, because there can be
+# several substitutions per line.
+#
+#
+# The result is about, hm, ... times blah... plus....  Ahem.  The
+# result is about much faster.
+define(_AC_OUTPUT_HEADERS,
 [cat >>$CONFIG_STATUS <<\EOF
-changequote(<<, >>)dnl
 
 #
 # CONFIG_HEADER section.
@@ -3846,16 +3882,16 @@ changequote(<<, >>)dnl
 # NAME is the cpp macro being defined and VALUE is the value it is being given.
 #
 # ac_d sets the value in "#define NAME VALUE" lines.
-ac_dA='s%^\([  ]*\)#\([        ]*<<define>>[   ][      ]*\)'
-ac_dB='\([     ][      ]*\)[^  ]*%\1#\2'
-ac_dC='\3'
-ac_dD='%;t t'
+dnl Double quote for the `[ ]' and `define'.
+[ac_dA='s%^\([         ]*\)#\([        ]*define[       ][      ]*\)'
+ac_dB='[       ].*$%\1#\2'
+ac_dC=' '
+ac_dD='%;t'
 # ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
 ac_uA='s%^\([  ]*\)#\([        ]*\)undef\([    ][      ]*\)'
-ac_uB='<<$>>%\1#\2define\3'
+ac_uB='$%\1#\2define\3'
 ac_uC=' '
-ac_uD='%;t t'
-changequote([, ])dnl
+ac_uD='%;t']
 
 for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
 changequote(, )dnl
@@ -3946,7 +3982,6 @@ do
   # Write a limited-size here document to $ac_cs_root.frag.
   echo '  cat >$ac_cs_root.frag <<CEOF' >>$CONFIG_STATUS
 dnl Speed up: don't consider the non `#define' lines.
-  echo ': t' >>$CONFIG_STATUS
   echo '/^@BKL@        @BKR@*#@BKL@    @BKR@*define/!b' >>$CONFIG_STATUS
   sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
   echo 'CEOF
@@ -3971,7 +4006,6 @@ do
   # Write a limited-size here document to $ac_cs_root.frag.
   echo '  cat >$ac_cs_root.frag <<CEOF' >>$CONFIG_STATUS
 dnl Speed up: don't consider the non `#undef'
-  echo ': t' >>$CONFIG_STATUS
   echo '/^@BKL@        @BKR@*#@BKL@    @BKR@*undef/!b' >>$CONFIG_STATUS
   sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
   echo 'CEOF
@@ -4016,7 +4050,7 @@ AC_LIST_HEADERS_COMMANDS()dnl
 ])dnl
 fi; done
 EOF
-])# AC_OUTPUT_HEADERS
+])# _AC_OUTPUT_HEADERS
 
 
 # AC_OUTPUT_LINKS
index 9d177aba581c4466a59c429a3befc7643081b821..9a6b88ffbc85a7235c742509689e7ac2e1924b84 100644 (file)
@@ -117,3 +117,62 @@ AT_CHECK([./config.status --recheck | sed -n -e 's/^result=//p'], 0,
 ], ignore)
 
 AT_CLEANUP(configure config.status config.log config.cache)
+
+
+
+## -------------------------------------------- ##
+## Check that `#define' templates are honored.  ##
+## -------------------------------------------- ##
+
+# Use various forms of `#define' templates, and make sure there are no
+# problems when a symbol is prefix of another.
+
+AT_SETUP([#define header templates])
+
+AT_DATA(configure.in,
+[[AC_INIT
+AC_CONFIG_HEADERS(config.h:config.hin)
+# I18n of dummy variables: their French translations.
+AC_DEFINE(foo, toto)
+AC_DEFINE(bar, tata)
+AC_DEFINE(baz, titi)
+AC_DEFINE(fubar, tutu)
+# Symbols which are prefixes of another.
+AC_DEFINE(a, A)
+AC_DEFINE(aaa, AAA)
+AC_DEFINE(aa, AA)
+AC_OUTPUT
+]])
+
+AT_DATA(config.hin,
+[[#define foo   0
+#  define bar bar
+#  define baz   "Archimedes was sinking in his baz"
+#  define fubar                                tutu
+#define a B
+#define aa BB
+#define aaa BBB
+#undef a
+#undef aa
+#undef aaa
+]])
+
+AT_DATA(expout,
+[[/* config.h.  Generated automatically by configure.  */
+#define foo toto
+#  define bar tata
+#  define baz titi
+#  define fubar tutu
+#define a A
+#define aa AA
+#define aaa AAA
+#define a A
+#define aa AA
+#define aaa AAA
+]])
+
+AT_CHECK([../autoconf -m .. -l $at_srcdir], 0)
+AT_CHECK([./configure], 0, ignore)
+AT_CHECK([cat config.h], 0, expout)
+
+AT_CLEANUP(configure config.status config.log config.cache config.h)