m4-discuss
[Top][All Lists]
Advanced

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

Re: How to patsubst the result of an include?


From: Gary V. Vaughan
Subject: Re: How to patsubst the result of an include?
Date: Fri, 04 Feb 2005 17:53:49 +0000
User-agent: Mozilla Thunderbird 0.9 (X11/20041103)

Hi!

Stepan Kasal wrote:
> 
>       indirq(`macro', a, b, c)
>       indirq(`include', `file')
> 
> The name `indirq' stands for `indir quoted', because expanding once is the
> same as returning quoted body of the macro.  That's why I said it's similar
> to `defn'--in fact, it's the same if the macro body doesn't contain any $.

You know, I rather like that... it certainly doesn't break legacy code :-)
I've attached a patch against CVS branch-1_4 that implements it (I called
it qindir to follow the convention set by sinclude).  What do you think?

> If you wish that all includes return the body quoted, you can do
> 
>       define(`include_orig', defn(`include'))
>       define(`include', `indirq(`include_orig', $1)')
> 
> and similarily for other builtins.

Actually, with the attached implementation, that won't work because when
GNU M4 puts a file on the input stack (ala include) any partial string
that doesn't come from the stack is lost :-(  So it still doesn't solve
Matthew's problem.  But in all other cases it does give proper additional
quoting :-)

    define(a, z)dnl
    define(foo, `a, $1, c')dnl
    foo(b)
       => z, b, c
    indir(`foo', `b')
       => z, b, c
    qindir(`foo', `b')
       => a, b, c
    qindir(`qindir', `foo', `b')
       => `a, b, c'

Cheers,
        Gary.
-- 
Gary V. Vaughan      ())_.  address@hidden,gnu.org}
Research Scientist   ( '/   http://tkd.kicks-ass.net
GNU Hacker           / )=   http://www.gnu.org/software/libtool
Technical Author   `(_~)_   http://sources.redhat.com/autobook
? Makefile
? autom4te.cache
? config.h
? config.log
? config.status
? m4-1.4.2a.tar.gz
? qindir.patch
? stamp-h
? checks/Makefile
? doc/Makefile
? examples/Makefile
? lib/Makefile
? src/Makefile
? src/foo
? src/foo.m4
? src/m4
Index: src/builtin.c
===================================================================
RCS file: /cvsroot/m4/m4/src/Attic/builtin.c,v
retrieving revision 1.1.1.1.2.2
diff -u -p -r1.1.1.1.2.2 builtin.c
--- src/builtin.c       21 Aug 2004 11:16:04 -0000      1.1.1.1.2.2
+++ src/builtin.c       4 Feb 2005 17:41:01 -0000
@@ -1,18 +1,18 @@
 /* GNU m4 -- A simple macro processor
 
-   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2000, 2004 Free
+   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2000, 2004, 2005 Free
    Software Foundation, Inc.
-  
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
    any later version.
-  
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-  
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -70,6 +70,7 @@ DECLARE (m4_maketemp);
 DECLARE (m4_patsubst);
 DECLARE (m4_popdef);
 DECLARE (m4_pushdef);
+DECLARE (m4_qindir);
 DECLARE (m4_regexp);
 DECLARE (m4_shift);
 DECLARE (m4_sinclude);
@@ -124,6 +125,7 @@ builtin_tab[] =
   { "patsubst",                TRUE,   FALSE,  TRUE,   m4_patsubst },
   { "popdef",          FALSE,  FALSE,  TRUE,   m4_popdef },
   { "pushdef",         FALSE,  TRUE,   TRUE,   m4_pushdef },
+  { "qindir",          TRUE,   FALSE,  FALSE,  m4_qindir },
   { "regexp",          TRUE,   FALSE,  TRUE,   m4_regexp },
   { "shift",           FALSE,  FALSE,  FALSE,  m4_shift },
   { "sinclude",                FALSE,  FALSE,  TRUE,   m4_sinclude },
@@ -386,9 +388,9 @@ dump_args (struct obstack *obs, int argc
 
 /* The rest of this file is code for builtins and expansion of user
    defined macros.  All the functions for builtins have a prototype as:
-   
+
        void m4_MACRONAME (struct obstack *obs, int argc, char *argv[]);
-   
+
    The function are expected to leave their expansion on the obstack OBS,
    as an unfinished object.  ARGV is a table of ARGC pointers to the
    individual arguments to the macro.  Please note that in general
@@ -696,13 +698,34 @@ m4_indir (struct obstack *obs, int argc,
     M4ERROR ((warning_status, 0,
              "Undefined macro `%s'", name));
   else
-    call_macro (s, argc - 1, argv + 1, obs);
+    call_macro (obs, s, argc - 1, argv + 1);
+}
+
+static void
+m4_qindir (struct obstack *obs, int argc, token_data **argv)
+{
+  symbol *s;
+  const char *name = ARG (1);
+
+  if (bad_argc (argv[0], argc, 1, -1))
+    return;
+
+  s = lookup_symbol (name, SYMBOL_LOOKUP);
+  if (s == NULL)
+    M4ERROR ((warning_status, 0,
+             "Undefined macro `%s'", name));
+  else
+    {
+      obstack_grow (obs, lquote.string, lquote.length);
+      call_macro (obs, s, argc -1, argv + 1);
+      obstack_grow (obs, rquote.string, rquote.length);
+    }
 }
 
 /*-------------------------------------------------------------------------.
 | 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
@@ -1523,7 +1546,7 @@ WARNING: \\0 will disappear, use \\& ins
          break;
 
        case '1': case '2': case '3': case '4': case '5': case '6':
-       case '7': case '8': case '9': 
+       case '7': case '8': case '9':
          ch -= '0';
          if (regs->end[ch] > 0)
            obstack_grow (obs, victim + regs->start[ch],
Index: src/m4.h
===================================================================
RCS file: /cvsroot/m4/m4/src/m4.h,v
retrieving revision 1.1.1.1.2.3
diff -u -p -r1.1.1.1.2.3 m4.h
--- src/m4.h    3 Feb 2005 17:11:46 -0000       1.1.1.1.2.3
+++ src/m4.h    4 Feb 2005 17:41:01 -0000
@@ -412,7 +412,7 @@ void hack_all_symbols _((hack_symbol *, 
 /* File: macro.c  --- macro expansion.  */
 
 void expand_input _((void));
-void call_macro _((symbol *, int, token_data **, struct obstack *));
+void call_macro _((struct obstack *, symbol *, int, token_data **));
 
 /* File: builtin.c  --- builtins.  */
 
Index: src/macro.c
===================================================================
RCS file: /cvsroot/m4/m4/src/Attic/macro.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 macro.c
--- src/macro.c 17 Feb 2000 03:03:19 -0000      1.1.1.1
+++ src/macro.c 4 Feb 2005 17:41:01 -0000
@@ -1,16 +1,18 @@
 /* GNU m4 -- A simple macro processor
-   Copyright (C) 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
-  
+
+   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2005 Free Software
+   Foundation, Inc.
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2, or (at your option)
    any later version.
-  
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-  
+
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
@@ -235,8 +237,8 @@ collect_arguments (symbol *sym, struct o
 `------------------------------------------------------------------------*/
 
 void
-call_macro (symbol *sym, int argc, token_data **argv,
-                struct obstack *expansion)
+call_macro (struct obstack *expansion, symbol *sym,
+               int argc, token_data **argv)
 {
   switch (SYMBOL_TYPE (sym))
     {
@@ -303,7 +305,7 @@ expand_macro (symbol *sym)
     trace_pre (SYMBOL_NAME (sym), my_call_id, argc, argv);
 
   expansion = push_string_init ();
-  call_macro (sym, argc, argv, expansion);
+  call_macro (expansion, sym, argc, argv);
   expanded = push_string_finish ();
 
   if (traced)

Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

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