[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
FYI: 13-gary-refactor-symtab-semantics.patch
From: |
Gary V. Vaughan |
Subject: |
FYI: 13-gary-refactor-symtab-semantics.patch |
Date: |
Tue, 17 Jun 2003 16:23:10 +0100 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030529 |
Applied to HEAD.
--
())_. Gary V. Vaughan gary@(oranda.demon.co.uk|gnu.org)
( '/ Research Scientist http://www.oranda.demon.co.uk ,_())____
/ )= GNU Hacker http://www.gnu.org/software/libtool \' `&
`(_~)_ Tech' Author http://sources.redhat.com/autobook =`---d__/
Index: ChangeLog
from Gary V. Vaughan <address@hidden>
Still refactoring furiously. This delta represents a change in
semantics to symtab.c. Instead of building temporary m4_tokens
in the caller, and copying fields in the methods, we now create
the actual m4_token for hashing in the caller so the methods just
slot them in directly. Also, this means that we don't lookup a
symbol and get back an allocated but VOID token to copy fields
into, we create the token we want to push and pass that to
m4_symbol_define or m4_symbol_pushdef. And that's it. There are
a few other small changes to stop knowledge of the implementation
of symtab.c leaking out into other files.
* m4/macro.c (expand_argument): Comment typo corrected.
* m4/symtab.c (symtab_fetch): New function to fetch the address of
an interned symbol.
(m4_symbol_pushdef): Take an extra value parameter and use this
directly as the new top of the value stack. All callers changed
to build a token and pass responsibility for memory in, rather
than copying as we used to.
(m4_symbol_define): Also use the new value parameter directly as a
replacement for the top of the value stack. All callers changed
to build a token as above.
(m4_set_symbol_traced): New function to set the traced bit on the
named symbol, creating it if necessary.
(symbol_popval): The guts of the old m4_symbol_popdef.
(m4_symbol_popdef): Use it.
* m4/builtin.c (m4_symbol_set_token): Removed,
(m4__symbol_set_builtin, m4__symbol_set_macro): Removed and
replaced...
* m4/module.c (m4_set_module_builtin_table)
(m4_set_module_macro_table): ...with these more orthogonal
functions.
* m4/m4module.h (m4_macro_pushdef, m4_macro_define)
(m4_builtin_pushdef, m4_builtin_define): Removed. No longer
required.
* m4/builtin.c (M4_ARG_SIGNATURE_DEFAULT_SIZE)
(m4_arg_signature_parse): Moved...
* m4/symtab.c: ...to here.
* m4/input.c (m4_token_copy): Arghh... I'm amazed this didn't
screw something up. Moved...
* m4/symtab.c (m4_token_copy): ...to here, and fixed so that it
actually does a proper deep copy of source to dest.
Index: m4/builtin.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/builtin.c,v
retrieving revision 1.19
diff -u -p -u -r1.19 builtin.c
--- m4/builtin.c 16 Jun 2003 16:29:06 -0000 1.19
+++ m4/builtin.c 17 Jun 2003 15:17:24 -0000
@@ -23,12 +23,6 @@
#include "m4.h"
#include "m4private.h"
-#define M4_ARG_SIGNATURE_DEFAULT_SIZE 7
-
-static m4_hash *m4_arg_signature_parse (const char *name, const char *param);
-
-
-
/* Find the builtin, which has NAME. If BP argument is supplied
then search only in table BP. */
const m4_builtin *
@@ -69,132 +63,4 @@ m4_builtin_find_by_func (const m4_builti
}
return NULL;
-}
-
-m4_symbol *
-m4_symbol_set_token (m4 *context, const char *name, m4_symbol_type type,
- m4_token *token,
- m4_symbol *(*getter) (m4_symtab *, const char *),
- m4_symbol *(*setter) (m4_symbol *, m4_token *))
-{
- const char *openp = NULL;
- const char *params = NULL;
- m4_symbol *symbol;
- size_t len;
-
- assert (name);
- assert (!token || (TOKEN_TYPE (token) == type));
- assert (getter);
- assert (setter);
-
- if (!no_gnu_extensions)
- {
- /* If name contains an open paren, then parse before that paren
- as the actual name, and the rest as a formal parameter list. */
- len = 0;
- for (openp = name; *openp && !M4_IS_OPEN (*openp); ++openp)
- ++len;
-
- if (*openp)
- {
- name = xstrzdup (name, len);
- params = 1+ openp;
- }
- }
-
- /* Get a symbol table entry for the name. */
- symbol = (*getter) (M4SYMTAB, name);
-
- if (symbol)
- {
- m4_token empty;
-
- if (!token)
- {
- bzero (&empty, sizeof (m4_token));
- TOKEN_TYPE (&empty) = type;
- switch (type)
- {
- case M4_TOKEN_TEXT:
- TOKEN_TEXT (&empty) = "";
- break;
-
- case M4_TOKEN_FUNC:
- case M4_TOKEN_VOID:
- break;
- }
-
- token = ∅
- }
-
- if (params)
- {
- /* Make a hash table to map formal parameter names to
- argv offsets, and store that in the symbol's token. */
- TOKEN_ARG_SIGNATURE (token) = m4_arg_signature_parse (name, params);
- }
-
- (*setter) (symbol, token);
- }
-
- /* If we split name on open paren, free the copied substring. */
- if (params)
- xfree ((char *) name);
-
- return symbol;
-}
-
-static m4_hash *
-m4_arg_signature_parse (const char *name, const char *params)
-{
- m4_hash *arg_signature;
- const char *commap;
- int offset;
-
- assert (params);
-
- arg_signature = m4_hash_new (M4_ARG_SIGNATURE_DEFAULT_SIZE,
- m4_hash_string_hash, m4_hash_string_cmp);
-
- for (offset = 1; *params && !M4_IS_CLOSE (*params); ++offset)
- {
- size_t len = 0;
-
- /* Skip leading whitespace. */
- while (M4_IS_SPACE (*params))
- ++params;
-
- for (commap = params; *commap && M4_IS_IDENT (*commap); ++commap)
- ++len;
-
- /* Skip trailing whitespace. */
- while (M4_IS_SPACE (*commap))
- ++commap;
-
- if (!M4_IS_COMMA (*commap) && !M4_IS_CLOSE (*commap))
- M4ERROR ((EXIT_FAILURE, 0,
- _("Error: %s: syntax error in parameter list at char `%c'"),
- name, *commap));
-
- /* Skip parameter delimiter. */
- if (M4_IS_COMMA (*commap))
- ++commap;
-
- if (len)
- {
- struct m4_token_arg *arg = XCALLOC (struct m4_token_arg, 1);
-
- TOKEN_ARG_INDEX (arg) = offset;
-
- m4_hash_insert (arg_signature, xstrzdup (params, len), arg);
-
- params = commap;
- }
- }
-
- if (!M4_IS_CLOSE (*commap))
- M4WARN ((warning_status, 0,
- _("Warning: %s: unterminated parameter list"), name));
-
- return arg_signature;
}
Index: m4/input.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/input.c,v
retrieving revision 1.24
diff -u -p -u -r1.24 input.c
--- m4/input.c 13 Jun 2003 13:05:45 -0000 1.24
+++ m4/input.c 17 Jun 2003 15:17:24 -0000
@@ -953,16 +953,6 @@ m4_next_token (m4_token *td)
return type;
}
-void
-m4_token_copy (m4_token *dest, m4_token *src)
-{
- TOKEN_TYPE (dest) = TOKEN_TYPE (src);
- TOKEN_FUNC (dest) = TOKEN_FUNC (src);
- TOKEN_HANDLE (dest) = TOKEN_HANDLE (src);
- TOKEN_FLAGS (dest) = TOKEN_FLAGS (src);
- TOKEN_MIN_ARGS (dest) = TOKEN_MIN_ARGS (src);
- TOKEN_MAX_ARGS (dest) = TOKEN_MAX_ARGS (src);
-}
#ifdef DEBUG_INPUT
Index: m4/m4module.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4module.h,v
retrieving revision 1.47
diff -u -p -u -r1.47 m4module.h
--- m4/m4module.h 16 Jun 2003 16:29:06 -0000 1.47
+++ m4/m4module.h 17 Jun 2003 15:17:24 -0000
@@ -60,12 +60,13 @@ typedef struct {
/* --- CONTEXT MANAGEMENT --- */
-extern m4 *m4_create (void);
-extern void m4_delete (m4 *);
-extern m4_symtab *m4_get_symtab (m4 *);
+extern m4 * m4_create (void);
+extern void m4_delete (m4 *);
+extern m4_symtab *m4_get_symtab (m4 *);
#define M4SYMTAB (m4_get_symtab (context))
+
/* --- MODULE MANAGEMENT --- */
@@ -75,15 +76,21 @@ typedef void m4_module_finish_func (m4 *
extern lt_dlhandle m4_module_load (m4 *, const char*, struct obstack*);
extern void m4_module_unload (m4 *, const char*, struct obstack*);
-extern const char *m4_get_module_name (lt_dlhandle);
-extern m4_builtin *m4_get_module_builtin_table (lt_dlhandle);
-extern m4_macro *m4_get_module_macro_table (lt_dlhandle);
+extern const char *m4_get_module_name (lt_dlhandle);
+extern m4_builtin *m4_get_module_builtin_table (lt_dlhandle);
+extern m4_macro *m4_get_module_macro_table (lt_dlhandle);
+
+extern void m4_set_module_macro_table (m4 *context, lt_dlhandle handle,
+ const m4_macro *table);
+extern void m4_set_module_builtin_table (m4 *context, lt_dlhandle handle,
+ const m4_builtin *table);
/* --- SYMBOL TABLE MANAGEMENT --- */
-typedef int m4_symtab_apply_func (m4_symtab *symtab, const void *key, void
*value, void *data);
+typedef int m4_symtab_apply_func (m4_symtab *symtab, const void *key,
+ void *value, void *data);
extern m4_symtab *m4_symtab_create (size_t);
extern void m4_symtab_delete (m4_symtab*);
@@ -92,9 +99,10 @@ extern int m4_symtab_apply (m4_symta
#define m4_symtab_apply(symtab, func, userdata)
\
(m4_hash_apply ((m4_hash*)(symtab), (m4_hash_apply_func*)(func), (userdata)))
+
extern m4_symbol *m4_symbol_lookup (m4_symtab*, const char *);
-extern m4_symbol *m4_symbol_pushdef (m4_symtab*, const char *);
-extern m4_symbol *m4_symbol_define (m4_symtab*, const char *);
+extern m4_symbol *m4_symbol_pushdef (m4_symtab*, const char *, m4_token *);
+extern m4_symbol *m4_symbol_define (m4_symtab*, const char *, m4_token *);
extern void m4_symbol_popdef (m4_symtab*, const char *);
extern void m4_symbol_delete (m4_symtab*, const char *);
@@ -102,6 +110,8 @@ extern void m4_symbol_delete (m4_
while (m4_symbol_lookup ((symtab), (name))) \
m4_symbol_popdef ((symtab), (name)); } M4_STMT_END
+extern void m4_set_symbol_traced (m4_symtab*, const char *);
+
/* Various different token types. */
typedef enum {
@@ -126,39 +136,10 @@ typedef enum {
/* --- MACRO (and builtin) MANAGEMENT --- */
-extern m4_symbol *m4_symbol_set_token (m4 *context, const char *name,
- m4_symbol_type type, m4_token *token,
- m4_symbol *(*getter) (m4_symtab *, const char *),
- m4_symbol *(*setter) (m4_symbol *, m4_token *));
-
-extern void m4_set_module_macro_table (m4 *context, lt_dlhandle handle,
- const m4_macro *table);
-extern void m4_set_module_builtin_table (m4 *context, lt_dlhandle handle,
- const m4_builtin *table);
-
extern const m4_builtin *m4_builtin_find_by_name (
const m4_builtin *, const char *);
extern const m4_builtin *m4_builtin_find_by_func (
const m4_builtin *, m4_builtin_func *);
-
-
-/* These 2 functions are not part of the documented API, but we need to
- declare them here so that the macros below will work. */
-extern m4_symbol *m4__symbol_set_builtin (m4_symbol*, m4_token*);
-extern m4_symbol *m4__symbol_set_macro (m4_symbol*, m4_token*);
-
-#define m4_macro_pushdef(context, name, macro) \
- m4_symbol_set_token ((context), (name), M4_TOKEN_TEXT, (macro), \
- m4_symbol_pushdef, m4__symbol_set_macro)
-#define m4_macro_define(context, name, macro) \
- m4_symbol_set_token ((context), (name), M4_TOKEN_TEXT, (macro), \
- m4_symbol_define, m4__symbol_set_macro)
-#define m4_builtin_pushdef(context, name, builtin) \
- m4_symbol_set_token ((context), (name), M4_TOKEN_FUNC, (builtin), \
- m4_symbol_pushdef, m4__symbol_set_builtin)
-#define m4_builtin_define(context, name, builtin) \
- m4_symbol_set_token ((context), (name), M4_TOKEN_FUNC, (builtin), \
- m4_symbol_define, m4__symbol_set_builtin)
extern m4__token_type m4_token_get_type (m4_token *);
extern char *m4_token_text (m4_token *);
Index: m4/macro.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/macro.c,v
retrieving revision 1.25
diff -u -p -u -r1.25 macro.c
--- m4/macro.c 16 Jun 2003 10:43:45 -0000 1.25
+++ m4/macro.c 17 Jun 2003 15:17:24 -0000
@@ -111,7 +111,7 @@ expand_token (m4 *context, struct obstac
caller. It skips leading whitespace, and reads and expands tokens,
until it finds a comma or a 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 arguments are build on the
+ the last for the active macro call. The arguments are built on the
obstack OBS, indirectly through expand_token (). */
static boolean
expand_argument (m4 *context, struct obstack *obs, m4_token *argp)
Index: m4/module.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/module.c,v
retrieving revision 1.20
diff -u -p -u -r1.20 module.c
--- m4/module.c 16 Jun 2003 16:29:06 -0000 1.20
+++ m4/module.c 17 Jun 2003 15:17:24 -0000
@@ -121,19 +121,25 @@ m4_set_module_builtin_table (m4 *context
const m4_builtin *table)
{
const m4_builtin *bp;
- m4_token token;
assert (handle);
assert (table);
- bzero (&token, sizeof (m4_token));
- TOKEN_TYPE (&token) = M4_TOKEN_FUNC;
- TOKEN_HANDLE (&token) = handle;
-
for (bp = table; bp->name != NULL; bp++)
{
- int flags = 0;
- char *name;
+ m4_token *token = XCALLOC (m4_token, 1);
+ char * name;
+
+ TOKEN_TYPE (token) = M4_TOKEN_FUNC;
+ TOKEN_FUNC (token) = bp->func;
+ TOKEN_HANDLE (token) = handle;
+ TOKEN_MIN_ARGS (token) = bp->min_args;
+ TOKEN_MAX_ARGS (token) = bp->max_args;
+
+ if (bp->groks_macro_args)
+ BIT_SET (TOKEN_FLAGS (token), TOKEN_MACRO_ARGS_BIT);
+ if (bp->blind_if_no_args)
+ BIT_SET (TOKEN_FLAGS (token), TOKEN_BLIND_ARGS_BIT);
if (prefix_all_builtins)
{
@@ -146,15 +152,8 @@ m4_set_module_builtin_table (m4 *context
else
name = (char *) bp->name;
- if (bp->groks_macro_args) BIT_SET (flags, TOKEN_MACRO_ARGS_BIT);
- if (bp->blind_if_no_args) BIT_SET (flags, TOKEN_BLIND_ARGS_BIT);
-
- TOKEN_FUNC (&token) = bp->func;
- TOKEN_FLAGS (&token) = flags;
- TOKEN_MIN_ARGS (&token) = bp->min_args;
- TOKEN_MAX_ARGS (&token) = bp->max_args;
- m4_builtin_pushdef (context, name, &token);
+ m4_symbol_pushdef (M4SYMTAB, name, token);
if (prefix_all_builtins)
xfree (name);
@@ -174,19 +173,20 @@ m4_get_module_macro_table (lt_dlhandle h
}
void
-m4_set_module_macro_table (m4 *context, lt_dlhandle handle, const m4_macro
*table)
+m4_set_module_macro_table (m4 *context, lt_dlhandle handle,
+ const m4_macro *table)
{
const m4_macro *mp;
- m4_token token;
-
- bzero (&token, sizeof (m4_token));
- TOKEN_TYPE (&token) = M4_TOKEN_TEXT;
- TOKEN_HANDLE (&token) = handle;
for (mp = table; mp->name != NULL; mp++)
{
- TOKEN_TEXT (&token) = (char *) mp->value;
- m4_macro_pushdef (context, mp->name, &token);
+ m4_token *token = XCALLOC (m4_token, 1);
+
+ TOKEN_TYPE (token) = M4_TOKEN_TEXT;
+ TOKEN_TEXT (token) = xstrdup (mp->value);
+ TOKEN_HANDLE (token) = handle;
+
+ m4_symbol_pushdef (M4SYMTAB, mp->name, token);
}
}
Index: m4/symtab.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/symtab.c,v
retrieving revision 1.36
diff -u -p -u -r1.36 symtab.c
--- m4/symtab.c 16 Jun 2003 16:29:06 -0000 1.36
+++ m4/symtab.c 17 Jun 2003 15:17:24 -0000
@@ -42,12 +42,16 @@
of fluff in these functions to make sure that such symbols (with empty
value stacks) are invisible to the users of this module. */
-#define M4_SYMTAB_DEFAULT_SIZE 2047
+#define M4_SYMTAB_DEFAULT_SIZE 2047
+#define M4_ARG_SIGNATURE_DEFAULT_SIZE 7
-static int symbol_destroy (m4_hash *hash, const void *name,
+static m4_symbol *symtab_fetch (m4_symtab*, const char *);
+static void symbol_popval (m4_symbol *symbol);
+static int symbol_destroy (m4_hash *hash, const void *name,
void *symbol, void *ignored);
-static int arg_destroy (m4_hash *hash, const void *name,
+static int arg_destroy (m4_hash *hash, const void *name,
void *arg, void *ignored);
+static m4_hash * arg_signature_parse (const char *name, const char *param);
@@ -71,6 +75,28 @@ m4_symtab_delete (m4_symtab *symtab)
m4_hash_delete ((m4_hash *) symtab);
}
+static m4_symbol *
+symtab_fetch (m4_symtab *symtab, const char *name)
+{
+ m4_symbol **psymbol;
+ m4_symbol *symbol;
+
+ assert (symtab);
+ assert (name);
+
+ psymbol = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab, name);
+ if (psymbol)
+ {
+ symbol = *psymbol;
+ }
+ else
+ {
+ symbol = XCALLOC (m4_symbol, 1);
+ m4_hash_insert ((m4_hash *) symtab, xstrdup (name), symbol);
+ }
+
+ return symbol;
+}
/* Remove every symbol that references the given module handle from
the symbol table. */
@@ -155,46 +181,60 @@ m4_symbol_lookup (m4_symtab *symtab, con
/* Insert NAME into the symbol table. If there is already a symbol
- associated with NAME, push the new value on top of the value stack
+ associated with NAME, push the new VALUE on top of the value stack
for this symbol. Otherwise create a new association. */
m4_symbol *
-m4_symbol_pushdef (m4_symtab *symtab, const char *name)
+m4_symbol_pushdef (m4_symtab *symtab, const char *name, m4_token *value)
{
- m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab,
- name);
-
- m4_symbol *symbol = 0;
- m4_token *value = XCALLOC (m4_token, 1);
+ m4_symbol *symbol;
- if (psymbol)
- {
- symbol = *psymbol;
- TOKEN_NEXT (value) = SYMBOL_TOKEN (symbol);
- }
- else
- symbol = XCALLOC (m4_symbol, 1);
+ assert (symtab);
+ assert (name);
+ assert (value);
+ symbol = symtab_fetch (symtab, name);
+ TOKEN_NEXT (value) = SYMBOL_TOKEN (symbol);
SYMBOL_TOKEN (symbol) = value;
- SYMBOL_TYPE (symbol) = M4_TOKEN_VOID;
- if (!psymbol)
- m4_hash_insert ((m4_hash *) symtab, xstrdup (name), symbol);
+ assert (SYMBOL_TOKEN (symbol));
return symbol;
}
-
/* Return the symbol associated with NAME in the symbol table, creating
- a new symbol if necessary. */
+ a new symbol if necessary. In either case set the symbol's VALUE. */
m4_symbol *
-m4_symbol_define (m4_symtab *symtab, const char *name)
+m4_symbol_define (m4_symtab *symtab, const char *name, m4_token *value)
{
- m4_symbol *symbol = m4_symbol_lookup (symtab, name);
+ m4_symbol *symbol;
- if (symbol)
- return symbol;
+ assert (symtab);
+ assert (name);
+ assert (value);
- return m4_symbol_pushdef (symtab, name);
+ symbol = symtab_fetch (symtab, name);
+ if (SYMBOL_TOKEN (symbol))
+ symbol_popval (symbol);
+
+ TOKEN_NEXT (value) = SYMBOL_TOKEN (symbol);
+ SYMBOL_TOKEN (symbol) = value;
+
+ assert (SYMBOL_TOKEN (symbol));
+
+ return symbol;
+}
+
+void
+m4_set_symbol_traced (m4_symtab *symtab, const char *name)
+{
+ m4_symbol *symbol;
+
+ assert (symtab);
+ assert (name);
+
+ symbol = symtab_fetch (symtab, name);
+
+ SYMBOL_TRACED (symbol) = TRUE;
}
@@ -206,16 +246,34 @@ m4_symbol_popdef (m4_symtab *symtab, con
{
m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup ((m4_hash *) symtab,
name);
- m4_token *stale = NULL;
-
assert (psymbol);
assert (*psymbol);
- stale = SYMBOL_TOKEN (*psymbol);
+ symbol_popval (*psymbol);
+
+ /* Only remove the hash table entry if the last value in the
+ symbol value stack was successfully removed. */
+ if (!SYMBOL_TOKEN (*psymbol))
+ if (no_gnu_extensions || !SYMBOL_TRACED (*psymbol))
+ {
+ XFREE (*psymbol);
+ xfree (m4_hash_remove ((m4_hash *) symtab, name));
+ }
+}
+
+
+static void
+symbol_popval (m4_symbol *symbol)
+{
+ m4_token *stale;
+
+ assert (symbol);
+
+ stale = SYMBOL_TOKEN (symbol);
if (stale)
{
- SYMBOL_TOKEN (*psymbol) = TOKEN_NEXT (stale);
+ SYMBOL_TOKEN (symbol) = TOKEN_NEXT (stale);
if (TOKEN_ARG_SIGNATURE (stale))
{
@@ -226,18 +284,8 @@ m4_symbol_popdef (m4_symtab *symtab, con
XFREE (TOKEN_TEXT (stale));
XFREE (stale);
}
-
- /* Only remove the hash table entry if the last value in the
- symbol value stack was successfully removed. */
- if (!SYMBOL_TOKEN (*psymbol))
- if (no_gnu_extensions || !SYMBOL_TRACED (*psymbol))
- {
- XFREE (*psymbol);
- xfree (m4_hash_remove ((m4_hash *) symtab, name));
- }
}
-
/* Callback used by m4_symbol_popdef () to release the memory used
by values in the arg_signature hash. */
static int
@@ -256,67 +304,162 @@ arg_destroy (m4_hash *hash, const void *
return 0;
}
-
-/* Set the type and value of a symbol according to the passed
- arguments. This function is usually passed a newly pushdef()d symbol
- that is already interned in the symbol table. The traced bit should
- be appropriately set by the caller. */
+#if 0
m4_symbol *
-m4__symbol_set_builtin (m4_symbol *symbol, m4_token *token)
+m4_symbol_push_token (m4_symtab *symtab, const char *name, m4_token *token)
{
- assert (symbol);
+ m4_token *next;
+
+ assert (symtab);
+ assert (name);
assert (token);
- assert (TOKEN_FUNC (token));
- assert (TOKEN_HANDLE (token));
- assert (TOKEN_TYPE (token) == M4_TOKEN_FUNC);
-
- if (SYMBOL_TYPE (symbol) == M4_TOKEN_TEXT)
- xfree (SYMBOL_TEXT (symbol));
-
- SYMBOL_TYPE (symbol) = TOKEN_TYPE (token);
- SYMBOL_FUNC (symbol) = TOKEN_FUNC (token);
- SYMBOL_HANDLE (symbol) = TOKEN_HANDLE (token);
- SYMBOL_FLAGS (symbol) = TOKEN_FLAGS (token);
- SYMBOL_ARG_SIGNATURE (symbol) = TOKEN_ARG_SIGNATURE (token);
- SYMBOL_MIN_ARGS (symbol) = TOKEN_MIN_ARGS (token);
- SYMBOL_MAX_ARGS (symbol) = TOKEN_MAX_ARGS (token);
+
+ /* If it's a function, it must have come from a module. */
+ assert ((TOKEN_TYPE (token) != M4_TOKEN_FUNC) || TOKEN_HANDLE (token));
+
+#if M4PARAMS
+ const char *openp = NULL;
+ const char *params = NULL;
+
+ if (!no_gnu_extensions)
+ {
+ /* If name contains an open paren, then parse before that paren
+ as the actual name, and the rest as a formal parameter list. */
+ size_t len = 0;
+ for (openp = name; *openp && !M4_IS_OPEN (*openp); ++openp)
+ ++len;
+
+ if (*openp)
+ {
+ name = xstrzdup (name, len);
+ params = 1+ openp;
+ }
+ }
+
+ if (params)
+ {
+ /* Make a hash table to map formal parameter names to
+ argv offsets, and store that in the symbol's token. */
+ TOKEN_ARG_SIGNATURE (token) = arg_signature_parse (name, params);
+ }
+#endif
+
+ SYMBOL_TOKEN (symbol) = token;
+
+#if M4PARAMS
+ /* If we split name on open paren, free the copied substring. */
+ if (params)
+ xfree ((char *) name);
+#endif
return symbol;
}
+#endif
-/* ...and similarly for macro valued symbols. */
-m4_symbol *
-m4__symbol_set_macro (m4_symbol *symbol, m4_token *token)
+void
+m4_token_copy (m4_token *dest, m4_token *src)
{
- assert (symbol);
- assert (TOKEN_TEXT (token));
- assert (TOKEN_TYPE (token) == M4_TOKEN_TEXT);
+ m4_token *next;
- if (SYMBOL_TYPE (symbol) == M4_TOKEN_TEXT)
- xfree (SYMBOL_TEXT (symbol));
+ assert (dest);
+ assert (src);
- SYMBOL_TYPE (symbol) = TOKEN_TYPE (token);
- SYMBOL_TEXT (symbol) = xstrdup (TOKEN_TEXT (token));
- SYMBOL_HANDLE (symbol) = TOKEN_HANDLE (token);
- SYMBOL_FLAGS (symbol) = TOKEN_FLAGS (token);
- SYMBOL_ARG_SIGNATURE (symbol) = TOKEN_ARG_SIGNATURE (token);
- SYMBOL_MIN_ARGS (symbol) = TOKEN_MIN_ARGS (token);
- SYMBOL_MAX_ARGS (symbol) = TOKEN_MAX_ARGS (token);
+ if (TOKEN_TYPE (dest) == M4_TOKEN_TEXT)
+ xfree (TOKEN_TEXT (dest));
- return symbol;
+#if M4PARAMS
+ if (TOKEN_ARG_SIGNATURE (dest))
+ {
+ m4_hash_apply (TOKEN_ARG_SIGNATURE (dest), arg_destroy, NULL);
+ m4_hash_delete (TOKEN_ARG_SIGNATURE (dest));
+ }
+#endif
+
+ /* Copy the token contents over, being careful to preserve
+ the next pointer. */
+ next = TOKEN_NEXT (dest);
+ bcopy (src, dest, sizeof (m4_token));
+ TOKEN_NEXT (dest) = next;
+
+ /* Caller is supposed to free text token strings, so we have to
+ copy the string not just its address in that case. */
+ if (TOKEN_TYPE (src) == M4_TOKEN_TEXT)
+ TOKEN_TEXT (dest) = xstrdup (TOKEN_TEXT (src));
+
+#if M4PARAMS
+ if (TOKEN_ARG_SIGNATURE (src))
+ TOKEN_ARG_SIGNATURE (dest) = m4_hash_dup (TOKEN_ARG_SIGNATURE (token));
+#endif
}
+#if M4PARAMS
+static m4_hash *
+arg_signature_parse (const char *name, const char *params)
+{
+ m4_hash *arg_signature;
+ const char *commap;
+ int offset;
+
+ assert (params);
+
+ arg_signature = m4_hash_new (M4_ARG_SIGNATURE_DEFAULT_SIZE,
+ m4_hash_string_hash, m4_hash_string_cmp);
+
+ for (offset = 1; *params && !M4_IS_CLOSE (*params); ++offset)
+ {
+ size_t len = 0;
+
+ /* Skip leading whitespace. */
+ while (M4_IS_SPACE (*params))
+ ++params;
+
+ for (commap = params; *commap && M4_IS_IDENT (*commap); ++commap)
+ ++len;
+
+ /* Skip trailing whitespace. */
+ while (M4_IS_SPACE (*commap))
+ ++commap;
+
+ if (!M4_IS_COMMA (*commap) && !M4_IS_CLOSE (*commap))
+ M4ERROR ((EXIT_FAILURE, 0,
+ _("Error: %s: syntax error in parameter list at char `%c'"),
+ name, *commap));
+
+ /* Skip parameter delimiter. */
+ if (M4_IS_COMMA (*commap))
+ ++commap;
+
+ if (len)
+ {
+ struct m4_token_arg *arg = XCALLOC (struct m4_token_arg, 1);
+
+ TOKEN_ARG_INDEX (arg) = offset;
+
+ m4_hash_insert (arg_signature, xstrzdup (params, len), arg);
+
+ params = commap;
+ }
+ }
+
+ if (!M4_IS_CLOSE (*commap))
+ M4WARN ((warning_status, 0,
+ _("Warning: %s: unterminated parameter list"), name));
+
+ return arg_signature;
+}
+#endif
#ifdef DEBUG_SYM
-static int symtab_print_list (const void *name, void *symbol, void *ignored);
-static void symtab_debug (void)
-static void symtab_dump (void);
+static int symtab_print_list (m4_hash *hash, const void *name, void *symbol,
+ void *ignored);
+static void symtab_debug (m4_symtab *symtab);
+static void symtab_dump (m4_symtab *symtab);
static void
-symtab_dump (void)
+symtab_dump (m4_symtab *symtab)
{
m4_hash_iterator *place = 0;
@@ -385,9 +528,9 @@ symtab_debug (m4_symtab *symtab)
printf (_("Name `%s' is unknown\n"), text);
if (delete)
- (void) m4_symbol_delete (symtab, text);
+ m4_symbol_delete (symtab, text);
else
- (void) m4_symbol_define (symtab, text);
+ symtab_fetch (symtab, text);
}
m4_symtab_apply (symtab, symtab_print_list, NULL);
}
Index: modules/m4.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/m4.c,v
retrieving revision 1.40
diff -u -p -u -r1.40 m4.c
--- modules/m4.c 16 Jun 2003 16:29:06 -0000 1.40
+++ modules/m4.c 17 Jun 2003 15:17:24 -0000
@@ -148,28 +148,23 @@ M4INIT_HANDLER (m4)
M4BUILTIN_HANDLER (define)
{
- if (TOKEN_TYPE (argv[1]) != M4_TOKEN_TEXT)
- return;
-
- if (argc == 2)
+ if (TOKEN_TYPE (argv[1]) == M4_TOKEN_TEXT)
{
- m4_macro_define (context, M4ARG (1), NULL);
- return;
- }
+ m4_token *token = XCALLOC (m4_token, 1);
- switch (TOKEN_TYPE (argv[2]))
- {
- case M4_TOKEN_TEXT:
- m4_macro_define (context, M4ARG (1), argv[2]);
- return;
-
- case M4_TOKEN_FUNC:
- m4_builtin_define (context, M4ARG (1), argv[2]);
- return;
- }
+ if (argc == 2)
+ {
+ TOKEN_TYPE (token) = M4_TOKEN_TEXT;
+ TOKEN_TEXT (token) = xstrdup ("");
+ }
+ else
+ {
+ m4_token_copy (token, argv[2]);
+ TOKEN_NEXT (token) = NULL;
+ }
- /*NOTREACHED*/
- assert (0);
+ m4_symbol_define (M4SYMTAB, M4ARG (1), token);
+ }
}
M4BUILTIN_HANDLER (undefine)
@@ -183,28 +178,23 @@ M4BUILTIN_HANDLER (undefine)
M4BUILTIN_HANDLER (pushdef)
{
- if (TOKEN_TYPE (argv[1]) != M4_TOKEN_TEXT)
- return;
-
- if (argc == 2)
+ if (TOKEN_TYPE (argv[1]) == M4_TOKEN_TEXT)
{
- m4_macro_pushdef (context, M4ARG (1), NULL);
- return;
- }
+ m4_token *token = XCALLOC (m4_token, 1);
- switch (TOKEN_TYPE (argv[2]))
- {
- case M4_TOKEN_TEXT:
- m4_macro_pushdef (context, M4ARG (1), argv[2]);
- return;
-
- case M4_TOKEN_FUNC:
- m4_builtin_pushdef (context, M4ARG (1), argv[2]);
- return;
- }
+ if (argc == 2)
+ {
+ TOKEN_TYPE (token) = M4_TOKEN_TEXT;
+ TOKEN_TEXT (token) = xstrdup ("");
+ }
+ else
+ {
+ m4_token_copy (token, argv[2]);
+ TOKEN_NEXT (token) = NULL;
+ }
- /*NOTREACHED*/
- assert (0);
+ m4_symbol_pushdef (M4SYMTAB, M4ARG (1), token);
+ }
}
M4BUILTIN_HANDLER (popdef)
Index: src/freeze.c
===================================================================
RCS file: /cvsroot/m4/m4/src/freeze.c,v
retrieving revision 1.27
diff -u -p -u -r1.27 freeze.c
--- src/freeze.c 16 Jun 2003 16:29:06 -0000 1.27
+++ src/freeze.c 17 Jun 2003 15:17:24 -0000
@@ -473,23 +473,20 @@ reload_frozen_state (m4 *context, const
if (bp)
{
- m4_token token;
- int flags = 0;
+ m4_token *token = XCALLOC (m4_token, 1);
if (bp->groks_macro_args)
- BIT_SET (flags, TOKEN_MACRO_ARGS_BIT);
+ BIT_SET (TOKEN_FLAGS (token), TOKEN_MACRO_ARGS_BIT);
if (bp->blind_if_no_args)
- BIT_SET (flags, TOKEN_BLIND_ARGS_BIT);
+ BIT_SET (TOKEN_FLAGS (token), TOKEN_BLIND_ARGS_BIT);
- bzero (&token, sizeof (m4_token));
- TOKEN_TYPE (&token) = M4_TOKEN_FUNC;
- TOKEN_FUNC (&token) = bp->func;
- TOKEN_HANDLE (&token) = handle;
- TOKEN_FLAGS (&token) = flags;
- TOKEN_MIN_ARGS (&token) = bp->min_args;
- TOKEN_MAX_ARGS (&token) = bp->max_args;
+ TOKEN_TYPE (token) = M4_TOKEN_FUNC;
+ TOKEN_FUNC (token) = bp->func;
+ TOKEN_HANDLE (token) = handle;
+ TOKEN_MIN_ARGS (token) = bp->min_args;
+ TOKEN_MAX_ARGS (token) = bp->max_args;
- m4_builtin_pushdef (context, string[0], &token);
+ m4_symbol_pushdef (M4SYMTAB, string[0], token);
}
else
M4ERROR ((warning_status, 0,
@@ -658,7 +655,7 @@ reload_frozen_state (m4 *context, const
/* Enter a macro having an expansion text as a definition. */
{
- m4_token token;
+ m4_token *token = XCALLOC (m4_token, 1);
lt_dlhandle handle = 0;
if (number[2] > 0)
@@ -666,13 +663,12 @@ reload_frozen_state (m4 *context, const
if (strcmp (m4_get_module_name (handle), string[2]) == 0)
break;
- bzero (&token, sizeof (m4_token));
- TOKEN_TYPE (&token) = M4_TOKEN_TEXT;
- TOKEN_TEXT (&token) = string[1];
- TOKEN_HANDLE (&token) = handle;
- TOKEN_MAX_ARGS (&token) = -1;
+ TOKEN_TYPE (token) = M4_TOKEN_TEXT;
+ TOKEN_TEXT (token) = xstrdup (string[1]);
+ TOKEN_HANDLE (token) = handle;
+ TOKEN_MAX_ARGS (token) = -1;
- m4_macro_pushdef (context, string[0], &token);
+ m4_symbol_pushdef (M4SYMTAB, string[0], token);
}
break;
Index: src/main.c
===================================================================
RCS file: /cvsroot/m4/m4/src/main.c,v
retrieving revision 1.38
diff -u -p -u -r1.38 main.c
--- src/main.c 16 Jun 2003 10:43:45 -0000 1.38
+++ src/main.c 17 Jun 2003 15:17:24 -0000
@@ -420,11 +420,6 @@ warranty; not even for MERCHANTABILITY o
/* Handle deferred command line macro definitions. Must come after
initialisation of the symbol table. */
{
- m4_token token;
-
- bzero (&token, sizeof (token));
- TOKEN_TYPE (&token) = M4_TOKEN_TEXT;
-
defines = head;
while (defines != NULL)
@@ -436,13 +431,19 @@ warranty; not even for MERCHANTABILITY o
switch (defines->code)
{
case 'D':
- macro_value = strchr (defines->macro, '=');
- if (macro_value == NULL)
- macro_value = "";
- else
- *macro_value++ = '\0';
- TOKEN_TEXT (&token) = macro_value;
- m4_macro_define (context, defines->macro, &token);
+ {
+ m4_token *token = XCALLOC (m4_token, 1);
+
+ macro_value = strchr (defines->macro, '=');
+ if (macro_value == NULL)
+ macro_value = "";
+ else
+ *macro_value++ = '\0';
+ TOKEN_TEXT (token) = xstrdup (macro_value);
+ TOKEN_TYPE (token) = M4_TOKEN_TEXT;
+
+ m4_symbol_pushdef (M4SYMTAB, defines->macro, token);
+ }
break;
case 'U':
@@ -450,8 +451,7 @@ warranty; not even for MERCHANTABILITY o
break;
case 't':
- symbol = m4_symbol_define (M4SYMTAB, defines->macro);
- SYMBOL_TRACED (symbol) = TRUE;
+ m4_set_symbol_traced (M4SYMTAB, defines->macro);
break;
case 'm':
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- FYI: 13-gary-refactor-symtab-semantics.patch,
Gary V. Vaughan <=