commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, master, updated. release-3.0-32-gdd3598a


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-3.0-32-gdd3598a
Date: Thu, 8 Dec 2016 08:48:22 +0000 (UTC)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=dd3598aa1d82c29132a24663781738fd321ceb8c

The branch, master has been updated
       via  dd3598aa1d82c29132a24663781738fd321ceb8c (commit)
      from  3895183977dee5585593cb1651db3ad4816a35a0 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit dd3598aa1d82c29132a24663781738fd321ceb8c
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Dec 8 07:49:12 2016 +0200

    sieve: fix the mu_sieve_vlist_compare API
    
    * libmu_sieve/util.c (mu_sieve_vlist_compare): Rewrite.
    * include/mailutils/sieve.h (mu_sieve_retrieve_t): Change signature.
    All uses changed.
    (mu_sieve_relational_count): Remove.
    (mu_sieve_vlist_compare): Change signature.
    * libmu_sieve/extensions/list.c (list_retrieve_header): Always
    return meaningful status.
    * libmu_sieve/tests.c (mu_sieve_relational_count): Remove.
    (retrieve_address,retrieve_envelope): Return meaningful status.
    (retrieve_header): Iterate over all mime parts, if required.
    (sieve_test_address,sieve_test_header): Rewrite.
    * libmu_sieve/variables.c (sieve_test_string): Rewrite using
    mu_sieve_vlist_compare.

-----------------------------------------------------------------------

Summary of changes:
 gint                          |    2 +-
 include/mailutils/sieve.h     |    9 +--
 libmu_sieve/extensions/list.c |   15 ++--
 libmu_sieve/tests.c           |  156 ++++++++++++++++++-----------------------
 libmu_sieve/util.c            |  119 +++++++++++++++++++++++--------
 libmu_sieve/variables.c       |   58 +++++++--------
 6 files changed, 201 insertions(+), 158 deletions(-)

diff --git a/gint b/gint
index fd86bf7..42f4712 160000
--- a/gint
+++ b/gint
@@ -1 +1 @@
-Subproject commit fd86bf7d44b0c970771830692ae7491447ebe8b1
+Subproject commit 42f4712085b40173eaea58e14b1a579291a6fe3a
diff --git a/include/mailutils/sieve.h b/include/mailutils/sieve.h
index 8dfa381..bbaccb5 100644
--- a/include/mailutils/sieve.h
+++ b/include/mailutils/sieve.h
@@ -51,7 +51,7 @@ typedef int (*mu_sieve_relcmp_t) (int, int);
 typedef int (*mu_sieve_relcmpn_t) (size_t, size_t);
 typedef int (*mu_sieve_comparator_t) (mu_sieve_machine_t mach,
                                      mu_sieve_string_t *, const char *);
-typedef int (*mu_sieve_retrieve_t) (void *item, void *data, int idx,
+typedef int (*mu_sieve_retrieve_t) (void *item, void *data, size_t idx,
                                    char **pval);
 typedef void (*mu_sieve_destructor_t) (void *data);
 typedef int (*mu_sieve_tag_checker_t) (mu_sieve_machine_t mach);
@@ -201,8 +201,6 @@ void mu_sieve_register_comparator (mu_sieve_machine_t mach, 
const char *name,
                                   mu_sieve_comparator_t eq);
 
 int mu_sieve_require_relational (mu_sieve_machine_t mach, const char *name);
-int mu_sieve_relational_count (mu_sieve_machine_t mach, size_t count,
-                              int retval);
   
 int mu_sieve_require_variables (mu_sieve_machine_t mach);
 int mu_sieve_has_variables (mu_sieve_machine_t mach);
@@ -254,9 +252,8 @@ int mu_sieve_vlist_do (mu_sieve_machine_t mach,
                       void *data);
 int mu_sieve_vlist_compare (mu_sieve_machine_t mach,
                            mu_sieve_value_t *a, mu_sieve_value_t *b,
-                           mu_sieve_comparator_t comp,
-                           mu_sieve_relcmp_t test, mu_sieve_retrieve_t ac,
-                           void *data, size_t *count);
+                           mu_sieve_retrieve_t ac, mu_list_folder_t fold,
+                           void *data);
 
 /* Functions to create and destroy sieve machine */
 int mu_sieve_machine_create (mu_sieve_machine_t *mach);
diff --git a/libmu_sieve/extensions/list.c b/libmu_sieve/extensions/list.c
index e31e763..91e4069 100644
--- a/libmu_sieve/extensions/list.c
+++ b/libmu_sieve/extensions/list.c
@@ -93,7 +93,7 @@ retrieve_next_header (struct header_closure *hc, char *name, 
char **pval)
 }
 
 static int
