[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FYI: erenamesyms and renamesyms builtins [m4--devo--1.0--patch-15]
From: |
Gary V. Vaughan |
Subject: |
FYI: erenamesyms and renamesyms builtins [m4--devo--1.0--patch-15] |
Date: |
Sun, 8 May 2005 01:39:17 +0100 (BST) |
User-agent: |
mailnotify/0.6 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Applied to HEAD.
* looking for address@hidden/m4--devo--1.0--patch-14 to compare with
* comparing to address@hidden/m4--devo--1.0--patch-14
M ChangeLog
M m4/symtab.c
M modules/gnu.c
M m4/m4module.h
M doc/m4.texinfo
M tests/generate.awk
* modified files
Index: Changelog
from Gary V. Vaughan <address@hidden>
* m4/symtab.c (m4_symbol_rename): New function that performs a low
level symbol rename.
* m4/m4module.h (m4_symbol_rename): Declare it as part of the API.
* modules/gnu.c (regsub): Factored out of m4_epatsubst_do...
(m4_patsubst_do, m4_renamesyms_do): ...wrappers that use
regsub...
(erenamesyms, renamesyms): ...builtins that use these to implement
macro renaming by regular expression.
* doc/m4.texinfo (Erenamesyms and Renamesyms): Document them.
* tests/generate.awk: Allow some forbidden `m4_' prefixed symbols
to stop the new generated tests from choking.
--- orig/doc/m4.texinfo
+++ mod/doc/m4.texinfo
@@ -22,8 +22,7 @@
@ifinfo
This file documents GNU @code{m4} @value{VERSION}
-Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1998, 1999, 2000,
-2001, 2004
+Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1998, 1999, 2000, 2001,
2004, 2005
Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
@@ -50,8 +49,7 @@
@page
@vskip 0pt plus 1filll
-Copyright @copyright{} 1989, 1990, 1991, 1992, 1993, 1994, 1998, 1999,
-2000, 2001 Free Software Foundation, Inc.
+Copyright @copyright{} 1989, 1990, 1991, 1992, 1993, 1994, 1998, 1999, 2000,
2001, 2004, 2005 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.1
@@ -158,6 +156,7 @@
* Undefine:: Deleting a macro
* Defn:: Renaming macros
* Pushdef:: Temporarily redefining macros
+* Erenamesyms and Renamesyms:: Renaming macros with regular expressions
* Indir:: Indirect call of macros
* Builtin:: Indirect call of builtins
@@ -996,6 +995,7 @@
* Undefine:: Deleting a macro
* Defn:: Renaming macros
* Pushdef:: Temporarily redefining macros
+* Erenamesyms and Renamesyms:: Renaming macros with regular expressions
* Indir:: Indirect call of macros
* Builtin:: Indirect call of builtins
@@ -1379,6 +1379,65 @@
It is possible to temporarily redefine a builtin with @code{pushdef}
and @code{defn}.
address@hidden Erenamesyms and Renamesyms
address@hidden Renaming macros with regular expressions
+
address@hidden regular expressions
address@hidden macros, how to rename
address@hidden renaming macros
address@hidden GNU extensions
address@hidden {Builtin (gnu)} erenamesyms (@var{regexp}, @var{replacement})
+Global renaming of macros is done by @code{erenamesyms}, which selects
+all macros with names that match @var{regexp}, and renames each match
+according to @var{replacement}.
+
+A macro that does not have a name that matches @var{regexp} is left
+with its original name. If only part of the name matches, any part of
+the name that is not covered by @var{regexp} is copied to the
+replacement name. Whenever a match is found in the name, the search
+proceeds from the end of the match, so no character in the original
+name can be substituted twice. If @var{regexp} matches a string of
+zero length, the start position for the continued search is
+incremented to avoid infinite loops.
+
+Where a replacement is to be made, @var{replacement} replaces the
+matched text in the original name, with @address@hidden substituted by
+the text matched by the @var{n}th parenthesized sub-expression of
address@hidden, and @samp{\&} being the text matched by the entire
+regular expression.
+
+The builtin macro @code{erenamesyms} is recognized only when given
+arguments.
address@hidden deffn
+
+Here is an example that performs the same renaming as the
address@hidden option. Where @option{--prefix-builtins}
+only renames M4 builtin macros, @code{erenamesyms} will rename any
+macros that match when it runs, including text macros.
+
address@hidden
+erenamesyms(`^.*$', `m4_\&')
address@hidden
address@hidden example
+
+Here is a more realistic example that performs a similar renaming on
+macros with lowercase names, except that it ignores macros with names
+that begin with @samp{_}, and avoids creating macros with names that
+begin with @samp{m4_m4}.
+
address@hidden
+erenamesyms(`^[^_]\w*$', `m4_\&')
address@hidden
+m4_erenamesyms(`^m4_m4(\w*)$', `m4_\1')
address@hidden
address@hidden example
+
address@hidden {Builtin (gnu)} renamesyms (@var{regexp}, @var{replacement})
+Same as @code{erenamesyms}, but using Basic Regular Expression syntax,
+see @xref{Eregexp and Regexp}, for more details.
address@hidden deffn
+
+
@node Indir
@section Indirect call of macros
@@ -3034,7 +3093,7 @@
@cindex substitution by regular expression
@cindex GNU extensions
@deffn {Builtin (gnu)} epatsubst (@var{string}, @var{regexp}, @w{opt
@var{replacement})}
-Global substitution in a string is done by @code{patsubst}, which
+Global substitution in a string is done by @code{epatsubst}, which
searches @var{string} for matches of @var{regexp}, and substitutes
@var{replacement} for each match. It uses Extended Regular Expressions
syntax.
@@ -3054,7 +3113,7 @@
The @var{replacement} argument can be omitted, in which case the text
matched by @var{regexp} is deleted.
-The builtin macro @code{patsubst} is recognized only when given
+The builtin macro @code{epatsubst} is recognized only when given
arguments.
@end deffn
--- orig/m4/m4module.h
+++ mod/m4/m4module.h
@@ -1,5 +1,7 @@
/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 1999, 2000, 2003, 2004 Free Software Foundation,
Inc.
+
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1999, 2000, 2003,
+ 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
@@ -176,6 +178,9 @@
extern m4_symbol *m4_symbol_define (m4_symbol_table*,
const char *, m4_symbol_value *);
extern void m4_symbol_popdef (m4_symbol_table*, const char *);
+extern m4_symbol *m4_symbol_rename (m4_symbol_table*, const char *,
+ const char *);
+
extern void m4_symbol_delete (m4_symbol_table*, const char *);
#define m4_symbol_delete(symtab, name) M4_STMT_START {
\
--- orig/m4/symtab.c
+++ mod/m4/symtab.c
@@ -1,5 +1,5 @@
/* GNU m4 -- A simple macro processor
- Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2001
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2001, 2005
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
@@ -285,7 +285,6 @@
}
}
-
static void
symbol_popval (m4_symbol *symbol)
{
@@ -310,6 +309,37 @@
}
}
+m4_symbol *
+m4_symbol_rename (m4_symbol_table *symtab, const char *name, const char
*rename)
+{
+ m4_symbol *symbol = NULL;
+ m4_symbol **psymbol;
+
+ assert (symtab);
+ assert (name);
+ assert (rename);
+
+ /* Use a low level hash fetch, so we can save the symbol value when
+ removing the symbol name from the symbol table. */
+ psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, name);
+
+ if (psymbol)
+ {
+ symbol = *psymbol;
+
+ /* Remove the old name from the symbol table. */
+ free (m4_hash_remove (symtab->table, name));
+ assert (!m4_hash_lookup (symtab->table, name));
+
+ m4_hash_insert (symtab->table, xstrdup (rename), *psymbol);
+ }
+ /* else
+ NAME does not name a symbol in symtab->table! */
+
+ return symbol;
+}
+
+
/* Callback used by m4_symbol_popdef () to release the memory used
by values in the arg_signature hash. */
static void *
--- orig/modules/gnu.c
+++ mod/modules/gnu.c
@@ -1,5 +1,6 @@
/* GNU m4 -- A simple macro processor
- Copyright (C) 2000,2004 Free Software Foundation, Inc.
+
+ Copyright (C) 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
@@ -37,6 +38,8 @@
int errno;
#endif
+#include <assert.h>
+
#ifdef NDEBUG
# include "m4private.h"
#endif
@@ -78,11 +81,13 @@
BUILTIN(debugfile, false, false, 1, 2 ) \
BUILTIN(eregexp, false, true, 3, 4 ) \
BUILTIN(epatsubst, false, true, 3, 4 ) \
+ BUILTIN(erenamesyms, false, true, 3, 3 ) \
BUILTIN(esyscmd, false, true, 2, 2 ) \
BUILTIN(format, false, true, 2, -1 ) \
BUILTIN(indir, false, true, 2, -1 ) \
BUILTIN(patsubst, false, true, 3, 4 ) \
BUILTIN(regexp, false, true, 3, 4 ) \
+ BUILTIN(renamesyms, false, true, 3, 3 ) \
BUILTIN(symbols, false, false, 0, -1 ) \
BUILTIN(syncoutput, false, true, 2, 2 ) \
@@ -120,10 +125,19 @@
{ 0, 0 },
};
-static void substitute (m4 *context, m4_obstack *obs, const char *victim,
- const char *repl, struct re_registers *regs);
-static void m4_patsubst_do (m4 *context, m4_obstack *obs, int argc,
- m4_symbol_value **argv, int syntax);
+static bool regsub (m4 *context, m4_obstack *obs, const char *caller,
+ const char *victim, int length, const char *regexp,
+ struct re_pattern_buffer *buf, const char *replace,
+ bool ignore_duplicates);
+static void substitute (m4 *context, m4_obstack *obs, const char
*victim,
+ const char *repl, struct re_registers *regs);
+
+static void m4_regexp_do (m4 *context, m4_obstack *obs, int argc,
+ m4_symbol_value **argv, int syntax);
+static void m4_patsubst_do (m4 *context, m4_obstack *obs, int argc,
+ m4_symbol_value **argv, int syntax);
+static void m4_renamesyms_do (m4 *context, m4_obstack *obs, int argc,
+ m4_symbol_value **argv, int syntax);
/* The builtin "builtin" allows calls to builtin macros, even if their
@@ -376,27 +390,39 @@
{
const char *victim; /* first argument */
const char *regexp; /* regular expression */
+ int length; /* length of first argument */
struct re_pattern_buffer *buf;/* compiled regular expression */
- struct re_registers regs; /* for subexpression matches */
- int matchpos; /* start position of match */
- int offset; /* current match offset */
- int length; /* length of first argument */
- regexp = M4ARG (2);
victim = M4ARG (1);
length = strlen (victim);
+ regexp = M4ARG (2);
buf = m4_regexp_compile (context, M4ARG(0), regexp, syntax);
if (!buf)
return;
- offset = 0;
- matchpos = 0;
+ regsub (context, obs, M4ARG(0), victim, length,
+ regexp, buf, M4ARG(3), false);
+}
+
+
+static bool
+regsub (m4 *context, m4_obstack *obs, const char *caller,
+ const char *victim, int length, const char *regexp,
+ struct re_pattern_buffer *buf, const char *replace,
+ bool ignore_duplicates)
+{
+ struct re_registers regs; /* for subexpression matches */
+
+ int matchpos = 0; /* start position of match */
+ int offset = 0; /* current match offset */
+
while (offset < length)
{
matchpos = re_search (buf, victim, length,
offset, length - offset, ®s);
+
if (matchpos < 0)
{
@@ -407,8 +433,8 @@
if (matchpos == -2)
M4ERROR ((m4_get_warning_status_opt (context), 0,
_("%s: error matching regular expression `%s'"),
- M4ARG (0), regexp));
- else if (offset < length)
+ caller, regexp));
+ else if (!ignore_duplicates && (offset < length))
obstack_grow (obs, victim + offset, length - offset);
break;
}
@@ -420,7 +446,7 @@
/* Handle the part of the string that was covered by the match. */
- substitute (context, obs, victim, M4ARG (3), ®s);
+ substitute (context, obs, victim, replace, ®s);
/* Update the offset to the end of the match. If the regexp
matched a null string, advance offset one more, to avoid
@@ -430,11 +456,14 @@
if (regs.start[0] == regs.end[0])
obstack_1grow (obs, victim[offset++]);
}
- obstack_1grow (obs, '\0');
- return;
+ if (!ignore_duplicates || (matchpos >= 0))
+ obstack_1grow (obs, '\0');
+
+ return (matchpos >= 0);
}
+
/**
* patsubst(STRING, REGEXP, [REPLACEMENT])
**/
@@ -478,6 +507,8 @@
}
obstack_free (&data_obs, NULL);
}
+ else
+ assert (!"Unable to import from m4 module");
}
@@ -537,6 +568,74 @@
}
}
+
+
+/**
+ * renamesyms(REGEXP, REPLACEMENT)
+ **/
+M4BUILTIN_HANDLER (renamesyms)
+{
+ m4_renamesyms_do (context, obs, argc, argv, RE_SYNTAX_BRE);
+}
+
+/**
+ * erenamesyms(REGEXP, REPLACEMENT)
+ **/
+M4BUILTIN_HANDLER (erenamesyms)
+{
+ m4_renamesyms_do (context, obs, argc, argv, RE_SYNTAX_ERE);
+}
+
+
+
+static void
+m4_renamesyms_do (m4 *context, m4_obstack *obs, int argc,
+ m4_symbol_value **argv, int syntax)
+{
+ const char *regexp; /* regular expression string */
+ const char *replace; /* replacement expression string */
+
+ struct re_pattern_buffer *buf;/* compiled regular expression */
+
+ m4_dump_symbol_data data;
+ m4_obstack data_obs;
+ m4_obstack rename_obs;
+
+ M4_MODULE_IMPORT (m4, m4_dump_symbols);
+
+ assert (m4_dump_symbols);
+
+ regexp = M4ARG(1);
+ replace = M4ARG(2);
+
+ buf = m4_regexp_compile (context, M4ARG(0), regexp, syntax);
+ if (!buf)
+ return;
+
+ obstack_init (&rename_obs);
+ obstack_init (&data_obs);
+ data.obs = &data_obs;
+
+ m4_dump_symbols (context, &data, 1, argv, false);
+
+ for (; data.size > 0; --data.size, data.base++)
+ {
+ const char * name = data.base[0];
+ int length = strlen (name);
+
+ if (regsub (context, &rename_obs, M4ARG(0), name, length,
+ regexp, buf, replace, true))
+ {
+ const char *renamed = obstack_finish (&rename_obs);
+
+ m4_symbol_rename (M4SYMTAB, name, renamed);
+ }
+ }
+
+ obstack_free (&data_obs, NULL);
+ obstack_free (&rename_obs, NULL);
+}
+
/* Frontend for printf like formatting. The function format () lives in
the file format.c. */
--- orig/tests/generate.awk
+++ mod/tests/generate.awk
@@ -31,6 +31,9 @@
print ;
print "AT_BANNER([Documentation examples.])";
print ;
+ # stop spurious warnings in the erenamesyms checks
+ print "m4_pattern_allow([^m4_(m4|erenamesyms|)$])"
+ print ;
}
/address@hidden / {
- --
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
_________________________________________________________
This patch notification generated by tlaapply version 0.9
http://tkd.kicks-ass.net/arch/address@hidden/cvs-utils--tla--1.0
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (Darwin)
iD8DBQFCfV+0FRMICSmD1gYRAuPvAKC3swldQ7cIXIdcMqVFq1O0vegROwCgnX3/
DuEL0baVPfiNs4yURYc8HDI=
=jGAN
-----END PGP SIGNATURE-----
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- FYI: erenamesyms and renamesyms builtins [m4--devo--1.0--patch-15],
Gary V. Vaughan <=