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=aaf838ab071e9e33d7635d683bf5f489334c3a6b The branch, branch-1_4 has been updated via aaf838ab071e9e33d7635d683bf5f489334c3a6b (commit) from b0f7df5d4b9ebb8dcf9500a88607516f4a9a0e44 (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 aaf838ab071e9e33d7635d683bf5f489334c3a6b Author: Eric Blake <[EMAIL PROTECTED]> Date: Wed Nov 14 15:15:31 2007 -0700 Avoid builtin concatenation in macro arguments. * doc/m4.texinfo (Defn): Add tests. * src/macro.c (warn_builtin_concat): New function. (expand_argument): Use it to warn on more corner cases. * NEWS: Mention new warning. Signed-off-by: Eric Blake <[EMAIL PROTECTED]> ----------------------------------------------------------------------- Summary of changes: ChangeLog | 8 ++++++++ NEWS | 8 +++++--- doc/m4.texinfo | 37 +++++++++++++++++++++++++++++-------- src/macro.c | 52 +++++++++++++++++++++++++++++++++++----------------- 4 files changed, 77 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index 068148d..ae487a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2007-11-14 Eric Blake <[EMAIL PROTECTED]> + + Avoid builtin concatenation in macro arguments. + * doc/m4.texinfo (Defn): Add tests. + * src/macro.c (warn_builtin_concat): New function. + (expand_argument): Use it to warn on more corner cases. + * NEWS: Mention new warning. + 2007-11-13 Eric Blake <[EMAIL PROTECTED]> Simplify previous patch. diff --git a/NEWS b/NEWS index b92630b..d988adf 100644 --- a/NEWS +++ b/NEWS @@ -7,11 +7,13 @@ Version 1.4.11 - ?? ??? 2007, by ???? (git version 1.4.10a-*) * Fix core dump in 'm4 -F file -t undefined', present since -F was introduced in 1.3. * Fix regression introduced in 1.4.9b in the `divert' builtin when more - than 512 kibibytes are saved in diversions on platforms like NetBSD - where fopen(name,"a+") seeks to the end of the file. + than 512 kibibytes are saved in diversions on platforms like NetBSD where + fopen(name,"a+") seeks to the end of the file. * Enhance the `defn' builtin to support concatenation of multiple text arguments, as required by POSIX. However, at this time, it is not - possible to concatenate a builtin macro with anything else. + possible to concatenate a builtin macro with anything else; a warning is + now issued if this is attempted, although a future version of M4 may lift + this restriction to match other implementations. * Several improvements in `index', `regexp', and `patsubst' builtins to speed up typical Autoconf usage. * Memory usage is greatly reduced in recursive macros. diff --git a/doc/m4.texinfo b/doc/m4.texinfo index f028e3d..6caa7c3 100644 --- a/doc/m4.texinfo +++ b/doc/m4.texinfo @@ -2077,9 +2077,9 @@ and it 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 @code{define} (and @code{pushdef}), and is silently converted to an -empty string in most other contexts. Combining a builtin with anything -else is not supported; a warning is issued and the builtin is omitted -from the final expansion. +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. The macro @code{defn} is recognized only with parameters. @end deffn @@ -2186,18 +2186,39 @@ define(defn(`divnum'), `cannot redefine a builtin token') @result{} divnum @result{}0 +define(`echo', `$@@') [EMAIL PROTECTED] +define(`mydivnum', echo(defn(`divnum'))) [EMAIL PROTECTED] +mydivnum [EMAIL PROTECTED] @end example Also note that @code{defn} with multiple arguments can only join text -macros, not builtins, although a future version of @acronym{GNU} M4 may -lift this restriction. +macros, not builtins. Likewise, when collecting macro arguments, a +builtin token is preserved only when it occurs in isolation. A future +version of @acronym{GNU} M4 may lift these restrictions. @example -define(`a', `A') +define(`a', `A')define(`AA', `b') @result{} -defn(`a', `defn', `a') [EMAIL PROTECTED]:stdin:2: Warning: cannot concatenate builtin `defn' +defn(`a', `divnum', `a') [EMAIL PROTECTED]:stdin:2: Warning: cannot concatenate builtin `divnum' @result{}AA +define(`mydivnum', defn(`divnum', `divnum'))mydivnum [EMAIL PROTECTED]:stdin:3: Warning: cannot concatenate builtin `divnum' [EMAIL PROTECTED]:stdin:3: Warning: cannot concatenate builtin `divnum' [EMAIL PROTECTED] +define(`mydivnum', defn(`divnum')defn(`divnum'))mydivnum [EMAIL PROTECTED]:stdin:4: Warning: cannot concatenate builtin `divnum' [EMAIL PROTECTED]:stdin:4: Warning: cannot concatenate builtin `divnum' [EMAIL PROTECTED] +define(`mydivnum', defn(`divnum')`a')mydivnum [EMAIL PROTECTED]:stdin:5: Warning: cannot concatenate builtin `divnum' [EMAIL PROTECTED] +define(`mydivnum', `a'defn(`divnum'))mydivnum [EMAIL PROTECTED]:stdin:6: Warning: cannot concatenate builtin `divnum' [EMAIL PROTECTED] @end example @node Pushdef diff --git a/src/macro.c b/src/macro.c index 76f9276..9a3123a 100644 --- a/src/macro.c +++ b/src/macro.c @@ -125,15 +125,28 @@ 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 (builtin_func *func) +{ + const builtin *bp = find_builtin_by_addr (func); + assert (bp); + M4ERROR ((warning_status, 0, "Warning: 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 | -| by the caller. It skips leading whitespace, then reads and | +| by the caller. It skips leading whitespace, then reads and | | expands tokens, until it finds a comma or right parenthesis at the | | same level of parentheses. It returns a flag indicating whether | -| the argument read is the last for the active macro call. The | -| argument is built on the obstack OBS, indirectly through | -| expand_token (). Report errors on behalf of CALLER. | +| the argument read is the last for the active macro call. The | +| argument is built on the obstack OBS, indirectly through | +| expand_token (). Report errors on behalf of CALLER. | `-------------------------------------------------------------------*/ static bool @@ -141,7 +154,6 @@ expand_argument (struct obstack *obs, token_data *argp, const char *caller) { token_type t; token_data td; - char *text; int paren_level; const char *file = current_file; int line = current_line; @@ -166,25 +178,23 @@ expand_argument (struct obstack *obs, token_data *argp, const char *caller) case TOKEN_CLOSE: if (paren_level == 0) { - /* The argument MUST be finished, whether we want it or not. */ - obstack_1grow (obs, '\0'); - text = (char *) obstack_finish (obs); - - if (TOKEN_DATA_TYPE (argp) == TOKEN_VOID) + if (TOKEN_DATA_TYPE (argp) == TOKEN_FUNC) { - TOKEN_DATA_TYPE (argp) = TOKEN_TEXT; - TOKEN_DATA_TEXT (argp) = text; + if (obstack_object_size (obs) == 0) + return t == TOKEN_COMMA; + warn_builtin_concat (TOKEN_DATA_FUNC (argp)); } + obstack_1grow (obs, '\0'); + TOKEN_DATA_TYPE (argp) = TOKEN_TEXT; + TOKEN_DATA_TEXT (argp) = (char *) obstack_finish (obs); return t == TOKEN_COMMA; } /* fallthru */ case TOKEN_OPEN: case TOKEN_SIMPLE: - text = TOKEN_DATA_TEXT (&td); - - if (*text == '(') + if (t == TOKEN_OPEN) paren_level++; - else if (*text == ')') + else if (t == TOKEN_CLOSE) paren_level--; expand_token (obs, t, &td, line); break; @@ -202,11 +212,19 @@ expand_argument (struct obstack *obs, token_data *argp, const char *caller) break; case TOKEN_MACDEF: - if (obstack_object_size (obs) == 0) + 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 (TOKEN_DATA_FUNC (argp)); + warn_builtin_concat (TOKEN_DATA_FUNC (&td)); + TOKEN_DATA_TYPE (argp) = TOKEN_TEXT; + } break; default: hooks/post-receive -- GNU M4 source repository
