Optimise scanning config for macros
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 16 Jul 2017 17:02:57 +0000 (18:02 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 16 Jul 2017 17:02:57 +0000 (18:02 +0100)
src/src/exim.c
src/src/macro_predef.c
src/src/readconf.c
src/src/structs.h

index 42cb710ebb3439dfe79073c0289d9e4689704687..0285e162a2bfad4a08206ce2ad1bcdefda266f8d 100644 (file)
@@ -1443,10 +1443,9 @@ for (m = macros; m; m = m->next) if (m->command_line)
       }
   if (!found)
     return FALSE;
-  if (m->replacement == NULL)
+  if (!m->replacement)
     continue;
-  len = Ustrlen(m->replacement);
-  if (len == 0)
+  if ((len = m->replen) == 0)
     continue;
   n = pcre_exec(regex_whitelisted_macro, NULL, CS m->replacement, len,
    0, PCRE_EOPT, NULL, 0);
index 5ba237929e8d59d54ff6d7e006d7469a71f5ad9e..59579a373f2bf2f683a6deb93152d2149c08121e 100644 (file)
@@ -29,7 +29,7 @@ if (mp_index == 0)
 else
   printf("&p%d,", mp_index-1);
 
-printf(" FALSE, %d, \"%s\", \"y\" };\n", Ustrlen(name), CS name);
+printf(" FALSE, %d, 1, \"%s\", \"y\" };\n", Ustrlen(name), CS name);
 mp_index++;
 }
 
index 53f815d53f5a80ed9a6126a259e3e4631449f2ee..df3fe823cbf527541eaef8457136576f5852992f 100644 (file)
@@ -604,13 +604,13 @@ Args:
 macro_item *
 macro_create(const uschar * name, const uschar * val, BOOL command_line)
 {
-unsigned namelen = Ustrlen(name);
 macro_item * m = store_get(sizeof(macro_item));
 
 /* fprintf(stderr, "%s: '%s' '%s'\n", __FUNCTION__, name, val); */
 m->next = NULL;
 m->command_line = command_line;
-m->namelen = namelen;
+m->namelen = Ustrlen(name);
+m->replen = Ustrlen(val);
 m->name = name;
 m->replacement = val;
 mlast->next = m;
@@ -701,7 +701,10 @@ if (m && m->command_line) return;
 
 if (redef)
   if (m)
+    {
+    m->replen = Ustrlen(s);
     m->replacement = string_copy(s);
+    }
   else
     log_write(0, LOG_CONFIG|LOG_PANIC_DIE, "can't redefine an undefined macro "
       "\"%s\"", name);
@@ -825,24 +828,28 @@ for (;;)
     if (*s != '=') s = ss;          /* Not a macro definition */
     }
 
+  /* Skip leading chars which cannot start a macro name, to avoid multiple
+  pointless rescans in Ustrstr calls. */
+
+  while (*s && !isupper(*s) && *s != '_') 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)
     {
-    uschar *p, *pp;
-    uschar *t = s;
+    uschar * p, *pp;
+    uschar * t = s;
 
     while ((p = Ustrstr(t, m->name)) != NULL)
       {
       int moveby;
-      int replen = Ustrlen(m->replacement);
 
-/* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, t); */
+/* fprintf(stderr, "%s: matched '%s' in '%s'\n", __FUNCTION__, m->name, ss); */
       /* Expand the buffer if necessary */
 
-      while (newlen - m->namelen + replen + 1 > big_buffer_size)
+      while (newlen - m->namelen + m->replen + 1 > big_buffer_size)
         {
         int newsize = big_buffer_size + BIG_BUFFER_SIZE;
         uschar *newbuffer = store_malloc(newsize);
@@ -861,13 +868,14 @@ for (;;)
       same macro. */
 
       pp = p + m->namelen;
-      if ((moveby = replen - m->namelen) != 0)
+      if ((moveby = m->replen - m->namelen) != 0)
         {
-        memmove(p + replen, pp, (big_buffer + newlen) - pp + 1);
+        memmove(p + m->replen, pp, (big_buffer + newlen) - pp + 1);
         newlen += moveby;
         }
-      Ustrncpy(p, m->replacement, replen);
-      t = p + replen;
+      Ustrncpy(p, m->replacement, m->replen);
+      t = p + m->replen;
+      while (*t && !isupper(*t) && *t != '_') t++;
       macro_found = TRUE;
       }
     }
index 14d109869ec4ceb67972f1e6f2cf4b365d67a6aa..885c1b50047e41f9ac8a412ff8f24ff1b4693e81 100644 (file)
@@ -31,6 +31,7 @@ typedef struct macro_item {
   struct  macro_item * next;
   BOOL         command_line;
   unsigned     namelen;
+  unsigned     replen;
   const uschar * name;
   const uschar * replacement;
 } macro_item;