summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <ebb9@byu.net>2009-02-18 13:36:15 -0700
committerEric Blake <ebb9@byu.net>2009-02-18 15:36:03 -0700
commitd8726aac7acd47435ad3e4dedef44d01cd828dc1 (patch)
tree9d48713e84c90ea15df2e12811ae37d53d7e21fa
parent028f5c5976a35256f5fa3804f33292a75ba56c6e (diff)
downloadm4-d8726aac7acd47435ad3e4dedef44d01cd828dc1.tar.gz
Prefer buffer over byte operations.
* modules/format.c (format): Use memchr for speed. * modules/gnu.c (substitute): Likewise. * m4/macro.c (locate_dollar): Inline into only caller... (process_macro): ...and rearrange for readability. * m4/input.c (consume_buffer): Allow C++ compilation. * doc/m4.texinfo (Changesyntax): Enhance test. Signed-off-by: Eric Blake <ebb9@byu.net> (cherry picked from commit 45a154e6d70517bf1b837715aae2fe366c9c1116)
-rw-r--r--ChangeLog8
-rw-r--r--doc/m4.texinfo5
-rw-r--r--m4/input.c2
-rw-r--r--m4/macro.c48
-rw-r--r--modules/format.c13
-rw-r--r--modules/gnu.c15
6 files changed, 56 insertions, 35 deletions
diff --git a/ChangeLog b/ChangeLog
index 51fda555..9469fbe8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
2009-02-18 Eric Blake <ebb9@byu.net>
+ Prefer buffer over byte operations.
+ * modules/format.c (format): Use memchr for speed.
+ * modules/gnu.c (substitute): Likewise.
+ * m4/macro.c (locate_dollar): Inline into only caller...
+ (process_macro): ...and rearrange for readability.
+ * m4/input.c (consume_buffer): Allow C++ compilation.
+ * doc/m4.texinfo (Changesyntax): Enhance test.
+
Speed up esyscmd with buffer reads.
* modules/gnu.c (esyscmd): Read blocks directly into obstack,
rather than repeatedly reading bytes. Detect read errors.
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index e3eee251..7f7bb3f3 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -5628,6 +5628,11 @@ define(`escape', `$?`'1$?1?')
@result{}
escape(foo)
@result{}$?1$foo?
+dnl Multiple argument identifiers.
+changesyntax(`$+$')
+@result{}
+argref(1, 2, 3)
+@result{}Dollar: 3, Question: 3
@end example
Macro calls can be given a @TeX{} or Texinfo like syntax using an
diff --git a/m4/input.c b/m4/input.c
index e061bcd7..1b40e5da 100644
--- a/m4/input.c
+++ b/m4/input.c
@@ -416,7 +416,7 @@ file_consume (m4_input_block *me, m4 *context, size_t len)
buf = freadptr (me->u.u_f.fp, &buf_len);
assert (buf && len <= buf_len);
buf_len = 0;
- while ((p = memchr (buf + buf_len, '\n', len - buf_len)))
+ while ((p = (char *) memchr (buf + buf_len, '\n', len - buf_len)))
{
if (p == buf + len - 1)
start_of_input_line = true;
diff --git a/m4/macro.c b/m4/macro.c
index 7295157f..fc28cd35 100644
--- a/m4/macro.c
+++ b/m4/macro.c
@@ -688,22 +688,6 @@ m4_macro_call (m4 *context, m4_symbol_value *value, m4_obstack *expansion,
trace_post (context, trace_start, argv->info);
}
-/* Locate the next byte with dollar syntax in string STR of length
- LEN, or return NULL. */
-static const char *
-locate_dollar (m4 *context, const char *str, size_t len)
-{
- if (m4_is_syntax_single_dollar (M4SYNTAX))
- return (char *) memchr (str, M4SYNTAX->dollar, len);
- while (len--)
- {
- if (m4_has_syntax (M4SYNTAX, *str, M4_SYNTAX_DOLLAR))
- return str;
- str++;
- }
- return NULL;
-}
-
/* This function handles all expansion of user defined and predefined
macros. It is called with an obstack OBS, where the macros expansion
will be placed, as an unfinished object. SYMBOL points to the macro
@@ -715,16 +699,38 @@ process_macro (m4 *context, m4_symbol_value *value, m4_obstack *obs,
{
const char *text = m4_get_symbol_value_text (value);
size_t len = m4_get_symbol_value_len (value);
+ const char *end = text + len;
int i;
- const char *dollar = locate_dollar (context, text, len);
-
- while (dollar)
+ while (1)
{
+ const char *dollar;
+ if (m4_is_syntax_single_dollar (M4SYNTAX))
+ dollar = (char *) memchr (text, M4SYNTAX->dollar, len);
+ else
+ {
+ dollar = text;
+ while (dollar != end)
+ {
+ if (m4_has_syntax (M4SYNTAX, *dollar, M4_SYNTAX_DOLLAR))
+ break;
+ dollar++;
+ }
+ if (dollar == end)
+ dollar = NULL;
+ }
+ if (!dollar)
+ {
+ obstack_grow (obs, text, len);
+ return;
+ }
obstack_grow (obs, text, dollar - text);
len -= dollar - text;
text = dollar;
if (len == 1)
- break;
+ {
+ obstack_1grow (obs, *dollar);
+ return;
+ }
len--;
switch (*++text)
{
@@ -813,9 +819,7 @@ process_macro (m4 *context, m4_symbol_value *value, m4_obstack *obs,
}
break;
}
- dollar = locate_dollar (context, text, len);
}
- obstack_grow (obs, text, len);
}
diff --git a/modules/format.c b/modules/format.c
index 55333bef..a402d38c 100644
--- a/modules/format.c
+++ b/modules/format.c
@@ -182,14 +182,17 @@ format (m4 *context, m4_obstack *obs, int argc, m4_macro_args *argv)
f_len = M4ARGLEN (1);
assert (!f[f_len]); /* Requiring a terminating NUL makes parsing simpler. */
memset (ok, 0, sizeof ok);
- while (f_len--)
+ while (1)
{
- c = *fmt++;
- if (c != '%')
+ const char *percent = (char *) memchr (fmt, '%', f_len);
+ if (!percent)
{
- obstack_1grow (obs, c);
- continue;
+ obstack_grow (obs, fmt, f_len);
+ break;
}
+ obstack_grow (obs, fmt, percent - fmt);
+ f_len -= percent - fmt + 1;
+ fmt = percent + 1;
if (*fmt == '%')
{
diff --git a/modules/gnu.c b/modules/gnu.c
index e6c7691e..53a3ecb8 100644
--- a/modules/gnu.c
+++ b/modules/gnu.c
@@ -238,22 +238,23 @@ substitute (m4 *context, m4_obstack *obs, const m4_call_info *caller,
m4_pattern_buffer *buf)
{
int ch;
-
- while (repl_len--)
+ while (1)
{
- ch = *repl++;
- if (ch != '\\')
+ const char *backslash = (char *) memchr (repl, '\\', repl_len);
+ if (!backslash)
{
- obstack_1grow (obs, ch);
- continue;
+ obstack_grow (obs, repl, repl_len);
+ return;
}
+ obstack_grow (obs, repl, backslash - repl);
+ repl_len -= backslash - repl + 1;
if (!repl_len)
{
m4_warn (context, 0, caller,
_("trailing \\ ignored in replacement"));
return;
}
-
+ repl = backslash + 1;
ch = *repl++;
repl_len--;
switch (ch)