[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[12/18] argv_ref speedup: several code cleanups
From: |
Eric Blake |
Subject: |
[12/18] argv_ref speedup: several code cleanups |
Date: |
Sat, 26 Jan 2008 00:26:54 -0700 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.9) Gecko/20071031 Thunderbird/2.0.0.9 Mnenhy/0.7.5.666 |
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Next in the series. This focuses on three general code cleanups that made
later patches in the series easier. First - make token_chain a
discriminated union (smaller struct with fewer fields to initialize per
use, and the ability to add new union types rather than a binary decision
of string vs $@ reference). Second - make passing quotes around simpler
(a single struct, with contents and lengths, which will make embedded NUL
in quotes easier to manage, and avoids some strlen). Third - add a new
macro for the common case of calling arg_len (a later patch adds a
parameter that is typically false; besides, with embedded NUL, the length
becomes a much more important query). On the master branch, I took the
time to split this into three commits, but since it was one commit in the
argv_ref series, and since some of the hunks overlap, I left it that way
for branch-1_4. There is a slight memory savings due to a smaller struct,
and a negligible net speed penalty due to added code such as new quote
handling.
2008-01-26 Eric Blake <address@hidden>
Stage 12: make token_chain a union, add string_pair.
Shrink size of symbol chains by using a union. Make passing quote
delimiters around more efficient. Other code cleanups.
Memory impact: slight improvement, due to smaller struct.
Speed impact: slight penalty, due to more bookkeeping.
* src/m4.h (STRING): Delete typedef.
(struct string_pair, enum token_chain_type): New types.
(struct token_chain): Reduce size via a union.
(ARG_LEN): New macro.
(ARG): Move here...
* src/builtin.c (ARG): ...from here.
(dump_args, define_macro, m4_dumpdef, m4_builtin, m4_indir)
(m4_defn, mkstemp_helper, m4_maketemp, m4_mkstemp, m4___file__)
(m4___program__, m4_m4wrap, m4_len, m4_index, m4_substr)
(m4_regexp, m4_patsubst): Adjust callers.
* src/input.c (rquote, lquote, bcomm, ecomm): Delete...
(curr_quote, curr_comm): ...replaced by these.
(make_text_link, push_token, pop_input, input_print, peek_input)
(next_char_1, input_init, set_quotes, set_comment, set_quote_age)
(next_token, peek_token): Adjust callers.
* src/macro.c (expand_macro, arg_token, arg_mark, arg_text)
(arg_equal, arg_len, make_argv_ref, push_arg, push_args):
Likewise.
* src/format.c (ARG_INT, ARG_LONG, ARG_STR, ARG_DOUBLE, format):
Likewise.
* src/freeze.c (produce_frozen_state): Likewise.
* src/debug.c (trace_format, trace_pre): Likewise.
(debug_decode): Don't lose partial traces prior to reducing
debugmode.
- --
Don't work too hard, make some time for fun as well!
Eric Blake address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
iD8DBQFHmuC884KuGfSFAYARAjpMAKCrnciqgfVV8Sld4Kc1OOFANlp4pACgnY0U
/7/ej+YFnmewMvk8VqGeZEo=
=lnQU
-----END PGP SIGNATURE-----
>From 29a7a47303ce73626300a1e3fd09f623bbd57e60 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Fri, 25 Jan 2008 22:45:17 -0700
Subject: [PATCH] Stage 12a: make m4_symbol_chain a union.
* m4/m4private.h (enum m4__symbol_chain_type): New enum.
(struct m4_symbol_chain): Rename...
(struct m4__symbol_chain): ...to this, since it is internal.
* m4/symtab.c (m4_symbol_value_copy, m4_symbol_value_print): All
callers updated.
* m4/input.c (struct m4_input_block, m4__push_symbol)
(composite_peek, composite_read, composite_unget)
(composite_clean, m4__make_text_link, append_quote_token): Likewise.
* m4/macro.c (expand_macro, arg_mark, m4_arg_symbol, m4_arg_text)
(m4_arg_equal, m4_arg_len, m4_make_argv_ref, m4_push_arg)
(m4_push_args): Likewise.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 19 ++++++++
m4/input.c | 126 ++++++++++++++++++++++++++++---------------------------
m4/m4private.h | 46 ++++++++++++++------
m4/macro.c | 108 ++++++++++++++++++++++++-----------------------
m4/symtab.c | 18 ++++----
5 files changed, 179 insertions(+), 138 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 81643e7..a3f821e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2008-01-26 Eric Blake <address@hidden>
+
+ Stage 12a: make m4_symbol_chain a union.
+ Shrink size of symbol chains by using a union.
+ Memory impact: slight improvement, due to smaller struct.
+ Speed impact: slight improvement, due to less bookkeeping.
+ * m4/m4private.h (enum m4__symbol_chain_type): New enum.
+ (struct m4_symbol_chain): Rename...
+ (struct m4__symbol_chain): ...to this, since it is internal.
+ * m4/symtab.c (m4_symbol_value_copy, m4_symbol_value_print): All
+ callers updated.
+ * m4/input.c (struct m4_input_block, m4__push_symbol)
+ (composite_peek, composite_read, composite_unget)
+ (composite_clean, composite_print, m4__make_text_link)
+ (append_quote_token): Likewise.
+ * m4/macro.c (expand_macro, arg_mark, m4_arg_symbol, m4_arg_text)
+ (m4_arg_equal, m4_arg_len, m4_make_argv_ref, m4_push_arg)
+ (m4_push_args): Likewise.
+
2008-01-23 Eric Blake <address@hidden>
Adjust to recent libtool interface change.
diff --git a/m4/input.c b/m4/input.c
index 0dcb0ae..f45db18 100644
--- a/m4/input.c
+++ b/m4/input.c
@@ -186,8 +186,8 @@ struct m4_input_block
u_b; /* See builtin_funcs. */
struct
{
- m4_symbol_chain *chain; /* Current link in chain. */
- m4_symbol_chain *end; /* Last link in chain. */
+ m4__symbol_chain *chain; /* Current link in chain. */
+ m4__symbol_chain *end; /* Last link in chain. */
}
u_c; /* See composite_funcs. */
}
@@ -539,7 +539,7 @@ m4_push_string_init (m4 *context)
bool
m4__push_symbol (m4 *context, m4_symbol_value *value, size_t level)
{
- m4_symbol_chain *chain;
+ m4__symbol_chain *chain;
bool result = false;
assert (next);
@@ -562,20 +562,18 @@ m4__push_symbol (m4 *context, m4_symbol_value *value,
size_t level)
next->u.u_c.chain = next->u.u_c.end = NULL;
}
m4__make_text_link (current_input, &next->u.u_c.chain, &next->u.u_c.end);
- chain = (m4_symbol_chain *) obstack_alloc (current_input, sizeof *chain);
+ chain = (m4__symbol_chain *) obstack_alloc (current_input, sizeof *chain);
if (next->u.u_c.end)
next->u.u_c.end->next = chain;
else
next->u.u_c.chain = chain;
next->u.u_c.end = chain;
chain->next = NULL;
+ chain->type = M4__CHAIN_STR;
chain->quote_age = m4_get_symbol_value_quote_age (value);
- chain->str = m4_get_symbol_value_text (value);
- chain->len = m4_get_symbol_value_len (value);
- chain->level = level;
- chain->argv = NULL;
- chain->index = 0;
- chain->flatten = false;
+ chain->u.u_s.str = m4_get_symbol_value_text (value);
+ chain->u.u_s.len = m4_get_symbol_value_len (value);
+ chain->u.u_s.level = level;
if (level < SIZE_MAX)
{
m4__adjust_refcount (context, level, true);
@@ -632,18 +630,19 @@ m4_push_string_finish (void)
static int
composite_peek (m4_input_block *me)
{
- m4_symbol_chain *chain = me->u.u_c.chain;
+ m4__symbol_chain *chain = me->u.u_c.chain;
while (chain)
{
- if (chain->str)
- {
- if (chain->len)
- return to_uchar (chain->str[0]);
- }
- else
+ switch (chain->type)
{
+ case M4__CHAIN_STR:
+ if (chain->u.u_s.len)
+ return to_uchar (chain->u.u_s.str[0]);
+ break;
+ case M4__CHAIN_ARGV:
/* TODO - peek into argv. */
- assert (!"implemented yet");
+ default:
+ assert (!"composite_peek");
abort ();
}
chain = chain->next;
@@ -654,29 +653,30 @@ composite_peek (m4_input_block *me)
static int
composite_read (m4_input_block *me, m4 *context, bool allow_quote, bool safe)
{
- m4_symbol_chain *chain = me->u.u_c.chain;
+ m4__symbol_chain *chain = me->u.u_c.chain;
while (chain)
{
if (allow_quote && chain->quote_age == m4__quote_age (M4SYNTAX))
return CHAR_QUOTE;
- if (chain->str)
+ switch (chain->type)
{
- if (chain->len)
+ case M4__CHAIN_STR:
+ if (chain->u.u_s.len)
{
/* Partial consumption invalidates quote age. */
chain->quote_age = 0;
- chain->len--;
- return to_uchar (*chain->str++);
+ chain->u.u_s.len--;
+ return to_uchar (*chain->u.u_s.str++);
}
- }
- else
- {
+ if (chain->u.u_s.level < SIZE_MAX)
+ m4__adjust_refcount (context, chain->u.u_s.level, false);
+ break;
+ case M4__CHAIN_ARGV:
/* TODO - peek into argv. */
- assert (!"implemented yet");
+ default:
+ assert (!"composite_read");
abort ();
}
- if (chain->level < SIZE_MAX)
- m4__adjust_refcount (context, chain->level, false);
me->u.u_c.chain = chain = chain->next;
}
return CHAR_RETRY;
@@ -685,17 +685,18 @@ composite_read (m4_input_block *me, m4 *context, bool
allow_quote, bool safe)
static void
composite_unget (m4_input_block *me, int ch)
{
- m4_symbol_chain *chain = me->u.u_c.chain;
- if (chain->str)
- {
- assert (ch < CHAR_EOF && to_uchar (chain->str[-1]) == ch);
- chain->str--;
- chain->len++;
- }
- else
+ m4__symbol_chain *chain = me->u.u_c.chain;
+ switch (chain->type)
{
+ case M4__CHAIN_STR:
+ assert (ch < CHAR_EOF && to_uchar (chain->u.u_s.str[-1]) == ch);
+ chain->u.u_s.str--;
+ chain->u.u_s.len++;
+ break;
+ case M4__CHAIN_ARGV:
/* TODO support argv ref. */
- assert (!"implemented yet");
+ default:
+ assert (!"composite_unget");
abort ();
}
}
@@ -703,20 +704,23 @@ composite_unget (m4_input_block *me, int ch)
static bool
composite_clean (m4_input_block *me, m4 *context, bool cleanup)
{
- m4_symbol_chain *chain = me->u.u_c.chain;
+ m4__symbol_chain *chain = me->u.u_c.chain;
assert (!chain || !cleanup);
while (chain)
{
- if (chain->str)
- assert (!chain->len);
- else
+ switch (chain->type)
{
+ case M4__CHAIN_STR:
+ assert (!chain->u.u_s.len);
+ if (chain->u.u_s.level < SIZE_MAX)
+ m4__adjust_refcount (context, chain->u.u_s.level, false);
+ break;
+ case M4__CHAIN_ARGV:
/* TODO - peek into argv. */
- assert (!"implemented yet");
+ default:
+ assert (!"composite_clean");
abort ();
}
- if (chain->level < SIZE_MAX)
- m4__adjust_refcount (context, chain->level, false);
me->u.u_c.chain = chain = chain->next;
}
return true;
@@ -727,7 +731,7 @@ composite_print (m4_input_block *me, m4 *context,
m4_obstack *obs)
{
bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
size_t maxlen = m4_get_max_debug_arg_length_opt (context);
- m4_symbol_chain *chain = me->u.u_c.chain;
+ m4__symbol_chain *chain = me->u.u_c.chain;
const char *lquote = m4_get_syntax_lquote (M4SYNTAX);
const char *rquote = m4_get_syntax_rquote (M4SYNTAX);
@@ -736,9 +740,9 @@ composite_print (m4_input_block *me, m4 *context,
m4_obstack *obs)
while (chain)
{
/* TODO support argv refs as well. */
- assert (chain->str);
- if (m4_shipout_string_trunc (context, obs, chain->str, chain->len, false,
- &maxlen))
+ assert (chain->type == M4__CHAIN_STR);
+ if (m4_shipout_string_trunc (context, obs, chain->u.u_s.str,
+ chain->u.u_s.len, false, &maxlen))
break;
chain = chain->next;
}
@@ -750,30 +754,28 @@ composite_print (m4_input_block *me, m4 *context,
m4_obstack *obs)
chain that starts at *START and ends at *END. START may be NULL if
*END is non-NULL. */
void
-m4__make_text_link (m4_obstack *obs, m4_symbol_chain **start,
- m4_symbol_chain **end)
+m4__make_text_link (m4_obstack *obs, m4__symbol_chain **start,
+ m4__symbol_chain **end)
{
- m4_symbol_chain *chain;
+ m4__symbol_chain *chain;
size_t len = obstack_object_size (obs);
assert (end && (start || *end));
if (len)
{
char *str = (char *) obstack_finish (obs);
- chain = (m4_symbol_chain *) obstack_alloc (obs, sizeof *chain);
+ chain = (m4__symbol_chain *) obstack_alloc (obs, sizeof *chain);
if (*end)
(*end)->next = chain;
else
*start = chain;
*end = chain;
chain->next = NULL;
+ chain->type = M4__CHAIN_STR;
chain->quote_age = 0;
- chain->str = str;
- chain->len = len;
- chain->level = SIZE_MAX;
- chain->argv = NULL;
- chain->index = 0;
- chain->flatten = false;
+ chain->u.u_s.str = str;
+ chain->u.u_s.len = len;
+ chain->u.u_s.level = SIZE_MAX;
}
}
@@ -918,8 +920,8 @@ init_builtin_token (m4 *context, m4_symbol_value *token)
static void
append_quote_token (m4_obstack *obs, m4_symbol_value *value)
{
- m4_symbol_chain *src_chain = isp->u.u_c.chain;
- m4_symbol_chain *chain;
+ m4__symbol_chain *src_chain = isp->u.u_c.chain;
+ m4__symbol_chain *chain;
assert (isp->funcs == &composite_funcs && obs);
if (value->type == M4_SYMBOL_VOID)
@@ -929,7 +931,7 @@ append_quote_token (m4_obstack *obs, m4_symbol_value *value)
}
assert (value->type == M4_SYMBOL_COMP);
m4__make_text_link (obs, &value->u.u_c.chain, &value->u.u_c.end);
- chain = (m4_symbol_chain *) obstack_copy (obs, src_chain, sizeof *chain);
+ chain = (m4__symbol_chain *) obstack_copy (obs, src_chain, sizeof *chain);
if (value->u.u_c.end)
value->u.u_c.end->next = chain;
else
diff --git a/m4/m4private.h b/m4/m4private.h
index 6a08455..dab41c0 100644
--- a/m4/m4private.h
+++ b/m4/m4private.h
@@ -185,7 +185,7 @@ extern m4_module * m4__module_find (const char *name);
/* --- SYMBOL TABLE MANAGEMENT --- */
-typedef struct m4_symbol_chain m4_symbol_chain;
+typedef struct m4__symbol_chain m4__symbol_chain;
struct m4_symbol
{
@@ -193,17 +193,35 @@ struct m4_symbol
m4_symbol_value *value; /* Linked list of pushdef'd values. */
};
+/* Type of a link in a symbol chain. */
+enum m4__symbol_chain_type
+{
+ M4__CHAIN_STR, /* Link contains a string, u.u_s is valid. */
+ /* TODO Add M4__CHAIN_FUNC. */
+ M4__CHAIN_ARGV /* Link contains a $@ reference, u.u_a is valid. */
+};
+
/* Composite symbols are built of a linked list of chain objects. */
-struct m4_symbol_chain
+struct m4__symbol_chain
{
- m4_symbol_chain *next;/* Pointer to next link of chain. */
- unsigned int quote_age; /* Quote_age of this link of chain, or 0. */
- const char *str; /* NUL-terminated string if text, or NULL. */
- size_t len; /* Length of str, or 0. */
- size_t level; /* Expansion level of content, or SIZE_MAX. */
- m4_macro_args *argv; /* Reference to earlier address@hidden */
- unsigned int index; /* Argument index within argv. */
- bool flatten; /* True to treat builtins as text. */
+ m4__symbol_chain *next; /* Pointer to next link of chain. */
+ enum m4__symbol_chain_type type; /* Type of this link. */
+ unsigned int quote_age; /* Quote_age of this link, or 0. */
+ union
+ {
+ struct
+ {
+ const char *str; /* Pointer to text. */
+ size_t len; /* Remaining length of str. */
+ size_t level; /* Expansion level of content, or SIZE_MAX. */
+ } u_s; /* M4__CHAIN_STR. */
+ struct
+ {
+ m4_macro_args *argv; /* Reference to earlier address@hidden */
+ unsigned int index; /* Argument index within argv. */
+ bool flatten; /* True to treat builtins as text. */
+ } u_a; /* M4__CHAIN_ARGV. */
+ } u;
};
/* A symbol value is used both for values associated with a macro
@@ -233,8 +251,8 @@ struct m4_symbol_value
const m4_builtin * builtin;/* Valid when type is FUNC. */
struct
{
- m4_symbol_chain * chain; /* First link of the chain. */
- m4_symbol_chain * end; /* Last link of the chain. */
+ m4__symbol_chain *chain; /* First link of the chain. */
+ m4__symbol_chain *end; /* Last link of the chain. */
} u_c; /* Valid when type is COMP. */
} u;
};
@@ -460,8 +478,8 @@ typedef enum {
M4_TOKEN_MACDEF /* Macro's definition (see "defn"), M4_SYMBOL_FUNC. */
} m4__token_type;
-extern void m4__make_text_link (m4_obstack *, m4_symbol_chain **,
- m4_symbol_chain **);
+extern void m4__make_text_link (m4_obstack *, m4__symbol_chain **,
+ m4__symbol_chain **);
extern bool m4__push_symbol (m4 *, m4_symbol_value *, size_t);
extern m4__token_type m4__next_token (m4 *, m4_symbol_value *, int *,
m4_obstack *, const char *);
diff --git a/m4/macro.c b/m4/macro.c
index 683dd26..6671c9c 100644
--- a/m4/macro.c
+++ b/m4/macro.c
@@ -525,7 +525,7 @@ recursion limit of %zu exceeded, use -L<N> to change it"),
/* If argv contains references, those refcounts must be reduced now. */
if (argv->has_ref)
{
- m4_symbol_chain *chain;
+ m4__symbol_chain *chain;
size_t i;
for (i = 0; i < argv->arraylen; i++)
if (argv->array[i]->type == M4_SYMBOL_COMP)
@@ -533,8 +533,9 @@ recursion limit of %zu exceeded, use -L<N> to change it"),
chain = argv->array[i]->u.u_c.chain;
while (chain)
{
- if (chain->level < SIZE_MAX)
- m4__adjust_refcount (context, chain->level, false);
+ assert (chain->type == M4__CHAIN_STR);
+ if (chain->u.u_s.level < SIZE_MAX)
+ m4__adjust_refcount (context, chain->u.u_s.level, false);
chain = chain->next;
}
}
@@ -991,8 +992,8 @@ arg_mark (m4_macro_args *argv)
assert (argv->arraylen == 1
&& argv->array[0]->type == M4_SYMBOL_COMP
&& !argv->array[0]->u.u_c.chain->next
- && !argv->array[0]->u.u_c.chain->str);
- argv->array[0]->u.u_c.chain->argv->inuse = true;
+ && argv->array[0]->u.u_c.chain->type == M4__CHAIN_ARGV);
+ argv->array[0]->u.u_c.chain->u.u_a.argv->inuse = true;
}
}
@@ -1017,17 +1018,18 @@ m4_arg_symbol (m4_macro_args *argv, unsigned int index)
value = argv->array[i];
if (value->type == M4_SYMBOL_COMP)
{
- m4_symbol_chain *chain = value->u.u_c.chain;
+ m4__symbol_chain *chain = value->u.u_c.chain;
/* TODO - for now we support only a single $@ chain. */
- assert (!chain->next && !chain->str);
- if (index < chain->argv->argc - (chain->index - 1))
+ assert (!chain->next && chain->type == M4__CHAIN_ARGV);
+ if (index < chain->u.u_a.argv->argc - (chain->u.u_a.index - 1))
{
- value = m4_arg_symbol (chain->argv, chain->index - 1 + index);
- if (chain->flatten && m4_is_symbol_value_func (value))
+ value = m4_arg_symbol (chain->u.u_a.argv,
+ chain->u.u_a.index - 1 + index);
+ if (chain->u.u_a.flatten && m4_is_symbol_value_func (value))
value = &empty_symbol;
break;
}
- index -= chain->argv->argc - chain->index;
+ index -= chain->u.u_a.argv->argc - chain->u.u_a.index;
}
else if (--index == 0)
break;
@@ -1068,7 +1070,7 @@ const char *
m4_arg_text (m4 *context, m4_macro_args *argv, unsigned int index)
{
m4_symbol_value *value;
- m4_symbol_chain *chain;
+ m4__symbol_chain *chain;
m4_obstack *obs;
if (index == 0)
@@ -1085,8 +1087,8 @@ m4_arg_text (m4 *context, m4_macro_args *argv, unsigned
int index)
obs = m4_arg_scratch (context);
while (chain)
{
- assert (chain->str);
- obstack_grow (obs, chain->str, chain->len);
+ assert (chain->type == M4__CHAIN_STR);
+ obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
chain = chain->next;
}
obstack_1grow (obs, '\0');
@@ -1103,10 +1105,10 @@ m4_arg_equal (m4_macro_args *argv, unsigned int indexa,
unsigned int indexb)
{
m4_symbol_value *sa = m4_arg_symbol (argv, indexa);
m4_symbol_value *sb = m4_arg_symbol (argv, indexb);
- m4_symbol_chain tmpa;
- m4_symbol_chain tmpb;
- m4_symbol_chain *ca = &tmpa;
- m4_symbol_chain *cb = &tmpb;
+ m4__symbol_chain tmpa;
+ m4__symbol_chain tmpb;
+ m4__symbol_chain *ca = &tmpa;
+ m4__symbol_chain *cb = &tmpb;
/* Quick tests. */
if (sa == &empty_symbol || sb == &empty_symbol)
@@ -1122,8 +1124,9 @@ m4_arg_equal (m4_macro_args *argv, unsigned int indexa,
unsigned int indexb)
if (m4_is_symbol_value_text (sa))
{
tmpa.next = NULL;
- tmpa.str = m4_get_symbol_value_text (sa);
- tmpa.len = m4_get_symbol_value_len (sa);
+ tmpa.type = M4__CHAIN_STR;
+ tmpa.u.u_s.str = m4_get_symbol_value_text (sa);
+ tmpa.u.u_s.len = m4_get_symbol_value_len (sa);
}
else
{
@@ -1133,8 +1136,9 @@ m4_arg_equal (m4_macro_args *argv, unsigned int indexa,
unsigned int indexb)
if (m4_is_symbol_value_text (sb))
{
tmpb.next = NULL;
- tmpb.str = m4_get_symbol_value_text (sb);
- tmpb.len = m4_get_symbol_value_len (sb);
+ tmpb.type = M4__CHAIN_STR;
+ tmpb.u.u_s.str = m4_get_symbol_value_text (sb);
+ tmpb.u.u_s.len = m4_get_symbol_value_len (sb);
}
else
{
@@ -1146,32 +1150,32 @@ m4_arg_equal (m4_macro_args *argv, unsigned int indexa,
unsigned int indexb)
while (ca && cb)
{
/* TODO support comparison against $@ refs. */
- assert (ca->str && cb->str);
- if (ca->len == cb->len)
+ assert (ca->type == M4__CHAIN_STR && cb->type == M4__CHAIN_STR);
+ if (ca->u.u_s.len == cb->u.u_s.len)
{
- if (memcmp (ca->str, cb->str, ca->len) != 0)
+ if (memcmp (ca->u.u_s.str, cb->u.u_s.str, ca->u.u_s.len) != 0)
return false;
ca = ca->next;
cb = cb->next;
}
- else if (ca->len < cb->len)
+ else if (ca->u.u_s.len < cb->u.u_s.len)
{
- if (memcmp (ca->str, cb->str, ca->len) != 0)
+ if (memcmp (ca->u.u_s.str, cb->u.u_s.str, ca->u.u_s.len) != 0)
return false;
tmpb.next = cb->next;
- tmpb.str = cb->str + ca->len;
- tmpb.len = cb->len - ca->len;
+ tmpb.u.u_s.str = cb->u.u_s.str + ca->u.u_s.len;
+ tmpb.u.u_s.len = cb->u.u_s.len - ca->u.u_s.len;
ca = ca->next;
cb = &tmpb;
}
else
{
- assert (cb->len < ca->len);
- if (memcmp (ca->str, cb->str, cb->len) != 0)
+ assert (cb->u.u_s.len < ca->u.u_s.len);
+ if (memcmp (ca->u.u_s.str, cb->u.u_s.str, cb->u.u_s.len) != 0)
return false;
tmpa.next = ca->next;
- tmpa.str = ca->str + cb->len;
- tmpa.len = ca->len - cb->len;
+ tmpa.u.u_s.str = ca->u.u_s.str + cb->u.u_s.len;
+ tmpa.u.u_s.len = ca->u.u_s.len - cb->u.u_s.len;
ca = &tmpa;
cb = cb->next;
}
@@ -1199,7 +1203,7 @@ size_t
m4_arg_len (m4_macro_args *argv, unsigned int index)
{
m4_symbol_value *value;
- m4_symbol_chain *chain;
+ m4__symbol_chain *chain;
size_t len;
if (index == 0)
@@ -1215,8 +1219,8 @@ m4_arg_len (m4_macro_args *argv, unsigned int index)
len = 0;
while (chain)
{
- assert (chain->str);
- len += chain->len;
+ assert (chain->type == M4__CHAIN_STR);
+ len += chain->u.u_s.len;
chain = chain->next;
}
assert (len);
@@ -1244,7 +1248,7 @@ m4_make_argv_ref (m4 *context, m4_macro_args *argv, const
char *argv0,
{
m4_macro_args *new_argv;
m4_symbol_value *value;
- m4_symbol_chain *chain;
+ m4__symbol_chain *chain;
unsigned int index = skip ? 2 : 1;
m4_obstack *obs = m4_arg_scratch (context);
@@ -1255,9 +1259,9 @@ m4_make_argv_ref (m4 *context, m4_macro_args *argv, const
char *argv0,
/* TODO for now we support only a single-length $@ chain. */
assert (argv->arraylen == 1 && argv->array[0]->type == M4_SYMBOL_COMP);
chain = argv->array[0]->u.u_c.chain;
- assert (!chain->next && !chain->str);
- argv = chain->argv;
- index += chain->index - 1;
+ assert (!chain->next && chain->type == M4__CHAIN_ARGV);
+ argv = chain->u.u_a.argv;
+ index += chain->u.u_a.index - 1;
}
if (argv->argc <= index)
{
@@ -1272,7 +1276,7 @@ m4_make_argv_ref (m4 *context, m4_macro_args *argv, const
char *argv0,
array)
+ sizeof value));
value = (m4_symbol_value *) obstack_alloc (obs, sizeof *value);
- chain = (m4_symbol_chain *) obstack_alloc (obs, sizeof *chain);
+ chain = (m4__symbol_chain *) obstack_alloc (obs, sizeof *chain);
new_argv->arraylen = 1;
new_argv->array[0] = value;
new_argv->wrapper = true;
@@ -1280,13 +1284,11 @@ m4_make_argv_ref (m4 *context, m4_macro_args *argv,
const char *argv0,
value->type = M4_SYMBOL_COMP;
value->u.u_c.chain = value->u.u_c.end = chain;
chain->next = NULL;
+ chain->type = M4__CHAIN_ARGV;
chain->quote_age = argv->quote_age;
- chain->str = NULL;
- chain->len = 0;
- chain->level = context->expansion_level - 1;
- chain->argv = argv;
- chain->index = index;
- chain->flatten = flatten;
+ chain->u.u_a.argv = argv;
+ chain->u.u_a.index = index;
+ chain->u.u_a.flatten = flatten;
}
new_argv->argc = argv->argc - (index - 1);
new_argv->inuse = false;
@@ -1326,11 +1328,11 @@ m4_push_arg (m4 *context, m4_obstack *obs,
m4_macro_args *argv,
{
/* TODO - really handle composites; for now, just flatten the
composite and push its text. */
- m4_symbol_chain *chain = value->u.u_c.chain;
+ m4__symbol_chain *chain = value->u.u_c.chain;
while (chain)
{
- assert (chain->str);
- obstack_grow (obs, chain->str, chain->len);
+ assert (chain->type == M4__CHAIN_STR);
+ obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
chain = chain->next;
}
}
@@ -1345,7 +1347,7 @@ m4_push_args (m4 *context, m4_obstack *obs, m4_macro_args
*argv, bool skip,
bool quote)
{
m4_symbol_value *value;
- m4_symbol_chain *chain;
+ m4__symbol_chain *chain;
unsigned int i = skip ? 2 : 1;
const char *sep = ",";
size_t sep_len = 1;
@@ -1398,8 +1400,8 @@ m4_push_args (m4 *context, m4_obstack *obs, m4_macro_args
*argv, bool skip,
chain = value->u.u_c.chain;
while (chain)
{
- assert (chain->str);
- obstack_grow (obs, chain->str, chain->len);
+ assert (chain->type == M4__CHAIN_STR);
+ obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
chain = chain->next;
}
}
diff --git a/m4/symtab.c b/m4/symtab.c
index 3ff6f0d..1c419eb 100644
--- a/m4/symtab.c
+++ b/m4/symtab.c
@@ -454,23 +454,23 @@ m4_symbol_value_copy (m4_symbol_value *dest,
m4_symbol_value *src)
break;
case M4_SYMBOL_COMP:
{
- m4_symbol_chain *chain = src->u.u_c.chain;
+ m4__symbol_chain *chain = src->u.u_c.chain;
size_t len = 0;
char *str;
char *p;
while (chain)
{
/* TODO for now, only text links are supported. */
- assert (chain->str);
- len += chain->len;
+ assert (chain->type == M4__CHAIN_STR);
+ len += chain->u.u_s.len;
chain = chain->next;
}
p = str = xcharalloc (len + 1);
chain = src->u.u_c.chain;
while (chain)
{
- memcpy (p, chain->str, chain->len);
- p += chain->len;
+ memcpy (p, chain->u.u_s.str, chain->u.u_s.len);
+ p += chain->u.u_s.len;
chain = chain->next;
}
*p = '\0';
@@ -576,15 +576,15 @@ m4_symbol_value_print (m4_symbol_value *value, m4_obstack
*obs, bool quote,
break;
case M4_SYMBOL_COMP:
{
- m4_symbol_chain *chain = value->u.u_c.chain;
+ m4__symbol_chain *chain = value->u.u_c.chain;
if (quote)
obstack_grow (obs, lquote, strlen (lquote));
while (chain)
{
/* TODO for now, assume all links are text. */
- assert (chain->str);
- if (m4_shipout_string_trunc (NULL, obs, chain->str, chain->len,
- false, &maxlen))
+ assert (chain->type == M4__CHAIN_STR);
+ if (m4_shipout_string_trunc (NULL, obs, chain->u.u_s.str,
+ chain->u.u_s.len, NULL, &maxlen))
break;
chain = chain->next;
}
--
1.5.3.8
>From 726430fec6c0f3807f8f9e4d2c681f5300dc7694 Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Fri, 25 Jan 2008 23:49:38 -0700
Subject: [PATCH] Stage 12b: add m4_string_pair.
* m4/m4module.h (m4_string_pair): New type.
(m4_get_syntax_quotes, m4_get_syntax_comments): New prototypes.
(m4_symbol_value_print, m4_symbol_print, m4_shipout_string_trunc):
Alter signature.
* m4/m4private.h (struct m4_string): Delete.
(struct m4_syntax_table): Combine quote and comment members.
(m4_get_syntax_lquote, m4_get_syntax_rquote, m4_get_syntax_bcomm)
(m4_get_syntax_ecomm): Adjust accessors.
(m4_get_syntax_quotes, m4_get_syntax_comments): New fast
accessors.
* m4/symtab.c (m4_symbol_value_print, m4_symbol_print):
Alter signatures.
* m4/input.c (string_print, composite_print, m4_input_print):
All callers updated.
* m4/syntax.c (m4_syntax_delete, m4_set_syntax)
(check_is_single_quotes, m4_set_quotes, set_quote_age)
(m4_get_syntax_lquote, m4_get_syntax_rquote)
(m4_get_syntax_quotes, check_is_single_comments, m4_set_comment)
(m4_get_syntax_bcomm, m4_get_syntax_ecomm)
(m4_get_syntax_comments): Likewise.
* m4/macro.c (trace_prepre, trace_pre, m4_push_args): Likewise.
* m4/output.c (m4_shipout_string, m4_shipout_string_trunc):
Likewise.
* modules/m4.c (dumpdef, m4_make_temp): Likewise.
* src/freeze.c (produce_frozen_state): Likewise.
* tests/freeze.at (reloading unknown builtin): Update test.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 63 +++++++++++++++++------
m4/input.c | 73 +++++++++++++++------------
m4/m4module.h | 27 +++++++---
m4/m4private.h | 21 +++-----
m4/macro.c | 37 +++++++-------
m4/output.c | 29 +++++------
m4/symtab.c | 64 +++++++++++-------------
m4/syntax.c | 150 ++++++++++++++++++++++++++++++------------------------
modules/m4.c | 21 +++-----
src/freeze.c | 31 +++++-------
tests/freeze.at | 4 +-
11 files changed, 281 insertions(+), 239 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index a3f821e..67ce533 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,21 +1,52 @@
2008-01-26 Eric Blake <address@hidden>
- Stage 12a: make m4_symbol_chain a union.
- Shrink size of symbol chains by using a union.
- Memory impact: slight improvement, due to smaller struct.
- Speed impact: slight improvement, due to less bookkeeping.
- * m4/m4private.h (enum m4__symbol_chain_type): New enum.
- (struct m4_symbol_chain): Rename...
- (struct m4__symbol_chain): ...to this, since it is internal.
- * m4/symtab.c (m4_symbol_value_copy, m4_symbol_value_print): All
- callers updated.
- * m4/input.c (struct m4_input_block, m4__push_symbol)
- (composite_peek, composite_read, composite_unget)
- (composite_clean, composite_print, m4__make_text_link)
- (append_quote_token): Likewise.
- * m4/macro.c (expand_macro, arg_mark, m4_arg_symbol, m4_arg_text)
- (m4_arg_equal, m4_arg_len, m4_make_argv_ref, m4_push_arg)
- (m4_push_args): Likewise.
+ Stage 12b: add m4_string_pair.
+ Make passing quote delimiters around more efficient.
+ Memory impact: none.
+ Speed impact: slight penalty, due to more bookkeeping.
+ * m4/m4module.h (m4_string_pair): New type.
+ (m4_get_syntax_quotes, m4_get_syntax_comments): New prototypes.
+ (m4_symbol_value_print, m4_symbol_print, m4_shipout_string_trunc):
+ Alter signature.
+ * m4/m4private.h (struct m4_string): Delete.
+ (struct m4_syntax_table): Combine quote and comment members.
+ (m4_get_syntax_lquote, m4_get_syntax_rquote, m4_get_syntax_bcomm)
+ (m4_get_syntax_ecomm): Adjust accessors.
+ (m4_get_syntax_quotes, m4_get_syntax_comments): New fast
+ accessors.
+ * m4/symtab.c (m4_symbol_value_print, m4_symbol_print):
+ Alter signatures.
+ * m4/input.c (string_print, composite_print, m4_input_print):
+ All callers updated.
+ * m4/syntax.c (m4_syntax_delete, m4_set_syntax)
+ (check_is_single_quotes, m4_set_quotes, set_quote_age)
+ (m4_get_syntax_lquote, m4_get_syntax_rquote)
+ (m4_get_syntax_quotes, check_is_single_comments, m4_set_comment)
+ (m4_get_syntax_bcomm, m4_get_syntax_ecomm)
+ (m4_get_syntax_comments): Likewise.
+ * m4/macro.c (trace_prepre, trace_pre, m4_push_args): Likewise.
+ * m4/output.c (m4_shipout_string, m4_shipout_string_trunc):
+ Likewise.
+ * modules/m4.c (dumpdef, m4_make_temp): Likewise.
+ * src/freeze.c (produce_frozen_state): Likewise.
+ * tests/freeze.at (reloading unknown builtin): Update test.
+
+ Stage 12a: make m4_symbol_chain a union.
+ Shrink size of symbol chains by using a union.
+ Memory impact: slight improvement, due to smaller struct.
+ Speed impact: slight improvement, due to less bookkeeping.
+ * m4/m4private.h (enum m4__symbol_chain_type): New enum.
+ (struct m4_symbol_chain): Rename...
+ (struct m4__symbol_chain): ...to this, since it is internal.
+ * m4/symtab.c (m4_symbol_value_copy, m4_symbol_value_print): All
+ callers updated.
+ * m4/input.c (struct m4_input_block, m4__push_symbol)
+ (composite_peek, composite_read, composite_unget)
+ (composite_clean, composite_print, m4__make_text_link)
+ (append_quote_token): Likewise.
+ * m4/macro.c (expand_macro, arg_mark, m4_arg_symbol, m4_arg_text)
+ (m4_arg_equal, m4_arg_len, m4_make_argv_ref, m4_push_arg)
+ (m4_push_args): Likewise.
2008-01-23 Eric Blake <address@hidden>
diff --git a/m4/input.c b/m4/input.c
index f45db18..4adce9d 100644
--- a/m4/input.c
+++ b/m4/input.c
@@ -502,8 +502,9 @@ string_print (m4_input_block *me, m4 *context, m4_obstack
*obs)
bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
size_t arg_length = m4_get_max_debug_arg_length_opt (context);
- m4_shipout_string_trunc (context, obs, me->u.u_s.str, me->u.u_s.len,
- quote, &arg_length);
+ m4_shipout_string_trunc (obs, me->u.u_s.str, me->u.u_s.len,
+ quote ? m4_get_syntax_quotes (M4SYNTAX) : NULL,
+ &arg_length);
}
/* First half of m4_push_string (). The pointer next points to the
@@ -732,22 +733,30 @@ composite_print (m4_input_block *me, m4 *context,
m4_obstack *obs)
bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
size_t maxlen = m4_get_max_debug_arg_length_opt (context);
m4__symbol_chain *chain = me->u.u_c.chain;
- const char *lquote = m4_get_syntax_lquote (M4SYNTAX);
- const char *rquote = m4_get_syntax_rquote (M4SYNTAX);
+ const m4_string_pair *quotes = m4_get_syntax_quotes (M4SYNTAX);
+ bool done = false;
if (quote)
- m4_shipout_string (context, obs, lquote, SIZE_MAX, false);
- while (chain)
+ m4_shipout_string (context, obs, quotes->str1, quotes->len1, false);
+ while (chain && !done)
{
- /* TODO support argv refs as well. */
- assert (chain->type == M4__CHAIN_STR);
- if (m4_shipout_string_trunc (context, obs, chain->u.u_s.str,
- chain->u.u_s.len, false, &maxlen))
- break;
+ switch (chain->type)
+ {
+ case M4__CHAIN_STR:
+ if (m4_shipout_string_trunc (obs, chain->u.u_s.str,
+ chain->u.u_s.len, NULL, &maxlen))
+ done = true;
+ break;
+ case M4__CHAIN_ARGV:
+ /* TODO support argv refs as well. */
+ default:
+ assert (!"composite_print");
+ abort ();
+ }
chain = chain->next;
}
if (quote)
- m4_shipout_string (context, obs, rquote, SIZE_MAX, false);
+ m4_shipout_string (context, obs, quotes->str2, quotes->len2, false);
}
/* Given an obstack OBS, capture any unfinished text as a link in the
@@ -789,13 +798,11 @@ m4_input_print (m4 *context, m4_obstack *obs,
m4_input_block *input)
assert (context && obs);
if (input == NULL)
{
- bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
- if (quote)
+ if (m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE))
{
- const char *lquote = m4_get_syntax_lquote (M4SYNTAX);
- const char *rquote = m4_get_syntax_rquote (M4SYNTAX);
- obstack_grow (obs, lquote, strlen (lquote));
- obstack_grow (obs, rquote, strlen (rquote));
+ const m4_string_pair *quotes = m4_get_syntax_quotes (M4SYNTAX);
+ obstack_grow (obs, quotes->str1, quotes->len1);
+ obstack_grow (obs, quotes->str2, quotes->len2);
}
}
else
@@ -1304,7 +1311,7 @@ m4__next_token (m4 *context, m4_symbol_value *token, int
*line,
type = M4_TOKEN_STRING;
}
else if (!m4_is_syntax_single_quotes (M4SYNTAX)
- && MATCH (context, ch, context->syntax->lquote.string, true))
+ && MATCH (context, ch, context->syntax->quote.str1, true))
{ /* QUOTED STRING, LONGER QUOTES
*/
if (obs)
obs_safe = obs;
@@ -1316,18 +1323,18 @@ m4__next_token (m4 *context, m4_symbol_value *token,
int *line,
if (ch == CHAR_EOF)
m4_error_at_line (context, EXIT_FAILURE, 0, file, *line, caller,
_("end of file in string"));
- if (MATCH (context, ch, context->syntax->rquote.string, true))
+ if (MATCH (context, ch, context->syntax->quote.str2, true))
{
if (--quote_level == 0)
break;
- obstack_grow (obs_safe, context->syntax->rquote.string,
- context->syntax->rquote.length);
+ obstack_grow (obs_safe, context->syntax->quote.str2,
+ context->syntax->quote.len2);
}
- else if (MATCH (context, ch, context->syntax->lquote.string, true))
+ else if (MATCH (context, ch, context->syntax->quote.str1, true))
{
quote_level++;
- obstack_grow (obs_safe, context->syntax->lquote.string,
- context->syntax->lquote.length);
+ obstack_grow (obs_safe, context->syntax->quote.str1,
+ context->syntax->quote.len2);
}
else
obstack_1grow (obs_safe, ch);
@@ -1354,20 +1361,20 @@ m4__next_token (m4 *context, m4_symbol_value *token,
int *line,
? M4_TOKEN_NONE : M4_TOKEN_STRING);
}
else if (!m4_is_syntax_single_comments (M4SYNTAX)
- && MATCH (context, ch, context->syntax->bcomm.string, true))
+ && MATCH (context, ch, context->syntax->comm.str1, true))
{ /* COMMENT, LONGER DELIM */
if (obs && !m4_get_discard_comments_opt (context))
obs_safe = obs;
- obstack_grow (obs_safe, context->syntax->bcomm.string,
- context->syntax->bcomm.length);
+ obstack_grow (obs_safe, context->syntax->comm.str1,
+ context->syntax->comm.len1);
while ((ch = next_char (context, false, true)) < CHAR_EOF
- && !MATCH (context, ch, context->syntax->ecomm.string, true))
+ && !MATCH (context, ch, context->syntax->comm.str2, true))
obstack_1grow (obs_safe, ch);
if (ch != CHAR_EOF)
{
assert (ch < CHAR_EOF);
- obstack_grow (obs_safe, context->syntax->ecomm.string,
- context->syntax->ecomm.length);
+ obstack_grow (obs_safe, context->syntax->comm.str2,
+ context->syntax->comm.len2);
}
else
m4_error_at_line (context, EXIT_FAILURE, 0, file, *line, caller,
@@ -1489,9 +1496,9 @@ m4__next_token_is_open (m4 *context)
| M4_SYNTAX_ALPHA | M4_SYNTAX_LQUOTE
| M4_SYNTAX_ACTIVE))
|| (!m4_is_syntax_single_comments (M4SYNTAX)
- && MATCH (context, ch, context->syntax->bcomm.string, false))
+ && MATCH (context, ch, context->syntax->comm.str1, false))
|| (!m4_is_syntax_single_quotes (M4SYNTAX)
- && MATCH (context, ch, context->syntax->lquote.string, false)))
+ && MATCH (context, ch, context->syntax->quote.str1, false)))
return false;
return m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_OPEN);
}
diff --git a/m4/m4module.h b/m4/m4module.h
index 330a90e..eac4c29 100644
--- a/m4/m4module.h
+++ b/m4/m4module.h
@@ -38,6 +38,7 @@ typedef struct m4_symbol_value m4_symbol_value;
typedef struct m4_input_block m4_input_block;
typedef struct m4_module m4_module;
typedef struct m4_macro_args m4_macro_args;
+typedef struct m4_string_pair m4_string_pair;
typedef struct obstack m4_obstack;
@@ -77,6 +78,15 @@ struct m4_macro
const char *value;
};
+/* Describe a pair of strings, such as begin and end quotes. */
+struct m4_string_pair
+{
+ char *str1; /* First string. */
+ size_t len1; /* First length. */
+ char *str2; /* Second string. */
+ size_t len2; /* Second length. */
+};
+
#define M4BUILTIN(name)
\
static void CONC (builtin_, name) \
(m4 *context, m4_obstack *obs, unsigned int argc, m4_macro_args *argv);
@@ -231,12 +241,11 @@ extern m4_symbol_value *m4_get_symbol_value
(m4_symbol*);
extern bool m4_get_symbol_traced (m4_symbol*);
extern bool m4_set_symbol_name_traced (m4_symbol_table*,
const char *, bool);
-extern void m4_symbol_value_print (m4_symbol_value *, m4_obstack *, bool,
- const char *, const char *, size_t,
+extern void m4_symbol_value_print (m4_symbol_value *, m4_obstack *,
+ const m4_string_pair *, size_t, bool);
+extern void m4_symbol_print (m4_symbol *, m4_obstack *,
+ const m4_string_pair *, bool, size_t,
bool);
-extern void m4_symbol_print (m4_symbol *, m4_obstack *, bool,
- const char *, const char *, bool,
- size_t, bool);
extern bool m4_symbol_value_groks_macro (m4_symbol_value *);
#define m4_is_symbol_void(symbol) \
@@ -313,7 +322,7 @@ extern size_t m4_arg_len (m4_macro_args
*, unsigned int);
extern m4_builtin_func *m4_arg_func (m4_macro_args *, unsigned int);
extern m4_obstack *m4_arg_scratch (m4 *);
extern m4_macro_args *m4_make_argv_ref (m4 *, m4_macro_args *, const char *,
- size_t, bool, bool);
+ size_t, bool, bool);
extern void m4_push_arg (m4 *, m4_obstack *, m4_macro_args *,
unsigned int);
extern void m4_push_args (m4 *, m4_obstack *, m4_macro_args *,
@@ -384,6 +393,8 @@ extern const char * m4_get_syntax_lquote
(m4_syntax_table *syntax);
extern const char * m4_get_syntax_rquote (m4_syntax_table *syntax);
extern const char * m4_get_syntax_bcomm (m4_syntax_table *syntax);
extern const char * m4_get_syntax_ecomm (m4_syntax_table *syntax);
+extern const m4_string_pair *m4_get_syntax_quotes (m4_syntax_table *);
+extern const m4_string_pair *m4_get_syntax_comments (m4_syntax_table *);
extern bool m4_is_syntax_single_quotes (m4_syntax_table *);
extern bool m4_is_syntax_single_comments (m4_syntax_table *);
@@ -462,8 +473,8 @@ extern void m4_divert_text (m4 *, m4_obstack *,
const char *,
extern void m4_shipout_int (m4_obstack *, int);
extern void m4_shipout_string (m4 *, m4_obstack *, const char *,
size_t, bool);
-extern bool m4_shipout_string_trunc (m4 *, m4_obstack *, const char *,
- size_t, bool, size_t *);
+extern bool m4_shipout_string_trunc (m4_obstack *, const char *, size_t,
+ const m4_string_pair *, size_t *);
extern void m4_make_diversion (m4 *, int);
extern void m4_insert_diversion (m4 *, int);
diff --git a/m4/m4private.h b/m4/m4private.h
index dab41c0..4261c4c 100644
--- a/m4/m4private.h
+++ b/m4/m4private.h
@@ -399,21 +399,14 @@ extern void m4__symtab_remove_module_references
(m4_symbol_table*,
#define DEF_BCOMM "#" /* Default begin comment delimiter. */
#define DEF_ECOMM "\n" /* Default end comment delimiter. */
-typedef struct {
- char *string; /* characters of the string */
- size_t length; /* length of the string */
-} m4_string;
-
struct m4_syntax_table {
/* Please read the comment at the top of input.c for details. table
holds the current syntax, and orig holds the default syntax. */
unsigned short table[CHAR_RETRY];
unsigned short orig[CHAR_RETRY];
- m4_string lquote;
- m4_string rquote;
- m4_string bcomm;
- m4_string ecomm;
+ m4_string_pair quote; /* Quote delimiters. */
+ m4_string_pair comm; /* Comment delimiters. */
/* True iff strlen(lquote) == strlen(rquote) == 1 and lquote is not
interfering with macro names. */
@@ -442,10 +435,12 @@ struct m4_syntax_table {
/* Fast macro versions of syntax table accessor functions,
that also have an identically named function exported in m4module.h. */
#ifdef NDEBUG
-# define m4_get_syntax_lquote(S) ((S)->lquote.string)
-# define m4_get_syntax_rquote(S) ((S)->rquote.string)
-# define m4_get_syntax_bcomm(S) ((S)->bcomm.string)
-# define m4_get_syntax_ecomm(S) ((S)->ecomm.string)
+# define m4_get_syntax_lquote(S) ((S)->quote.str1)
+# define m4_get_syntax_rquote(S) ((S)->quote.str2)
+# define m4_get_syntax_bcomm(S) ((S)->comm.str1)
+# define m4_get_syntax_ecomm(S) ((S)->comm.str2)
+# define m4_get_syntax_quotes(S) (&(S)->quote)
+# define m4_get_syntax_comments(S) (&(S)->comm)
# define m4_is_syntax_single_quotes(S) ((S)->is_single_quotes)
# define m4_is_syntax_single_comments(S) ((S)->is_single_comments)
diff --git a/m4/macro.c b/m4/macro.c
index 6671c9c..4753984 100644
--- a/m4/macro.c
+++ b/m4/macro.c
@@ -888,16 +888,16 @@ trace_flush (m4 *context)
static void
trace_prepre (m4 *context, const char *name, size_t id, m4_symbol_value *value)
{
- bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
- const char *lquote = m4_get_syntax_lquote (M4SYNTAX);
- const char *rquote = m4_get_syntax_rquote (M4SYNTAX);
+ const m4_string_pair *quotes = NULL;
size_t arg_length = m4_get_max_debug_arg_length_opt (context);
bool module = m4_is_debug_bit (context, M4_DEBUG_TRACE_MODULE);
+ if (m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE))
+ quotes = m4_get_syntax_quotes (M4SYNTAX);
trace_header (context, id);
trace_format (context, "%s ... = ", name);
- m4_symbol_value_print (value, &context->trace_messages,
- quote, lquote, rquote, arg_length, module);
+ m4_symbol_value_print (value, &context->trace_messages, quotes, arg_length,
+ module);
trace_flush (context);
}
@@ -914,12 +914,12 @@ trace_pre (m4 *context, size_t id, m4_macro_args *argv)
if (1 < argc && m4_is_debug_bit (context, M4_DEBUG_TRACE_ARGS))
{
- bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
- const char *lquote = m4_get_syntax_lquote (M4SYNTAX);
- const char *rquote = m4_get_syntax_rquote (M4SYNTAX);
+ const m4_string_pair *quotes = NULL;
size_t arg_length = m4_get_max_debug_arg_length_opt (context);
bool module = m4_is_debug_bit (context, M4_DEBUG_TRACE_MODULE);
+ if (m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE))
+ quotes = m4_get_syntax_quotes (M4SYNTAX);
trace_format (context, "(");
for (i = 1; i < argc; i++)
{
@@ -927,8 +927,8 @@ trace_pre (m4 *context, size_t id, m4_macro_args *argv)
trace_format (context, ", ");
m4_symbol_value_print (m4_arg_symbol (argv, i),
- &context->trace_messages, quote, lquote,
- rquote, arg_length, module);
+ &context->trace_messages, quotes, arg_length,
+ module);
}
trace_format (context, ")");
}
@@ -1353,8 +1353,7 @@ m4_push_args (m4 *context, m4_obstack *obs, m4_macro_args
*argv, bool skip,
size_t sep_len = 1;
bool use_sep = false;
bool inuse = false;
- const char *lquote = m4_get_syntax_lquote (M4SYNTAX);
- const char *rquote = m4_get_syntax_rquote (M4SYNTAX);
+ const m4_string_pair *quotes = m4_get_syntax_quotes (M4SYNTAX);
m4_obstack *scratch = m4_arg_scratch (context);
if (argv->argc <= i)
@@ -1363,22 +1362,22 @@ m4_push_args (m4 *context, m4_obstack *obs,
m4_macro_args *argv, bool skip,
if (argv->argc == i + 1)
{
if (quote)
- obstack_grow (obs, lquote, strlen (lquote));
+ obstack_grow (obs, quotes->str1, quotes->len1);
m4_push_arg (context, obs, argv, i);
if (quote)
- obstack_grow (obs, rquote, strlen (rquote));
+ obstack_grow (obs, quotes->str2, quotes->len2);
return;
}
/* Compute the separator in the scratch space. */
if (quote)
{
- obstack_grow (obs, lquote, strlen (lquote));
- obstack_grow (scratch, rquote, strlen (rquote));
+ obstack_grow (obs, quotes->str1, quotes->len1);
+ obstack_grow (scratch, quotes->str2, quotes->len2);
obstack_1grow (scratch, ',');
- obstack_grow0 (scratch, lquote, strlen (lquote));
+ obstack_grow0 (scratch, quotes->str1, quotes->len1);
sep = (char *) obstack_finish (scratch);
- sep_len += strlen (lquote) + strlen (rquote);
+ sep_len += quotes->len1 + quotes->len2;
}
/* TODO push entire $@ ref, rather than each arg. */
@@ -1407,7 +1406,7 @@ m4_push_args (m4 *context, m4_obstack *obs, m4_macro_args
*argv, bool skip,
}
}
if (quote)
- obstack_grow (obs, rquote, strlen (rquote));
+ obstack_grow (obs, quotes->str2, quotes->len2);
if (inuse)
arg_mark (argv);
}
diff --git a/m4/output.c b/m4/output.c
index dc2194f..21a28f7 100644
--- a/m4/output.c
+++ b/m4/output.c
@@ -595,27 +595,27 @@ void
m4_shipout_string (m4 *context, m4_obstack *obs, const char *s, size_t len,
bool quoted)
{
- m4_shipout_string_trunc (context, obs, s, len, quoted, NULL);
+ m4_shipout_string_trunc (obs, s, len,
+ quoted ? m4_get_syntax_quotes (M4SYNTAX) : NULL,
+ NULL);
}
-/* Output the text S, of length LEN, to OBS. If QUOTED, also output
- current quote characters around S. If LEN is SIZE_MAX, use the
- string length of S instead. If MAX_LEN, reduce *MAX_LEN by LEN.
- If LEN is larger than *MAX_LEN, then truncate output and return
- true; otherwise return false. CONTEXT may be NULL if QUOTED is
- false. */
+/* Output the text S, of length LEN, to OBS. If QUOTES, also output
+ quote characters around S. If LEN is SIZE_MAX, use the string
+ length of S instead. If MAX_LEN, reduce *MAX_LEN by LEN. If LEN
+ is larger than *MAX_LEN, then truncate output and return true;
+ otherwise return false. */
bool
-m4_shipout_string_trunc (m4 *context, m4_obstack *obs, const char *s,
- size_t len, bool quoted, size_t *max_len)
+m4_shipout_string_trunc (m4_obstack *obs, const char *s, size_t len,
+ const m4_string_pair *quotes, size_t *max_len)
{
size_t max = max_len ? *max_len : SIZE_MAX;
assert (obs && s);
if (len == SIZE_MAX)
len = strlen (s);
- if (quoted)
- obstack_grow (obs, context->syntax->lquote.string,
- context->syntax->lquote.length);
+ if (quotes)
+ obstack_grow (obs, quotes->str1, quotes->len1);
if (len < max)
{
obstack_grow (obs, s, len);
@@ -627,9 +627,8 @@ m4_shipout_string_trunc (m4 *context, m4_obstack *obs,
const char *s,
obstack_grow (obs, "...", 3);
max = 0;
}
- if (quoted)
- obstack_grow (obs, context->syntax->rquote.string,
- context->syntax->rquote.length);
+ if (quotes)
+ obstack_grow (obs, quotes->str2, quotes->len2);
if (max_len)
*max_len = max;
return max == 0;
diff --git a/m4/symtab.c b/m4/symtab.c
index 1c419eb..60afe63 100644
--- a/m4/symtab.c
+++ b/m4/symtab.c
@@ -532,13 +532,13 @@ m4_set_symbol_name_traced (m4_symbol_table *symtab, const
char *name,
return result;
}
-/* Grow OBS with a text representation of VALUE. If QUOTE, then
- surround a text definition by LQUOTE and RQUOTE. If MAXLEN is less
- than SIZE_MAX, then truncate text definitions to that length. If
- MODULE, then include which module defined a builtin. */
+/* Grow OBS with a text representation of VALUE. If QUOTES, then use
+ it to surround a text definition. If MAXLEN is less than SIZE_MAX,
+ then truncate text definitions to that length. If MODULE, then
+ include which module defined a builtin. */
void
-m4_symbol_value_print (m4_symbol_value *value, m4_obstack *obs, bool quote,
- const char *lquote, const char *rquote, size_t maxlen,
+m4_symbol_value_print (m4_symbol_value *value, m4_obstack *obs,
+ const m4_string_pair *quotes, size_t maxlen,
bool module)
{
const char *text;
@@ -559,37 +559,34 @@ m4_symbol_value_print (m4_symbol_value *value, m4_obstack
*obs, bool quote,
case M4_SYMBOL_FUNC:
{
const m4_builtin *bp = m4_get_symbol_value_builtin (value);
+ static const m4_string_pair q1 = { "<", 1, ">", 1 };
text = bp->name;
len = strlen (text);
- lquote = "<";
- rquote = ">";
- quote = true;
+ quotes = &q1;
}
break;
case M4_SYMBOL_PLACEHOLDER:
text = m4_get_symbol_value_placeholder (value);
- /* FIXME - is it worth translating "placeholder for "? */
+ static const m4_string_pair q2 = { "<<", 2, ">>", 2 };
len = strlen (text);
- lquote = "<placeholder for ";
- rquote = ">";
- quote = true;
+ quotes = &q2;
break;
case M4_SYMBOL_COMP:
{
m4__symbol_chain *chain = value->u.u_c.chain;
- if (quote)
- obstack_grow (obs, lquote, strlen (lquote));
+ if (quotes)
+ obstack_grow (obs, quotes->str1, quotes->len1);
while (chain)
{
/* TODO for now, assume all links are text. */
assert (chain->type == M4__CHAIN_STR);
- if (m4_shipout_string_trunc (NULL, obs, chain->u.u_s.str,
+ if (m4_shipout_string_trunc (obs, chain->u.u_s.str,
chain->u.u_s.len, NULL, &maxlen))
break;
chain = chain->next;
}
- if (quote)
- obstack_grow (obs, rquote, strlen (rquote));
+ if (quotes)
+ obstack_grow (obs, quotes->str2, quotes->len2);
assert (!module);
return;
}
@@ -598,13 +595,13 @@ m4_symbol_value_print (m4_symbol_value *value, m4_obstack
*obs, bool quote,
abort ();
}
- if (quote)
- obstack_grow (obs, lquote, strlen (lquote));
+ if (quotes)
+ obstack_grow (obs, quotes->str1, quotes->len1);
obstack_grow (obs, text, len);
if (truncated)
obstack_grow (obs, "...", 3);
- if (quote)
- obstack_grow (obs, rquote, strlen (rquote));
+ if (quotes)
+ obstack_grow (obs, quotes->str2, quotes->len2);
if (module && VALUE_MODULE (value))
{
obstack_1grow (obs, '{');
@@ -614,16 +611,15 @@ m4_symbol_value_print (m4_symbol_value *value, m4_obstack
*obs, bool quote,
}
}
-/* Grow OBS with a text representation of SYMBOL. If QUOTE, then
- surround each text definition by LQUOTE and RQUOTE. If STACK, then
- append all pushdef'd values, rather than just the top. If
- ARG_LENGTH is less than SIZE_MAX, then truncate text definitions to
- that length. If MODULE, then include which module defined a
- builtin. */
+/* Grow OBS with a text representation of SYMBOL. If QUOTES, then use
+ it to surround each text definition. If STACK, then append all
+ pushdef'd values, rather than just the top. If ARG_LENGTH is less
+ than SIZE_MAX, then truncate text definitions to that length. If
+ MODULE, then include which module defined a builtin. */
void
-m4_symbol_print (m4_symbol *symbol, m4_obstack *obs, bool quote,
- const char *lquote, const char *rquote, bool stack,
- size_t arg_length, bool module)
+m4_symbol_print (m4_symbol *symbol, m4_obstack *obs,
+ const m4_string_pair *quotes, bool stack, size_t arg_length,
+ bool module)
{
m4_symbol_value *value;
@@ -631,8 +627,7 @@ m4_symbol_print (m4_symbol *symbol, m4_obstack *obs, bool
quote,
assert (obs);
value = m4_get_symbol_value (symbol);
- m4_symbol_value_print (value, obs, quote, lquote, rquote, arg_length,
- module);
+ m4_symbol_value_print (value, obs, quotes, arg_length, module);
if (stack)
{
value = VALUE_NEXT (value);
@@ -640,8 +635,7 @@ m4_symbol_print (m4_symbol *symbol, m4_obstack *obs, bool
quote,
{
obstack_1grow (obs, ',');
obstack_1grow (obs, ' ');
- m4_symbol_value_print (value, obs, quote, lquote, rquote,
- arg_length, module);
+ m4_symbol_value_print (value, obs, quotes, arg_length, module);
value = VALUE_NEXT (value);
}
}
diff --git a/m4/syntax.c b/m4/syntax.c
index 0bce3c0..c39a9be 100644
--- a/m4/syntax.c
+++ b/m4/syntax.c
@@ -1,6 +1,6 @@
/* GNU m4 -- A simple macro processor
- Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2002, 2004, 2006, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2002, 2004, 2006,
+ 2007, 2008 Free Software Foundation, Inc.
This file is part of GNU M4.
@@ -168,10 +168,10 @@ m4_syntax_delete (m4_syntax_table *syntax)
{
assert (syntax);
- free (syntax->lquote.string);
- free (syntax->rquote.string);
- free (syntax->bcomm.string);
- free (syntax->ecomm.string);
+ free (syntax->quote.str1);
+ free (syntax->quote.str2);
+ free (syntax->comm.str1);
+ free (syntax->comm.str2);
free (syntax);
}
@@ -371,23 +371,23 @@ m4_set_syntax (m4_syntax_table *syntax, char key, char
action,
properties. */
memcpy (syntax->table, syntax->orig, sizeof syntax->orig);
- free (syntax->lquote.string);
- free (syntax->rquote.string);
- free (syntax->bcomm.string);
- free (syntax->ecomm.string);
-
- syntax->lquote.string = xstrdup (DEF_LQUOTE);
- syntax->lquote.length = strlen (syntax->lquote.string);
- syntax->rquote.string = xstrdup (DEF_RQUOTE);
- syntax->rquote.length = strlen (syntax->rquote.string);
- syntax->bcomm.string = xstrdup (DEF_BCOMM);
- syntax->bcomm.length = strlen (syntax->bcomm.string);
- syntax->ecomm.string = xstrdup (DEF_ECOMM);
- syntax->ecomm.length = strlen (syntax->ecomm.string);
-
- add_syntax_attribute (syntax, to_uchar (syntax->rquote.string[0]),
+ free (syntax->quote.str1);
+ free (syntax->quote.str2);
+ free (syntax->comm.str1);
+ free (syntax->comm.str2);
+
+ syntax->quote.str1 = xstrdup (DEF_LQUOTE);
+ syntax->quote.len1 = 1;
+ syntax->quote.str2 = xstrdup (DEF_RQUOTE);
+ syntax->quote.len2 = 1;
+ syntax->comm.str1 = xstrdup (DEF_BCOMM);
+ syntax->comm.len1 = 1;
+ syntax->comm.str2 = xstrdup (DEF_ECOMM);
+ syntax->comm.len2 = 1;
+
+ add_syntax_attribute (syntax, to_uchar (syntax->quote.str2[0]),
M4_SYNTAX_RQUOTE);
- add_syntax_attribute (syntax, to_uchar (syntax->ecomm.string[0]),
+ add_syntax_attribute (syntax, to_uchar (syntax->comm.str2[0]),
M4_SYNTAX_ECOMM);
syntax->is_single_quotes = true;
@@ -432,10 +432,10 @@ check_is_single_quotes (m4_syntax_table *syntax)
if (! syntax->is_single_quotes)
return false;
- assert (syntax->lquote.length == 1 && syntax->rquote.length == 1);
+ assert (syntax->quote.len1 == 1 && syntax->quote.len2 == 1);
- if (m4_has_syntax (syntax, *syntax->lquote.string, M4_SYNTAX_LQUOTE)
- && m4_has_syntax (syntax, *syntax->rquote.string, M4_SYNTAX_RQUOTE))
+ if (m4_has_syntax (syntax, *syntax->quote.str1, M4_SYNTAX_LQUOTE)
+ && m4_has_syntax (syntax, *syntax->quote.str2, M4_SYNTAX_RQUOTE))
return true;
/* The most recent action invalidated our current lquote/rquote. If
@@ -470,8 +470,8 @@ check_is_single_quotes (m4_syntax_table *syntax)
syntax->is_single_quotes = false;
else if (syntax->is_single_quotes)
{
- *syntax->lquote.string = lquote;
- *syntax->rquote.string = rquote;
+ *syntax->quote.str1 = lquote;
+ *syntax->quote.str2 = rquote;
}
return syntax->is_single_quotes;
}
@@ -485,10 +485,10 @@ check_is_single_comments (m4_syntax_table *syntax)
if (! syntax->is_single_comments)
return false;
- assert (syntax->bcomm.length == 1 && syntax->ecomm.length == 1);
+ assert (syntax->comm.len1 == 1 && syntax->comm.len2 == 1);
- if (m4_has_syntax (syntax, *syntax->bcomm.string, M4_SYNTAX_BCOMM)
- && m4_has_syntax (syntax, *syntax->ecomm.string, M4_SYNTAX_ECOMM))
+ if (m4_has_syntax (syntax, *syntax->comm.str1, M4_SYNTAX_BCOMM)
+ && m4_has_syntax (syntax, *syntax->comm.str2, M4_SYNTAX_ECOMM))
return true;
/* The most recent action invalidated our current bcomm/ecomm. If
@@ -523,8 +523,8 @@ check_is_single_comments (m4_syntax_table *syntax)
syntax->is_single_comments = false;
else if (syntax->is_single_comments)
{
- *syntax->bcomm.string = bcomm;
- *syntax->ecomm.string = ecomm;
+ *syntax->comm.str1 = bcomm;
+ *syntax->comm.str2 = ecomm;
}
return syntax->is_single_comments;
}
@@ -572,24 +572,24 @@ m4_set_quotes (m4_syntax_table *syntax, const char *lq,
const char *rq)
else if (!rq || (*lq && !*rq))
rq = DEF_RQUOTE;
- if (strcmp (syntax->lquote.string, lq) == 0
- && strcmp (syntax->rquote.string, rq) == 0)
+ if (strcmp (syntax->quote.str1, lq) == 0
+ && strcmp (syntax->quote.str2, rq) == 0)
return;
- free (syntax->lquote.string);
- free (syntax->rquote.string);
- syntax->lquote.string = xstrdup (lq);
- syntax->lquote.length = strlen (syntax->lquote.string);
- syntax->rquote.string = xstrdup (rq);
- syntax->rquote.length = strlen (syntax->rquote.string);
+ free (syntax->quote.str1);
+ free (syntax->quote.str2);
+ syntax->quote.str1 = xstrdup (lq);
+ syntax->quote.len1 = strlen (lq);
+ syntax->quote.str2 = xstrdup (rq);
+ syntax->quote.len2 = strlen (rq);
/* changequote overrides syntax_table, but be careful when it is
used to select a start-quote sequence that is effectively
disabled. */
syntax->is_single_quotes
- = (syntax->lquote.length == 1 && syntax->rquote.length == 1
- && !m4_has_syntax (syntax, *syntax->lquote.string,
+ = (syntax->quote.len1 == 1 && syntax->quote.len2 == 1
+ && !m4_has_syntax (syntax, *syntax->quote.str1,
(M4_SYNTAX_IGNORE | M4_SYNTAX_ESCAPE
| M4_SYNTAX_ALPHA | M4_SYNTAX_NUM)));
@@ -605,9 +605,9 @@ m4_set_quotes (m4_syntax_table *syntax, const char *lq,
const char *rq)
if (syntax->is_single_quotes)
{
- add_syntax_attribute (syntax, to_uchar (syntax->lquote.string[0]),
+ add_syntax_attribute (syntax, to_uchar (syntax->quote.str1[0]),
M4_SYNTAX_LQUOTE);
- add_syntax_attribute (syntax, to_uchar (syntax->rquote.string[0]),
+ add_syntax_attribute (syntax, to_uchar (syntax->quote.str2[0]),
M4_SYNTAX_RQUOTE);
}
if (syntax->is_macro_escaped)
@@ -634,24 +634,24 @@ m4_set_comment (m4_syntax_table *syntax, const char *bc,
const char *ec)
else if (!ec || (*bc && !*ec))
ec = DEF_ECOMM;
- if (strcmp (syntax->bcomm.string, bc) == 0
- && strcmp (syntax->ecomm.string, ec) == 0)
+ if (strcmp (syntax->comm.str1, bc) == 0
+ && strcmp (syntax->comm.str2, ec) == 0)
return;
- free (syntax->bcomm.string);
- free (syntax->ecomm.string);
- syntax->bcomm.string = xstrdup (bc);
- syntax->bcomm.length = strlen (syntax->bcomm.string);
- syntax->ecomm.string = xstrdup (ec);
- syntax->ecomm.length = strlen (syntax->ecomm.string);
+ free (syntax->comm.str1);
+ free (syntax->comm.str2);
+ syntax->comm.str1 = xstrdup (bc);
+ syntax->comm.len1 = strlen (bc);
+ syntax->comm.str2 = xstrdup (ec);
+ syntax->comm.len2 = strlen (ec);
/* changecom overrides syntax_table, but be careful when it is used
to select a start-comment sequence that is effectively
disabled. */
syntax->is_single_comments
- = (syntax->bcomm.length == 1 && syntax->ecomm.length == 1
- && !m4_has_syntax (syntax, *syntax->bcomm.string,
+ = (syntax->comm.len1 == 1 && syntax->comm.len2 == 1
+ && !m4_has_syntax (syntax, *syntax->comm.str1,
(M4_SYNTAX_IGNORE | M4_SYNTAX_ESCAPE
| M4_SYNTAX_ALPHA | M4_SYNTAX_NUM
| M4_SYNTAX_LQUOTE)));
@@ -667,9 +667,9 @@ m4_set_comment (m4_syntax_table *syntax, const char *bc,
const char *ec)
}
if (syntax->is_single_comments)
{
- add_syntax_attribute (syntax, to_uchar (syntax->bcomm.string[0]),
+ add_syntax_attribute (syntax, to_uchar (syntax->comm.str1[0]),
M4_SYNTAX_BCOMM);
- add_syntax_attribute (syntax, to_uchar (syntax->ecomm.string[0]),
+ add_syntax_attribute (syntax, to_uchar (syntax->comm.str2[0]),
M4_SYNTAX_ECOMM);
}
if (syntax->is_macro_escaped)
@@ -728,22 +728,22 @@ set_quote_age (m4_syntax_table *syntax, bool reset, bool
change)
else
local_syntax_age = syntax->syntax_age;
if (local_syntax_age < 0xffff && syntax->is_single_quotes
- && !m4_has_syntax (syntax, *syntax->lquote.string,
+ && !m4_has_syntax (syntax, *syntax->quote.str1,
(M4_SYNTAX_ALPHA | M4_SYNTAX_NUM | M4_SYNTAX_OPEN
| M4_SYNTAX_COMMA | M4_SYNTAX_CLOSE
| M4_SYNTAX_SPACE))
- && !m4_has_syntax (syntax, *syntax->rquote.string,
+ && !m4_has_syntax (syntax, *syntax->quote.str2,
(M4_SYNTAX_ALPHA | M4_SYNTAX_NUM | M4_SYNTAX_OPEN
| M4_SYNTAX_COMMA | M4_SYNTAX_CLOSE
| M4_SYNTAX_SPACE))
- && *syntax->lquote.string != *syntax->rquote.string
- && *syntax->bcomm.string != *syntax->lquote.string
- && !m4_has_syntax (syntax, *syntax->bcomm.string,
+ && *syntax->quote.str1 != *syntax->quote.str2
+ && *syntax->comm.str1 != *syntax->quote.str2
+ && !m4_has_syntax (syntax, *syntax->comm.str1,
M4_SYNTAX_OPEN | M4_SYNTAX_COMMA | M4_SYNTAX_CLOSE))
{
syntax->quote_age = ((local_syntax_age << 16)
- | ((*syntax->lquote.string & 0xff) << 8)
- | (*syntax->rquote.string & 0xff));
+ | ((*syntax->quote.str1 & 0xff) << 8)
+ | (*syntax->quote.str2 & 0xff));
}
else
syntax->quote_age = 0;
@@ -757,7 +757,7 @@ const char *
m4_get_syntax_lquote (m4_syntax_table *syntax)
{
assert (syntax);
- return syntax->lquote.string;
+ return syntax->quote.str1;
}
#undef m4_get_syntax_rquote
@@ -765,7 +765,15 @@ const char *
m4_get_syntax_rquote (m4_syntax_table *syntax)
{
assert (syntax);
- return syntax->rquote.string;
+ return syntax->quote.str2;
+}
+
+#undef m4_get_syntax_quotes
+const m4_string_pair *
+m4_get_syntax_quotes (m4_syntax_table *syntax)
+{
+ assert (syntax);
+ return &syntax->quote;
}
#undef m4_is_syntax_single_quotes
@@ -781,7 +789,7 @@ const char *
m4_get_syntax_bcomm (m4_syntax_table *syntax)
{
assert (syntax);
- return syntax->bcomm.string;
+ return syntax->comm.str1;
}
#undef m4_get_syntax_ecomm
@@ -789,7 +797,15 @@ const char *
m4_get_syntax_ecomm (m4_syntax_table *syntax)
{
assert (syntax);
- return syntax->ecomm.string;
+ return syntax->comm.str2;
+}
+
+#undef m4_get_syntax_comments
+const m4_string_pair *
+m4_get_syntax_comments (m4_syntax_table *syntax)
+{
+ assert (syntax);
+ return &syntax->comm;
}
#undef m4_is_syntax_single_comments
diff --git a/modules/m4.c b/modules/m4.c
index 4b1416e..42dd661 100644
--- a/modules/m4.c
+++ b/modules/m4.c
@@ -341,13 +341,13 @@ m4_dump_symbols (m4 *context, m4_dump_symbol_data *data,
unsigned int argc,
M4BUILTIN_HANDLER (dumpdef)
{
m4_dump_symbol_data data;
- bool quote = m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE);
- const char *lquote = m4_get_syntax_lquote (M4SYNTAX);
- const char *rquote = m4_get_syntax_rquote (M4SYNTAX);
+ const m4_string_pair *quotes = NULL;
bool stack = m4_is_debug_bit (context, M4_DEBUG_TRACE_STACK);
size_t arg_length = m4_get_max_debug_arg_length_opt (context);
bool module = m4_is_debug_bit (context, M4_DEBUG_TRACE_MODULE);
+ if (m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE))
+ quotes = m4_get_syntax_quotes (M4SYNTAX);
data.obs = m4_arg_scratch (context);
m4_dump_symbols (context, &data, argc, argv, true);
@@ -359,8 +359,7 @@ M4BUILTIN_HANDLER (dumpdef)
obstack_grow (obs, data.base[0], strlen (data.base[0]));
obstack_1grow (obs, ':');
obstack_1grow (obs, '\t');
- m4_symbol_print (symbol, obs, quote, lquote, rquote, stack, arg_length,
- module);
+ m4_symbol_print (symbol, obs, quotes, stack, arg_length, module);
obstack_1grow (obs, '\n');
}
@@ -698,8 +697,7 @@ m4_make_temp (m4 *context, m4_obstack *obs, const char
*macro,
int fd;
int i;
char *name;
- const char *tmp;
- size_t qlen;
+ const m4_string_pair *quotes = m4_get_syntax_quotes (M4SYNTAX);
if (m4_get_safer_opt (context))
{
@@ -711,15 +709,13 @@ m4_make_temp (m4 *context, m4_obstack *obs, const char
*macro,
user forgot to supply them. Output must be quoted if
successful. */
assert (obstack_object_size (obs) == 0);
- tmp = m4_get_syntax_lquote (M4SYNTAX);
- qlen = strlen (tmp);
- obstack_grow (obs, tmp, qlen);
+ obstack_grow (obs, quotes->str1, quotes->len1);
obstack_grow (obs, pattern, len);
for (i = 0; len > 0 && i < 6; i++)
if (pattern[--len] != 'X')
break;
obstack_grow0 (obs, "XXXXXX", 6 - i);
- name = (char *) obstack_base (obs) + qlen;
+ name = (char *) obstack_base (obs) + quotes->len1;
/* Make the temporary object. */
errno = 0;
@@ -741,8 +737,7 @@ m4_make_temp (m4 *context, m4_obstack *obs, const char
*macro,
close (fd);
/* Remove NUL, then finish quote. */
obstack_blank (obs, -1);
- tmp = m4_get_syntax_rquote (M4SYNTAX);
- obstack_grow (obs, tmp, strlen (tmp));
+ obstack_grow (obs, quotes->str2, quotes->len2);
}
}
diff --git a/src/freeze.c b/src/freeze.c
index cdadf60..941b761 100644
--- a/src/freeze.c
+++ b/src/freeze.c
@@ -1,6 +1,6 @@
/* GNU m4 -- A simple macro processor
- Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2004, 2005, 2006, 2007
- Free Software Foundation, Inc.
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2004, 2005, 2006,
+ 2007, 2008 Free Software Foundation, Inc.
This file is part of GNU M4.
@@ -213,6 +213,7 @@ produce_frozen_state (m4 *context, const char *name)
{
FILE *file = fopen (name, O_BINARY ? "wb" : "w");
const char *str;
+ const m4_string_pair *pair;
if (!file)
{
@@ -227,28 +228,22 @@ produce_frozen_state (m4 *context, const char *name)
fputs ("V2\n", file);
/* Dump quote delimiters. */
-
- if (strcmp (m4_get_syntax_lquote (M4SYNTAX), DEF_LQUOTE)
- || strcmp (m4_get_syntax_rquote (M4SYNTAX), DEF_RQUOTE))
+ pair = m4_get_syntax_quotes (M4SYNTAX);
+ if (strcmp (pair->str1, DEF_LQUOTE) || strcmp (pair->str2, DEF_RQUOTE))
{
- xfprintf (file, "Q%zu,%zu\n", M4SYNTAX->lquote.length,
- M4SYNTAX->rquote.length);
- produce_mem_dump (file, M4SYNTAX->lquote.string,
- M4SYNTAX->lquote.length);
- produce_mem_dump (file, M4SYNTAX->rquote.string,
- M4SYNTAX->rquote.length);
+ xfprintf (file, "Q%zu,%zu\n", pair->len1, pair->len2);
+ produce_mem_dump (file, pair->str1, pair->len1);
+ produce_mem_dump (file, pair->str2, pair->len2);
fputc ('\n', file);
}
/* Dump comment delimiters. */
-
- if (strcmp (m4_get_syntax_bcomm (M4SYNTAX), DEF_BCOMM)
- || strcmp (m4_get_syntax_ecomm (M4SYNTAX), DEF_ECOMM))
+ pair = m4_get_syntax_comments (M4SYNTAX);
+ if (strcmp (pair->str1, DEF_BCOMM) || strcmp (pair->str2, DEF_ECOMM))
{
- xfprintf (file, "C%zu,%zu\n", M4SYNTAX->bcomm.length,
- M4SYNTAX->ecomm.length);
- produce_mem_dump (file, M4SYNTAX->bcomm.string, M4SYNTAX->bcomm.length);
- produce_mem_dump (file, M4SYNTAX->ecomm.string, M4SYNTAX->ecomm.length);
+ xfprintf (file, "C%zu,%zu\n", pair->len1, pair->len2);
+ produce_mem_dump (file, pair->str1, pair->len1);
+ produce_mem_dump (file, pair->str2, pair->len2);
fputc ('\n', file);
}
diff --git a/tests/freeze.at b/tests/freeze.at
index 530553a..2a84843 100644
--- a/tests/freeze.at
+++ b/tests/freeze.at
@@ -1,5 +1,5 @@
# Hand crafted tests for GNU M4. -*- Autotest -*-
-# Copyright (C) 2006, 2007 Free Software Foundation, Inc.
+# Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
# This file is part of GNU M4.
#
@@ -360,7 +360,7 @@ a
[[m4:input.m4:4: Warning: a: builtin `b' requested by frozen file not found
m4:input.m4:6: Warning: a: builtin `b' requested by frozen file not found
m4:input.m4:8: Warning: a: builtin `b' requested by frozen file not found
-a: <placeholder for b>
+a: <<b>>
c: `'
]])
--
1.5.3.8
>From 88382ff9ef2efddf6279fb8af908ddd07210e70c Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Sat, 26 Jan 2008 00:08:48 -0700
Subject: [PATCH] Stage 12c: add macro for m4_arg_len.
* m4/m4module.h (M4ARGLEN): New macro.
* m4/macro.c (process_macro): Adjust all callers.
* m4/utility.c (m4_dump_args): Likewise.
* modules/m4.c (divert, maketemp, mkstemp, m4wrap, len, index)
(substr): Likewise.
* modules/gnu.c (builtin, indir, mkdtemp, patsubst, regexp)
(renamesyms): Likewise.
* modules/stdlib.c (setenv): Likewise.
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 71 ++++++++++++++++++++++++++++++++----------------------
m4/m4module.h | 5 ++++
m4/macro.c | 4 +-
m4/utility.c | 5 +--
modules/gnu.c | 24 ++++++++----------
modules/m4.c | 23 +++++++----------
modules/stdlib.c | 9 ++++---
7 files changed, 77 insertions(+), 64 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 67ce533..25c408e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,35 +1,48 @@
2008-01-26 Eric Blake <address@hidden>
- Stage 12b: add m4_string_pair.
- Make passing quote delimiters around more efficient.
+ Stage 12c: add macro for m4_arg_len.
+ Make a common action easier to type.
Memory impact: none.
- Speed impact: slight penalty, due to more bookkeeping.
- * m4/m4module.h (m4_string_pair): New type.
- (m4_get_syntax_quotes, m4_get_syntax_comments): New prototypes.
- (m4_symbol_value_print, m4_symbol_print, m4_shipout_string_trunc):
- Alter signature.
- * m4/m4private.h (struct m4_string): Delete.
- (struct m4_syntax_table): Combine quote and comment members.
- (m4_get_syntax_lquote, m4_get_syntax_rquote, m4_get_syntax_bcomm)
- (m4_get_syntax_ecomm): Adjust accessors.
- (m4_get_syntax_quotes, m4_get_syntax_comments): New fast
- accessors.
- * m4/symtab.c (m4_symbol_value_print, m4_symbol_print):
- Alter signatures.
- * m4/input.c (string_print, composite_print, m4_input_print):
- All callers updated.
- * m4/syntax.c (m4_syntax_delete, m4_set_syntax)
- (check_is_single_quotes, m4_set_quotes, set_quote_age)
- (m4_get_syntax_lquote, m4_get_syntax_rquote)
- (m4_get_syntax_quotes, check_is_single_comments, m4_set_comment)
- (m4_get_syntax_bcomm, m4_get_syntax_ecomm)
- (m4_get_syntax_comments): Likewise.
- * m4/macro.c (trace_prepre, trace_pre, m4_push_args): Likewise.
- * m4/output.c (m4_shipout_string, m4_shipout_string_trunc):
- Likewise.
- * modules/m4.c (dumpdef, m4_make_temp): Likewise.
- * src/freeze.c (produce_frozen_state): Likewise.
- * tests/freeze.at (reloading unknown builtin): Update test.
+ Speed impact: none.
+ * m4/m4module.h (M4ARGLEN): New macro.
+ * m4/macro.c (process_macro): Adjust all callers.
+ * m4/utility.c (m4_dump_args): Likewise.
+ * modules/m4.c (divert, maketemp, mkstemp, m4wrap, len, index)
+ (substr): Likewise.
+ * modules/gnu.c (builtin, indir, mkdtemp, patsubst, regexp)
+ (renamesyms): Likewise.
+ * modules/stdlib.c (setenv): Likewise.
+
+ Stage 12b: add m4_string_pair.
+ Make passing quote delimiters around more efficient.
+ Memory impact: none.
+ Speed impact: slight penalty, due to more bookkeeping.
+ * m4/m4module.h (m4_string_pair): New type.
+ (m4_get_syntax_quotes, m4_get_syntax_comments): New prototypes.
+ (m4_symbol_value_print, m4_symbol_print, m4_shipout_string_trunc):
+ Alter signature.
+ * m4/m4private.h (struct m4_string): Delete.
+ (struct m4_syntax_table): Combine quote and comment members.
+ (m4_get_syntax_lquote, m4_get_syntax_rquote, m4_get_syntax_bcomm)
+ (m4_get_syntax_ecomm): Adjust accessors.
+ (m4_get_syntax_quotes, m4_get_syntax_comments): New fast
+ accessors.
+ * m4/symtab.c (m4_symbol_value_print, m4_symbol_print):
+ Alter signatures.
+ * m4/input.c (string_print, composite_print, m4_input_print):
+ All callers updated.
+ * m4/syntax.c (m4_syntax_delete, m4_set_syntax)
+ (check_is_single_quotes, m4_set_quotes, set_quote_age)
+ (m4_get_syntax_lquote, m4_get_syntax_rquote)
+ (m4_get_syntax_quotes, check_is_single_comments, m4_set_comment)
+ (m4_get_syntax_bcomm, m4_get_syntax_ecomm)
+ (m4_get_syntax_comments): Likewise.
+ * m4/macro.c (trace_prepre, trace_pre, m4_push_args): Likewise.
+ * m4/output.c (m4_shipout_string, m4_shipout_string_trunc):
+ Likewise.
+ * modules/m4.c (dumpdef, m4_make_temp): Likewise.
+ * src/freeze.c (produce_frozen_state): Likewise.
+ * tests/freeze.at (reloading unknown builtin): Update test.
Stage 12a: make m4_symbol_chain a union.
Shrink size of symbol chains by using a union.
diff --git a/m4/m4module.h b/m4/m4module.h
index eac4c29..24d6a45 100644
--- a/m4/m4module.h
+++ b/m4/m4module.h
@@ -116,6 +116,11 @@ struct m4_string_pair
in scope. */
#define M4ARG(i) m4_arg_text (context, argv, i)
+/* Grab the length of the text contents of argument I, or abort if the
+ argument is not text. Assumes that `m4_macro_args *argv' is in
+ scope. */
+#define M4ARGLEN(i) m4_arg_len (argv, i)
+
extern bool m4_bad_argc (m4 *, int, const char *,
unsigned int, unsigned int, bool);
extern bool m4_numeric_arg (m4 *, const char *, const char *, int *);
diff --git a/m4/macro.c b/m4/macro.c
index 4753984..88ee391 100644
--- a/m4/macro.c
+++ b/m4/macro.c
@@ -763,8 +763,8 @@ process_macro (m4 *context, m4_symbol_value *value,
m4_obstack *obs,
{
i = SYMBOL_ARG_INDEX (*arg);
assert (i < argc);
- m4_shipout_string (context, obs, M4ARG (i),
- m4_arg_len (argv, i), false);
+ m4_shipout_string (context, obs, M4ARG (i), M4ARGLEN (i),
+ false);
}
}
else
diff --git a/m4/utility.c b/m4/utility.c
index b367717..d95e44e 100644
--- a/m4/utility.c
+++ b/m4/utility.c
@@ -1,6 +1,6 @@
/* GNU m4 -- A simple macro processor
Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 1998, 1999, 2003,
- 2006, 2007 Free Software Foundation, Inc.
+ 2006, 2007, 2008 Free Software Foundation, Inc.
This file is part of GNU M4.
@@ -114,8 +114,7 @@ m4_dump_args (m4 *context, m4_obstack *obs, unsigned int
start,
else
need_sep = true;
- m4_shipout_string (context, obs, M4ARG (i), m4_arg_len (argv, i),
- quoted);
+ m4_shipout_string (context, obs, M4ARG (i), M4ARGLEN (i), quoted);
}
}
diff --git a/modules/gnu.c b/modules/gnu.c
index 91cfb54..841e660 100644
--- a/modules/gnu.c
+++ b/modules/gnu.c
@@ -1,5 +1,6 @@
/* GNU m4 -- A simple macro processor
- Copyright (C) 2000, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2004, 2005, 2006, 2007, 2008 Free Software
+ Foundation, Inc.
This file is part of GNU M4.
@@ -446,8 +447,7 @@ M4BUILTIN_HANDLER (builtin)
{
m4_macro_args *new_argv;
bool flatten = (bp->flags & M4_BUILTIN_GROKS_MACRO) == 0;
- new_argv = m4_make_argv_ref (context, argv, name,
- m4_arg_len (argv, 1),
+ new_argv = m4_make_argv_ref (context, argv, name, M4ARGLEN (1),
true, flatten);
bp->func (context, obs, argc - 1, new_argv);
}
@@ -682,8 +682,8 @@ M4BUILTIN_HANDLER (indir)
{
m4_macro_args *new_argv;
bool flatten = !m4_symbol_groks_macro (symbol);
- new_argv = m4_make_argv_ref (context, argv, name,
- m4_arg_len (argv, 1), true, flatten);
+ new_argv = m4_make_argv_ref (context, argv, name, M4ARGLEN (1),
+ true, flatten);
m4_macro_call (context, m4_get_symbol_value (symbol), obs,
argc - 1, new_argv);
}
@@ -701,8 +701,7 @@ M4BUILTIN_HANDLER (mkdtemp)
M4_MODULE_IMPORT (m4, m4_make_temp);
if (m4_make_temp)
- m4_make_temp (context, obs, M4ARG (0), M4ARG (1), m4_arg_len (argv, 1),
- true);
+ m4_make_temp (context, obs, M4ARG (0), M4ARG (1), M4ARGLEN (1), true);
else
assert (!"Unable to import from m4 module");
}
@@ -746,11 +745,11 @@ M4BUILTIN_HANDLER (patsubst)
return;
}
- buf = regexp_compile (context, me, pattern, m4_arg_len (argv, 2), resyntax);
+ buf = regexp_compile (context, me, pattern, M4ARGLEN (2), resyntax);
if (!buf)
return;
- regexp_substitute (context, obs, me, M4ARG (1), m4_arg_len (argv, 1),
+ regexp_substitute (context, obs, me, M4ARG (1), M4ARGLEN (1),
pattern, buf, replace, false);
}
@@ -817,12 +816,12 @@ M4BUILTIN_HANDLER (regexp)
return;
}
- buf = regexp_compile (context, me, pattern, m4_arg_len (argv, 2), resyntax);
+ buf = regexp_compile (context, me, pattern, M4ARGLEN (2), resyntax);
if (!buf)
return;
victim = M4ARG (1);
- len = m4_arg_len (argv, 1);
+ len = M4ARGLEN (1);
startpos = regexp_search (buf, victim, len, 0, len, replace == NULL);
if (startpos == -2)
@@ -873,8 +872,7 @@ M4BUILTIN_HANDLER (renamesyms)
return;
}
- buf = regexp_compile (context, me, regexp, m4_arg_len (argv, 1),
- resyntax);
+ buf = regexp_compile (context, me, regexp, M4ARGLEN (1), resyntax);
if (!buf)
return;
diff --git a/modules/m4.c b/modules/m4.c
index 42dd661..cd4c230 100644
--- a/modules/m4.c
+++ b/modules/m4.c
@@ -560,7 +560,7 @@ M4BUILTIN_HANDLER (divert)
if (argc >= 2 && !m4_numeric_arg (context, M4ARG (0), M4ARG (1), &i))
return;
m4_make_diversion (context, i);
- m4_divert_text (context, NULL, M4ARG (2), m4_arg_len (argv, 2),
+ m4_divert_text (context, NULL, M4ARG (2), M4ARGLEN (2),
m4_get_current_line (context));
}
@@ -758,9 +758,9 @@ M4BUILTIN_HANDLER (maketemp)
maketemp(XXXXXXXX) -> `X00nnnnn', where nnnnn is 16-bit pid
*/
const char *str = M4ARG (1);
- size_t len = m4_arg_len (argv, 1);
- int i;
- int len2;
+ size_t len = M4ARGLEN (1);
+ size_t i;
+ size_t len2;
for (i = len; i > 1; i--)
if (str[i - 1] != 'X')
@@ -778,15 +778,13 @@ M4BUILTIN_HANDLER (maketemp)
}
}
else
- m4_make_temp (context, obs, M4ARG (0), M4ARG (1), m4_arg_len (argv, 1),
- false);
+ m4_make_temp (context, obs, M4ARG (0), M4ARG (1), M4ARGLEN (1), false);
}
/* Use the first argument as a template for a temporary file name. */
M4BUILTIN_HANDLER (mkstemp)
{
- m4_make_temp (context, obs, M4ARG (0), M4ARG (1), m4_arg_len (argv, 1),
- false);
+ m4_make_temp (context, obs, M4ARG (0), M4ARG (1), M4ARGLEN (1), false);
}
/* Print all arguments on standard error. */
@@ -850,7 +848,7 @@ M4BUILTIN_HANDLER (m4wrap)
{
assert (obstack_object_size (obs) == 0);
if (m4_get_posixly_correct_opt (context))
- m4_shipout_string (context, obs, M4ARG (1), m4_arg_len (argv, 1), false);
+ m4_shipout_string (context, obs, M4ARG (1), M4ARGLEN (1), false);
else
m4_dump_args (context, obs, 1, argv, " ", false);
obstack_1grow (obs, '\0');
@@ -894,7 +892,7 @@ M4BUILTIN_HANDLER (traceoff)
/* Expand to the length of the first argument. */
M4BUILTIN_HANDLER (len)
{
- m4_shipout_int (obs, m4_arg_len (argv, 1));
+ m4_shipout_int (obs, M4ARGLEN (1));
}
/* The macro expands to the first index of the second argument in the first
@@ -908,8 +906,7 @@ M4BUILTIN_HANDLER (index)
/* Rely on the optimizations guaranteed by gnulib's memmem
module. */
- result = (char *) memmem (haystack, m4_arg_len (argv, 1),
- needle, m4_arg_len (argv, 2));
+ result = (char *) memmem (haystack, M4ARGLEN (1), needle, M4ARGLEN (2));
if (result)
retval = result - haystack;
@@ -934,7 +931,7 @@ M4BUILTIN_HANDLER (substr)
return;
}
- length = avail = m4_arg_len (argv, 1);
+ length = avail = M4ARGLEN (1);
if (!m4_numeric_arg (context, me, M4ARG (2), &start))
return;
diff --git a/modules/stdlib.c b/modules/stdlib.c
index 0063ed8..0849d3d 100644
--- a/modules/stdlib.c
+++ b/modules/stdlib.c
@@ -1,5 +1,6 @@
/* GNU m4 -- A simple macro processor
- Copyright (C) 1999, 2000, 2001, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001, 2006, 2007, 2008 Free Software
+ Foundation, Inc.
This file is part of GNU M4.
@@ -122,12 +123,12 @@ M4BUILTIN_HANDLER (setenv)
return;
assert (obstack_object_size (obs) == 0);
- obstack_grow (obs, M4ARG (1), m4_arg_len (argv, 1));
+ obstack_grow (obs, M4ARG (1), M4ARGLEN (1));
obstack_1grow (obs, '=');
- obstack_grow0 (obs, M4ARG (2), m4_arg_len (argv, 2));
+ obstack_grow0 (obs, M4ARG (2), M4ARGLEN (2));
{
- char *env = obstack_finish (obs);
+ char *env = (char *) obstack_finish (obs);
putenv (env);
}
#endif /* HAVE_PUTENV */
--
1.5.3.8
>From 6ef07af4d24ef59c2a6939ef9b7265cb4d01e19c Mon Sep 17 00:00:00 2001
From: Eric Blake <address@hidden>
Date: Sat, 27 Oct 2007 08:03:03 -0600
Subject: [PATCH] Stage 12: make token_chain a union, add string_pair.
* src/m4.h (STRING): Delete typedef.
(struct string_pair, enum token_chain_type): New types.
(struct token_chain): Reduce size via a union.
(ARG_LEN): New macro.
(ARG): Move here...
* src/builtin.c (ARG): ...from here.
(dump_args, define_macro, m4_dumpdef, m4_builtin, m4_indir)
(m4_defn, mkstemp_helper, m4_maketemp, m4_mkstemp, m4___file__)
(m4___program__, m4_m4wrap, m4_len, m4_index, m4_substr)
(m4_regexp, m4_patsubst): Adjust callers.
* src/input.c (rquote, lquote, bcomm, ecomm): Delete...
(curr_quote, curr_comm): ...replaced by these.
(make_text_link, push_token, pop_input, input_print, peek_input)
(next_char_1, input_init, set_quotes, set_comment, set_quote_age)
(next_token, peek_token): Adjust callers.
* src/macro.c (expand_macro, arg_token, arg_mark, arg_text)
(arg_equal, arg_len, make_argv_ref, push_arg, push_args):
Likewise.
* src/format.c (ARG_INT, ARG_LONG, ARG_STR, ARG_DOUBLE, format):
Likewise.
* src/freeze.c (produce_frozen_state): Likewise.
* src/debug.c (trace_format, trace_pre): Likewise.
(debug_decode): Don't lose partial traces prior to reducing
debugmode.
(cherry picked from commit d8324ac481f69682f6953ba3fb0c60cf67c7e8d7)
Signed-off-by: Eric Blake <address@hidden>
---
ChangeLog | 32 ++++++++++
src/builtin.c | 62 +++++++++----------
src/debug.c | 39 ++++++-------
src/format.c | 10 ++--
src/freeze.c | 23 +++-----
src/input.c | 185 ++++++++++++++++++++++++++++++--------------------------
src/m4.h | 60 +++++++++++++++----
src/macro.c | 103 +++++++++++++++++---------------
8 files changed, 292 insertions(+), 222 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 15549a6..7213833 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2008-01-26 Eric Blake <address@hidden>
+
+ Stage 12: make token_chain a union, add string_pair.
+ Shrink size of symbol chains by using a union. Make passing quote
+ delimiters around more efficient. Other code cleanups.
+ Memory impact: slight improvement, due to smaller struct.
+ Speed impact: slight penalty, due to more bookkeeping.
+ * src/m4.h (STRING): Delete typedef.
+ (struct string_pair, enum token_chain_type): New types.
+ (struct token_chain): Reduce size via a union.
+ (ARG_LEN): New macro.
+ (ARG): Move here...
+ * src/builtin.c (ARG): ...from here.
+ (dump_args, define_macro, m4_dumpdef, m4_builtin, m4_indir)
+ (m4_defn, mkstemp_helper, m4_maketemp, m4_mkstemp, m4___file__)
+ (m4___program__, m4_m4wrap, m4_len, m4_index, m4_substr)
+ (m4_regexp, m4_patsubst): Adjust callers.
+ * src/input.c (rquote, lquote, bcomm, ecomm): Delete...
+ (curr_quote, curr_comm): ...replaced by these.
+ (make_text_link, push_token, pop_input, input_print, peek_input)
+ (next_char_1, input_init, set_quotes, set_comment, set_quote_age)
+ (next_token, peek_token): Adjust callers.
+ * src/macro.c (expand_macro, arg_token, arg_mark, arg_text)
+ (arg_equal, arg_len, make_argv_ref, push_arg, push_args):
+ Likewise.
+ * src/format.c (ARG_INT, ARG_LONG, ARG_STR, ARG_DOUBLE, format):
+ Likewise.
+ * src/freeze.c (produce_frozen_state): Likewise.
+ * src/debug.c (trace_format, trace_pre): Likewise.
+ (debug_decode): Don't lose partial traces prior to reducing
+ debugmode.
+
2008-01-22 Eric Blake <address@hidden>
Stage 11: full circle for single argument references.
diff --git a/src/builtin.c b/src/builtin.c
index 007ca55..c89ad44 100644
--- a/src/builtin.c
+++ b/src/builtin.c
@@ -30,10 +30,6 @@
# include <sys/wait.h>
#endif
-/* Grab the text at argv index I. Assumes a macro_argument *argv is
- in scope. */
-#define ARG(i) arg_text (argv, i)
-
/* Initialization of builtin and predefined macros. The table
"builtin_tab" is both used for initialization, and by the "builtin"
builtin. */
@@ -623,10 +619,10 @@ dump_args (struct obstack *obs, int start,
macro_arguments *argv,
else
dump_sep = true;
if (quoted)
- obstack_grow (obs, lquote.string, lquote.length);
- obstack_grow (obs, ARG (i), arg_len (argv, i));
+ obstack_grow (obs, curr_quote.str1, curr_quote.len1);
+ obstack_grow (obs, ARG (i), ARG_LEN (i));
if (quoted)
- obstack_grow (obs, rquote.string, rquote.length);
+ obstack_grow (obs, curr_quote.str2, curr_quote.len2);
}
}
@@ -668,14 +664,14 @@ define_macro (int argc, macro_arguments *argv,
symbol_lookup mode)
if (argc == 2)
{
- define_user_macro (ARG (1), arg_len (argv, 1), "", mode);
+ define_user_macro (ARG (1), ARG_LEN (1), "", mode);
return;
}
switch (arg_type (argv, 2))
{
case TOKEN_TEXT:
- define_user_macro (ARG (1), arg_len (argv, 1), ARG (2), mode);
+ define_user_macro (ARG (1), ARG_LEN (1), ARG (2), mode);
break;
case TOKEN_FUNC:
@@ -865,7 +861,8 @@ m4_dumpdef (struct obstack *obs, int argc, macro_arguments
*argv)
case TOKEN_TEXT:
if (debug_level & DEBUG_TRACE_QUOTE)
DEBUG_PRINT3 ("%s%s%s\n",
- lquote.string, SYMBOL_TEXT (data.base[0]),
rquote.string);
+ curr_quote.str1, SYMBOL_TEXT (data.base[0]),
+ curr_quote.str2);
else
DEBUG_PRINT1 ("%s\n", SYMBOL_TEXT (data.base[0]));
break;
@@ -916,7 +913,7 @@ m4_builtin (struct obstack *obs, int argc, macro_arguments
*argv)
m4_warn (0, me, _("undefined builtin `%s'"), name);
else
{
- macro_arguments *new_argv = make_argv_ref (argv, name, arg_len (argv, 1),
+ macro_arguments *new_argv = make_argv_ref (argv, name, ARG_LEN (1),
true, !bp->groks_macro_args);
bp->func (obs, argc - 1, new_argv);
}
@@ -950,7 +947,7 @@ m4_indir (struct obstack *obs, int argc, macro_arguments
*argv)
m4_warn (0, me, _("undefined macro `%s'"), name);
else
{
- macro_arguments *new_argv = make_argv_ref (argv, name, arg_len (argv, 1),
+ macro_arguments *new_argv = make_argv_ref (argv, name, ARG_LEN (1),
true, !SYMBOL_MACRO_ARGS (s));
call_macro (s, argc - 1, new_argv, obs);
}
@@ -982,9 +979,9 @@ m4_defn (struct obstack *obs, int argc, macro_arguments
*argv)
switch (SYMBOL_TYPE (s))
{
case TOKEN_TEXT:
- obstack_grow (obs, lquote.string, lquote.length);
+ obstack_grow (obs, curr_quote.str1, curr_quote.len1);
obstack_grow (obs, SYMBOL_TEXT (s), strlen (SYMBOL_TEXT (s)));
- obstack_grow (obs, rquote.string, rquote.length);
+ obstack_grow (obs, curr_quote.str2, curr_quote.len2);
break;
case TOKEN_FUNC:
@@ -1429,13 +1426,13 @@ mkstemp_helper (struct obstack *obs, const char *me,
const char *pattern,
/* Guarantee that there are six trailing 'X' characters, even if the
user forgot to supply them. Output must be quoted if
successful. */
- obstack_grow (obs, lquote.string, lquote.length);
+ obstack_grow (obs, curr_quote.str1, curr_quote.len1);
obstack_grow (obs, pattern, len);
for (i = 0; len > 0 && i < 6; i++)
if (pattern[--len] != 'X')
break;
obstack_grow0 (obs, "XXXXXX", 6 - i);
- name = (char *) obstack_base (obs) + lquote.length;
+ name = (char *) obstack_base (obs) + curr_quote.len1;
errno = 0;
fd = mkstemp (name);
@@ -1449,7 +1446,7 @@ mkstemp_helper (struct obstack *obs, const char *me,
const char *pattern,
close (fd);
/* Remove NUL, then finish quote. */
obstack_blank (obs, -1);
- obstack_grow (obs, rquote.string, rquote.length);
+ obstack_grow (obs, curr_quote.str2, curr_quote.len2);
}
}
@@ -1474,7 +1471,7 @@ m4_maketemp (struct obstack *obs, int argc,
macro_arguments *argv)
maketemp(XXXXXXXX) -> `X00nnnnn', where nnnnn is 16-bit pid
*/
const char *str = ARG (1);
- size_t len = arg_len (argv, 1);
+ size_t len = ARG_LEN (1);
size_t i;
size_t len2;
@@ -1495,7 +1492,7 @@ m4_maketemp (struct obstack *obs, int argc,
macro_arguments *argv)
}
}
else
- mkstemp_helper (obs, me, ARG (1), arg_len (argv, 1));
+ mkstemp_helper (obs, me, ARG (1), ARG_LEN (1));
}
static void
@@ -1505,7 +1502,7 @@ m4_mkstemp (struct obstack *obs, int argc,
macro_arguments *argv)
if (bad_argc (me, argc, 1, 1))
return;
- mkstemp_helper (obs, me, ARG (1), arg_len (argv, 1));
+ mkstemp_helper (obs, me, ARG (1), ARG_LEN (1));
}
/*----------------------------------------.
@@ -1532,9 +1529,9 @@ static void
m4___file__ (struct obstack *obs, int argc, macro_arguments *argv)
{
bad_argc (ARG (0), argc, 0, 0);
- obstack_grow (obs, lquote.string, lquote.length);
+ obstack_grow (obs, curr_quote.str1, curr_quote.len1);
obstack_grow (obs, current_file, strlen (current_file));
- obstack_grow (obs, rquote.string, rquote.length);
+ obstack_grow (obs, curr_quote.str2, curr_quote.len2);
}
static void
@@ -1548,9 +1545,9 @@ static void
m4___program__ (struct obstack *obs, int argc, macro_arguments *argv)
{
bad_argc (ARG (0), argc, 0, 0);
- obstack_grow (obs, lquote.string, lquote.length);
+ obstack_grow (obs, curr_quote.str1, curr_quote.len1);
obstack_grow (obs, program_name, strlen (program_name));
- obstack_grow (obs, rquote.string, rquote.length);
+ obstack_grow (obs, curr_quote.str2, curr_quote.len2);
}
/* This section contains various macros for exiting, saving input until
@@ -1601,7 +1598,7 @@ m4_m4wrap (struct obstack *obs, int argc, macro_arguments
*argv)
if (bad_argc (ARG (0), argc, 1, -1))
return;
if (no_gnu_extensions)
- obstack_grow (obs, ARG (1), arg_len (argv, 1));
+ obstack_grow (obs, ARG (1), ARG_LEN (1));
else
dump_args (obs, 1, argv, " ", false);
obstack_1grow (obs, '\0');
@@ -1748,7 +1745,7 @@ m4_len (struct obstack *obs, int argc, macro_arguments
*argv)
{
if (bad_argc (ARG (0), argc, 1, 1))
return;
- shipout_int (obs, arg_len (argv, 1));
+ shipout_int (obs, ARG_LEN (1));
}
/*-------------------------------------------------------------------------.
@@ -1777,8 +1774,7 @@ m4_index (struct obstack *obs, int argc, macro_arguments
*argv)
/* Rely on the optimizations guaranteed by gnulib's memmem
module. */
- result = (char *) memmem (haystack, arg_len (argv, 1),
- needle, arg_len (argv, 2));
+ result = (char *) memmem (haystack, ARG_LEN (1), needle, ARG_LEN (2));
if (result)
retval = result - haystack;
@@ -1808,7 +1804,7 @@ m4_substr (struct obstack *obs, int argc, macro_arguments
*argv)
return;
}
- length = avail = arg_len (argv, 1);
+ length = avail = ARG_LEN (1);
if (!numeric_arg (me, ARG (2), &start))
return;
@@ -2074,14 +2070,14 @@ m4_regexp (struct obstack *obs, int argc,
macro_arguments *argv)
argc == 3 ? "" : "{", repl, argc == 3 ? "" : "}");
#endif /* DEBUG_REGEX */
- msg = compile_pattern (regexp, arg_len (argv, 2), &buf, ®s);
+ msg = compile_pattern (regexp, ARG_LEN (2), &buf, ®s);
if (msg != NULL)
{
m4_warn (0, me, _("bad regular expression: `%s': %s"), regexp, msg);
return;
}
- length = arg_len (argv, 1);
+ length = ARG_LEN (1);
/* Avoid overhead of allocating regs if we won't use it. */
startpos = re_search (buf, victim, length, 0, length,
argc == 3 ? NULL : regs);
@@ -2142,14 +2138,14 @@ m4_patsubst (struct obstack *obs, int argc,
macro_arguments *argv)
xfprintf (trace_file, "p:{%s}:{%s}\n", regexp, repl);
#endif /* DEBUG_REGEX */
- msg = compile_pattern (regexp, arg_len (argv, 2), &buf, ®s);
+ msg = compile_pattern (regexp, ARG_LEN (2), &buf, ®s);
if (msg != NULL)
{
m4_warn (0, me, _("bad regular expression `%s': %s"), regexp, msg);
return;
}
- length = arg_len (argv, 1);
+ length = ARG_LEN (1);
offset = 0;
matchpos = 0;
diff --git a/src/debug.c b/src/debug.c
index 2ca7a0d..d6b2ddc 100644
--- a/src/debug.c
+++ b/src/debug.c
@@ -1,7 +1,7 @@
/* GNU m4 -- A simple macro processor
- Copyright (C) 1991, 1992, 1993, 1994, 2004, 2006, 2007 Free Software
- Foundation, Inc.
+ Copyright (C) 1991, 1992, 1993, 1994, 2004, 2006, 2007, 2008 Free
+ Software Foundation, Inc.
This file is part of GNU M4.
@@ -110,12 +110,6 @@ debug_decode (const char *opts)
}
}
}
-
- /* This is to avoid screwing up the trace output due to changes in the
- debug_level. */
-
- obstack_free (&trace, obstack_finish (&trace));
-
return level;
}
@@ -283,11 +277,11 @@ trace_format (const char *fmt, ...)
break;
case 'l':
- s = (debug_level & DEBUG_TRACE_QUOTE) ? lquote.string : "";
+ s = (debug_level & DEBUG_TRACE_QUOTE) ? curr_quote.str1 : "";
break;
case 'r':
- s = (debug_level & DEBUG_TRACE_QUOTE) ? rquote.string : "";
+ s = (debug_level & DEBUG_TRACE_QUOTE) ? curr_quote.str2 : "";
break;
case 'd':
@@ -309,6 +303,7 @@ trace_format (const char *fmt, ...)
/*------------------------------------------------------------------.
| Format the standard header attached to all tracing output lines. |
+| ID is the current macro id. |
`------------------------------------------------------------------*/
static void
@@ -342,10 +337,10 @@ trace_flush (void)
obstack_free (&trace, line);
}
-/*-------------------------------------------------------------.
-| Do pre-argument-collction tracing for macro NAME. Used from |
-| expand_macro (). |
-`-------------------------------------------------------------*/
+/*----------------------------------------------------------------.
+| Do pre-argument-collection tracing for macro NAME, with a given |
+| ID. Used from expand_macro (). |
+`----------------------------------------------------------------*/
void
trace_prepre (const char *name, int id)
@@ -355,10 +350,11 @@ trace_prepre (const char *name, int id)
trace_flush ();
}
-/*-----------------------------------------------------------------------.
-| Format the parts of a trace line, that can be made before the macro is |
-| actually expanded. Used from expand_macro (). |
-`-----------------------------------------------------------------------*/
+/*-----------------------------------------------------------------.
+| Format the parts of a trace line that are known before the macro |
+| is actually expanded. Called for the macro NAME with ID, and |
+| arguments ARGV. Used from expand_macro (). |
+`-----------------------------------------------------------------*/
void
trace_pre (const char *name, int id, macro_arguments *argv)
@@ -382,7 +378,7 @@ trace_pre (const char *name, int id, macro_arguments *argv)
switch (arg_type (argv, i))
{
case TOKEN_TEXT:
- trace_format ("%l%S%r", arg_text (argv, i));
+ trace_format ("%l%S%r", ARG (i));
break;
case TOKEN_FUNC:
@@ -412,8 +408,9 @@ trace_pre (const char *name, int id, macro_arguments *argv)
}
/*-------------------------------------------------------------------.
-| Format the final part of a trace line and print it all. Used from |
-| expand_macro (). |
+| Format the final part of a trace line and print it all. Print |
+| details for macro NAME with ID, given arguemnts ARGV and expansion |
+| EXPANDED. Used from expand_macro (). |
`-------------------------------------------------------------------*/
void
diff --git a/src/format.c b/src/format.c
index 9c9508d..6808ad5 100644
--- a/src/format.c
+++ b/src/format.c
@@ -101,16 +101,16 @@ arg_double (const char *me, const char *str)
}
#define ARG_INT(i, argc, argv) \
- ((argc <= ++i) ? 0 : arg_int (me, arg_text (argv, i)))
+ ((argc <= ++i) ? 0 : arg_int (me, ARG (i)))
#define ARG_LONG(i, argc, argv)
\
- ((argc <= ++i) ? 0L : arg_long (me, arg_text (argv, i)))
+ ((argc <= ++i) ? 0L : arg_long (me, ARG (i)))
#define ARG_STR(i, argc, argv) \
- ((argc <= ++i) ? "" : arg_text (argv, i))
+ ((argc <= ++i) ? "" : ARG (i))
#define ARG_DOUBLE(i, argc, argv) \
- ((argc <= ++i) ? 0.0 : arg_double (me, arg_text (argv, i)))
+ ((argc <= ++i) ? 0.0 : arg_double (me, ARG (i)))
/*------------------------------------------------------------------.
@@ -124,7 +124,7 @@ arg_double (const char *me, const char *str)
void
format (struct obstack *obs, int argc, macro_arguments *argv)
{
- const char *me = arg_text (argv, 0);
+ const char *me = ARG (0); /* Macro name. */
const char *f; /* Format control string. */
const char *fmt; /* Position within f. */
char fstart[] = "%'+- 0#*.*hhd"; /* Current format spec. */
diff --git a/src/freeze.c b/src/freeze.c
index 52a69d1..383d008 100644
--- a/src/freeze.c
+++ b/src/freeze.c
@@ -1,6 +1,6 @@
/* GNU m4 -- A simple macro processor
- Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2006, 2007
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GNU M4.
@@ -71,23 +71,16 @@ produce_frozen_state (const char *name)
/* Dump quote delimiters. */
- if (strcmp (lquote.string, DEF_LQUOTE) || strcmp (rquote.string, DEF_RQUOTE))
- {
- xfprintf (file, "Q%d,%d\n", (int) lquote.length, (int) rquote.length);
- fputs (lquote.string, file);
- fputs (rquote.string, file);
- fputc ('\n', file);
- }
+ if (strcmp (curr_quote.str1, DEF_LQUOTE)
+ || strcmp (curr_quote.str2, DEF_RQUOTE))
+ xfprintf (file, "Q%d,%d\n%s%s\n", (int) curr_quote.len1,
+ (int) curr_quote.len2, curr_quote.str1, curr_quote.str2);
/* Dump comment delimiters. */
- if (strcmp (bcomm.string, DEF_BCOMM) || strcmp (ecomm.string, DEF_ECOMM))
- {
- xfprintf (file, "C%d,%d\n", (int) bcomm.length, (int) ecomm.length);
- fputs (bcomm.string, file);
- fputs (ecomm.string, file);
- fputc ('\n', file);
- }
+ if (strcmp (curr_comm.str1, DEF_BCOMM) || strcmp (curr_comm.str2, DEF_ECOMM))
+ xfprintf (file, "C%d,%d\n%s%s\n", (int) curr_comm.len1,
+ (int) curr_comm.len2, curr_comm.str1, curr_comm.str2);
/* Dump all symbols. */
diff --git a/src/input.c b/src/input.c
index 9f25e8f..5890bd2 100644
--- a/src/input.c
+++ b/src/input.c
@@ -156,12 +156,10 @@ static bool input_change;
#define CHAR_QUOTE 258 /* Character return for quoted string. */
/* Quote chars. */
-STRING rquote;
-STRING lquote;
+string_pair curr_quote;
/* Comment chars. */
-STRING bcomm;
-STRING ecomm;
+string_pair curr_comm;
#ifdef ENABLE_CHANGEWORD
@@ -219,13 +217,11 @@ make_text_link (struct obstack *obs, token_chain **start,
token_chain **end)
*start = chain;
*end = chain;
chain->next = NULL;
+ chain->type = CHAIN_STR;
chain->quote_age = 0;
- chain->str = str;
- chain->len = len;
- chain->level = -1;
- chain->argv = NULL;
- chain->index = 0;
- chain->flatten = false;
+ chain->u.u_s.str = str;
+ chain->u.u_s.len = len;
+ chain->u.u_s.level = -1;
}
}
@@ -363,13 +359,11 @@ push_token (token_data *token, int level)
next->u.u_c.chain = chain;
next->u.u_c.end = chain;
chain->next = NULL;
+ chain->type = CHAIN_STR;
chain->quote_age = TOKEN_DATA_QUOTE_AGE (token);
- chain->str = TOKEN_DATA_TEXT (token);
- chain->len = TOKEN_DATA_LEN (token);
- chain->level = level;
- chain->argv = NULL;
- chain->index = 0;
- chain->flatten = false;
+ chain->u.u_s.str = TOKEN_DATA_TEXT (token);
+ chain->u.u_s.len = TOKEN_DATA_LEN (token);
+ chain->u.u_s.level = level;
if (level >= 0)
{
adjust_refcount (level, true);
@@ -478,19 +472,20 @@ pop_input (bool cleanup)
assert (!chain || !cleanup);
while (chain)
{
- if (chain->str)
+ switch (chain->type)
{
- if (chain->len)
+ case CHAIN_STR:
+ if (chain->u.u_s.len)
return false;
- }
- else
- {
+ if (chain->u.u_s.level >= 0)
+ adjust_refcount (chain->u.u_s.level, false);
+ break;
+ case CHAIN_ARGV:
/* TODO - peek into argv. */
- assert (!"implemented yet");
+ default:
+ assert (!"pop_input");
abort ();
}
- if (chain->level >= 0)
- adjust_refcount (chain->level, false);
isp->u.u_c.chain = chain = chain->next;
}
break;
@@ -601,8 +596,8 @@ input_print (struct obstack *obs, const input_block *input)
while (chain)
{
/* TODO support argv refs as well. */
- assert (chain->str);
- if (obstack_print (obs, chain->str, chain->len, &maxlen))
+ assert (chain->type == CHAIN_STR);
+ if (obstack_print (obs, chain->u.u_s.str, chain->u.u_s.len, &maxlen))
return;
chain = chain->next;
}
@@ -659,15 +654,16 @@ peek_input (void)
chain = block->u.u_c.chain;
while (chain)
{
- if (chain->str)
- {
- if (chain->len)
- return to_uchar (chain->str[0]);
- }
- else
+ switch (chain->type)
{
+ case CHAIN_STR:
+ if (chain->u.u_s.len)
+ return to_uchar (*chain->u.u_s.str);
+ break;
+ case CHAIN_ARGV:
/* TODO - peek into argv. */
- assert (!"implemented yet");
+ default:
+ assert (!"peek_input");
abort ();
}
chain = chain->next;
@@ -760,24 +756,25 @@ next_char_1 (bool allow_quote)
{
if (allow_quote && chain->quote_age == current_quote_age)
return CHAR_QUOTE;
- if (chain->str)
+ switch (chain->type)
{
- if (chain->len)
+ case CHAIN_STR:
+ if (chain->u.u_s.len)
{
/* Partial consumption invalidates quote age. */
chain->quote_age = 0;
- chain->len--;
- return to_uchar (*chain->str++);
+ chain->u.u_s.len--;
+ return to_uchar (*chain->u.u_s.str++);
}
- }
- else
- {
+ if (chain->u.u_s.level >= 0)
+ adjust_refcount (chain->u.u_s.level, false);
+ break;
+ case CHAIN_ARGV:
/* TODO - read from argv. */
- assert (!"implemented yet");
+ default:
+ assert (!"next_char_1");
abort ();
}
- if (chain->level >= 0)
- adjust_refcount (chain->level, false);
isp->u.u_c.chain = chain = chain->next;
}
break;
@@ -958,14 +955,14 @@ input_init (void)
start_of_input_line = false;
- lquote.string = xstrdup (DEF_LQUOTE);
- lquote.length = strlen (lquote.string);
- rquote.string = xstrdup (DEF_RQUOTE);
- rquote.length = strlen (rquote.string);
- bcomm.string = xstrdup (DEF_BCOMM);
- bcomm.length = strlen (bcomm.string);
- ecomm.string = xstrdup (DEF_ECOMM);
- ecomm.length = strlen (ecomm.string);
+ curr_quote.str1 = xstrdup (DEF_LQUOTE);
+ curr_quote.len1 = strlen (curr_quote.str1);
+ curr_quote.str2 = xstrdup (DEF_RQUOTE);
+ curr_quote.len2 = strlen (curr_quote.str2);
+ curr_comm.str1 = xstrdup (DEF_BCOMM);
+ curr_comm.len1 = strlen (curr_comm.str1);
+ curr_comm.str2 = xstrdup (DEF_ECOMM);
+ curr_comm.len2 = strlen (curr_comm.str2);
#ifdef ENABLE_CHANGEWORD
set_word_regexp (NULL, user_word_regexp);
@@ -999,15 +996,15 @@ set_quotes (const char *lq, const char *rq)
else if (!rq || (*lq && !*rq))
rq = DEF_RQUOTE;
- if (strcmp (lquote.string, lq) == 0 && strcmp (rquote.string, rq) == 0)
+ if (strcmp (curr_quote.str1, lq) == 0 && strcmp (curr_quote.str2, rq) == 0)
return;
- free (lquote.string);
- free (rquote.string);
- lquote.string = xstrdup (lq);
- lquote.length = strlen (lquote.string);
- rquote.string = xstrdup (rq);
- rquote.length = strlen (rquote.string);
+ free (curr_quote.str1);
+ free (curr_quote.str2);
+ curr_quote.str1 = xstrdup (lq);
+ curr_quote.len1 = strlen (curr_quote.str1);
+ curr_quote.str2 = xstrdup (rq);
+ curr_quote.len2 = strlen (curr_quote.str2);
set_quote_age ();
}
@@ -1032,15 +1029,15 @@ set_comment (const char *bc, const char *ec)
else if (!ec || (*bc && !*ec))
ec = DEF_ECOMM;
- if (strcmp (bcomm.string, bc) == 0 && strcmp (ecomm.string, ec) == 0)
+ if (strcmp (curr_comm.str1, bc) == 0 && strcmp (curr_comm.str2, ec) == 0)
return;
- free (bcomm.string);
- free (ecomm.string);
- bcomm.string = xstrdup (bc);
- bcomm.length = strlen (bcomm.string);
- ecomm.string = xstrdup (ec);
- ecomm.length = strlen (ecomm.string);
+ free (curr_comm.str1);
+ free (curr_comm.str2);
+ curr_comm.str1 = xstrdup (bc);
+ curr_comm.len1 = strlen (curr_comm.str1);
+ curr_comm.str2 = xstrdup (ec);
+ curr_comm.len2 = strlen (curr_comm.str2);
set_quote_age ();
}
@@ -1136,14 +1133,14 @@ set_quote_age (void)
static const char unsafe[] = Letters "_0123456789(,) \t\n\r\f\v";
#undef Letters
- if (lquote.length == 1 && rquote.length == 1
- && strpbrk(lquote.string, unsafe) == NULL
- && strpbrk(rquote.string, unsafe) == NULL
- && default_word_regexp && *lquote.string != *rquote.string
- && *bcomm.string != '(' && *bcomm.string != ','
- && *bcomm.string != ')' && *bcomm.string != *lquote.string)
- current_quote_age = (((*lquote.string & 0xff) << 8)
- | (*rquote.string & 0xff));
+ if (curr_quote.len1 == 1 && curr_quote.len2 == 1
+ && strpbrk (curr_quote.str1, unsafe) == NULL
+ && strpbrk (curr_quote.str2, unsafe) == NULL
+ && default_word_regexp && *curr_quote.str1 != *curr_quote.str2
+ && *curr_comm.str1 != '(' && *curr_comm.str1 != ','
+ && *curr_comm.str1 != ')' && *curr_comm.str1 != *curr_quote.str1)
+ current_quote_age = (((*curr_quote.str1 & 0xff) << 8)
+ | (*curr_quote.str2 & 0xff));
else
current_quote_age = 0;
}
@@ -1239,18 +1236,18 @@ next_token (token_data *td, int *line, struct obstack
*obs, const char *caller)
next_char (false); /* Consume character we already peeked at. */
file = current_file;
*line = current_line;
- if (MATCH (ch, bcomm.string, true))
+ if (MATCH (ch, curr_comm.str1, true))
{
if (obs)
obs_td = obs;
- obstack_grow (obs_td, bcomm.string, bcomm.length);
+ obstack_grow (obs_td, curr_comm.str1, curr_comm.len1);
while ((ch = next_char (false)) < CHAR_EOF
- && !MATCH (ch, ecomm.string, true))
+ && !MATCH (ch, curr_comm.str2, true))
obstack_1grow (obs_td, ch);
if (ch != CHAR_EOF)
{
assert (ch < CHAR_EOF);
- obstack_grow (obs_td, ecomm.string, ecomm.length);
+ obstack_grow (obs_td, curr_comm.str2, curr_comm.len2);
}
else
/* Current_file changed to "" if we see CHAR_EOF, use the
@@ -1306,7 +1303,7 @@ next_token (token_data *td, int *line, struct obstack
*obs, const char *caller)
#endif /* ENABLE_CHANGEWORD */
- else if (!MATCH (ch, lquote.string, true))
+ else if (!MATCH (ch, curr_quote.str1, true))
{
switch (ch)
{
@@ -1341,16 +1338,16 @@ next_token (token_data *td, int *line, struct obstack
*obs, const char *caller)
if (ch == CHAR_QUOTE)
append_quote_token (obs, td);
- else if (MATCH (ch, rquote.string, true))
+ else if (MATCH (ch, curr_quote.str2, true))
{
if (--quote_level == 0)
break;
- obstack_grow (obs_td, rquote.string, rquote.length);
+ obstack_grow (obs_td, curr_quote.str2, curr_quote.len2);
}
- else if (MATCH (ch, lquote.string, true))
+ else if (MATCH (ch, curr_quote.str1, true))
{
quote_level++;
- obstack_grow (obs_td, lquote.string, lquote.length);
+ obstack_grow (obs_td, curr_quote.str1, curr_quote.len1);
}
else
{
@@ -1392,8 +1389,24 @@ next_token (token_data *td, int *line, struct obstack
*obs, const char *caller)
{
assert (TOKEN_DATA_TYPE (td) == TOKEN_COMP && type == TOKEN_STRING);
#ifdef DEBUG_INPUT
- xfprintf (stderr, "next_token -> %s <chain>\n",
- token_type_string (type));
+ {
+ token_chain *chain;
+ size_t len = 0;
+ int links = 0;
+ chain = td->u.u_c.chain;
+ xfprintf (stderr, "next_token -> %s <chain> (",
+ token_type_string (type));
+ while (chain)
+ {
+ assert (chain->type == CHAIN_STR);
+ xfprintf (stderr, "%s", chain->u.u_s.str);
+ len += chain->u.u_s.len;
+ links++;
+ chain = chain->next;
+ }
+ xfprintf (stderr, "), %d links, len %zu\n",
+ links, len);
+ }
#endif /* DEBUG_INPUT */
}
return type;
@@ -1417,7 +1430,7 @@ peek_token (void)
{
result = TOKEN_MACDEF;
}
- else if (MATCH (ch, bcomm.string, false))
+ else if (MATCH (ch, curr_comm.str1, false))
{
result = TOKEN_STRING;
}
@@ -1429,7 +1442,7 @@ peek_token (void)
{
result = TOKEN_WORD;
}
- else if (MATCH (ch, lquote.string, false))
+ else if (MATCH (ch, curr_quote.str1, false))
{
result = TOKEN_STRING;
}
diff --git a/src/m4.h b/src/m4.h
index 474338b..a541687 100644
--- a/src/m4.h
+++ b/src/m4.h
@@ -79,12 +79,15 @@
/* Various declarations. */
-struct string
+/* Describes a pair of strings, such as begin and end quotes. */
+struct string_pair
{
- char *string; /* characters of the string */
- size_t length; /* length of the string */
+ char *str1;
+ size_t len1;
+ char *str2;
+ size_t len2;
};
-typedef struct string STRING;
+typedef struct string_pair string_pair;
/* Memory allocation. */
#define obstack_chunk_alloc xmalloc
@@ -274,17 +277,40 @@ enum token_data_type
TOKEN_COMP /* Composite argument, u.u_c is valid. */
};
-/* Composite tokens are built of a linked list of chains. */
+/* A link in a chain of token data. */
+enum token_chain_type
+{
+ CHAIN_STR, /* Link contains a string, u.u_s is valid. */
+ /* TODO add CHAIN_FUNC. */
+ CHAIN_ARGV /* Link contains a $@ reference, u.u_a is valid. */
+};
+
+/* Composite tokens are built of a linked list of chains. Each link
+ of the chain is either a single text reference (ie. $1), or an argv
+ reference (ie. $@). */
struct token_chain
{
token_chain *next; /* Pointer to next link of chain. */
+ enum token_chain_type type; /* Type of this link. */
unsigned int quote_age; /* Quote_age of this link of chain, or 0. */
- const char *str; /* NUL-terminated string if text, or NULL. */
- size_t len; /* Length of str, else 0. */
- int level; /* Expansion level of link content, or -1. */
- macro_arguments *argv; /* Reference to earlier address@hidden */
- unsigned int index; /* Argument index within argv. */
- bool flatten; /* True to treat builtins as text. */
+ union
+ {
+ struct
+ {
+ const char *str; /* Pointer to text. */
+ size_t len; /* Remaining length of str. */
+ int level; /* Expansion level of link content, or -1. */
+ }
+ u_s;
+ struct
+ {
+ macro_arguments *argv; /* Reference to earlier address@hidden
*/
+ unsigned int index; /* Argument index within argv. */
+ bool flatten; /* True to treat builtins as text. */
+ }
+ u_a;
+ }
+ u;
};
/* The content of a token or macro argument. */
@@ -363,8 +389,8 @@ extern const char *current_file;
extern int current_line;
/* left and right quote, begin and end comment */
-extern STRING bcomm, ecomm;
-extern STRING lquote, rquote;
+extern string_pair curr_comm;
+extern string_pair curr_quote;
#define DEF_LQUOTE "`"
#define DEF_RQUOTE "\'"
@@ -465,6 +491,14 @@ void push_arg (struct obstack *, macro_arguments *,
unsigned int);
void push_args (struct obstack *, macro_arguments *, bool, bool);
size_t adjust_refcount (int, bool);
+/* 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)
+
+/* Grab the text length at argv index I. Assumes macro_argument *argv
+ is in scope, and aborts if the argument is not text. */
+#define ARG_LEN(i) arg_len (argv, i)
+
/* File: builtin.c --- builtins. */
diff --git a/src/macro.c b/src/macro.c
index 62af398..d22226e 100644
--- a/src/macro.c
+++ b/src/macro.c
@@ -673,8 +673,9 @@ expand_macro (symbol *sym)
chain = argv->array[i]->u.u_c.chain;
while (chain)
{
- if (chain->level >= 0)
- adjust_refcount (chain->level, false);
+ assert (chain->type == CHAIN_STR);
+ if (chain->u.u_s.level >= 0)
+ adjust_refcount (chain->u.u_s.level, false);
chain = chain->next;
}
}
@@ -753,15 +754,17 @@ arg_token (macro_arguments *argv, unsigned int index)
{
token_chain *chain = token->u.u_c.chain;
/* TODO - for now we support only a single-length $@ chain. */
- assert (!chain->next && !chain->str);
- if (index < chain->argv->argc - (chain->index - 1))
+ assert (!chain->next && chain->type == CHAIN_ARGV);
+ if (index < chain->u.u_a.argv->argc - (chain->u.u_a.index - 1))
{
- token = arg_token (chain->argv, chain->index - 1 + index);
- if (chain->flatten && TOKEN_DATA_TYPE (token) == TOKEN_FUNC)
+ token = arg_token (chain->u.u_a.argv,
+ chain->u.u_a.index - 1 + index);
+ if (chain->u.u_a.flatten
+ && TOKEN_DATA_TYPE (token) == TOKEN_FUNC)
token = &empty_token;
break;
}
- index -= chain->argv->argc - chain->index;
+ index -= chain->u.u_a.argv->argc - chain->u.u_a.index;
}
else if (--index == 0)
break;
@@ -781,8 +784,8 @@ arg_mark (macro_arguments *argv)
assert (argv->arraylen == 1
&& TOKEN_DATA_TYPE (argv->array[0]) == TOKEN_COMP
&& !argv->array[0]->u.u_c.chain->next
- && !argv->array[0]->u.u_c.chain->str);
- argv->array[0]->u.u_c.chain->argv->inuse = true;
+ && argv->array[0]->u.u_c.chain->type == CHAIN_ARGV);
+ argv->array[0]->u.u_c.chain->u.u_a.argv->inuse = true;
}
}
@@ -820,7 +823,7 @@ arg_text (macro_arguments *argv, unsigned int index)
{
token_data *token;
token_chain *chain;
- struct obstack *obs;
+ struct obstack *obs; /* Scratch space; cleaned at end of macro_expand. */
if (index == 0)
return argv->argv0;
@@ -838,8 +841,8 @@ arg_text (macro_arguments *argv, unsigned int index)
obs = arg_scratch ();
while (chain)
{
- assert (chain->str);
- obstack_grow (obs, chain->str, chain->len);
+ assert (chain->type == CHAIN_STR);
+ obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
chain = chain->next;
}
obstack_1grow (obs, '\0');
@@ -879,8 +882,9 @@ arg_equal (macro_arguments *argv, unsigned int indexa,
unsigned int indexb)
if (TOKEN_DATA_TYPE (ta) == TOKEN_TEXT)
{
tmpa.next = NULL;
- tmpa.str = TOKEN_DATA_TEXT (ta);
- tmpa.len = TOKEN_DATA_LEN (ta);
+ tmpa.type = CHAIN_STR;
+ tmpa.u.u_s.str = TOKEN_DATA_TEXT (ta);
+ tmpa.u.u_s.len = TOKEN_DATA_LEN (ta);
}
else
{
@@ -890,8 +894,9 @@ arg_equal (macro_arguments *argv, unsigned int indexa,
unsigned int indexb)
if (TOKEN_DATA_TYPE (tb) == TOKEN_TEXT)
{
tmpb.next = NULL;
- tmpb.str = TOKEN_DATA_TEXT (tb);
- tmpb.len = TOKEN_DATA_LEN (tb);
+ tmpb.type = CHAIN_STR;
+ tmpb.u.u_s.str = TOKEN_DATA_TEXT (tb);
+ tmpb.u.u_s.len = TOKEN_DATA_LEN (tb);
}
else
{
@@ -903,32 +908,34 @@ arg_equal (macro_arguments *argv, unsigned int indexa,
unsigned int indexb)
while (ca && cb)
{
/* TODO support comparison against $@ refs. */
- assert (ca->str && cb->str);
- if (ca->len == cb->len)
+ assert (ca->type == CHAIN_STR && cb->type == CHAIN_STR);
+ if (ca->u.u_s.len == cb->u.u_s.len)
{
- if (memcmp (ca->str, cb->str, ca->len) != 0)
+ if (memcmp (ca->u.u_s.str, cb->u.u_s.str, ca->u.u_s.len) != 0)
return false;
ca = ca->next;
cb = cb->next;
}
- else if (ca->len < cb->len)
+ else if (ca->u.u_s.len < cb->u.u_s.len)
{
- if (memcmp (ca->str, cb->str, ca->len) != 0)
+ if (memcmp (ca->u.u_s.str, cb->u.u_s.str, ca->u.u_s.len) != 0)
return false;
tmpb.next = cb->next;
- tmpb.str = cb->str + ca->len;
- tmpb.len = cb->len - ca->len;
+ tmpb.type = CHAIN_STR;
+ tmpb.u.u_s.str = cb->u.u_s.str + ca->u.u_s.len;
+ tmpb.u.u_s.len = cb->u.u_s.len - ca->u.u_s.len;
ca = ca->next;
cb = &tmpb;
}
else
{
- assert (ca->len > cb->len);
- if (memcmp (ca->str, cb->str, cb->len) != 0)
+ assert (ca->u.u_s.len > cb->u.u_s.len);
+ if (memcmp (ca->u.u_s.str, cb->u.u_s.str, cb->u.u_s.len) != 0)
return false;
tmpa.next = ca->next;
- tmpa.str = ca->str + cb->len;
- tmpa.len = ca->len - cb->len;
+ tmpa.type = CHAIN_STR;
+ tmpa.u.u_s.str = ca->u.u_s.str + cb->u.u_s.len;
+ tmpa.u.u_s.len = ca->u.u_s.len - cb->u.u_s.len;
ca = &tmpa;
cb = cb->next;
}
@@ -979,8 +986,8 @@ arg_len (macro_arguments *argv, unsigned int index)
len = 0;
while (chain)
{
- assert (chain->str);
- len += chain->len;
+ assert (chain->type == CHAIN_STR);
+ len += chain->u.u_s.len;
chain = chain->next;
}
assert (len);
@@ -1039,9 +1046,9 @@ make_argv_ref (macro_arguments *argv, const char *argv0,
size_t argv0_len,
assert (argv->arraylen == 1
&& TOKEN_DATA_TYPE (argv->array[0]) == TOKEN_COMP);
chain = argv->array[0]->u.u_c.chain;
- assert (!chain->next && !chain->str);
- argv = chain->argv;
- index += chain->index - 1;
+ assert (!chain->next && chain->type == CHAIN_ARGV);
+ argv = chain->u.u_a.argv;
+ index += chain->u.u_a.index - 1;
}
if (argv->argc <= index)
{
@@ -1065,13 +1072,11 @@ make_argv_ref (macro_arguments *argv, const char
*argv0, size_t argv0_len,
TOKEN_DATA_TYPE (token) = TOKEN_COMP;
token->u.u_c.chain = token->u.u_c.end = chain;
chain->next = NULL;
+ chain->type = CHAIN_ARGV;
chain->quote_age = argv->quote_age;
- chain->str = NULL;
- chain->len = 0;
- chain->level = expansion_level - 1;
- chain->argv = argv;
- chain->index = index;
- chain->flatten = flatten;
+ chain->u.u_a.argv = argv;
+ chain->u.u_a.index = index;
+ chain->u.u_a.flatten = flatten;
}
new_argv->argc = argv->argc - (index - 1);
new_argv->inuse = false;
@@ -1111,8 +1116,8 @@ push_arg (struct obstack *obs, macro_arguments *argv,
unsigned int index)
token_chain *chain = token->u.u_c.chain;
while (chain)
{
- assert (chain->str);
- obstack_grow (obs, chain->str, chain->len);
+ assert (chain->type == CHAIN_STR);
+ obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
chain = chain->next;
}
}
@@ -1140,22 +1145,22 @@ push_args (struct obstack *obs, macro_arguments *argv,
bool skip, bool quote)
if (i + 1 == argv->argc)
{
if (quote)
- obstack_grow (obs, lquote.string, lquote.length);
+ obstack_grow (obs, curr_quote.str1, curr_quote.len1);
push_arg (obs, argv, i);
if (quote)
- obstack_grow (obs, rquote.string, rquote.length);
+ obstack_grow (obs, curr_quote.str2, curr_quote.len2);
return;
}
/* Compute the separator in the scratch space. */
if (quote)
{
- obstack_grow (obs, lquote.string, lquote.length);
- obstack_grow (scratch, rquote.string, rquote.length);
+ obstack_grow (obs, curr_quote.str1, curr_quote.len1);
+ obstack_grow (scratch, curr_quote.str2, curr_quote.len2);
obstack_1grow (scratch, ',');
- obstack_grow0 (scratch, lquote.string, lquote.length);
+ obstack_grow0 (scratch, curr_quote.str1, curr_quote.len1);
sep = (char *) obstack_finish (scratch);
- sep_len += lquote.length + rquote.length;
+ sep_len += curr_quote.len1 + curr_quote.len2;
}
/* TODO push entire $@ reference, rather than pushing each arg. */
for ( ; i < argv->argc; i++)
@@ -1175,14 +1180,14 @@ push_args (struct obstack *obs, macro_arguments *argv,
bool skip, bool quote)
chain = token->u.u_c.chain;
while (chain)
{
- assert (chain->str);
- obstack_grow (obs, chain->str, chain->len);
+ assert (chain->type == CHAIN_STR);
+ obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
chain = chain->next;
}
}
}
if (quote)
- obstack_grow (obs, rquote.string, rquote.length);
+ obstack_grow (obs, curr_quote.str2, curr_quote.len2);
if (inuse)
arg_mark (argv);
}
--
1.5.3.8
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [12/18] argv_ref speedup: several code cleanups,
Eric Blake <=