summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2008-05-03 11:51:55 -0600
committerEric Blake <ebb9@byu.net>2008-05-03 11:51:55 -0600
commit26b3c17ceb4f4155ff5dd13bcd9cc63039b3f242 (patch)
treeb43dc15c474a845063b42cc2317046358ee67918
parentf87a1e3fe98dd9bf9c746f24a0e8d18958c693e3 (diff)
downloadm4-26b3c17ceb4f4155ff5dd13bcd9cc63039b3f242.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 1454e02d..63628096 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-04-24 Eric Blake <ebb9@byu.net>
Fix debugmode regression from 2008-04-14.
diff --git a/THANKS b/THANKS
index eb2a79d3..19c1d92f 100644
--- a/THANKS
+++ b/THANKS
@@ -74,6 +74,7 @@ Michael Fetterman mafetter@ichips.intel.com
Michael L. Welcome welcome@bigbird.llnl.gov
Mike Frysinger vapier@gentoo.org
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 0da6b002..4781567a 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -2761,6 +2761,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