]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Don't swallow $1 in textual local variables.
authorEric Blake <ebb9@byu.net>
Fri, 21 Mar 2008 17:07:08 +0000 (11:07 -0600)
committerEric Blake <ebb9@byu.net>
Fri, 21 Mar 2008 17:32:46 +0000 (11:32 -0600)
* lib/m4sugar/m4sugar.m4 (m4_combine): Don't use overquoting and
expansion of text arguments, as that swallows $1.
(m4_text_wrap): Likewise, by splitting out...
(_m4_text_wrap): ...new helper macro.  Also, allow arbitrary
expression for width.
* tests/m4sugar.at (m4@&t@_text_wrap): Test this.
(m4@&t@_combine): Likewise.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
lib/m4sugar/m4sugar.m4
tests/m4sugar.at

index 5be2fca472238a482b022f0fb0d2069a558658b0..97e8ddc54205a6be511ab4e68bb92b0084c2eb0b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2008-03-21  Eric Blake  <ebb9@byu.net>
+
+       Don't swallow $1 in textual local variables.
+       * lib/m4sugar/m4sugar.m4 (m4_combine): Don't use overquoting and
+       expansion of text arguments, as that swallows $1.
+       (m4_text_wrap): Likewise, by splitting out...
+       (_m4_text_wrap): ...new helper macro.  Also, allow arbitrary
+       expression for width.
+       * tests/m4sugar.at (m4@&t@_text_wrap): Test this.
+       (m4@&t@_combine): Likewise.
+
 2008-03-21  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 
        Avoid leftover files on Leopard.
index e755f98ab86413111d81acda596748a0c8d73d5b..f6b9f942b149f64f72c919671bde75ce277b24e2 100644 (file)
@@ -1852,19 +1852,19 @@ m4_define([_m4_join],
 #   => a-1, a-2, a-3, b-1, b-2, b-3, c-1, c-2, c-3
 #
 # In order to have the correct number of SEPARATORs, we use a temporary
-# variable that redefines itself after the first use.  Note that since there
-# is no user expansion, we can avoid m4_defn overhead by overquoting the
-# second definition of m4_Separator, and by using m4_builtin.  Likewise,
-# we compute the m4_shift3 only once, rather than in each iteration of the
-# outer m4_foreach.
+# variable that redefines itself after the first use.  We use m4_builtin
+# to avoid m4_defn overhead, but must use defn rather than overquoting
+# in case PREFIX or SUFFIX contains $1.  Likewise, we compute the m4_shift3
+# only once, rather than in each iteration of the outer m4_foreach.
 m4_define([m4_combine],
 [m4_if(m4_eval([$# > 3]), [1],
-       [m4_pushdef([m4_Separator], [m4_define([m4_Separator], [[$1]])])]]dnl
+       [m4_pushdef([m4_Separator], [m4_define([m4_Separator],
+                                   m4_builtin([defn], [m4_echo]))])]]dnl
 [[m4_foreach([m4_Prefix], [$2],
             [m4_foreach([m4_Suffix], ]m4_dquote(m4_dquote(m4_shift3($@)))[,
-                        [m4_Separator[]m4_builtin([defn],
-                                       [m4_Prefix])[$3]m4_builtin([defn],
-                                                       [m4_Suffix])])])]]dnl
+                        [m4_Separator([$1])[]m4_builtin([defn],
+                                     [m4_Prefix])[$3]m4_builtin([defn],
+                                                     [m4_Suffix])])])]]dnl
 [[m4_builtin([popdef], [m4_Separator])])])
 
 
