branch-1_4 builtin vs. defn

Eric Blake <[email protected]>
Newsgroups gmane.comp.gnu.m4.patches
Message-ID <[email protected]>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I found it annoying that builtin(`define', `foo', defn(`dnl')) didn't work
the same way as define(`foo', defn(`dnl')).  I will be porting this to
head as well.

2006-10-13  Eric Blake  <[email protected]>

	* src/builtin.c (m4_builtin, m4_indir): Allow transparent
	handling of defn results.
	* doc/m4.texinfo (Builtin, Indir): Add test cases.
	* NEWS: Document this.

- --
Life is short - so eat dessert first!

Eric Blake             [email protected]
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2.1 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFFL42F84KuGfSFAYARAv3TAJ94L8+7xrp0ahq7v0A2+EJIb3IA4ACgq6Oz
suDwj8XYQuuo7PM08W/kNTU=
=RMLZ
-----END PGP SIGNATURE-----

_______________________________________________
M4-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/m4-patches
m4.patch183 (text/plain, 6.3 KB)
Index: NEWS
===================================================================
RCS file: /sources/m4/m4/NEWS,v
retrieving revision 1.1.1.1.2.70
diff -u -p -r1.1.1.1.2.70 NEWS
--- NEWS	11 Oct 2006 23:34:21 -0000	1.1.1.1.2.70
+++ NEWS	13 Oct 2006 12:56:28 -0000
@@ -20,6 +20,8 @@ Version 1.4.8 - ?? ??? 2006, by ??  (CVS
   rather than changing to line 0 and the empty string for a file.  The
   macros `__line__' and `__file__' now work correctly even as the last
   token in an included file.
+* The `builtin' and `indir' macros now transparently handle builtin
+  tokens generated by `defn'.
 
 Version 1.4.7 - 25 September 2006, by Eric Blake  (CVS version 1.4.6a)
 
Index: doc/m4.texinfo
===================================================================
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision 1.1.1.1.2.83
diff -u -p -r1.1.1.1.2.83 m4.texinfo
--- doc/m4.texinfo	12 Oct 2006 14:10:35 -0000	1.1.1.1.2.83
+++ doc/m4.texinfo	13 Oct 2006 12:56:29 -0000
@@ -1768,6 +1768,27 @@ indir(`f', undefine(`f'))
 @result{}
 @end example
 
+When handed the result of @code{defn} (@pxref{Defn}) as one of its
+arguments, @code{indir} defers to the invoked @var{name} for whether a
+token representing a builtin is recognized or flattened to the empty
+string.
+
+@example
+indir(defn(`defn'), `divnum')
+@error{}m4:stdin:1: Warning: indir: invalid macro name ignored
+@result{}
+indir(`define', defn(`defn'), `divnum')
+@error{}m4:stdin:2: Warning: define: invalid macro name ignored
+@result{}
+indir(`define', `foo', defn(`divnum'))
+@result{}
+foo
+@result{}0
+indir(`divert', defn(`foo'))
+@error{}m4:stdin:5: empty string treated as 0 in builtin `divert'
+@result{}
+@end example
+
 @node Builtin
 @section Indirect call of builtins
 
@@ -1798,6 +1819,10 @@ define(`foo', `bar')
 @result{}hidden
 foo
 @result{}foo
+builtin(`define', `foo', defn(`divnum'))
+@result{}
+foo
+@result{}0
 builtin(`define', `foo', `BAR')
 @result{}
 foo
Index: src/builtin.c
===================================================================
RCS file: /sources/m4/m4/src/Attic/builtin.c,v
retrieving revision 1.1.1.1.2.41
diff -u -p -r1.1.1.1.2.41 builtin.c
--- src/builtin.c	10 Oct 2006 03:54:26 -0000	1.1.1.1.2.41
+++ src/builtin.c	13 Oct 2006 12:56:29 -0000
@@ -19,7 +19,7 @@
    02110-1301  USA
 */
 
-/* Code for all builtin macros, initialisation of symbol table, and
+/* Code for all builtin macros, initialization of symbol table, and
    expansion of user defined macros.  */
 
 #include "m4.h"
@@ -34,8 +34,8 @@ extern FILE *popen ();
 
 #define ARG(i)	(argc > (i) ? TOKEN_DATA_TEXT (argv[i]) : "")
 
-/* Initialisation of builtin and predefined macros.  The table
-   "builtin_tab" is both used for initialisation, and by the "builtin"
+/* Initialization of builtin and predefined macros.  The table
+   "builtin_tab" is both used for initialization, and by the "builtin"
    builtin.  */
 
 #define DECLARE(name) \
