From: Eric Blake Date: Fri, 21 Mar 2008 17:07:08 +0000 (-0600) Subject: Don't swallow $1 in textual local variables. X-Git-Tag: v2.62~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6bc7b22d4e0ca0209bd3133cc56f4dc681a6209;p=thirdparty%2Fautoconf.git 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. Signed-off-by: Eric Blake --- diff --git a/ChangeLog b/ChangeLog index 5be2fca4..97e8ddc5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-03-21 Eric Blake + + 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 Avoid leftover files on Leopard. diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4 index e755f98a..f6b9f942 100644 --- a/lib/m4sugar/m4sugar.m4 +++ b/lib/m4sugar/m4sugar.m4 @@ -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 = `-']) diff --git a/tests/m4sugar.at b/tests/m4sugar.at index 163dea1f..244c5f67 100644 --- a/tests/m4sugar.at +++ b/tests/m4sugar.at @@ -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