-list_retrieve_header (void *item, void *data, int idx, char **pval)
+list_retrieve_header (void *item, void *data, size_t idx, char **pval)
 {
   struct header_closure *hc = data;
   char *p;
@@ -106,7 +106,7 @@ list_retrieve_header (void *item, void *data, int idx, char 
**pval)
       if (!hc->valv)
        {
          if (retrieve_next_header (hc, (char*) item, &p))
-           return 1;
+           return MU_ERR_NOENT;
        }
       else if (hc->vali == hc->valc)
        {
@@ -117,11 +117,11 @@ list_retrieve_header (void *item, void *data, int idx, 
char **pval)
        p = hc->valv[hc->vali++];
   
       if ((*pval = strdup (p)) == NULL)
-        return 1;
+        return errno;
       return 0;
     }
   
-  return 1;
+  return MU_ERR_NOENT;
 }
 
 
@@ -148,7 +148,6 @@ static int
 list_test (mu_sieve_machine_t mach)
 {
   mu_sieve_value_t *h, *v;
-  mu_sieve_comparator_t comp = mu_sieve_get_comparator (mach);
   struct header_closure clos;
   int result;
 
@@ -159,10 +158,8 @@ list_test (mu_sieve_machine_t mach)
   h = mu_sieve_get_arg_untyped (mach, 0);
   v = mu_sieve_get_arg_untyped (mach, 1);
   mu_message_get_header (mu_sieve_get_message (mach), &clos.header);
-  result = mu_sieve_vlist_compare (mach, h, v, comp,
-                                  mu_sieve_get_relcmp (mach),
-                                  list_retrieve_header,
-                                  &clos, NULL) > 0;
+  result = mu_sieve_vlist_compare (mach, h, v, list_retrieve_header, NULL,
+                                  &clos);
   cleanup (&clos);
   return result; 
 }
diff --git a/libmu_sieve/tests.c b/libmu_sieve/tests.c
index e7b6406..ba0e6e6 100644
--- a/libmu_sieve/tests.c
+++ b/libmu_sieve/tests.c
@@ -55,35 +55,8 @@ struct address_closure
   mu_address_t addr;       /* Obtained address */
 };  
 
