summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2008-05-03 13:31:14 -0600
committerEric Blake <ebb9@byu.net>2008-05-03 13:31:14 -0600
commitbc9b4d7bf16c7571efe03debaf2c6f1d52a6a08d (patch)
tree43c9b8ebd1bd9328d89533350b79af6692441407
parent1dd98ea10e065300cfa110b7305362c1f12ed00f (diff)
downloadm4-bc9b4d7bf16c7571efe03debaf2c6f1d52a6a08d.tar.gz
Document define_blind.
* doc/m4.texinfo (Ifelse): Add a new composite macro. * THANKS: Update. Suggested by Mike R. Signed-off-by: Eric Blake <ebb9@byu.net>
-rw-r--r--ChangeLog7
-rw-r--r--THANKS1
-rw-r--r--doc/m4.texinfo57
3 files changed, 65 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index 44df3708..cd1f9276 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2008-05-03 Eric Blake <ebb9@byu.net>
+
+ Document define_blind.
+ * doc/m4.texinfo (Ifelse): Add a new composite macro.
+ * THANKS: Update.
+ Suggested by Mike R.
+
2008-05-01 Eric Blake <ebb9@byu.net>
Avoid -Wshadow compiler warnings.
diff --git a/THANKS b/THANKS
index 4fd8db40..807bd1b7 100644
--- a/THANKS
+++ b/THANKS
@@ -97,6 +97,7 @@ Mike Andrews kramer@fragile.termfrost.org
Mike Frysinger vapier@gentoo.org
Mike Howard mike@clove.com
Mike Lijewski lijewski@theory.tc.cornell.edu
+Mike R. mroberge@aol.com
Mikhail Teterin Mikhail.Teterin@murex.com
Nelson H. F. Beebe beebe@math.utah.edu
Nick S. Kanakakorn skanan@otl.scu.edu
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index c593a8da..75d7fc84 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -2996,6 +2996,63 @@ foo(`a', `b', `c')
@result{}arguments:3
@end example
+Since m4 is a macro language, it is even possible to write a macro that
+makes defining blind macros easier:
+
+@deffn Composite define_blind (@var{name}, @ovar{value})
+Defines @var{name} as a blind macro, such that @var{name} will expand to
+@var{value} only when given explicit arguments. @var{value} should not
+be the result of @code{defn} (@pxref{Defn}). This macro is only
+recognized with parameters, and results in an empty string.
+@end deffn
+
+Defining a macro to define another macro can be a bit tricky. We want
+to use a literal @samp{$#} in the argument to the nested @code{define}.
+However, if @samp{$} and @samp{#} are adjacent in the definition of
+@code{define_blind}, then it would be expanded as the number of
+arguments to @code{define_blind} rather than the intended number of
+arguments to @var{name}. The solution is to pass the difficult
+characters through extra arguments to a helper macro
+@code{_define_blind}.
+
+As for the limitation against using @code{defn}, there are two reasons.
+If a macro was previously defined with @code{define_blind}, then it can
+safely be renamed to a new blind macro using plain @code{define}; using
+@code{define_blind} to rename it just adds another layer of
+@code{ifelse}, occupying memory and slowing down execution. And if a
+macro is a builtin, then it would result in an attempt to define a macro
+consisting of both text and a builtin token; this is not supported, and
+the builtin token is flattened to an empty string.
+
+With that explanation, here's the definition, and some sample usage.
+Notice that @code{define_blind} is itself a blind macro.
+
+@example
+$ @kbd{m4 -d}
+define(`define_blind', `ifelse(`$#', `0', ``$0'',
+`_$0(`$1', `$2', `$'`#', `$'`0')')')
+@result{}
+define(`_define_blind', `define(`$1',
+`ifelse(`$3', `0', ``$4'', `$2')')')
+@result{}
+define_blind
+@result{}define_blind
+define_blind(`foo', `arguments were $*')
+@result{}
+foo
+@result{}foo
+foo(`bar')
+@result{}arguments were bar
+define(`blah', defn(`foo'))
+@result{}
+blah
+@result{}blah
+blah(`a', `b')
+@result{}arguments were a,b
+defn(`blah')
+@result{}ifelse(`$#', `0', ``$0'', `arguments were $*')
+@end example
+
@cindex multibranches
@cindex switch statement
@cindex case statement