m4-commit
[Top][All Lists]
Advanced

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

[SCM] GNU M4 source repository branch, branch-1.6, updated. v1.5.89a-18-


From: Eric Blake
Subject: [SCM] GNU M4 source repository branch, branch-1.6, updated. v1.5.89a-18-g50fabc4
Date: Tue, 06 May 2008 03:55:39 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU M4 source repository".

http://git.sv.gnu.org/gitweb/?p=m4.git;a=commitdiff;h=50fabc46c235da6682f1bd76b1b43151e147c7bc

The branch, branch-1.6 has been updated
       via  50fabc46c235da6682f1bd76b1b43151e147c7bc (commit)
      from  26b3c17ceb4f4155ff5dd13bcd9cc63039b3f242 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 50fabc46c235da6682f1bd76b1b43151e147c7bc
Author: Eric Blake <address@hidden>
Date:   Thu Dec 6 14:47:26 2007 -0700

    Stage 22: allow builtin token concatenation outside address@hidden
    
    * src/m4.h (arg_text): Add parameter.
    (ARG): Adjust callers.
    * src/input.c (init_macro_token): Add parameter.
    (next_token): Support concatenating builtins.
    * src/macro.c (warn_builtin_concat): Delete warning.
    (expand_argument, arg_adjust_refcount): Handle builtin tokens.
    (arg_text): Add parameter.
    (arg_print): Adjust caller.
    * src/builtin.c (define_macro): Flatten builtins, rather than
    doing nothing.
    (defn): Warn on undefined macro name.
    * src/m4.c (main): Avoid atoi.
    * src/output.c: Whitespace fixes.
    * doc/m4.texinfo (Defn): Document the new semantics.
    (Ifelse, Debug Levels, M4wrap): Enhance tests.
    * NEWS: Document this change.
    
    (cherry picked from commit 8a47a2029b7eb60ac61abb1b6423d4a67b371281)
    
    Signed-off-by: Eric Blake <address@hidden>

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog      |   25 ++++++++++++++++
 NEWS           |   10 ++++++
 doc/m4.texinfo |   80 ++++++++++++++++++++++++++++------------------------
 src/builtin.c  |   21 ++++++-------
 src/input.c    |   84 +++++++++++++++++++++++--------------------------------
 src/m4.c       |    2 +-
 src/m4.h       |    6 ++--
 src/macro.c    |   76 ++++++++++++++++++++------------------------------
 src/output.c   |    4 +-
 9 files changed, 159 insertions(+), 149 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6362809..91c1845 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2008-05-05  Eric Blake  <address@hidden>
+
+       Stage 22: allow builtin token concatenation outside address@hidden
+       Adjust the input and argument parsing engines to append builtins
+       alongside text.  Make define warn when builtins must be
+       flattened.
+       Memory impact: slight penalty, with fewer builtins flattened.
+       Speed impact: slight penalty, from more bookkeeping.
+       * src/m4.h (arg_text): Add parameter.
+       (ARG): Adjust callers.
+       * src/input.c (init_macro_token): Add parameter.
+       (next_token): Support concatenating builtins.
+       * src/macro.c (warn_builtin_concat): Delete warning.
+       (expand_argument, arg_adjust_refcount): Handle builtin tokens.
+       (arg_text): Add parameter.
+       (arg_print): Adjust caller.
+       * src/builtin.c (define_macro): Flatten builtins, rather than
+       doing nothing.
+       (defn): Warn on undefined macro name.
+       * src/m4.c (main): Avoid atoi.
+       * src/output.c: Whitespace fixes.
+       * doc/m4.texinfo (Defn): Document the new semantics.
+       (Ifelse, Debug Levels, M4wrap): Enhance tests.
+       * NEWS: Document this change.
+
 2008-05-03  Eric Blake  <address@hidden>
 
        Document define_blind.
diff --git a/NEWS b/NEWS
index 0ca3094..052cbbc 100644
--- a/NEWS
+++ b/NEWS
@@ -33,9 +33,19 @@ Foundation, Inc.
    then apply this patch:
      http://git.sv.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=56d42fa71
 