@@ -99,7 +99,7 @@ builtin_tab[] =
   { "__file__",		TRUE,	FALSE,	FALSE,	m4___file__ },
   { "__line__",		TRUE,	FALSE,	FALSE,	m4___line__ },
   { "__program__",	TRUE,	FALSE,	FALSE,	m4___program__ },
-  { "builtin",		TRUE,	FALSE,	TRUE,	m4_builtin },
+  { "builtin",		TRUE,	TRUE,	TRUE,	m4_builtin },
   { "changecom",	FALSE,	FALSE,	FALSE,	m4_changecom },
   { "changequote",	FALSE,	FALSE,	FALSE,	m4_changequote },
 #ifdef ENABLE_CHANGEWORD
@@ -123,7 +123,7 @@ builtin_tab[] =
   { "include",		FALSE,	FALSE,	TRUE,	m4_include },
   { "incr",		FALSE,	FALSE,	TRUE,	m4_incr },
   { "index",		FALSE,	FALSE,	TRUE,	m4_index },
-  { "indir",		TRUE,	FALSE,	TRUE,	m4_indir },
+  { "indir",		TRUE,	TRUE,	TRUE,	m4_indir },
   { "len",		FALSE,	FALSE,	TRUE,	m4_len },
   { "m4exit",		FALSE,	FALSE,	FALSE,	m4_m4exit },
   { "m4wrap",		FALSE,	FALSE,	TRUE,	m4_m4wrap },
@@ -239,7 +239,7 @@ define_user_macro (const char *name, con
 }
 
 /*-----------------------------------------------.
-| Initialise all builtin and predefined macros.	 |
+| Initialize all builtin and predefined macros.	 |
 `-----------------------------------------------*/
 
 void
@@ -712,17 +712,34 @@ static void
 m4_builtin (struct obstack *obs, int argc, token_data **argv)
 {
   const builtin *bp;
-  const char *name = ARG (1);
+  const char *name;
 
   if (bad_argc (argv[0], argc, 2, -1))
     return;
+  if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
+    {
+      M4ERROR ((warning_status, 0,
+		"Warning: %s: invalid macro name ignored", ARG (0)));
+      return;
+    }
 
+  name = ARG (1);
   bp = find_builtin_by_name (name);
   if (bp->func == m4_placeholder)
     M4ERROR ((warning_status, 0,
 	      "undefined builtin `%s'", name));
   else
-    (*bp->func) (obs, argc - 1, argv + 1);
+    {
+      int i;
+      if (! bp->groks_macro_args)
+	for (i = 2; i < argc; i++)
+	  if (TOKEN_DATA_TYPE (argv[i]) != TOKEN_TEXT)
+	    {
+	      TOKEN_DATA_TYPE (argv[i]) = TOKEN_TEXT;
+	      TOKEN_DATA_TEXT (argv[i]) = "";
+	    }
+      bp->func (obs, argc - 1, argv + 1);
+    }
 }
 
 /*------------------------------------------------------------------------.
@@ -736,23 +753,40 @@ static void
 m4_indir (struct obstack *obs, int argc, token_data **argv)
 {
   symbol *s;
-  const char *name = ARG (1);
+  const char *name;
 
   if (bad_argc (argv[0], argc, 2, -1))
     return;
+  if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
+    {
+      M4ERROR ((warning_status, 0,
+		"Warning: %s: invalid macro name ignored", ARG (0)));
+      return;
+    }
 
+  name = ARG (1);
   s = lookup_symbol (name, SYMBOL_LOOKUP);
   if (s == NULL || SYMBOL_TYPE (s) == TOKEN_VOID)
     M4ERROR ((warning_status, 0,
 	      "undefined macro `%s'", name));
   else
-    call_macro (s, argc - 1, argv + 1, obs);
+    {
+      int i;
+      if (! SYMBOL_MACRO_ARGS (s))
+	for (i = 2; i < argc; i++)
+	  if (TOKEN_DATA_TYPE (argv[i]) != TOKEN_TEXT)
+	    {
+	      TOKEN_DATA_TYPE (argv[i]) = TOKEN_TEXT;
+	      TOKEN_DATA_TEXT (argv[i]) = "";
+	    }
+      call_macro (s, argc - 1, argv + 1, obs);
+    }
 }
 
 /*-------------------------------------------------------------------------.
 | The macro "defn" returns the quoted definition of the macro named by the |
 | first argument.  If the macro is builtin, it will push a special	   |
-| macro-definition token on ht input stack.				   |
+| macro-definition token on the input stack.				   |
 `-------------------------------------------------------------------------*/
 
 static void
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.