-int
-mu_sieve_relational_count (mu_sieve_machine_t mach, size_t count, int retval)
-{
-  char *relcmp;
-  
-  if (mu_sieve_get_tag (mach, "count", SVT_STRING, &relcmp))
-    {
-      size_t limit;
-      char *str, *p;
-      struct mu_sieve_slice slice;
-      mu_sieve_relcmpn_t stest;
-      
-      mu_sieve_get_arg (mach, 1, SVT_STRING_LIST, &slice);
-      str = mu_sieve_string (mach, &slice, 0);
-      limit = strtoul (str, &p, 10);
-      if (*p)
-       {
-         mu_sieve_error (mach, _("%s: not an integer"), str);
-         mu_sieve_abort (mach);
-       }
-
-      mu_sieve_str_to_relcmp (relcmp, NULL, &stest);
-      return stest (count, limit);
-    }
-  return retval;
-}
-
-int
-retrieve_address (void *item, void *data, int idx, char **pval)
+static int
+retrieve_address (void *item, void *data, size_t idx, char **pval)
 {
   struct address_closure *ap = data;
   char *val;
@@ -91,8 +64,9 @@ retrieve_address (void *item, void *data, int idx, char 
**pval)
       
   if (!ap->addr)
     {
-      if (mu_header_aget_value ((mu_header_t)ap->data, (char*)item, &val))
-       return 1;
+      rc = mu_header_aget_value ((mu_header_t)ap->data, (char*)item, &val);
+      if (rc)
+       return rc;
       rc = mu_address_create (&ap->addr, val);
       free (val);
       if (rc)
@@ -110,11 +84,8 @@ sieve_test_address (mu_sieve_machine_t mach)
 {
   mu_sieve_value_t *h, *v;
   mu_header_t header = NULL;
-  mu_sieve_comparator_t comp = mu_sieve_get_comparator (mach);
-  mu_sieve_relcmp_t test = mu_sieve_get_relcmp (mach);
   struct address_closure clos;
   int rc;
-  size_t count = 0;
   
   h = mu_sieve_get_arg_untyped (mach, 0);
   v = mu_sieve_get_arg_untyped (mach, 1);
@@ -123,89 +94,105 @@ sieve_test_address (mu_sieve_machine_t mach)
   clos.data = header;
   clos.aget = sieve_get_address_part (mach);
   clos.addr = NULL;
-  rc = mu_sieve_vlist_compare (mach, h, v, comp, test, retrieve_address, &clos,
-                              &count);
+  rc = mu_sieve_vlist_compare (mach, h, v, retrieve_address, NULL, &clos);
   mu_address_destroy (&clos.addr);
   
-  return mu_sieve_relational_count (mach, count, rc);
+  return rc;
 }
 
 struct header_closure
 {
+  mu_message_t message;
+  size_t nparts;
+  
+  size_t part;
   mu_header_t header;
-  int index;
+  size_t index;
 };
 
 int
-retrieve_header (void *item, void *data, int idx, char **pval)
+retrieve_header (void *item, void *data, size_t idx, char **pval)
 {
   struct header_closure *hc = data;
-  char buf[512];
-  size_t n;
+  char const *hname;
+  int rc;
   
   if (idx == 0)
-    hc->index = 1;
-
-  while (!mu_header_get_field_name (hc->header, hc->index, buf, sizeof(buf), 
&n))
     {
-      int i = hc->index++;
-      if (mu_c_strcasecmp (buf, (char*)item) == 0)
+      rc = mu_message_get_header (hc->message, &hc->header);
+      if (rc)
+       return rc;
+      hc->index = 1;
+      hc->part = 1;
+    }
+  
+  do
+    {
+      if (!hc->header)
        {
-         if (mu_header_aget_field_value_unfold (hc->header, i, pval))
+         if (hc->part <= hc->nparts)
+           {
+             mu_message_t msg;
+             rc = mu_message_get_part (hc->message, hc->part, &msg);
+             if (rc)
+               return rc;
+             hc->part++;
+             rc = mu_message_get_header (msg, &hc->header);
+             if (rc)
+               return rc;
+             hc->index = 1;
+           }
+         else
            return 1;
-         return 0;
        }
-    }
+  
+      while (!mu_header_sget_field_name (hc->header, hc->index, &hname))
+       {
+         int i = hc->index++;
+         if (mu_c_strcasecmp (hname, (char*)item) == 0)
+           {
+             if (mu_header_aget_field_value_unfold (hc->header, i, pval))
+               return -1;
+             return 0;
+           }
+       }
 
-  return 1;
+      hc->header = NULL;
+    }
+  while (hc->part <= hc->nparts);
+  
+  return MU_ERR_NOENT;
 }
 
 int
 sieve_test_header (mu_sieve_machine_t mach)
 {
   mu_sieve_value_t *h, *v;
-  mu_sieve_comparator_t comp = mu_sieve_get_comparator (mach);
-  mu_sieve_relcmp_t test = mu_sieve_get_relcmp (mach);
-  size_t count = 0, mcount = 0;
+  int rc;
   struct header_closure clos;
   
   h = mu_sieve_get_arg_untyped (mach, 0);
   v = mu_sieve_get_arg_untyped (mach, 1);
 
+  clos.message = mach->msg;
+  
   if (mu_sieve_get_tag (mach, "mime", SVT_VOID, NULL))
     {
       int ismime = 0;
 
       mu_message_is_multipart (mach->msg, &ismime);
       if (ismime)
-       {
-         size_t i, nparts = 0;
-         
-         mu_message_get_num_parts (mach->msg, &nparts);
-         for (i = 1; i <= nparts; i++)
-           {
-             mu_message_t message = NULL;
-
-             if (mu_message_get_part (mach->msg, i, &message) == 0)
-               {
-                 mu_message_get_header (message, &clos.header);
-                 if (mu_sieve_vlist_compare (mach, h, v, comp, test,
-                                          retrieve_header, &clos, &mcount))
-                   return 1;
-               }
-           }
-       }
+       mu_message_get_num_parts (mach->msg, &clos.nparts);
     }
-  mu_message_get_header (mach->msg, &clos.header);
-  if (mu_sieve_vlist_compare (mach, h, v, comp, test, retrieve_header, &clos,
-                             &count))
-    return 1;
-
-  return mu_sieve_relational_count (mach, count + mcount, 0);
+  else
+    clos.nparts = 0;
+  
+  rc = mu_sieve_vlist_compare (mach, h, v, retrieve_header, NULL, &clos);
+  return rc;
 }
 
 int
-retrieve_envelope (void *item, void *data, int idx, char **pval)
+retrieve_envelope (void *item, void *data, size_t idx, char **pval)
 {
   struct address_closure *ap = data;
   int rc;
@@ -215,10 +202,11 @@ retrieve_envelope (void *item, void *data, int idx, char 
**pval)
       const char *buf;
       
       if (mu_c_strcasecmp ((char*)item, "from") != 0)
-       return 1;
+       return MU_ERR_NOENT;
 
-      if (mu_envelope_sget_sender ((mu_envelope_t)ap->data, &buf))
-       return 1;
+      rc = mu_envelope_sget_sender ((mu_envelope_t)ap->data, &buf);
+      if (rc)
+       return rc;
 
       rc = mu_address_create (&ap->addr, buf);
       if (rc)
@@ -235,11 +223,8 @@ int
 sieve_test_envelope (mu_sieve_machine_t mach)
 {
   mu_sieve_value_t *h, *v;
-  mu_sieve_comparator_t comp = mu_sieve_get_comparator (mach);
-  mu_sieve_relcmp_t test = mu_sieve_get_relcmp (mach);
   struct address_closure clos;
   int rc;
-  size_t count = 0;
   
   h = mu_sieve_get_arg_untyped (mach, 0);
   v = mu_sieve_get_arg_untyped (mach, 1);
@@ -248,10 +233,9 @@ sieve_test_envelope (mu_sieve_machine_t mach)
                           (mu_envelope_t*)&clos.data);
   clos.aget = sieve_get_address_part (mach);
   clos.addr = NULL;
-  rc = mu_sieve_vlist_compare (mach, h, v, comp, test, retrieve_envelope, 
&clos,
-                              &count);
+  rc = mu_sieve_vlist_compare (mach, h, v, retrieve_envelope, NULL, &clos);
   mu_address_destroy (&clos.addr);
-  return mu_sieve_relational_count (mach, count, rc);
+  return rc;
 }
 
 int
diff --git a/libmu_sieve/util.c b/libmu_sieve/util.c
index 6716682..15a2ea7 100644
--- a/libmu_sieve/util.c
+++ b/libmu_sieve/util.c
@@ -358,49 +358,112 @@ mu_sieve_vlist_do (mu_sieve_machine_t mach, 
mu_sieve_value_t *val,
       return EINVAL;
     }
 }
