Testsuite: perl version oddity
[exim.git] / src / src / match.c
index 07070362df3199f2956aceee614810c33b3bc831..956ce60ad01af635b38b3670ca13436d8c71225e 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) The Exim Maintainers 2020 - 2022 */
+/* Copyright (c) The Exim Maintainers 2020 - 2023 */
 /* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
 /* SPDX-License-Identifier: GPL-2.0-or-later */
@@ -194,27 +194,23 @@ if (cb->flags & MCS_AT_SPECIAL && pattern[0] == '@')
     {
     int rc;
     host_item h;
-    BOOL prim = FALSE;
-    BOOL secy = FALSE;
-    BOOL removed = FALSE;
+    BOOL prim = FALSE, secy = FALSE, removed = FALSE;
     const uschar *ss = pattern + 4;
     const uschar *ignore_target_hosts = NULL;
 
-    if (strncmpic(ss, US"any", 3) == 0) ss += 3;
+    if (strncmpic(ss, US"any", 3) == 0)
+      ss += 3;
     else if (strncmpic(ss, US"primary", 7) == 0)
-      {
-      ss += 7;
-      prim = TRUE;
-      }
+      { ss += 7; prim = TRUE; }
     else if (strncmpic(ss, US"secondary", 9) == 0)
-      {
-      ss += 9;
-      secy = TRUE;
-      }
-    else goto NOT_AT_SPECIAL;
+      { ss += 9; secy = TRUE; }
+    else
+      goto NOT_AT_SPECIAL;
 
-    if (strncmpic(ss, US"/ignore=", 8) == 0) ignore_target_hosts = ss + 8;
-    else if (*ss) goto NOT_AT_SPECIAL;
+    if (strncmpic(ss, US"/ignore=", 8) == 0)
+      ignore_target_hosts = ss + 8;
+    else if (*ss)
+      goto NOT_AT_SPECIAL;
 
     h.next = NULL;
     h.name = s;
@@ -431,24 +427,24 @@ unsigned int * original_cache_bits = *cache_ptr;
 BOOL include_unknown = FALSE, ignore_unknown = FALSE,
       include_defer = FALSE, ignore_defer = FALSE;
 const uschar * list;
-uschar * sss;
-uschar * ot = NULL;
+uschar * ot = NULL, * sss;
 BOOL textonly_re;
 
 /* Save time by not scanning for the option name when we don't need it. */
 
 HDEBUG(D_any)
   {
-  uschar * listname = readconf_find_option(listptr);
+  const uschar * listname = readconf_find_option(listptr);
   if (*listname) ot = string_sprintf("%s in %s?", name, listname);
   }
 
-/* If the list is empty, the answer is no. Skip the debugging output for
-an unnamed list. */
+/* If the list is empty, the answer is no. */
 
 if (!*listptr)
   {
-  HDEBUG(D_lists) if (ot) debug_printf_indent("%s no (option unset)\n", ot);
+  HDEBUG(D_lists)
+    if (ot) debug_printf_indent("%s no (option unset)\n", ot);
+    else    debug_printf_indent("%s not in empty list (option unset? cannot trace name)\n", name);
   return FAIL;
   }
 
@@ -505,7 +501,7 @@ if (textonly_re) switch (type)
 #define LIST_LIMIT_PR 2048
 
 HDEBUG(D_any) if (!ot)
-  {
+  {    /* We failed to identify an option name, so give the list text */
   int n, m;
   gstring * g = string_fmt_append(NULL, "%s in \"%n%.*s%n\"",
     name, &n, LIST_LIMIT_PR, list, &m);
@@ -527,7 +523,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
   {
   uschar * ss = sss;
 
-  HDEBUG(D_lists) debug_printf_indent("list element: %s\n", ss);
+  HDEBUG(D_lists) debug_printf_indent("list element: %W\n", ss);
 
   /* Address lists may contain +caseful, to restore caseful matching of the
   local part. We have to know the layout of the control block, unfortunately.
@@ -599,7 +595,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
   if (*ss == '!')
     {
     yield = FAIL;
-    while (isspace((*(++ss))));
+    while (isspace(*++ss)) ;
     }
   else
     yield = OK;
@@ -618,7 +614,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
       namedlist_block * nb;
       tree_node * t;
 
-      DEBUG(D_lists)
+      HDEBUG(D_lists)
        { debug_printf_indent(" start sublist %s\n", ss+1); expand_level += 2; }
 
       if (!(t = tree_search(*anchorptr, ss+1)))
@@ -655,7 +651,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
         {
         int res = match_check_list(&(nb->string), 0, anchorptr, &use_cache_bits,
                 func, arg, type, name, valueptr);
-       DEBUG(D_lists)
+       HDEBUG(D_lists)
          { expand_level -= 2; debug_printf_indent(" end sublist %s\n", ss+1); }
 
         switch (res)
@@ -695,7 +691,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
             p->next = nb->cache_data;
             nb->cache_data = p;
             if (*valueptr)
-              DEBUG(D_lists) debug_printf_indent("data from lookup saved for "
+              HDEBUG(D_lists) debug_printf_indent("data from lookup saved for "
                 "cache for %s: key '%s' value '%s'\n", ss, p->key, *valueptr);
             }
           }
@@ -707,7 +703,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
 
       else
         {
-        DEBUG(D_lists)
+        HDEBUG(D_lists)
          {
          expand_level -= 2;
          debug_printf_indent("cached %s match for %s\n",
@@ -725,7 +721,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
               *valueptr = p->data;
               break;
               }
-          DEBUG(D_lists) debug_printf_indent("cached lookup data = %s\n", *valueptr);
+          HDEBUG(D_lists) debug_printf_indent("cached lookup data = %s\n", *valueptr);
           }
         }
 
@@ -749,7 +745,7 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
         {
         case OK:
          HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\")\n", ot,
-           (yield == OK)? "yes" : "no", sss);
+           yield == OK ? "yes" : "no", sss);
          goto YIELD_RETURN;
 
         case DEFER:
@@ -757,8 +753,8 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
            error = string_sprintf("DNS lookup of \"%s\" deferred", ss);
          if (ignore_defer)
            {
-           HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_defer\n",
-             error);
+           HDEBUG(D_lists)
+             debug_printf_indent("%s: item ignored by +ignore_defer\n", error);
            break;
            }
          if (include_defer)
@@ -777,8 +773,8 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
         case ERROR:
          if (ignore_unknown)
            {
-           HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_unknown\n",
-             error);
+           HDEBUG(D_lists) debug_printf_indent(
+             "%s: item ignored by +ignore_unknown\n", error);
            }
          else
            {
@@ -812,8 +808,8 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
 
     if (!f)
       {
-      uschar * listname = readconf_find_option(listptr);
-      if (listname[0] == 0)
+      const uschar * listname = readconf_find_option(listptr);
+      if (!*listname)
         listname = string_sprintf("\"%s\"", *listptr);
       log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s",
         string_open_failed("%s when checking %s", sss, listname));
@@ -825,15 +821,14 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
 
     while (Ufgets(filebuffer, sizeof(filebuffer), f) != NULL)
       {
-      uschar *error;
-      uschar *sss = filebuffer;
+      uschar * error, * sss = filebuffer;
 
       while ((ss = Ustrchr(sss, '#')) != NULL)
         {
         if ((type != MCL_ADDRESS && type != MCL_LOCALPART) ||
               ss == filebuffer || isspace(ss[-1]))
           {
-          *ss = 0;
+          *ss = '\0';
           break;
           }
         sss = ss + 1;
@@ -841,28 +836,27 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
 
       ss = filebuffer + Ustrlen(filebuffer);           /* trailing space */
       while (ss > filebuffer && isspace(ss[-1])) ss--;
-      *ss = 0;
+      *ss = '\0';
 
       ss = filebuffer;
-      while (isspace(*ss)) ss++;                       /* leading space */
-
-      if (!*ss) continue;                              /* ignore empty */
+      if (!Uskip_whitespace(&ss))                      /* leading space */
+       continue;                                       /* ignore empty */
 
       file_yield = yield;                              /* positive yield */
       sss = ss;                                                /* for debugging */
 
       if (*ss == '!')                                  /* negation */
         {
-        file_yield = (file_yield == OK)? FAIL : OK;
-        while (isspace((*(++ss))));
+        file_yield = file_yield == OK ? FAIL : OK;
+        while (isspace(*++ss)) ;
         }
 
       switch ((func)(arg, ss, valueptr, &error))
         {
         case OK:
          (void)fclose(f);
-         HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\" in %s)\n", ot,
-           yield == OK ? "yes" : "no", sss, filename);
+         HDEBUG(D_lists) debug_printf_indent("%s %s (matched \"%s\" in %s)\n",
+           ot, yield == OK ? "yes" : "no", sss, filename);
 
          /* The "pattern" being matched came from the file; we use a stack-local.
          Copy it to allocated memory now we know it matched. */
@@ -876,8 +870,8 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
            error = string_sprintf("DNS lookup of %s deferred", ss);
          if (ignore_defer)
            {
-           HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_defer\n",
-             error);
+           HDEBUG(D_lists)
+             debug_printf_indent("%s: item ignored by +ignore_defer\n", error);
            break;
            }
          (void)fclose(f);
@@ -886,16 +880,21 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
          log_write(0, LOG_MAIN, "%s: accepted by +include_defer", error);
          goto OK_RETURN;
 
-        case ERROR:            /* host name lookup failed - this can only */
-         if (ignore_unknown)   /* be for an incoming host (not outgoing) */
+        /* The ERROR return occurs when checking hosts, when either a forward
+        or reverse lookup has failed. It can also occur in a match_ip list if a
+        non-IP address item is encountered. The error string gives details of
+        which it was. */
+
+        case ERROR:
+         if (ignore_unknown)
            {
-           HDEBUG(D_lists) debug_printf_indent("%s: item ignored by +ignore_unknown\n",
-             error);
+           HDEBUG(D_lists) debug_printf_indent(
+             "%s: item ignored by +ignore_unknown\n", error);
            }
          else
-          {
+           {
            HDEBUG(D_lists) debug_printf_indent("%s %s (%s)\n", ot,
-             include_unknown? "yes":"no", error);
+             include_unknown ? "yes":"no", error);
            (void)fclose(f);
            if (!include_unknown)
              {
@@ -919,20 +918,19 @@ while ((sss = string_nextinlist(&list, &sep, NULL, 0)))
 
 /* End of list reached: if the last item was negated yield OK, else FAIL. */
 
-HDEBUG(D_lists)
-  HDEBUG(D_lists)
-    {
-    expand_level--;
-    debug_printf_indent("%s %s (end of list)\n", ot, yield == OK ? "no":"yes");
-    }
-  return yield == OK ? FAIL : OK;
-
+HDEBUG(D_any)
+  {
+  HDEBUG(D_lists) expand_level--;
+  debug_printf_indent("%s %s (end of list)\n", ot, yield == OK ? "no":"yes");
+  }
+return yield == OK ? FAIL : OK;
 /* Something deferred */
 
 DEFER_RETURN:
-  HDEBUG(D_lists)
+  HDEBUG(D_any)
     {
-    expand_level--;
+    HDEBUG(D_lists) expand_level--;
     debug_printf_indent("%s list match deferred for %s\n", ot, sss);
     }
   return DEFER;
@@ -1152,7 +1150,7 @@ if (pattern[0] == '@' && pattern[1] == '@')
       if (*ss == '!')
         {
         local_yield = FAIL;
-        while (isspace((*(++ss))));
+        while (isspace(*++ss)) ;
         }
       else local_yield = OK;
 
@@ -1387,3 +1385,5 @@ return match_address_list(address, TRUE, TRUE, listptr, NULL, -1, sep, NULL);
 }
 
 /* End of match.c */
+/* vi: aw ai sw=2
+*/