Re: [17/18] argv_ref speedup: reuse $@ inside quoted strings

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

According to Eric Blake on 2/22/2008 6:31 AM:
| Also, since a $@ ref can contain arguments that are builtin function
| tokens from defn, those tokens should only be flattened to the empty
| string at the site(s) where they are used as strings rather than during
| argument collection.

And I missed a site on the master branch, leading to a regression in
defining certain macro values:

$ echo 'changequote([,])define(q,[[$@]])define(foo,q(a,b))' | tests/m4
lt-m4: m4/symtab.c:474: <unknown>: Assertion `chain->type ==
M4__CHAIN_STR' failed.
Aborted

Fortunately branch-1.6 is immune - the difference between branches is that
on the master, I hope to add code to allow defining a macro with a builtin
token concatenated with text.

- --
Don't work too hard, make some time for fun as well!

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

iEYEARECAAYFAkgZv4gACgkQ84KuGfSFAYAxyQCfU3mE5nAVOshuHfVEYZlm+9mZ
qaEAn2un+ueThaO0+0wL2XWnRErdQbIG
=bhZR
-----END PGP SIGNATURE-----

_______________________________________________
M4-patches mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/m4-patches
m4.patch342 (text/plain, 5.3 KB)
From c3e7dc183995ae374f6aedec21893b23196a5b39 Mon Sep 17 00:00:00 2001
From: Eric Blake <[email protected]>
Date: Thu, 1 May 2008 06:53:47 -0600
Subject: [PATCH] Fix regression in define from 2008-02-22.

* m4/m4module.h (m4_symbol_value_copy): Add parameter.
* m4/symtab.c (m4_symbol_value_copy): Support copying $@
back-references.
* m4/macro.c (expand_argument): Update callers.
* modules/m4.c (define, pushdef): Likewise.
* tests/builtins.at (define): Enhance test to catch this.

Signed-off-by: Eric Blake <[email protected]>
---
 ChangeLog         |   10 ++++++++++
 m4/m4module.h     |    2 +-
 m4/macro.c        |    2 +-
 m4/symtab.c       |   41 +++++++++++++++++++++++++----------------
 modules/m4.c      |    4 ++--
 tests/builtins.at |   10 ++++++++++
 6 files changed, 49 insertions(+), 20 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f53f91a..79da06b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2008-05-01  Eric Blake  <[email protected]>
+
+	Fix regression in define from 2008-02-22.
+	* m4/m4module.h (m4_symbol_value_copy): Add parameter.
+	* m4/symtab.c (m4_symbol_value_copy): Support copying $@
+	back-references.
+	* m4/macro.c (expand_argument): Update callers.
+	* modules/m4.c (define, pushdef): Likewise.
+	* tests/builtins.at (define): Enhance test to catch this.
+
 2008-04-21  Eric Blake  <[email protected]>
 
 	Simplify previous patch.
diff --git a/m4/m4module.h b/m4/m4module.h
index ced18d5..5b5e01b 100644
--- a/m4/m4module.h
+++ b/m4/m4module.h
@@ -312,7 +312,7 @@ extern bool	m4_symbol_value_flatten_args (m4_symbol_value *);
 
 extern m4_symbol_value *m4_symbol_value_create	  (void);
 extern void		m4_symbol_value_delete	  (m4_symbol_value *);
-extern void		m4_symbol_value_copy	  (m4_symbol_value *,
+extern void		m4_symbol_value_copy	  (m4 *, m4_symbol_value *,
 						   m4_symbol_value *);
 extern bool		m4_is_symbol_value_text   (m4_symbol_value *);
 extern bool		m4_is_symbol_value_func   (m4_symbol_value *);
diff --git a/m4/macro.c b/m4/macro.c
index 3072444..bd0f88b 100644
--- a/m4/macro.c
+++ b/m4/macro.c
@@ -392,7 +392,7 @@ expand_argument (m4 *context, m4_obstack *obs, m4_symbol_value *argp,
 
 	case M4_TOKEN_MACDEF:
 	  if (argp->type == M4_SYMBOL_VOID && obstack_object_size (obs) == 0)
-	    m4_symbol_value_copy (argp, &token);
+	    m4_symbol_value_copy (context, argp, &token);
 	  else
 	    argp->type = M4_SYMBOL_TEXT;
 	  break;
diff --git a/m4/symtab.c b/m4/symtab.c
index f4bb855..69f2200 100644
--- a/m4/symtab.c
+++ b/m4/symtab.c
@@ -406,7 +406,7 @@ arg_destroy_CB (m4_hash *hash, const void *name, void *arg, void *ignored)
 }
 
 void
-m4_symbol_value_copy (m4_symbol_value *dest, m4_symbol_value *src)
+m4_symbol_value_copy (m4 *context, m4_symbol_value *dest, m4_symbol_value *src)
 {
   m4_symbol_value *next;
 
@@ -465,26 +465,35 @@ m4_symbol_value_copy (m4_symbol_value *dest, m4_symbol_value *src)
     case M4_SYMBOL_COMP:
       {
 	m4__symbol_chain *chain = src->u.u_c.chain;
-	size_t len = 0;
+	size_t len;
 	char *str;
-	char *p;
+	const m4_string_pair *quotes;
+	m4_obstack *obs = m4_arg_scratch (context);
 	while (chain)
 	  {
-	    /* TODO for now, only text links are supported.  */
-	    assert (chain->type == M4__CHAIN_STR);
-	    len += chain->u.u_s.len;
+	    switch (chain->type)
+	      {
+	      case M4__CHAIN_STR:
+		obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
+		break;
+	      case M4__CHAIN_ARGV:
+		quotes = m4__quote_cache (M4SYNTAX, NULL, chain->quote_age,
+					  chain->u.u_a.quotes);
+		m4__arg_print (context, obs, chain->u.u_a.argv,
+			       chain->u.u_a.index, quotes, true, NULL, NULL,
+			       NULL, false, false);
+		break;
+	      default:
+		assert (!"m4_symbol_value_copy");
+		abort ();
+	      }
 	    chain = chain->next;
 	  }
-	p = str = xcharalloc (len + 1);
-	chain = src->u.u_c.chain;
-	while (chain)
-	  {
-	    memcpy (p, chain->u.u_s.str, chain->u.u_s.len);
-	    p += chain->u.u_s.len;
-	    chain = chain->next;
-	  }
-	*p = '\0';
-	m4_set_symbol_value_text (dest, str, len, 0);
+	obstack_1grow (obs, '\0');
+	len = obstack_object_size (obs);
+	str = xcharalloc (len);
+	memcpy (str, obstack_finish (obs), len);
+	m4_set_symbol_value_text (dest, str, len - 1, 0);
       }
       break;
     default:
diff --git a/modules/m4.c b/modules/m4.c
index f4013ef..b8562ec 100644
--- a/modules/m4.c
+++ b/modules/m4.c
@@ -157,7 +157,7 @@ M4BUILTIN_HANDLER (define)
     {
       m4_symbol_value *value = m4_symbol_value_create ();
 
-      m4_symbol_value_copy (value, m4_arg_symbol (argv, 2));
+      m4_symbol_value_copy (context, value, m4_arg_symbol (argv, 2));
       m4_symbol_define (M4SYMTAB, M4ARG (1), value);
     }
   else
@@ -179,7 +179,7 @@ M4BUILTIN_HANDLER (pushdef)
     {
       m4_symbol_value *value = m4_symbol_value_create ();
 
-      m4_symbol_value_copy (value, m4_arg_symbol (argv, 2));
+      m4_symbol_value_copy (context, value, m4_arg_symbol (argv, 2));
       m4_symbol_pushdef (M4SYMTAB, M4ARG (1), value);
     }
   else
diff --git a/tests/builtins.at b/tests/builtins.at
index c63246b..b059e7b 100644
--- a/tests/builtins.at
+++ b/tests/builtins.at
@@ -210,6 +210,16 @@ base value.
 ]], [[m4:define.m4:1: Warning: undefine: undefined macro `macro'
 ]])
 
+dnl check regression present 2008-02-22 to 2008-04-30.
+AT_DATA([in.m4], [[define(`qq', ``$*;$@'')dnl
+define(`foo', qq(`a', `b'))dnl
+foo
+defn(`foo')
+]])
+AT_CHECK_M4([in.m4], [0], [[a,b;a,b
+a,b;`a',`b'
+]])
+
 AT_CLEANUP
 
 
-- 
1.5.5.1
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.