-
+
 int
 mu_sieve_vlist_compare (mu_sieve_machine_t mach,
                        mu_sieve_value_t *a, mu_sieve_value_t *b,
-                       mu_sieve_comparator_t comp, mu_sieve_relcmp_t test,
-                       mu_sieve_retrieve_t retr,
-                       void *data, size_t *count)
+                       mu_sieve_retrieve_t retr, mu_list_folder_t fold,
+                       void *data)
 {
   int rc = 0;
   size_t i;
+  mu_sieve_comparator_t comp = mu_sieve_get_comparator (mach);
+  mu_sieve_relcmp_t test = mu_sieve_get_relcmp (mach);
+  char *relcmp;
+  mu_list_t tmp;
   
-  switch (a->type)
+  if (!(a->type == SVT_STRING_LIST || a->type == SVT_STRING))
+    abort ();
+
+  rc = mu_list_create (&tmp);
+  if (rc)
     {
-    case SVT_STRING_LIST:
-    case SVT_STRING:
-      for (i = 0; i < a->v.list.count; i++)
+      mu_sieve_error (mach, "mu_list_create: %s", mu_strerror (rc));
+      mu_sieve_abort (mach);
+    }
+  mu_list_set_destroy_item (tmp, mu_list_free_item);
+  for (i = 0; i < a->v.list.count; i++)
+    {
+      char *item = mu_sieve_string (mach, &a->v.list, i);
+      char *sample;
+      size_t j;
+      
+      for (j = 0; (rc = retr (item, data, j, &sample)) == 0; j++)
        {
-         char *item = mu_sieve_string (mach, &a->v.list, i);
-         char *sample;
-         size_t j, k;
-  
-         for (j = 0; rc == 0 && retr (item, data, j, &sample) == 0; j++)
+         rc = mu_list_append (tmp, sample);
+         if (rc)
            {
-             if (count)
-               (*count)++;
-             for (k = 0; k < b->v.list.count; k++)
-               {
-                 mu_sieve_string_t *s = mu_sieve_string_raw (mach, &b->v.list, 
k);
-                 rc = test (comp (mach, s, sample), 0);
-                 if (rc)
-                   {
-                     free (sample);
-                     return rc;
-                   }
-               }
              free (sample);
+             mu_list_destroy (&tmp);
+             mu_sieve_error (mach, "mu_list_append: %s", mu_strerror (rc));
+             mu_sieve_abort (mach);
            }
        }
-      break;
+
+      if (rc != MU_ERR_NOENT)
+       {
+         mu_list_destroy (&tmp);
+         mu_sieve_error (mach, "retriever failure: %s", mu_strerror (rc));
+         mu_sieve_abort (mach);
+       }
+    }
+
+  if (mu_sieve_get_tag (mach, "count", SVT_STRING, &relcmp))
+    {
+      size_t limit;
+      size_t count;
+      mu_sieve_relcmpn_t stest;
+      struct mu_sieve_slice slice;
+      char *str, *p;
       
-    default:
-      abort ();
+      if (fold)
+       {
+         count = 0;
+         rc = mu_list_fold (tmp, fold, data, &count, &count);
+         if (rc)
+           {
+             mu_sieve_error (mach, "mu_list_fold: %s", mu_strerror (rc));
+             mu_sieve_abort (mach);
+           }
+       }
+      else
+       mu_list_count (tmp, &count);
+      
+      mu_sieve_get_arg (mach, 1, SVT_STRING_LIST, &slice);
+      str = mu_sieve_string (mach, &slice, 0);
+      limit = strtoul (str, &p, 10);
+      if (*p)
+       {
+         mu_sieve_error (mach, _("%s: not an integer"), str);
+         mu_sieve_abort (mach);
+       }
+
+      mu_sieve_str_to_relcmp (relcmp, NULL, &stest);
+      rc = stest (count, limit);
+    }
+  else
+    {
+      mu_iterator_t itr;
+      
+      mu_list_get_iterator (tmp, &itr);
+      rc = 0;
+      for (mu_iterator_first (itr); rc == 0 && !mu_iterator_is_done (itr);
+          mu_iterator_next (itr))
+       {
+         char const *val;
+         mu_iterator_current (itr, (void**)&val);
+         
+         for (i = 0; i < b->v.list.count; i++)
+           {
+             mu_sieve_string_t *s = mu_sieve_string_raw (mach, &b->v.list, i);
+             rc = test (comp (mach, s, val), 0);
+             if (rc)
+               break;
+           }
+       }
+      mu_iterator_destroy (&itr);
     }
+  mu_list_destroy (&tmp);
   return rc;
 }
 