+** The `defn' builtin now warns when operating on an undefined macro name.
+   To simulate 1.4.x behavior, use:
+     pushdef(`defn', `ifdef(`$1', `builtin(`defn', `$1')')')
+
 ** Enhance the `ifdef', `ifelse', and `shift' builtins, as well as all
    user macros, to transparently handle builtin tokens generated by `defn'.
 
+** Allow the concatenation of builtin macros with arbitrary text in
+   several contexts, via the `defn' builtin or argument expansion, rather
+   than warning and converting the builtin token to an empty string.
+   However, it is still not possible to use a concatenated builtin when
+   defining a macro.
+
 ** Enhance the `defn', `dumpdef', `ifdef', `popdef', `traceon', `traceoff',
    and `undefine' macros to warn when encountering a builtin token in the
    context of a macro name, rather than acting on the empty string.  This
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index 4781567..fd04622 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -2112,17 +2112,14 @@ the builtin @code{defn}:
 @deffn Builtin defn (@address@hidden)
 Expands to the @emph{quoted definition} of each @var{name}.  If an
 argument is not a defined macro, the expansion for that argument is
-empty.
+empty and triggers a warning.
 
 If @var{name} is a user-defined macro, the quoted definition is simply
-the quoted expansion text.  If, instead, there is only one @var{name}
-and it is a builtin, the
+the quoted expansion text.  If, instead, @var{name} is a builtin, the
 expansion is a special token, which points to the builtin's internal
-definition.  This token is only meaningful as the second argument to
+definition.  This token meaningful primarily as the second argument to
 @code{define} (and @code{pushdef}), and is silently converted to an
-empty string in most other contexts.  Using multiple @var{name} to
-combine a builtin with anything else is not supported; a warning is
-issued and the builtin is omitted from the final expansion.
+empty string in many other contexts.
 
 The macro @code{defn} is recognized only with parameters.
 @end deffn
@@ -2281,14 +2278,18 @@ bar
 @result{}0
 @end example
 
-Also note that as of M4 1.6, @code{defn} with multiple arguments can
-join text with builtin tokens.  However, when collecting macro
-arguments, a builtin token is preserved only when it occurs in
-isolation.  A future version of @acronym{GNU} M4 may lift this
-restriction.
+A warning is issued if @var{name} is undefined.  Also note that as of M4
+1.6, @code{defn} with multiple arguments can join text with builtin
+tokens.  However, when defining a macro via @code{define} or
address@hidden, a warning is issued and the builtin token ignored if the
+builtin token does not occur in isolation.  A future version of
address@hidden M4 may lift this restriction.
 
 @example
 $ @kbd{m4 -d}
+defn(`foo')
address@hidden:stdin:1: Warning: defn: undefined macro `foo'
address@hidden
 define(`a', `A')define(`AA', `b')
 @result{}
 traceon(`defn', `define')
@@ -2298,29 +2299,28 @@ defn(`a', `divnum', `a')
 @result{}AA
 define(`mydivnum', defn(`divnum', `divnum'))mydivnum
 @error{}m4trace: -2- defn(`divnum', `divnum') -> `<divnum><divnum>'
address@hidden:stdin:4: Warning: define: cannot concatenate builtin `divnum'
address@hidden:stdin:4: Warning: define: cannot concatenate builtin `divnum'
address@hidden: -1- define(`mydivnum', `')
address@hidden:stdin:5: Warning: define: cannot concatenate builtins
address@hidden: -1- define(`mydivnum', `<divnum><divnum>')
 @result{}
-traceoff(`defn', `define')
+traceoff(`defn', `define')dumpdef(`mydivnum')
address@hidden:@tabchar{}`'
 @result{}
 define(`mydivnum', defn(`divnum')defn(`divnum'))mydivnum
address@hidden:stdin:6: Warning: define: cannot concatenate builtin `divnum'
address@hidden:stdin:6: Warning: define: cannot concatenate builtin `divnum'
address@hidden:stdin:7: Warning: define: cannot concatenate builtins
 @result{}
 define(`mydivnum', defn(`divnum')`a')mydivnum
address@hidden:stdin:7: Warning: define: cannot concatenate builtin `divnum'
address@hidden:stdin:8: Warning: define: cannot concatenate builtins
 @result{}A
 define(`mydivnum', `a'defn(`divnum'))mydivnum
address@hidden:stdin:8: Warning: define: cannot concatenate builtin `divnum'
address@hidden:stdin:9: Warning: define: cannot concatenate builtins
 @result{}A
 define(`q', ``$@@'')
 @result{}
 define(`foo', q(`a', defn(`divnum')))foo
address@hidden:stdin:10: Warning: define: cannot concatenate builtins
address@hidden
address@hidden:stdin:11: Warning: define: cannot concatenate builtins
address@hidden,
 ifdef(`foo', `yes', `no')
address@hidden
address@hidden
 @end example
 
 @node Pushdef
@@ -2853,6 +2853,8 @@ ifelse(defn(`defn'), defn(`divnum'), `yes', `no')
 @result{}no
 ifelse(defn(`defn'), defn(`defn'), `yes', `no')
 @result{}yes
+ifelse(defn(`defn', `divnum'), defn(`defn')defn(`divnum'), `yes', `no')
address@hidden
 define(`foo', ifelse(`', `', defn(`divnum')))
 @result{}
 foo
@@ -2917,8 +2919,6 @@ ifelse(`-01234567890123456789', `-'e(long)`-', `yes', 
`no')
 @result{}no
 @end example
 
address@hidden It would be nice to allow concatenation of builtins without
address@hidden using $@ handling.
 @example
 define(`e', `$@@')define(`q', ``$@@'')define(`u', `$*')
 @result{}
@@ -2928,16 +2928,12 @@ cmp(`defn(`defn')', `defn(`d')')
 @result{}yes
 cmp(`defn(`defn')', ``<defn>'')
 @result{}no
-cmp(`q(defn(`defn'))', `q(defn(`d'))')-fixme
address@hidden:stdin:5: Warning: ifelse: cannot quote builtin
address@hidden:stdin:5: Warning: ifelse: cannot quote builtin
address@hidden
-cmp(`q(defn(`defn'))', `q(`<defn>')')-fixme
address@hidden:stdin:6: Warning: ifelse: cannot quote builtin
address@hidden
-cmp(`q(defn(`defn'))', ``'')-fixme
address@hidden:stdin:7: Warning: ifelse: cannot quote builtin
address@hidden
+cmp(`q(defn(`defn'))', `q(defn(`d'))')
address@hidden
+cmp(`q(defn(`defn'))', `q(`<defn>')')
address@hidden
+cmp(`q(defn(`defn'))', ``'')
address@hidden
 cmp(`q(`1', `2', defn(`defn'))', `q(`1', `2', defn(`d'))')
 @result{}yes
 cmp(`q(`1', `2', defn(`defn'))', `q(`1', `2', `<defn>')')
@@ -3834,7 +3830,17 @@ debugmode()
 foo
 @error{}m4trace: -1- foo -> `FOO'
 @result{}FOO
+debugmode(`V')
address@hidden
+foo(`ignored')
address@hidden:stdin:6: -1- id 6: foo ...
address@hidden:stdin:6: -1- id 6: foo(`ignored') -> ???
address@hidden:stdin:6: -1- id 6: foo(...) -> `FOO'
address@hidden
 debugmode
address@hidden:stdin:7: -1- id 7: debugmode ...
address@hidden:stdin:7: -1- id 7: debugmode -> ???
address@hidden
 @result{}
 foo
 @error{}m4trace: -1- foo
@@ -3842,7 +3848,7 @@ foo
 debugmode(`+l')
 @result{}
 foo
address@hidden:8: -1- foo
address@hidden:10: -1- foo
 @result{}FOO
 @end example
 
@@ -4799,7 +4805,7 @@ than computing the builtin token up front, as is done for 
@code{bar}.
 m4wrap(`define(`foo', defn(`divnum'))foo
 ')
 @result{}
-m4wrap(`define(`bar', ')m4wrap(defn(`divnum'))m4wrap(`)bar
+m4wrap(`define(`bar', 'defn(`divnum')`)bar
 ')
 @result{}
 ^D
diff --git a/src/builtin.c b/src/builtin.c
index 2e963e3..8ce6cf7 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -678,13 +678,9 @@ define_macro (int argc, macro_arguments *argv, 
symbol_lookup mode)
     {
     case TOKEN_COMP:
       m4_warn (0, me, _("cannot concatenate builtins"));
-      /* TODO fall through instead.  */
-      break;
-
+      /* fallthru */
     case TOKEN_TEXT:
-      /* TODO flatten TOKEN_COMP value, or support concatenation of
-        builtins in definitions.  */
-      define_user_macro (ARG (1), ARG_LEN (1), ARG (2), mode);
+      define_user_macro (ARG (1), ARG_LEN (1), arg_text (argv, 2, true), mode);
       break;
 
     case TOKEN_FUNC:
@@ -1012,7 +1008,10 @@ m4_defn (struct obstack *obs, int argc, macro_arguments 
*argv)
        }
       s = lookup_symbol (ARG (i), SYMBOL_LOOKUP);
       if (s == NULL)
-       continue;
+       {
+         m4_warn (0, me, _("undefined macro `%s'"), ARG (i));
+         continue;
+       }
 
       switch (SYMBOL_TYPE (s))
        {
@@ -1046,10 +1045,10 @@ m4_defn (struct obstack *obs, int argc, macro_arguments 
*argv)
 
 /* Helper macros for readability.  */
 #if UNIX || defined WEXITSTATUS
-# define M4SYSVAL_EXITBITS(status)                       \
-   (WIFEXITED (status) ? WEXITSTATUS (status) : 0)
-# define M4SYSVAL_TERMSIGBITS(status)                    \
-   (WIFSIGNALED (status) ? WTERMSIG (status) << 8 : 0)
+# define M4SYSVAL_EXITBITS(status)                      \
+  (WIFEXITED (status) ? WEXITSTATUS (status) : 0)
+# define M4SYSVAL_TERMSIGBITS(status)                   \
+  (WIFSIGNALED (status) ? WTERMSIG (status) << 8 : 0)
 
 #else /* !UNIX && !defined WEXITSTATUS */
 /* Platforms such as mingw do not support the notion of reporting
diff --git a/src/input.c b/src/input.c
index aacab61..df5a791 100644
--- a/src/input.c
+++ b/src/input.c
@@ -340,18 +340,18 @@ push_string_init (void)
 | rather than copying everything consecutively onto the input stack.  |
 | Must be called between push_string_init and push_string_finish.     |
 |                                                                     |
-| If TOKEN contains text, then convert the current input block into   |
-| a chain if it is not one already, and add the contents of TOKEN as  |
-| a new link in the chain.  LEVEL describes the current expansion     |
-| level, or -1 if TOKEN is composite, its contents reside entirely    |
-| on the current_input stack, and TOKEN lives in temporary storage.   |
-| If TOKEN is a simple string, then it belongs to the current macro   |
-| expansion.  If TOKEN is composite, then each text link has a level  |
-| of -1 if it belongs to the current macro expansion, otherwise it    |
-| is a back-reference where level tracks which stack it came from.    |
-| The resulting input block chain contains links with a level of -1   |
-| if the text belongs to the input stack, otherwise the level where   |
-| the back-reference comes from.                                     |
+| Convert the current input block into a chain if it is not one              |
+| already, and add the contents of TOKEN as a new link in the chain.  |
+| LEVEL describes the current expansion level, or -1 if TOKEN is      |
+| composite, its contents reside entirely on the current_input       |
+| stack, and TOKEN lives in temporary storage.  If TOKEN is a simple  |
+| string, then it belongs to the current macro expansion.  If TOKEN   |
+| is composite, then each text link has a level of -1 if it belongs   |
+| to the current macro expansion, otherwise it is a back-reference    |
+| where level tracks which stack it came from.  The resulting input   |
+| block chain contains links with a level of -1 if the text belongs   |
+| to the input stack, otherwise the level where the back-reference    |
+| comes from.                                                        |
 |                                                                     |
 | Return true only if a reference was created to the contents of      |
 | TOKEN, in which case, LEVEL was non-negative and the lifetime of    |
@@ -1062,19 +1062,35 @@ skip_line (const char *name)
 | When next_token() sees a builtin token with peek_input, this     |
 | retrieves the value of the function pointer, stores it in TD, and |
 | consumes the input so the caller does not need to do next_char.   |
-| If TD is NULL, discard the token instead.                        |
+| If OBS, TD will be converted to a composite token using storage   |
+| from OBS as necessary; otherwise, if TD is NULL, the builtin is   |
+| discarded.                                                        |
 `------------------------------------------------------------------*/
 
 static void
-init_macro_token (token_data *td)
+init_macro_token (struct obstack *obs, token_data *td)
 {
   token_chain *chain;
 
   assert (isp->type == INPUT_CHAIN);
   chain = isp->u.u_c.chain;
   assert (!chain->quote_age && chain->type == CHAIN_FUNC && chain->u.func);
-  if (td)
+  if (obs)
     {
+      assert (td);
+      if (TOKEN_DATA_TYPE (td) == TOKEN_VOID)
+       {
+         TOKEN_DATA_TYPE (td) = TOKEN_COMP;
+         td->u.u_c.chain = td->u.u_c.end = NULL;
+         td->u.u_c.wrapper = false;
+         td->u.u_c.has_func = true;
+       }
+      assert (TOKEN_DATA_TYPE (td) == TOKEN_COMP);
+      append_macro (obs, chain->u.func, &td->u.u_c.chain, &td->u.u_c.end);
+    }
+  else if (td)
+    {
+      assert (TOKEN_DATA_TYPE (td) == TOKEN_VOID);
       TOKEN_DATA_TYPE (td) = TOKEN_FUNC;
       TOKEN_DATA_FUNC (td) = chain->u.func;
     }
@@ -1597,7 +1613,7 @@ next_token (token_data *td, int *line, struct obstack 
*obs, bool allow_argv,
     }
   if (ch == CHAR_MACRO)
     {
-      init_macro_token (td);
+      init_macro_token (obs, td);
 #ifdef DEBUG_INPUT
       xfprintf (stderr, "next_token -> MACDEF (%s)\n",
                find_builtin_by_addr (TOKEN_DATA_FUNC (td))->name);
@@ -1633,10 +1649,7 @@ next_token (token_data *td, int *line, struct obstack 
*obs, bool allow_argv,
                              _("end of file in comment"));
          if (ch == CHAR_MACRO)
            {
-             /* TODO support concatenation of builtins.  */
-             m4_warn_at_line (0, file, *line, caller,
-                              _("cannot comment builtin"));
-             init_macro_token (NULL);
+             init_macro_token (obs, obs ? td : NULL);
              continue;
            }
          if (MATCH (ch, curr_comm.str2, true))
@@ -1732,35 +1745,8 @@ next_token (token_data *td, int *line, struct obstack 
*obs, bool allow_argv,
                              _("end of file in string"));
 
          if (ch == CHAR_MACRO)
-           {
-             /* TODO support concatenation of builtins.  */
-             if (obstack_object_size (obs_td) == 0
-                 && TOKEN_DATA_TYPE (td) == TOKEN_VOID)
-               {
-                 assert (quote_level == 1);
-                 init_macro_token (td);
-                 ch = peek_input (false);
-                 if (MATCH (ch, curr_quote.str2, false))
-                   {
-#ifdef DEBUG_INPUT
-                     const builtin *bp
-                       = find_builtin_by_addr (TOKEN_DATA_FUNC (td));
-                     xfprintf (stderr, "next_token -> MACDEF (%s)\n",
-                               bp->name);
-#endif
-                     ch = next_char (false, false);
-                     MATCH (ch, curr_quote.str2, true);
-                     return TOKEN_MACDEF;
-                   }
-                 TOKEN_DATA_TYPE (td) = TOKEN_VOID;
-               }
-             else
-               init_macro_token (NULL);
-             m4_warn_at_line (0, file, *line, caller,
-                              _("cannot quote builtin"));
-             continue;
-           }
-         if (ch == CHAR_QUOTE)
+           init_macro_token (obs, obs ? td : NULL);
+         else if (ch == CHAR_QUOTE)
            append_quote_token (obs, td);
          else if (MATCH (ch, curr_quote.str2, true))
            {
diff --git a/src/m4.c b/src/m4.c
index fe8c548..2ad82c2 100644
--- a/src/m4.c
+++ b/src/m4.c
@@ -573,7 +573,7 @@ main (int argc, char *const *argv, char *const *envp)
 
       case 'l':
        {
-         int tmp = atoi (optarg);
+         long tmp = strtol (optarg, NULL, 10);
          max_debug_argument_length = tmp <= 0 ? SIZE_MAX : (size_t) tmp;
        }
        break;
diff --git a/src/m4.h b/src/m4.h
index 59d9be3..b3cb7e1 100644
--- a/src/m4.h
+++ b/src/m4.h
@@ -266,7 +266,7 @@ enum token_type
   TOKEN_COMMA, /* Active character `,', TOKEN_TEXT.  */
   TOKEN_CLOSE, /* Active character `)', TOKEN_TEXT.  */
   TOKEN_SIMPLE,        /* Any other single character, TOKEN_TEXT.  */
-  TOKEN_MACDEF,        /* A macro's definition (see "defn"), TOKEN_FUNC.  */
+  TOKEN_MACDEF,        /* A builtin macro, TOKEN_FUNC or TOKEN_COMP.  */
   TOKEN_ARGV   /* A series of parameters, TOKEN_COMP.  */
 };
 
@@ -504,7 +504,7 @@ size_t adjust_refcount (int, bool);
 bool arg_adjust_refcount (macro_arguments *, bool);
 unsigned int arg_argc (macro_arguments *);
 token_data_type arg_type (macro_arguments *, unsigned int);
-const char *arg_text (macro_arguments *, unsigned int);
+const char *arg_text (macro_arguments *, unsigned int, bool);
 bool arg_equal (macro_arguments *, unsigned int, unsigned int);
 bool arg_empty (macro_arguments *, unsigned int);
 size_t arg_len (macro_arguments *, unsigned int);
@@ -523,7 +523,7 @@ void wrap_args (macro_arguments *);
 
 /* Grab the text at argv index I.  Assumes macro_argument *argv is in
    scope, and aborts if the argument is not text.  */
-#define ARG(i) arg_text (argv, i)
+#define ARG(i) arg_text (argv, i, false)
 
 /* Grab the text length at argv index I.  Assumes macro_argument *argv
    is in scope, and aborts if the argument is not text.  */
diff --git a/src/macro.c b/src/macro.c
index d871fc2..8290818 100644
--- a/src/macro.c
+++ b/src/macro.c
@@ -329,18 +329,6 @@ expand_token (struct obstack *obs, token_type t, 
token_data *td, int line,
 }
 
 
-/*---------------------------------------------------------------.
-| Helper function to print warning about concatenating FUNC with |
-| text.                                                          |
-`---------------------------------------------------------------*/
-static void
-warn_builtin_concat (const char *caller, builtin_func *func)
-{
-  const builtin *bp = find_builtin_by_addr (func);
-  assert (bp);
-  m4_warn (0, caller, _("cannot concatenate builtin `%s'"), bp->name);
-}
-
 /*-------------------------------------------------------------------.
 | This function parses one argument to a macro call.  It expects the |
 | first left parenthesis or the separating comma to have been read   |
@@ -383,15 +371,10 @@ expand_argument (struct obstack *obs, token_data *argp, 
const char *caller)
        case TOKEN_CLOSE:
          if (paren_level == 0)
            {
-             size_t len = obstack_object_size (obs);
-             if (TOKEN_DATA_TYPE (argp) == TOKEN_FUNC)
-               {
-                 if (!len)
-                   return t == TOKEN_COMMA;
-                 warn_builtin_concat (caller, TOKEN_DATA_FUNC (argp));
-               }
+             assert (TOKEN_DATA_TYPE (argp) != TOKEN_FUNC);
              if (TOKEN_DATA_TYPE (argp) != TOKEN_COMP)
                {
+                 size_t len = obstack_object_size (obs);
                  TOKEN_DATA_TYPE (argp) = TOKEN_TEXT;
                  if (len)
                    {
@@ -404,7 +387,16 @@ expand_argument (struct obstack *obs, token_data *argp, 
const char *caller)
                  TOKEN_DATA_QUOTE_AGE (argp) = age;
                }
              else
-               make_text_link (obs, NULL, &argp->u.u_c.end);
+               {
+                 make_text_link (obs, NULL, &argp->u.u_c.end);
+                 if (argp->u.u_c.chain == argp->u.u_c.end
+                     && argp->u.u_c.chain->type == CHAIN_FUNC)
+                   {
+                     builtin_func *func = argp->u.u_c.chain->u.func;
+                     TOKEN_DATA_TYPE (argp) = TOKEN_FUNC;
+                     TOKEN_DATA_FUNC (argp) = func;
+                   }
+               }
              return t == TOKEN_COMMA;
            }
          /* fallthru */
@@ -427,14 +419,13 @@ expand_argument (struct obstack *obs, token_data *argp, 
const char *caller)
 
        case TOKEN_WORD:
        case TOKEN_STRING:
+       case TOKEN_MACDEF:
          if (!expand_token (obs, t, &td, line, first))
            age = 0;
          if (TOKEN_DATA_TYPE (&td) == TOKEN_COMP)
            {
              if (TOKEN_DATA_TYPE (argp) != TOKEN_COMP)
                {
-                 if (TOKEN_DATA_TYPE (argp) == TOKEN_FUNC)
-                   warn_builtin_concat (caller, TOKEN_DATA_FUNC (argp));
                  TOKEN_DATA_TYPE (argp) = TOKEN_COMP;
                  argp->u.u_c.chain = td.u.u_c.chain;
                  argp->u.u_c.wrapper = argp->u.u_c.has_func = false;
@@ -450,22 +441,6 @@ expand_argument (struct obstack *obs, token_data *argp, 
const char *caller)
            }
          break;
 
-       case TOKEN_MACDEF:
-         if (TOKEN_DATA_TYPE (argp) == TOKEN_VOID
-             && obstack_object_size (obs) == 0)
-           {
-             TOKEN_DATA_TYPE (argp) = TOKEN_FUNC;
-             TOKEN_DATA_FUNC (argp) = TOKEN_DATA_FUNC (&td);
-           }
-         else
-           {
-             if (TOKEN_DATA_TYPE (argp) == TOKEN_FUNC)
-               warn_builtin_concat (caller, TOKEN_DATA_FUNC (argp));
-             warn_builtin_concat (caller, TOKEN_DATA_FUNC (&td));
-             TOKEN_DATA_TYPE (argp) = TOKEN_TEXT;
-           }
-         break;
-
        case TOKEN_ARGV:
          assert (paren_level == 0 && TOKEN_DATA_TYPE (argp) == TOKEN_VOID
                  && obstack_object_size (obs) == 0
@@ -798,6 +773,8 @@ arg_adjust_refcount (macro_arguments *argv, bool increase)
                  if (chain->u.u_s.level >= 0)
                    adjust_refcount (chain->u.u_s.level, increase);
                  break;
+               case CHAIN_FUNC:
+                 break;
                case CHAIN_ARGV:
                  assert (chain->u.u_a.argv->inuse);
                  arg_adjust_refcount (chain->u.u_a.argv, increase);
@@ -914,10 +891,11 @@ arg_type (macro_arguments *argv, unsigned int arg)
 
 /* Given ARGV, return the text at argument ARG.  Abort if the argument
    is not text.  Arg 0 is always text, and indices beyond argc return
-   the empty string.  The result is always NUL-terminated, even if it
-   includes embedded NUL characters.  */
+   the empty string.  If FLATTEN, builtins are ignored.  The result is
+   always NUL-terminated, even if it includes embedded NUL
+   characters.  */
 const char *
-arg_text (macro_arguments *argv, unsigned int arg)
+arg_text (macro_arguments *argv, unsigned int arg, bool flatten)
 {
   token_data *token;
   token_chain *chain;
@@ -927,7 +905,7 @@ arg_text (macro_arguments *argv, unsigned int arg)
     return argv->argv0;
   if (arg >= argv->argc)
     return "";
-  token = arg_token (argv, arg, NULL, false);
+  token = arg_token (argv, arg, NULL, flatten);
   switch (TOKEN_DATA_TYPE (token))
     {
     case TOKEN_TEXT:
@@ -942,13 +920,18 @@ arg_text (macro_arguments *argv, unsigned int arg)
            case CHAIN_STR:
              obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
              break;
+           case CHAIN_FUNC:
+             if (flatten)
+               break;
+             assert (!"arg_text");
+             abort ();
            case CHAIN_ARGV:
-             assert (!chain->u.u_a.has_func || argv->flatten);
+             assert (!chain->u.u_a.has_func || flatten || argv->flatten);
              arg_print (obs, chain->u.u_a.argv, chain->u.u_a.index,
                         quote_cache (NULL, chain->quote_age,
                                      chain->u.u_a.quotes),
-                        argv->flatten || chain->u.u_a.flatten, NULL, NULL,
-                        NULL, false);
+                        flatten || argv->flatten || chain->u.u_a.flatten,
+                        NULL, NULL, NULL, false);
              break;
            default:
              assert (!"arg_text");
@@ -969,7 +952,7 @@ arg_text (macro_arguments *argv, unsigned int arg)
 /* Given ARGV, compare text arguments INDEXA and INDEXB for equality.
    Both indices must be non-zero and less than argc.  Return true if
    the arguments contain the same contents; often more efficient than
-   strcmp (arg_text (argv, indexa), arg_text (argv, indexb)) == 0.  */
+   strcmp (arg_text (argv, a, 1), arg_text (argv, b, 1)) == 0.  */
 bool
 arg_equal (macro_arguments *argv, unsigned int indexa, unsigned int indexb)
 {
@@ -1249,6 +1232,7 @@ arg_print (struct obstack *obs, macro_arguments *argv, 
unsigned int arg,
   size_t sep_len;
   size_t *plen = quote_each ? NULL : &len;
 
+  flatten |= argv->flatten;
   if (chainp)
     assert (!max_len && *chainp);
   if (!sep)
diff --git a/src/output.c b/src/output.c
index d7f8570..ee1907b 100644
--- a/src/output.c
+++ b/src/output.c
@@ -199,7 +199,7 @@ m4_tmpname (int divnum)
       obstack_1grow (&diversion_storage, '-');
       offset = obstack_object_size (&diversion_storage);
       buffer = (char *) obstack_alloc (&diversion_storage,
-                                       INT_BUFSIZE_BOUND (divnum));
+                                      INT_BUFSIZE_BOUND (divnum));
     }
   if (snprintf (&buffer[offset], INT_BUFSIZE_BOUND (divnum), "%d", divnum) < 0)
     m4_error (EXIT_FAILURE, errno, NULL,
@@ -387,7 +387,7 @@ make_room_for (int length)
 
       /* The current buffer may be safely reallocated.  */
       output_diversion->u.buffer = xrealloc (output_diversion->u.buffer,
-                                             (size_t) wanted_size);
+                                            (size_t) wanted_size);
 
       total_buffer_size += wanted_size - output_diversion->size;
       output_diversion->size = wanted_size;


hooks/post-receive
--
GNU M4 source repository




reply via email to

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