autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Handling of single-quoted comma [was: m4_defn overhead]


From: Eric Blake
Subject: Handling of single-quoted comma [was: m4_defn overhead]
Date: Mon, 15 Oct 2007 19:12:52 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Eric Blake <ebb9 <at> byu.net> writes:

> > For a counter example, the first argument to AS_HELP_STRING needs to be
> > doubly quoted if it contains a comma (the node `Autoconf Language' in
> > the manual hints the alert reader that this may be needed, but it's a
> > rather obscure hint).
> 
> Not for long.  I still have one of my pending patches [1] that allows single-
> quoted commas in AS_HELP_STRING without eating the trailing whitespace, via 
my 
> new macro m4_expand (or whatever better name we can come up with).
> 

Here goes.  In two pieces - one to fix the AT_SETUP regression, the other to 
fix AS_HELP_STRING.

2007-10-15  Eric Blake  <address@hidden>

        Enhance AS_HELP_STRING.
        * lib/m4sugar/m4sugar.m4 (m4_text_wrap): Don't expand arguments,
        and reduce number of expansions.
        * lib/m4sugar/m4sh.m4 (AS_HELP_STRING): Rework to use m4_expand,
        and to take indent and wrap column numbers.
        * tests/m4sh.at (AS@&address@hidden): Update the test.
        * doc/autoconf.texi (Pretty Help Strings): Document details about
        arguments.
        (Text processing Macros): Minor tweaks.
        * NEWS: Document this change.

        Fix 2007-10-03 regression with AT_SETUP([a, b]).
        * lib/m4sugar/m4sugar.m4 (m4_expand): New macro.
        (m4_text_box): Use it.
        * lib/autotest/general.m4 (AT_SETUP): Use it.
        * lib/m4sugar/m4sh.m4 (_AS_RUN): Use it.
        * tests/autotest.at (AT_CHECK_AT_TITLE_CHAR): Test this.
        * NEWS: Revert caveat about semantics change on comma.
        * doc/autoconf.texi (Evaluation Macros): Document m4_expand.

>From fd1344033ba482b72e6e77084b8bd4ad1fd96c09 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Mon, 8 Oct 2007 11:53:00 -0600
Subject: [PATCH] Fix 2007-10-03 regression with AT_SETUP([a, b]).

* lib/m4sugar/m4sugar.m4 (m4_expand): New macro.
* lib/autotest/general.m4 (AT_SETUP): Use it to preserve
whitespace after single-quoted comma.
* tests/autotest.at (AT_CHECK_AT_TITLE_CHAR): Test this.
* NEWS: Revert caveat about semantics change on comma.
* doc/autoconf.texi (Programming in M4): Lighten the warning on
using m4sugar; it is stabilizing.
(Redefined M4 Macros): Touch up wording on M4 builtins.
(Evaluation Macros): Document m4_expand.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog               |   11 +++++++++
 NEWS                    |    9 ++-----
 doc/autoconf.texi       |   57 +++++++++++++++++++++++++++++++++++++---------
 lib/autotest/general.m4 |    2 +-
 lib/m4sugar/m4sh.m4     |    2 +-
 lib/m4sugar/m4sugar.m4  |   32 +++++++++++++++++++++++++-
 tests/autotest.at       |    2 +-
 7 files changed, 94 insertions(+), 21 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9efbbe4..3d25d0d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2007-10-15  Eric Blake  <address@hidden>
+
+       Fix 2007-10-03 regression with AT_SETUP([a, b]).
+       * lib/m4sugar/m4sugar.m4 (m4_expand): New macro.
+       (m4_text_box): Use it.
+       * lib/autotest/general.m4 (AT_SETUP): Use it.
+       * lib/m4sugar/m4sh.m4 (_AS_RUN): Use it.
+       * tests/autotest.at (AT_CHECK_AT_TITLE_CHAR): Test this.
+       * NEWS: Revert caveat about semantics change on comma.
+       * doc/autoconf.texi (Evaluation Macros): Document m4_expand.
+
 2007-10-13  Eric Blake  <address@hidden>
 
        Change m4_join to match libtool's ltsugar semantics.
diff --git a/NEWS b/NEWS
index 95c7e3b..8804f93 100644
--- a/NEWS
+++ b/NEWS
@@ -61,10 +61,7 @@ GNU Autoconf NEWS - User visible changes.
    expanded libdir value of /usr/lib, not /usr//lib.
 
 ** AT_SETUP now handles macro expansions properly when calculating line
-   length.  However, as a side effect, any whitespace immediately
-   following a single-quoted comma is lost.  If you previously used
-   AT_SETUP([a, b]), you could change to AT_SETUP([a,[] b]) to keep
-   the space.
+   length.
 
 ** Autotest now determines $srcdir correctly.
 
@@ -117,8 +114,8 @@ GNU Autoconf NEWS - User visible changes.
    be used to take action depending on whether anything was appended.
 
 ** The following m4sugar macros are new:
-   m4_cond  m4_ignore  m4_max  m4_min  m4_newline  m4_shift2
-   m4_shift3  m4_unquote
+   m4_cond  m4_expand  m4_ignore  m4_max  m4_min  m4_newline
+   m4_shift2  m4_shift3  m4_unquote
 
 ** Warnings are now generated by default when an installer invokes
    'configure' with an unknown --enable-* or --with-* option.
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index 3a8c126..fb7a3ad 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -10696,6 +10696,32 @@ Conveniently, if there is just one @var{arg}, this 
effectively adds a
 level of quoting.
 @end defmac
 
address@hidden m4_expand (@var{arg})
address@hidden
+Return the expansion of @var{arg} as a quoted string.  Whereas
address@hidden is designed to collect expanded text into a single
+argument, @code{m4_expand} is designed to perform one level of expansion
+on quoted text.  The distinction is in the treatment of whitespace
+following a comma in the original @var{arg}.  Any time multiple
+arguments are collected into one with @code{m4_quote}, the M4 argument
+collection rules discard the whitespace.  But with @code{m4_quote},
+whitespace is discarded only if it results from unquoted commas in the
+expansion of macros contained in @var{arg}.
+
address@hidden
+m4_define([active], [ACT, IVE])dnl
+m4_define([active2], [[ACT, IVE]])dnl
+m4_quote(active, active)
address@hidden,IVE,ACT,IVE
+m4_expand([active, active])
address@hidden,IVE, ACT,IVE
+m4_quote(active2, active2)
address@hidden, IVE,ACT, IVE
+m4_expand([active2, active2])
address@hidden, IVE, ACT, IVE
address@hidden example
address@hidden defmac
+
 @defmac m4_ignore (@dots{})
 @msindex{ignore}
 This macro was introduced in Autoconf 2.62.  Expands to nothing,
@@ -10735,34 +10761,43 @@ with @code{m4_split}, in order to convert a single 
quoted list into a
 series of quoted elements.
 @end defmac
 
-The following example aims at emphasizing the difference between (i), not
-using these macros, (ii), using @code{m4_quote}, and (iii), using
address@hidden
+The following example aims at emphasizing the difference between several
+scenarios: not using these macros, using @code{m4_defn}, using
address@hidden, using @code{m4_dquote}, and using @code{m4_expand}.
 
 @example
 $ @kbd{cat example.m4}
 # Overquote, so that quotes are visible.
 m4_define([show], [$[]1 = [$1], $[]@@ = [$@@]])
-m4_define([mkargs], [1, 2, 3])
+m4_define([a], [A])
+m4_define([mkargs], [1, 2[,] 3])
 m4_define([arg1], [[$1]])
-m4_divert(0)dnl
+m4_divert([0])dnl
 show(a, b)
+show([a, b])
 show(m4_quote(a, b))
 show(m4_dquote(a, b))
+show(m4_expand([a, b]))
+
 arg1(mkargs)
 arg1([mkargs])
 arg1(m4_defn([mkargs]))
 arg1(m4_quote(mkargs))
 arg1(m4_dquote(mkargs))
+arg1(m4_expand([mkargs]))
 $ @kbd{autom4te -l m4sugar example.m4}
-$1 = a, $@@ = [a],[b]
-$1 = a,b, $@@ = [a,b]
-$1 = [a],[b], $@@ = [[a],[b]]
+$1 = A, $@@ = [A],[b]
+$1 = a, b, $@@ = [a, b]
+$1 = A,b, $@@ = [A,b]
+$1 = [A],[b], $@@ = [[A],[b]]
+$1 = A, b, $@@ = [A, b]
+
 1
 mkargs
-1, 2, 3
-1,2,3
-[1],[2],[3]
+1, 2[,] 3
+1,2, 3
+[1],[2, 3]
+1,2, 3
 @end example
 
 
diff --git a/lib/autotest/general.m4 b/lib/autotest/general.m4
index e34055e..ce8abc8 100644
--- a/lib/autotest/general.m4
+++ b/lib/autotest/general.m4
@@ -1289,7 +1289,7 @@ m4_define([AT_SETUP],
 m4_define([AT_capture_files], [])
 m4_define([AT_line], AT_LINE)
 m4_define([AT_xfail], [at_xfail=no])
-m4_define([AT_description], m4_quote($1))
+m4_define([AT_description], m4_expand([$1]))
 m4_define([AT_ordinal], m4_incr(AT_ordinal))
 m4_append([AT_groups_all], [ ]m4_defn([AT_ordinal]))
 m4_divert_push([TEST_FUNCTIONS])dnl
diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4
index 157b844..31fecbc 100644
--- a/lib/m4sugar/m4sh.m4
+++ b/lib/m4sugar/m4sh.m4
@@ -197,7 +197,7 @@ _AS_BOURNE_COMPATIBLE
 $1
 _ASEOF
 }],
-[(eval "AS_ESCAPE(m4_quote($1))")])])
+[(eval "AS_ESCAPE(m4_expand([$1]))")])])
 
 
 # _AS_DETECT_REQUIRED(TEST)
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index 8c7070b..dc9f1da 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -615,6 +615,36 @@ m4_define([m4_do],
 m4_define([m4_dquote],  address@hidden)
 
 
+# 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 (however, it does not preserve whitespace after any unquoted
+# commas encountered in the expansion).
+#
+#   m4_define([active], [ACT, IVE])
+#   m4_define([active2], [[ACT, IVE]])
+#   m4_quote(active, active2)
+#   => ACT,IVE,ACT, IVE
+#   m4_expand([active, active2])
+#   => ACT,IVE, ACT, IVE
+#
+# Splitting a quoted ARG on `,' preserves space, but produces a quoted list.
+# Unquote the list, then expand each argument while preserving the leading
+# spaces; finally, collect each argument back into the final string.
+m4_define([m4_expand],
+[m4_quote(_$0(m4_unquote(m4_split([$1], [,]))))])
+
+# _m4_expand(ARGS)
+# ----------------
+# Return the expansion of each ARG, separated by `,'.  Less efficient than
+# m4_unquote, but preserves quoted leading space in each ARG.
+m4_define([_m4_expand],
+[m4_if([$#], [0], [],
+       [$#], [1], [$1],
+       [$1,$0(m4_shift($@))])])
+
+
 # m4_ignore(ARGS)
 # ---------------
 # Expands to nothing.  Useful for conditionally ignoring an arbitrary
@@ -1834,7 +1864,7 @@ m4_builtin([popdef], [m4_Prefix])dnl
 # using FRAME-CHARACTER in the border.
 m4_define([m4_text_box],
 [m4_pushdef([m4_Border],
-           m4_translit(m4_format([%*s], m4_qlen(m4_quote($1)), []),
+           m4_translit(m4_format([%*s], m4_qlen(m4_expand([$1])), []),
                        [ ], m4_if([$2], [], [[-]], [[$2]])))dnl
 @%:@@%:@ m4_Border @%:@@%:@
 @%:@@%:@ $1 @%:@@%:@
diff --git a/tests/autotest.at b/tests/autotest.at
index c84cfce..2a339e1 100644
--- a/tests/autotest.at
+++ b/tests/autotest.at
@@ -290,7 +290,7 @@ AT_CHECK_AT_TITLE_CHAR([Backslash],     [\])
 AT_CHECK_AT_TITLE_CHAR([Brackets],   [[[]]], [[]])
 AT_CHECK_AT_TITLE_CHAR([Pound],       [[#]], [#])
 AT_CHECK_AT_TITLE_CHAR([Quoted comma],[[,]], [,])
-AT_CHECK_AT_TITLE_CHAR([Comma],       [,[]], [,])
+AT_CHECK_AT_TITLE_CHAR([Comma],         [,], [,])
 
 AT_CHECK_AT_TITLE_CHAR([Quoted Macro], [[macro_name]], [macro_name])
 AT_CHECK_AT_TITLE_CHAR([Macro],        [macro_name],   [macro_expanded])
-- 
1.5.3.2


>From 10a850e84a0b7c20a59692a19c47e1048f2d086f Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Mon, 15 Oct 2007 12:18:24 -0600
Subject: [PATCH] Enhance AS_HELP_STRING.

* lib/m4sugar/m4sugar.m4 (m4_text_wrap): Don't expand arguments,
and reduce number of expansions.
* lib/m4sugar/m4sh.m4 (AS_HELP_STRING): Rework to use m4_expand,
and to take indent and wrap column numbers.
* tests/m4sh.at (AS@&address@hidden): Update the test.
* doc/autoconf.texi (Pretty Help Strings): Document details about
arguments.
(Text processing Macros): Minor tweaks.
* NEWS: Document this change.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog              |   11 ++++++
 NEWS                   |    8 ++++-
 doc/autoconf.texi      |   72 ++++++++++++++++++++++++++++-------------
 lib/m4sugar/m4sh.m4    |   37 ++++++++++++---------
 lib/m4sugar/m4sugar.m4 |   82 ++++++++++++++++++++++++++---------------------
 tests/m4sh.at          |   25 +++++++++++++--
 6 files changed, 155 insertions(+), 80 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3d25d0d..c665485 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2007-10-15  Eric Blake  <address@hidden>
 
+       Enhance AS_HELP_STRING.
+       * lib/m4sugar/m4sugar.m4 (m4_text_wrap): Don't expand arguments,
+       and reduce number of expansions.
+       * lib/m4sugar/m4sh.m4 (AS_HELP_STRING): Rework to use m4_expand,
+       and to take indent and wrap column numbers.
+       * tests/m4sh.at (AS@&address@hidden): Update the test.
+       * doc/autoconf.texi (Pretty Help Strings): Document details about
+       arguments.
+       (Text processing Macros): Minor tweaks.
+       * NEWS: Document this change.
+
        Fix 2007-10-03 regression with AT_SETUP([a, b]).
        * lib/m4sugar/m4sugar.m4 (m4_expand): New macro.
        (m4_text_box): Use it.
diff --git a/NEWS b/NEWS
index 8804f93..e423906 100644
--- a/NEWS
+++ b/NEWS
@@ -50,7 +50,13 @@ GNU Autoconf NEWS - User visible changes.
 
 ** AC_USE_SYSTEM_EXTENSIONS now defines _ALL_SOURCE for Interix platforms.
 
-** AS_HELP_STRING no longer underquotes its first argument.
+** AS_HELP_STRING no longer underquotes its first argument; it also handles
+   the case where the first argument contains single-quoted commas.
+   For example, "AS_HELP_STRING([-a, [--arg[=foo]]], [bar])" produces:
+     "  -a, --arg=[foo]         bar"
+   Additionally, the macro now takes two additional arguments,
+   indent-column and wrap-column; these should not normally be needed,
+   but can be used to fine-tune how the output text is wrapped.
 
 ** The command 'autoconf -' now correctly processes a file from stdin.
 
diff --git a/doc/autoconf.texi b/doc/autoconf.texi
index fb7a3ad..addb7b1 100644
--- a/doc/autoconf.texi
+++ b/doc/autoconf.texi
@@ -10821,9 +10821,9 @@ are expanded during this macro; instead, they are 
expanded when
 
 @code{m4_append} can be used to grow strings, and @code{m4_append_uniq}
 to grow strings without duplicating substrings.  Additionally,
address@hidden takes two optional parameters; @var{if-uniq} is
-expanded if @var{string} was appended, and @var{if-duplicate} is
-expanded if @var{string} was already present.
address@hidden takes two optional parameters as of Autoconf 2.62;
address@hidden is expanded if @var{string} was appended, and
address@hidden is expanded if @var{string} was already present.
 
 @example
 m4_define([active], [ACTIVE])dnl
@@ -10935,25 +10935,27 @@ format those words to wrap within @var{width} 
columns, and without
 trailing whitespace.  If given, @var{prefix1} is prepended to the first
 line, and @var{prefix} is prepended to each continuation line.  As a
 special case, if @var{prefix1} is longer than @var{prefix}, the first
-line will consist solely of @var{prefix1}.
+line will consist solely of @var{prefix1}.  No expansions occur on
address@hidden, @var{prefix1}, or the words of @var{string}, although
+quadrigraphs are recognized.
 
 For some examples:
 @example
-m4_text_wrap([Short string */], [@ @ @ ], [/* ], [20])
+m4_text_wrap([Short string */], [   ], [/* ], [20])
 @result{}/* Short string */
-m4_text_wrap([Much longer string */], [@ @ @ ], [/* ], [20])
+m4_text_wrap([Much longer string */], [   ], [/* ], [20])
 @result{}/* Much longer
address@hidden@ @ @ string */
-m4_text_wrap([Short doc.], [@ @ @ @ @ @ @ @ @ @ ], [@ @ --short ], [30])
address@hidden@ @ --short Short doc.
-m4_text_wrap([Short doc.], [@ @ @ @ @ @ @ @ @ @ ], [@ @ --too-wide ], [30])
address@hidden@ @ --too-wide
address@hidden@ @ @ @ @ @ @ @ @ @ Short doc.
-m4_text_wrap([Super long documentation.], [@ @ @ @ @ ],
-             [@ @ --too-wide ], 30)
address@hidden@ @ --too-wide
address@hidden@ @ @ @ @ Super long
address@hidden@ @ @ @ @ documentation.
address@hidden   string */
+m4_text_wrap([Short doc.], [          ], [  --short ], [30])
address@hidden  --short Short doc.
+m4_text_wrap([Short doc.], [          ], [  --too-wide ], [30])
address@hidden  --too-wide
address@hidden          Short doc.
+m4_text_wrap([Super long documentation.], [     ],
+             [  --too-wide ], 30)
address@hidden  --too-wide
address@hidden     Super long
address@hidden     documentation.
 @end example
 @end defmac
 
@@ -17199,7 +17201,8 @@ your own @samp{help strings} to line up in the 
appropriate columns of
 strings} do.  This is the purpose of the @code{AS_HELP_STRING} macro.
 
 @anchor{AS_HELP_STRING}
address@hidden AS_HELP_STRING (@var{left-hand-side}, @var{right-hand-side})
address@hidden AS_HELP_STRING (@var{left-hand-side}, @var{right-hand-side} @
+  @dvar{indent-column, 26}, @dvar{wrap-column, 79})
 @asindex{HELP_STRING}
 
 Expands into an help string that looks pretty when the user executes
@@ -17215,9 +17218,6 @@ AC_ARG_WITH([foo],
   [use_foo=no])
 @end example
 
-The second argument of @code{AS_HELP_STRING} is
-not a literal, and should not be double quoted.
address@hidden Language}, for a more detailed explanation.
 Then the last few lines of @samp{configure --help} appear like
 this:
 
@@ -17226,16 +17226,42 @@ this:
   --with-foo              use foo (default is no)
 @end example
 
+Macro expansion is performed on the first argument.  However, the second
+argument of @code{AS_HELP_STRING} is treated as a whitespace separated
+list of text to be reformatted, and is not subject to macro expansion.
+Since it is not expanded, it should not be double quoted.
address@hidden Language}, for a more detailed explanation.
+
 The @code{AS_HELP_STRING} macro is particularly helpful when the
 @var{left-hand-side} and/or @var{right-hand-side} are composed of macro
 arguments, as shown in the following example.
 
 @example
 AC_DEFUN([MY_ARG_WITH],
-  [AC_ARG_WITH([$1],
-     [AS_HELP_STRING([--with-$1], [use $1 (default is $2)])],
+  [AC_ARG_WITH(m4_translit([[$1]], [_], [-]),
+     [AS_HELP_STRING([--with-m4_translit([$1], [_], [-])],
+                     [use $1 (default is $2)])],
      [use_[]$1=$withval],
      [use_[]$1=$2])])
+MY_ARG_WITH([a_b], [no])
address@hidden example
address@hidden
+Here, the last few lines of @samp{configure --help} will include:
+
address@hidden
+--enable and --with options recognized:
+  --with-a-b              use a_b (default is no)
address@hidden example
+
+The parameters @var{indent-column} and @var{wrap-column} were introduced
+in Autoconf 2.62.  Generally, they should not be specified; they exist
+for fine-tuning of the wrapping.
address@hidden
+AS_HELP_STRING([--option], [description of option])
address@hidden  --option                description of option
+AS_HELP_STRING([--option], [description of option], [15], [30])
address@hidden  --option     description of
address@hidden               option
 @end example
 @end defmac
 
diff --git a/lib/m4sugar/m4sh.m4 b/lib/m4sugar/m4sh.m4
index 31fecbc..debf208 100644
--- a/lib/m4sugar/m4sh.m4
+++ b/lib/m4sugar/m4sh.m4
@@ -1158,14 +1158,21 @@ m4_define([_AS_BOX_INDIR],
 _ASBOX])
 
 
-# AS_HELP_STRING(LHS, RHS, [COLUMN])
-# ----------------------------------
+# AS_HELP_STRING(LHS, RHS, [INDENT-COLUMN = 26], [WRAP-COLUMN = 79])
+# ------------------------------------------------------------------
+#
+# Format a help string so that it looks pretty when the user executes
+# "script --help".  This macro takes up to four arguments, a
+# "left hand side" (LHS), a "right hand side" (RHS), a decimal
+# INDENT-COLUMN which is the column where wrapped lines should begin
+# (the default of 26 is recommended), and a decimal WRAP-COLUMN which is
+# the column where lines should wrap (the default of 79 is recommended).
+# LHS is expanded, RHS is not.
 #
-# Format a help string so that it looks pretty when
-# the user executes "script --help".  This macro takes three
-# arguments, a "left hand side" (LHS), a "right hand side" (RHS), and
-# the COLUMN which is a string of white spaces which leads to the
-# the RHS column (default: 26 white spaces).
+# For backwards compatibility not documented in the manual, INDENT-COLUMN
+# can also be specified as a string of white spaces, whose width
+# determines the indentation column.  Using TABs in INDENT-COLUMN is not
+# recommended, since screen width of TAB is not computed.
 #
 # The resulting string is suitable for use in other macros that require
 # a help string (e.g. AC_ARG_WITH).
@@ -1185,9 +1192,9 @@ _ASBOX])
 # "--with-readline", while the RHS is "support fancy command line
 # editing".
 #
-# If the LHS contains more than (COLUMN - 3) characters, then the LHS is
-# terminated with a newline so that the RHS starts on a line of its own
-# beginning with COLUMN.  In the default case, this corresponds to an
+# If the LHS contains more than (INDENT-COLUMN - 3) characters, then the
+# LHS is terminated with a newline so that the RHS starts on a line of its
+# own beginning at INDENT-COLUMN.  In the default case, this corresponds to an
 # LHS with more than 23 characters.
 #
 # Therefore, in the example, if the LHS were instead
@@ -1206,12 +1213,10 @@ _ASBOX])
 # know quadrigraphs.
 #
 m4_define([AS_HELP_STRING],
-[m4_pushdef([AS_Prefix], m4_default([$3], [                          ]))dnl
-m4_pushdef([AS_Prefix_Format],
-          [  %-]m4_eval(m4_len(AS_Prefix) - 3)[s ])dnl [  %-23s ]
-m4_text_wrap([$2], AS_Prefix, m4_format(AS_Prefix_Format, [[$1]]))dnl
-m4_popdef([AS_Prefix_Format])dnl
-m4_popdef([AS_Prefix])dnl
+[m4_text_wrap([$2], m4_cond([[$3]], [], [                          ],
+                           [m4_eval([$3]+0)], [0], [[$3]],
+                           [m4_format([[%*s]], [$3], [])]),
+             m4_expand([  $1 ]), [$4])dnl
 ])# AS_HELP_STRING
 
 
diff --git a/lib/m4sugar/m4sugar.m4 b/lib/m4sugar/m4sugar.m4
index dc9f1da..9b3a615 100644
--- a/lib/m4sugar/m4sugar.m4
+++ b/lib/m4sugar/m4sugar.m4
@@ -1785,6 +1785,9 @@ m4_define([m4_append_uniq],
 # if the length of FIRST-PREFIX is greater than that of PREFIX, then
 # FIRST-PREFIX will be left alone on the first line.
 #
+# No expansion occurs on the contents STRING, PREFIX, or FIRST-PREFIX,
+# although quadrigraphs are correctly recognized.
+#
 # Typical outputs are:
 #
 # m4_text_wrap([Short string */], [   ], [/* ], 20)
@@ -1815,44 +1818,49 @@ m4_define([m4_append_uniq],
 # 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_Prefix1 to avoid m4_defn overhead, and bypasses
-# m4_popdef overhead with m4_builtin since no user macro expansion occurs in
-# the meantime.
+# The algorithm overquotes m4_Prefix and m4_Prefix1 to avoid m4_defn
+# overhead, and 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],
-[m4_pushdef([m4_Prefix], [$2])dnl
-m4_pushdef([m4_Prefix1], m4_dquote(m4_default([$3], [m4_Prefix])))dnl
-m4_pushdef([m4_Width], m4_default([$4], 79))dnl
-m4_pushdef([m4_Cursor], m4_qlen(m4_Prefix1))dnl
-m4_pushdef([m4_Separator], [])dnl
-m4_Prefix1[]dnl
-m4_cond([m4_eval(m4_qlen(m4_Prefix1) > m4_len(m4_Prefix))],
-       [1], [m4_define([m4_Cursor], m4_len(m4_Prefix))
-m4_Prefix],
-       [m4_eval(m4_qlen(m4_Prefix1) < m4_len(m4_Prefix))],
-       [0], [],
-       [m4_define([m4_Cursor], m4_len(m4_Prefix))[]dnl
-m4_format([%*s],
-         m4_max([0], m4_eval(m4_len(m4_Prefix) - m4_qlen(m4_Prefix1))),
-         [])])[]dnl
-m4_foreach_w([m4_Word], [$1],
-[m4_define([m4_Cursor],
-          m4_eval(m4_Cursor + m4_qlen(m4_builtin([defn], [m4_Word])) + 1))dnl
-dnl New line if too long, else insert a space unless it is the first
-dnl of the words.
-m4_if(m4_eval(m4_Cursor > m4_Width),
-      1, [m4_define([m4_Cursor],
-                   m4_eval(m4_len(m4_Prefix)
-                           + m4_qlen(m4_builtin([defn], [m4_Word])) + 1))]
-m4_Prefix,
-       [m4_Separator])[]dnl
-m4_builtin([defn], [m4_Word])[]dnl
-m4_define([m4_Separator], [ ])])dnl
-m4_builtin([popdef], [m4_Separator])dnl
-m4_builtin([popdef], [m4_Cursor])dnl
-m4_builtin([popdef], [m4_Width])dnl
-m4_builtin([popdef], [m4_Prefix1])dnl
-m4_builtin([popdef], [m4_Prefix])dnl
-])
+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_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],
+  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
+dnl if so, reset cursor, and insert newline and prefix
+dnl if not, insert the separator (usually a space)
+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_define([m4_Cursor],
+                     m4_eval(m4_Indent
+                             + m4_qlen(m4_builtin([defn], [m4_Word])) + 1))
+m4_Prefix[]],
+      [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_text_box(MESSAGE, [FRAME-CHARACTER = `-'])
diff --git a/tests/m4sh.at b/tests/m4sh.at
index a523785..9c6624c 100644
--- a/tests/m4sh.at
+++ b/tests/m4sh.at
@@ -490,10 +490,8 @@ AT_CLEANUP
 ## AS_HELP_STRING ##
 ## -------------- ##
 
-# I'm not totally certain that we want to enforce the defaults here,
-# but at least it is being tested.
-
 AT_SETUP([AS@&address@hidden)
+AT_KEYWORDS([m4@&address@hidden)
 
 AT_DATA_M4SH([script.as],
 [[AS_INIT
@@ -545,6 +543,18 @@ echo "AS_HELP_STRING([[--foo[=bar]123456789012]],
 [some other t[]t which should wrap at our default of 80 characters.])"
 echo "AS_HELP_STRING([[--foo[=bar]1234567890123]],
 [some other t[]t which should wrap at our default of 80 characters.])"
+m4_define([mac], [MACRO])dnl
+echo "AS_HELP_STRING([--mac], [mac])"
+echo "AS_HELP_STRING([--o1, --o2], [two
+options,       one  description])"
+echo "AS_HELP_STRING([--tune1], [check out the tuned formatting],
+[            ])"
+echo "AS_HELP_STRING([--tune2], [check out the tuned formatting],
+[12])"
+echo "AS_HELP_STRING([--tune3], [check out the tuned formatting],
+[], [40])"
+echo "AS_HELP_STRING([--tune4], [check out the tuned formatting],
+[12], [40])"
 ]])
 
 AT_CHECK_M4SH
@@ -600,6 +610,15 @@ AT_CHECK([./script], [0],
   --foo[=bar]1234567890123
                           some other t[]t which should wrap at our default of
                           80 characters.
+  --MACRO                 mac
+  --o1, --o2              two options, one description
+  --tune1   check out the tuned formatting
+  --tune2   check out the tuned formatting
+  --tune3                 check out the
+                          tuned
+                          formatting
+  --tune4   check out the tuned
+            formatting
 ]])
 
 AT_CLEANUP
-- 
1.5.3.2









reply via email to

[Prev in Thread] Current Thread [Next in Thread]