@@ -1988,27 +1988,28 @@ m4_define([m4_append_uniq_w],
 # all the words are preceded by m4_Separator which is defined to empty for
 # the first word, and then ` ' (single space) for all the others.
 #
-# The algorithm overquotes m4_Prefix and m4_Prefix1 to avoid m4_defn
-# overhead, and bypasses m4_popdef overhead with m4_builtin since no user
+# The algorithm uses a helper that uses $2 through $4 directly, rather than
+# using local variables, to avoid m4_defn overhead, or expansion swallowing
+# any $.  It also bypasses m4_popdef overhead with m4_builtin since no user
 # macro expansion occurs in the meantime.  Also, the definition is written
 # with m4_do, to avoid time wasted on dnl during expansion (since this is
 # already a time-consuming macro).
 m4_define([m4_text_wrap],
+[_$0([$1], [$2], m4_if([$3], [], [[$2]], [[$3]]),
+     m4_if([$4], [], [79], [[$4]]))])
+m4_define([_m4_text_wrap],
 m4_do(dnl set up local variables, to avoid repeated calculations
-[[m4_pushdef([m4_Prefix], [[$2]])]],
-[[m4_pushdef([m4_Prefix1], m4_if([$3], [], [m4_Prefix], [[[$3]]]))]],
-[[m4_pushdef([m4_Width], m4_default([$4], 79))]],
-[[m4_pushdef([m4_Indent], m4_qlen(m4_Prefix))]],
-[[m4_pushdef([m4_Cursor], m4_qlen(m4_Prefix1))]],
+[[m4_pushdef([m4_Indent], m4_qlen([$2]))]],
+[[m4_pushdef([m4_Cursor], m4_qlen([$3]))]],
 [[m4_pushdef([m4_Separator], [m4_define([m4_Separator], [ ])])]],
 dnl expand the first prefix, then check its length vs. regular prefix
 dnl same length: nothing special
 dnl prefix1 longer: output on line by itself, and reset cursor
 dnl prefix1 shorter: pad to length of prefix, and reset cursor
-[[m4_Prefix1[]m4_cond([m4_Cursor], m4_Indent, [],
-                     [m4_eval(m4_Cursor > m4_Indent)], [1], [
-m4_Prefix[]m4_define([m4_Cursor], m4_Indent)],
-                     [m4_format([%*s], m4_max([0],
+[[[$3]m4_cond([m4_Cursor], m4_Indent, [],
+             [m4_eval(m4_Cursor > m4_Indent)], [1], [
+[$2]m4_define([m4_Cursor], m4_Indent)],
+             [m4_format([%*s], m4_max([0],
   m4_eval(m4_Indent - m4_Cursor)), [])m4_define([m4_Cursor], m4_Indent)])]],
 dnl now, for each word, compute the curser after the word is output, then
 dnl check if the cursor would exceed the wrap column
@@ -2018,19 +2019,16 @@ dnl either way, insert the word
 [[m4_foreach_w([m4_Word], [$1],
   [m4_define([m4_Cursor],
             m4_eval(m4_Cursor + m4_qlen(m4_builtin([defn], [m4_Word]))
-                    + 1))m4_if(m4_eval(m4_Cursor > m4_Width),
+                    + 1))m4_if(m4_eval(m4_Cursor > ([$4])),
       [1], [m4_define([m4_Cursor],
                      m4_eval(m4_Indent
                              + m4_qlen(m4_builtin([defn], [m4_Word])) + 1))
-m4_Prefix[]],
+[$2]],
       [m4_Separator[]])m4_builtin([defn], [m4_Word])])]],
 dnl finally, clean up the local variabls
 [[m4_builtin([popdef], [m4_Separator])]],
 [[m4_builtin([popdef], [m4_Cursor])]],
-[[m4_builtin([popdef], [m4_Indent])]],
-[[m4_builtin([popdef], [m4_Width])]],
-[[m4_builtin([popdef], [m4_Prefix1])]],
-[[m4_builtin([popdef], [m4_Prefix])]]))
+[[m4_builtin([popdef], [m4_Indent])]]))
 
 
 # m4_text_box(MESSAGE, [FRAME-CHARACTER = `-'])
index 163dea1f40c5f0e0ca8ef0d760cb5d3a47edd573..244c5f67742a865c14cb775e89cdd34a8dd335a6 100644 (file)
@@ -2,7 +2,8 @@
 
 AT_BANNER([M4sugar.])
 
-# Copyright (C) 2000, 2001, 2002, 2005, 2006, 2007 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2001, 2002, 2005, 2006, 2007, 2008 Free Software
+# Foundation, Inc.
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -312,7 +313,7 @@ AT_CLEANUP
 AT_SETUP([m4@&t@_text_wrap])
 
 # m4_text_wrap is used to display the help strings.  Also, check that
-# commas are not swallowed.  This can easily happen because of
+# commas and $ are not swallowed.  This can easily happen because of
 # m4-listification.
 
 AT_DATA_M4SUGAR([script.4s],
@@ -328,6 +329,8 @@ m4_text_wrap([Short doc.], [          ], [  --too-wide], 30)
 m4_text_wrap([Super long documentation.], [          ], [  --too-wide], 30)
 
 m4_text_wrap([First, second  , third, [,quoted]])
+m4_define([xfff], [oops])
+m4_text_wrap([Some $1 $2 $3 $4 embedded dollars.], [ $* ], [ $@ ], [0xfff & 20])
 ]])
 
 AT_DATA([expout],
@@ -346,6 +349,10 @@ AT_DATA([expout],
           documentation.
 
 First, second , third, [,quoted]
+
+ $@ Some $1 $2 $3
+ $* $4 embedded
+ $* dollars.
 ]])
 
 AT_CHECK_M4SUGAR([-o-], 0, [expout])
@@ -583,6 +590,7 @@ m4_combine([, ], [[a], [b]], [-], [])
 m4_combine([, ], [], [-], [a], [b])
 m4_combine([, ], [[]], [-], [a], [b])
 m4_combine([ a ], [[-], [+]], [a], [-], [+])
+m4_combine([$* ], [[$1], [$2]], [$#], [$@])
 ]],
 [[a-1, a-2, a-3, b-1, b-2, b-3, c-1, c-2, c-3
 
@@ -590,6 +598,7 @@ a-, b-
 
 -a, -b
 -a- a -a+ a +a- a +a+
+$1$#$@$* $2$#$@
 ]], [])
 
 AT_CLEANUP