m4-patches
[Top][All Lists]
Advanced

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

more foreach documentation


From: Eric Blake
Subject: more foreach documentation
Date: Tue, 19 Feb 2008 21:04:12 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

In trying to decide what semantics would make sense for a new list module, I 
discovered another reason why foreachq2.m4 is better than foreachq.m4.  I'm 
installing this patch to head, and a similar one to the branch (the branch 
lacks m4symbols, so we can't filter on defined symbols on the branch).

From: Eric Blake <address@hidden>
Date: Tue, 19 Feb 2008 12:18:05 -0700
Subject: [PATCH] Clean up example on filtering defined symbols.

* doc/m4.texinfo (Foreach, Improved foreach): Document another
shortcoming in foreach.m4, and improve filter example by using
foreach2.m4.

Signed-off-by: Eric Blake <address@hidden>
---
 ChangeLog      |    5 +++
 doc/m4.texinfo |   81 +++++++++++++++++++++++++++++++++++++------------------
 2 files changed, 59 insertions(+), 27 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index d6e258d..1832be1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,10 @@
 2008-02-19  Eric Blake  <address@hidden>
 
+       Clean up example on filtering defined symbols.
+       * doc/m4.texinfo (Foreach, Improved foreach): Document another
+       shortcoming in foreach.m4, and improve filter example by using
+       foreach2.m4.
+
        * src/main.c (usage): Fix typo.
 
 2008-02-18  Eric Blake  <address@hidden>
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index 571c0dc..011fbfb 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -3362,38 +3362,26 @@ has its own severe flaw.  Whereas the @code{foreach} 
implementation was
 linear, this macro is quadratic in the number of list elements, and is
 much more likely to trip up the limit set by the command line option
 @option{--nesting-limit} (or @option{-L}, @pxref{Limits control, ,
-Invoking m4}).  (It is possible to have robust iteration with linear
-behavior for either list style.  See if you can learn from the best
-elements of both of these implementations to create robust macros; or
address@hidden foreach, , Answers}).
-
-With a robust @code{foreach} implementation, it is possible to create a
-filter on a list of defined symbols.  This next example will find all
-symbols that contain @samp{if}.  Notice the use of @code{dquote} and
address@hidden to ensure that the list of macro names is properly
-quoted; without these, the iteration would be invoking various macros
-with catastrophic effects.  This example also shows a trick for
-generating the correct number of commas in the resulting output.
+Invoking m4}).  Additionally, this implementation does not expand
address@hidden(address@hidden')} very well, when compared with
address@hidden
 
 @comment examples
 @example
 $ @kbd{m4 -I examples}
-include(`quote.m4')include(`foreachq.m4')
address@hidden
-pushdef(`sep', ``, '')
address@hidden
-pushdef(`cleanup', `popdef(`sep', `cleanup')')
address@hidden
-pushdef(`sep', `define(`cleanup',
-  `popdef(`cleanup')')popdef(`sep')')
address@hidden
-foreachq(`macro', dquote(dquote_elt(m4symbols)),
-  `regexp(macro, `.*if.*', `sep`\&'')')
address@hidden, ifelse, shift
-cleanup
+include(`foreach.m4')include(`foreachq.m4')
 @result{}
+foreach(`name', `(`a', `b')', ` defn(`name')')
address@hidden a b
+foreachq(`name', ``a', `b'', ` defn(`name')')
address@hidden _arg1(`a', `b') _arg1(shift(`a', `b'))
 @end example
 
+It is possible to have robust iteration with linear behavior and sane
address@hidden contents for either list style.  See if you can learn
+from the best elements of both of these implementations to create robust
+macros (or @pxref{Improved foreach, , Answers}).
+
 @node Debugging
 @chapter How to debug macros and input
 
@@ -8405,7 +8393,9 @@ Note that the fixed version calls unquoted helper macros 
in
 in turn must re-supply the layer of quotes lost in the macro invocation.
 Contrast the use of @address@hidden, which quotes the first list
 element, with @address@hidden of the earlier implementation that
-returned the first list element directly.
+returned the first list element directly.  Additionally, by calling the
+helper method immediately, the @samp{defn(address@hidden')} no longer
+contains unexpanded macros.
 
 The astute m4 programmer might notice that the solution above still uses
 more memory, and thus more time, than strictly necessary.  Note that
@@ -8501,10 +8491,43 @@ foreach(`x', `(`1', `2', `3', `4')', `x
 @error{}m4trace: -3- shift(``4'')
 @end example
 
address@hidden filtering defined symbols
address@hidden subset of defined symbols
address@hidden defined symbols, filtering
+With a robust @code{foreachq} implementation, it is possible to create a
+filter on a list of defined symbols.  This next example will find all
+symbols that contain @samp{if} or @samp{def}, via two different
+approaches.  In the first approach, @code{dquote_elt} is used to
+overquote each list element, then @code{dquote} forms the list; that
+way, the iterator @code{macro} can be expanded in place because its
+contents are already quoted.  This approach also uses a self-modifying
+macro @code{sep} to provide the correct number of commas.  In the second
+approach, the iterator @code{macro} contains live text, so it must be
+used with @code{defn} to avoid unintentional expansion.  The correct
+number of commas is achieved by using @code{shift} to ignore the first
+one, although a leading space still remains.
+
address@hidden examples
address@hidden
+$ @kbd{m4 -I examples}
+include(`quote.m4')include(`foreachq2.m4')
address@hidden
+pushdef(`sep', `define(`sep', ``, '')')
address@hidden
+foreachq(`macro', dquote(dquote_elt(m4symbols)),
+  `regexp(macro, `.*if.*', `sep`\&'')')
address@hidden, ifelse, shift
+popdef(`sep')
address@hidden
+shift(foreachq(`macro', dquote(m4symbols),
+  `regexp(defn(`macro'), `def', `,` ''dquote(defn(`macro')))'))
address@hidden define, defn, dumpdef, ifdef, popdef, pushdef, undefine
address@hidden example
+
 In summary, recursion over list elements is trickier than it appeared at
 first glance, but provides a powerful idiom within @code{m4} processing.
 As a final demonstration, both list styles are now able to handle
-several scenarios that would wreak havoc on the original
+several scenarios that would wreak havoc on one or both of the original
 implementations.  This points out one other difference between the
 list styles.  @code{foreach} evaluates unquoted list elements only once,
 in preparation for calling @address@hidden, similary for
@@ -8538,6 +8561,10 @@ foreach(`x', `(`,')', `<x>') / foreachq(`x', ``,'', 
`<x>')
 dnl 2-element list of unbalanced parentheses
 foreach(`x', `(`(', `)')', `<x>') / foreachq(`x', ``(', `)'', `<x>')
 @result{}<(><)> / <(><)>
+define(`ab', `oops')dnl using defn(`iterator')
+foreach(`x', `(`a', `b')', `defn(`x')') /dnl
+ foreachq(`x', ``a', `b'', `defn(`x')')
address@hidden / ab
 define(`active', `ACT, IVE')
 @result{}
 traceon(`active')
-- 
1.5.4







reply via email to

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