summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2018-02-14 14:08:08 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2018-02-14 14:08:08 +0000
commit85e03244290d3fc3f98d1a5bd6b963bb21025883 (patch)
treea081dd30209fc2514a585465424757fcdd212c90
parent7c714e25526fdd15330fc1c852845d3632e29823 (diff)
Macros: speedup expansion processing
-rw-r--r--doc/doc-txt/ChangeLog4
-rw-r--r--src/src/exim.c8
-rw-r--r--src/src/globals.c1
-rw-r--r--src/src/globals.h1
-rw-r--r--src/src/readconf.c26
5 files changed, 26 insertions, 14 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog
index 6dd768c8a..370e1b7e7 100644
--- a/doc/doc-txt/ChangeLog
+++ b/doc/doc-txt/ChangeLog
@@ -99,6 +99,10 @@ JH/17 Bug 2113: Fix conversation closedown with the Avast malware scanner.
JH/18 Bug 2239: Enforce non-usability of control=utf8_downconvert in the mail
ACL. Previously, a crash would result.
+JH/19 Speed up macro lookups during configuration file read, by skipping non-
+ macro text after a replacement (previously it was only once per line) and
+ by skipping builtin macros when searching for an uppercase lead character.
+
Exim version 4.90
-----------------
diff --git a/src/src/exim.c b/src/src/exim.c
index 327a8ecfe..fe1b1c19d 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -1372,7 +1372,7 @@ whites[i] = NULL;
/* The list of commandline macros should be very short.
Accept the N*M complexity. */
-for (m = macros; m; m = m->next) if (m->command_line)
+for (m = macros_user; m; m = m->next) if (m->command_line)
{
found = FALSE;
for (w = whites; *w; ++w)
@@ -2422,14 +2422,14 @@ for (i = 1; i < argc; i++)
while (isspace(*s)) s++;
}
- for (m = macros; m; m = m->next)
+ for (m = macros_user; m; m = m->next)
if (Ustrcmp(m->name, name) == 0)
{
fprintf(stderr, "exim: duplicated -D in command line\n");
exit(EXIT_FAILURE);
}
- m = macro_create(string_copy(name), string_copy(s), TRUE);
+ m = macro_create(name, s, TRUE);
if (clmacro_count >= MAX_CLMACROS)
{
@@ -4988,7 +4988,7 @@ if (expansion_test)
/* Only admin users may see config-file macros this way */
- if (!admin_user) macros = mlast = NULL;
+ if (!admin_user) macros_user = macros = mlast = NULL;
/* Allow $recipients for this testing */
diff --git a/src/src/globals.c b/src/src/globals.c
index 762e889d1..bcc2a7a32 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -953,6 +953,7 @@ uschar *lookup_dnssec_authenticated = NULL;
int lookup_open_max = 25;
uschar *lookup_value = NULL;
+macro_item *macros_user = NULL;
uschar *mailstore_basename = NULL;
#ifdef WITH_CONTENT_SCAN
uschar *malware_name = NULL; /* Virus Name */
diff --git a/src/src/globals.h b/src/src/globals.h
index 766b8a42f..d6bc96a83 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -566,6 +566,7 @@ extern int lookup_open_max; /* Max lookup files to cache */
extern uschar *lookup_value; /* Value looked up from file */
extern macro_item *macros; /* Configuration macros */
+extern macro_item *macros_user; /* Non-builtin configuration macros */
extern macro_item *mlast; /* Last item in macro list */
extern uschar *mailstore_basename; /* For mailstore deliveries */
#ifdef WITH_CONTENT_SCAN
diff --git a/src/src/readconf.c b/src/src/readconf.c
index 5d519e996..cbbef6efd 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -599,8 +599,8 @@ return US"";
/* We have a new definition; append to the list.
Args:
- name Name of the macro. Must be in storage persistent past the call
- val Expansion result for the macro. Ditto persistence.
+ name Name of the macro; will be copied
+ val Expansion result for the macro; will be copied
*/
macro_item *
@@ -613,13 +613,15 @@ m->next = NULL;
m->command_line = command_line;
m->namelen = Ustrlen(name);
m->replen = Ustrlen(val);
-m->name = name;
-m->replacement = val;
+m->name = string_copy(name);
+m->replacement = string_copy(val);
if (mlast)
mlast->next = m;
else
macros = m;
mlast = m;
+if (!macros_user)
+ macros_user = m;
return m;
}
@@ -731,7 +733,7 @@ if (redef)
/* We have a new definition. */
else
- (void) macro_create(string_copy(name), string_copy(s), FALSE);
+ (void) macro_create(name, s, FALSE);
return TRUE;
}
@@ -741,7 +743,7 @@ return TRUE;
/* Process line for macros. The line is in big_buffer starting at offset len.
Expand big_buffer if needed. Handle definitions of new macros, and
-imacro expansions, rewriting the line in thw buffer.
+macro expansions, rewriting the line in the buffer.
Arguments:
len Offset in buffer of start of line
@@ -780,17 +782,21 @@ if (len == 0 && isupper(*s))
/* Skip leading chars which cannot start a macro name, to avoid multiple
pointless rescans in Ustrstr calls. */
-while (*s && !isupper(*s) && *s != '_') s++;
+while (*s && !isupper(*s) && !(*s == '_' && isupper(s[1]))) s++;
/* For each defined macro, scan the line (from after XXX= if present),
replacing all occurrences of the macro. */
*macro_found = FALSE;
-for (m = macros; m; m = m->next)
+if (*s) for (m = *s == '_' ? macros : macros_user; m; m = m->next)
{
uschar * p, *pp;
- uschar * t = s;
+ uschar * t;
+
+ while (*s && !isupper(*s) && !(*s == '_' && isupper(s[1]))) s++;
+ if (!*s) break;
+ t = s;
while ((p = Ustrstr(t, m->name)) != NULL)
{
int moveby;
@@ -824,7 +830,7 @@ for (m = macros; m; m = m->next)
}
Ustrncpy(p, m->replacement, m->replen);
t = p + m->replen;
- while (*t && !isupper(*t) && *t != '_') t++;
+ while (*t && !isupper(*t) && !(*t == '_' && isupper(t[1]))) t++;
*macro_found = TRUE;
}
}