diff --git a/libmu_sieve/variables.c b/libmu_sieve/variables.c
index 5c6ddac..3474577 100644
--- a/libmu_sieve/variables.c
+++ b/libmu_sieve/variables.c
@@ -243,43 +243,45 @@ static mu_sieve_data_type set_args[] = {
   SVT_VOID
 };
 
+static int
+retrieve_string (void *item, void *data, size_t idx, char **pval)
+{
+  if (idx)
+    return MU_ERR_NOENT;
+  *pval = strdup ((char*)item);
+  if (!*pval)
+    return errno;
+  return 0;
+}
+
+int
+fold_string (void *item, void *data, void *prev, void **ret)
+{
+  char *str = item;
+  size_t count = *(size_t*) prev;
+
+  /* The "relational" extension [RELATIONAL] adds a match type called
+     ":count".  The count of a single string is 0 if it is the empty
+     string, or 1 otherwise.  The count of a string list is the sum of the
+     counts of the member strings.
+  */
+  if (*str)
+    ++count;
+  *(size_t*)ret = count;
+  return 0;
+}
+    
 /* RFC 5229, 5. Test string */
 int
 sieve_test_string (mu_sieve_machine_t mach)
 {
   mu_sieve_value_t *source, *key_list;
-  mu_sieve_comparator_t comp = mu_sieve_get_comparator (mach);
-  mu_sieve_relcmp_t test = mu_sieve_get_relcmp (mach);
-  size_t count = 0;
-  int rc = 0;
-  size_t i;
   
   source = mu_sieve_get_arg_untyped (mach, 0);
   key_list = mu_sieve_get_arg_untyped (mach, 1);
 
-  for (i = 0; i < source->v.list.count; i++)
-    {
-      char *item = mu_sieve_string (mach, &source->v.list, i);
-      size_t k;
-
-      /* The "relational" extension [RELATIONAL] adds a match type called
-        ":count".  The count of a single string is 0 if it is the empty
-        string, or 1 otherwise.  The count of a string list is the sum of the
-        counts of the member strings.
-      */
-      if (item[0])
-       count++;
-      for (k = 0; k < key_list->v.list.count; k++)
-       {
-         mu_sieve_string_t *s =
-           mu_sieve_string_raw (mach, &key_list->v.list, k);
-         rc = test (comp (mach, s, item), 0);
-         if (rc)
-           return rc;
-       }
-    }
-
-  return mu_sieve_relational_count (mach, count, 0);
+  return mu_sieve_vlist_compare (mach, source, key_list,
+                                retrieve_string, fold_string, mach);
 }
 
 mu_sieve_data_type string_args[] = {


hooks/post-receive
-- 
GNU Mailutils



reply via email to

[Prev in Thread] Current Thread [Next in Thread]