[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Changes to m4/modules/gnu.c
From: |
Gary V . Vaughan |
Subject: |
Changes to m4/modules/gnu.c |
Date: |
Sat, 07 May 2005 20:37:48 -0400 |
Index: m4/modules/gnu.c
diff -u m4/modules/gnu.c:1.36 m4/modules/gnu.c:1.37
--- m4/modules/gnu.c:1.36 Wed May 4 18:56:36 2005
+++ m4/modules/gnu.c Sun May 8 00:37:44 2005
@@ -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. */