]> git.ipfire.org Git - thirdparty/autoconf.git/commitdiff
Improve m4_expand robustness, part 1.
authorEric Blake <ebb9@byu.net>
Wed, 19 Nov 2008 16:00:55 +0000 (09:00 -0700)
committerEric Blake <ebb9@byu.net>
Thu, 20 Nov 2008 22:53:22 +0000 (15:53 -0700)
* lib/m4sugar/m4sugar.m4 (_m4_expand): Tolerate unquoted
unbalanced `)'.
* tests/m4sugar.at (m4@&t@_expand): New test.

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

index d2d2f7bccf0bb211fb21d60704eede6d7cf531ac..380f7c78c1f2320f4e3d0896c333e0139ff28ac7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-11-20  Eric Blake  <ebb9@byu.net>
+
+       Improve m4_expand robustness, part 1.
+       * lib/m4sugar/m4sugar.m4 (_m4_expand): Tolerate unquoted
+       unbalanced `)'.
+       * tests/m4sugar.at (m4@&t@_expand): New test.
+
 2008-11-20  Eric Blake  <ebb9@byu.net>
 
        Add m4_chomp, m4_esyscmd_s.
index c9a7f9893e2e7c77735375218cabd508cab4c51a..7074d90c8991072df219667d111ea535e489eebf 100644 (file)
@@ -814,9 +814,10 @@ m4_define([m4_echo], [$@])
 
 # m4_expand(ARG)
 # --------------
-# Return the expansion of ARG as a single string.  Unlike m4_quote($1), this
-# correctly preserves whitespace following single-quoted commas that appeared
-# within ARG.
+# Return the expansion of ARG as a single string.  Unlike
+# m4_quote($1), this preserves whitespace following single-quoted
+# commas that appear within ARG.  It also deals with shell case
+# statements.
 #
 #   m4_define([active], [ACT, IVE])
 #   m4_define([active2], [[ACT, IVE]])
@@ -825,19 +826,31 @@ m4_define([m4_echo], [$@])
 #   m4_expand([active, active2])
 #   => ACT, IVE, ACT, IVE
 #
-# Unfortunately, due to limitations in m4, ARG must expand to something
-# with balanced quotes (use quadrigraphs to get around this).  The input
-# is not likely to have unbalanced -=<{(/)}>=- quotes, and it is possible
-# to have unbalanced (), provided it was specified with proper [] quotes.
-# Likewise, ARG must either avoid unquoted comments, or must be sure
-# to include the trailing newline to end the comment.
-#
-# Exploit that extra () will group unquoted commas and the following
-# whitespace, then convert () to [].  m4_bpatsubst can't handle newlines
-# inside $1, and m4_substr strips quoting.  So we (ab)use m4_changequote.
-m4_define([m4_expand], [_$0(-=<{($1)}>=-)])
+# Unfortunately, due to limitations in m4, ARG must expand to
+# something with balanced quotes (use quadrigraphs to get around
+# this), and should not contain the unlikely delimiters -=<{( or
+# )}>=-.  It is possible to have unbalanced quoted `(' or `)', as well
+# as unbalanced unquoted `)'.
+#
+# Exploit that extra unquoted () will group unquoted commas and the
+# following whitespace.  m4_bpatsubst can't handle newlines inside $1,
+# and m4_substr strips quoting.  So we (ab)use m4_changequote, using
+# temporary quotes to remove the delimiters that conveniently included
+# the unquoted () that were added prior to the changequote.
+#
+# Thanks to shell case statements, too many people are prone to pass
+# underquoted `)', so we try to detect that by passing a marker as a
+# fourth argument; if the marker is not present, then we assume that
+# we encountered an early `)', and re-expand the first argument, but
+# this time with one more `(' in the second argument and in the
+# open-quote delimiter.  We must also ignore the slop from the
+# previous try.  The final macro is thus half line-noise, half art.
+m4_define([m4_expand], [_$0([$1], [(], -=<{($1)}>=-, [}>=-])])
+
 m4_define([_m4_expand],
-[m4_changequote([-=<{(], [)}>=-])$1m4_changequote([, ])])
+[m4_if([$4], [}>=-],
+       [m4_changequote([-=<{$2], [)}>=-])$3m4_changequote([, ])],
+       [$0([$1], [($2], -=<{($2$1)}>=-, [}>=-])m4_ignore$2])])
 
 
 # m4_ignore(ARGS)
index d1ee1fe6affe9aa058b06f3bdb6f9ccb35a9327f..89e0fde6c753ce68407a0d433c7b20343523a9aa 100644 (file)
@@ -676,6 +676,52 @@ one
 AT_CLEANUP
 
 
+## ----------- ##
+## m4_expand.  ##
+## ----------- ##
+
+AT_SETUP([m4@&t@_expand])
+
+AT_CHECK_M4SUGAR_TEXT(
+[[m4_define([active], [ACTIVE])dnl
+m4_expand([#active
+active])
+m4_expand([[active]])
+dnl properly quoted case statements
+m4_expand([case a in @%:@(
+  *) echo active, ;;
+esac
+case b in
+  *[)] echo active, ;;
+esac])
+dnl unbalanced underquoted `)', but we manage anyway (gasp!)
+m4_expand([case c in #(
+  *) echo active, ;;
+esac
+case d in
+  *) echo active, ;;
+esac])
+]],
+[[#active
+ACTIVE
+active
+case a in #(
+  *) echo ACTIVE, ;;
+esac
+case b in
+  *) echo ACTIVE, ;;
+esac
+case c in #(
+  *) echo ACTIVE, ;;
+esac
+case d in
+  *) echo ACTIVE, ;;
+esac
+]])
+
+AT_CLEANUP
+
+
 ## -------------- ##
 ## m4_text_wrap.  ##
 ## -------------- ##