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-15-g1528dfd


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-3.0-15-g1528dfd
Date: Sun, 27 Nov 2016 18:43:21 +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=1528dfded819e3c8ccba459425b0dc18b1f3a722

The branch, master has been updated
       via  1528dfded819e3c8ccba459425b0dc18b1f3a722 (commit)
       via  56217f1e53ebd0527b0fa1457c0b214d0ea76fd6 (commit)
      from  f5a1ff9b5a2caa67c1bee2cbf4a00dc4f7946bb4 (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 1528dfded819e3c8ccba459425b0dc18b1f3a722
Author: Sergey Poznyakoff <address@hidden>
Date:   Sat Nov 26 10:54:48 2016 +0200

    sieve: improve argument/tag runtime access API
    
    * include/mailutils/sieve.h (mu_sieve_data_type): Remove SVT_VALUE_LIST.
    (mu_sieve_value_storage): Named union for use in mu_sieve_value_t; remove
    the tag field.
    (mu_sieve_tag_lookup): Change prototype.
    (mu_sieve_value_get): Change prototype.
    (mu_sieve_value_get_optional)
    (mu_sieve_value_get_untyped): New functions.
    (mu_sieve_arg_error): Removed proto.
    
    * libmu_sieve/sieve.y: Remove SVT_VALUE_LIST support.
    * libmu_sieve/util.c (mu_sieve_value_create)
    (mu_sieve_type_str,mu_sieve_vlist_do): Remove SVT_VALUE_LIST support.
    (mu_sieve_value_get): Rewrite.
    (mu_sieve_value_get_untyped)
    (mu_sieve_value_get_optional): New functions.
    (mu_sieve_arg_error): Remove.
    (mu_sieve_tag_lookup): Rewrite.
    (mu_sieve_tag_lookup_untyped): New function.
    
    * doc/texinfo/libmu_sieve.texi: Update.
    
    libmu_sieve/tests.c
    libmu_sieve/actions.c
    libmu_sieve/extensions/editheader.c
    libmu_sieve/extensions/list.c
    libmu_sieve/extensions/moderator.c
    libmu_sieve/extensions/pipe.c
    libmu_sieve/extensions/spamd.c
    libmu_sieve/extensions/timestamp.c
    libmu_sieve/extensions/vacation.c
    libmu_sieve/relational.c
    
    examples/numaddr.c

commit 56217f1e53ebd0527b0fa1457c0b214d0ea76fd6
Author: Sergey Poznyakoff <address@hidden>
Date:   Sat Nov 26 08:01:13 2016 +0200

    Minor fixes
    
    * libmu_sieve/sieve-priv.h (sieve_op_t) <unum>: New field.
    * libmu_sieve/sieve.l: Leave one string interpreter slot.

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

Summary of changes:
 doc/texinfo/libmu_sieve.texi        |    4 --
 examples/numaddr.c                  |   19 ++-----
 gint                                |    2 +-
 include/mailutils/sieve.h           |   39 +++++++++------
 libmu_sieve/actions.c               |   45 +++++++----------
 libmu_sieve/comparator.c            |    3 +-
 libmu_sieve/extensions/editheader.c |   44 +++-------------
 libmu_sieve/extensions/list.c       |   21 ++------
 libmu_sieve/extensions/moderator.c  |   18 +++----
 libmu_sieve/extensions/pipe.c       |   27 ++++------
 libmu_sieve/extensions/spamd.c      |   27 +++++-----
 libmu_sieve/extensions/timestamp.c  |   25 +++-------
 libmu_sieve/extensions/vacation.c   |   60 +++++++++-------------
 libmu_sieve/relational.c            |    6 +--
 libmu_sieve/sieve-priv.h            |    1 +
 libmu_sieve/sieve.l                 |   48 +++++++-----------
 libmu_sieve/sieve.y                 |    6 ---
 libmu_sieve/tests.c                 |   94 +++++++++++------------------------
 libmu_sieve/util.c                  |   94 +++++++++++++++++++++++++++++------
 19 files changed, 249 insertions(+), 334 deletions(-)

diff --git a/doc/texinfo/libmu_sieve.texi b/doc/texinfo/libmu_sieve.texi
index d4c4451..1d673a8 100644
--- a/doc/texinfo/libmu_sieve.texi
+++ b/doc/texinfo/libmu_sieve.texi
@@ -85,9 +85,6 @@ A sieve tag. See @code{mu_sieve_runtime_tag_t} below.
 @item SVT_IDENT
 A character string representing an identifier. 
 
address@hidden SVT_VALUE_LIST
-A @code{mu_list_t}. Each item in this list is of @code{mu_sieve_value_t} type.
-
 @item SVT_POINTER
 An opaque pointer.
 @end table
@@ -128,7 +125,6 @@ The numeric value is kept in @code{number} member.
 The string is kept in @code{string} member.
 
 @item SVT_STRING_LIST
address@hidden SVT_VALUE_LIST
 The list itself is pointed to by @code{list} member
 
 @item SVT_TAG
diff --git a/examples/numaddr.c b/examples/numaddr.c
index 66602ad..b073793 100644
--- a/examples/numaddr.c
+++ b/examples/numaddr.c
@@ -80,37 +80,26 @@ _count_items (void *item, void *data)
 static int
 numaddr_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
 {
-  mu_sieve_value_t *h, *v;
+  mu_sieve_value_t *h;
   struct val_ctr vc;
   int rc;
   
   /* Retrieve required arguments: */
   /* First argument: list of header names */
-  h = mu_sieve_value_get (args, 0);
-  if (!h)
-    {
-      mu_sieve_error (mach, "numaddr: can't get argument 1");
-      mu_sieve_abort (mach);
-    }
+  h = mu_sieve_value_get_untyped (mach, args, 0);
   /* Second argument: Limit on the number of addresses */
-  v = mu_sieve_value_get (args, 1);
-  if (!v)
-    {
-      mu_sieve_error (mach, "numaddr: can't get argument 2");
-      mu_sieve_abort (mach);
-    }
+  mu_sieve_value_get (mach, args, 1, SVT_NUMBER, &vc.limit);
 
   /* Fill in the val_ctr structure */
   mu_message_get_header (mu_sieve_get_message (mach), &vc.hdr);
   vc.count = 0;
-  vc.limit = v->v.number;
 
   /* Count the addresses */
   rc = mu_sieve_vlist_do (h, _count_items, &vc);
 
   /* Here rc >= 1 iff the counted number of addresses is greater or equal
      to vc.limit. If `:under' tag was given we reverse the return value */
-  if (mu_sieve_tag_lookup (tags, "under", NULL))
+  if (mu_sieve_tag_lookup (mach, tags, "under", SVT_VOID, NULL))
     rc = !rc;
 
   return rc;
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 019ee61..4fc91c2 100644
--- a/include/mailutils/sieve.h
+++ b/include/mailutils/sieve.h
@@ -57,24 +57,24 @@ typedef enum
   SVT_STRING_LIST,
   SVT_TAG,
   SVT_IDENT,
-  SVT_VALUE_LIST,
   SVT_POINTER
 }
 mu_sieve_data_type;
 
 typedef struct mu_sieve_runtime_tag mu_sieve_runtime_tag_t;
 
+union mu_sieve_value_storage
+{
+  char *string;
+  size_t number;
+  mu_list_t list;
+  void *ptr;
+};
+
 typedef struct
 {
   mu_sieve_data_type type;
-  union
-  {
-    char *string;
-    size_t number;
-    mu_list_t list;
-    mu_sieve_runtime_tag_t *tag;
-    void *ptr;
-  } v;
+  union mu_sieve_value_storage v;
 } mu_sieve_value_t;
 
 typedef struct
@@ -184,8 +184,12 @@ mu_sieve_relcmp_t mu_sieve_get_relcmp (mu_sieve_machine_t 
mach,
 
 void mu_sieve_require (mu_sieve_machine_t mach, mu_list_t slist);
 
-int mu_sieve_tag_lookup (mu_list_t taglist, char *name,
-                        mu_sieve_value_t ** arg);
+int mu_sieve_tag_lookup (mu_sieve_machine_t mach,
+                        mu_list_t taglist, char *name,
+                        mu_sieve_data_type type, void *ret);
+int mu_sieve_tag_lookup_untyped (mu_sieve_machine_t mach, mu_list_t taglist,
+                                char *name, mu_sieve_value_t **ret);
+  
 int mu_sieve_load_ext (mu_sieve_machine_t mach, const char *name);
 int mu_sieve_match_part_checker (mu_sieve_machine_t mach,
                                 const char *name, mu_list_t tags,
@@ -193,8 +197,16 @@ int mu_sieve_match_part_checker (mu_sieve_machine_t mach,
 int mu_sieve_match_part_checker (mu_sieve_machine_t mach,
                                 const char *name, mu_list_t tags,
                                 mu_list_t args);
-/* Operations in value lists */
-mu_sieve_value_t *mu_sieve_value_get (mu_list_t vlist, size_t index);
+/* Operations on value lists */
+mu_sieve_value_t *mu_sieve_value_get_optional (mu_sieve_machine_t mach,
+                                              mu_list_t vlist,
+                                              size_t index);
+mu_sieve_value_t *mu_sieve_value_get_untyped (mu_sieve_machine_t mach,
+                                             mu_list_t vlist,
+                                             size_t index);
+int mu_sieve_value_get (mu_sieve_machine_t mach, mu_list_t vlist,
+                       size_t index,
+                       mu_sieve_data_type type, void *ret);
 int mu_sieve_vlist_do (mu_sieve_value_t *val, mu_list_action_t ac,
                       void *data);
 int mu_sieve_vlist_compare (mu_sieve_value_t *a, mu_sieve_value_t *b,
@@ -251,7 +263,6 @@ void mu_sieve_log_action (mu_sieve_machine_t mach, const 
char *action,
                          const char *fmt, ...)
                          MU_PRINTFLIKE(3,4);
 void mu_sieve_abort (mu_sieve_machine_t mach);
-void mu_sieve_arg_error (mu_sieve_machine_t mach, int n);
 
 int mu_sieve_is_dry_run (mu_sieve_machine_t mach);
 const char *mu_sieve_type_str (mu_sieve_data_type type);
diff --git a/libmu_sieve/actions.c b/libmu_sieve/actions.c
index 84bd368..f6c37f7 100644
--- a/libmu_sieve/actions.c
+++ b/libmu_sieve/actions.c
@@ -79,32 +79,29 @@ sieve_action_fileinto (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
 {
   int rc;
   int mbflags = 0;
-  mu_sieve_value_t *opt;
-  mu_sieve_value_t *val = mu_sieve_value_get (args, 0);
-  if (!val)
-    {
-      mu_sieve_error (mach, _("cannot get filename!"));
-      mu_sieve_abort (mach);
-    }
+  char *filename;
+  char *perms;
 
-  if (mu_sieve_tag_lookup (tags, "permissions", &opt))
+  mu_sieve_value_get (mach, args, 0, SVT_STRING, &filename);
+
+  if (mu_sieve_tag_lookup (mach, tags, "permissions", SVT_STRING, &perms))
     {
       const char *p;
       
-      if (mu_parse_stream_perm_string (&mbflags, opt->v.string, &p))
+      if (mu_parse_stream_perm_string (&mbflags, perms, &p))
        {
          /* Should not happen, but anyway... */
          mu_sieve_error (mach, _("invalid permissions (near %s)"), p);
-         return 1;
+         mu_sieve_abort (mach);
        }
     }
   
   mu_sieve_log_action (mach, "FILEINTO",
-                      _("delivering into %s"), val->v.string);
+                      _("delivering into %s"), filename);
   if (mu_sieve_is_dry_run (mach))
     return 0;
 
-  rc = mu_message_save_to_mailbox (mach->msg, val->v.string, mbflags);
+  rc = mu_message_save_to_mailbox (mach->msg, filename, mbflags);
   if (rc)
     mu_sieve_error (mach, _("cannot save to mailbox: %s"),
                    mu_strerror (rc));
@@ -293,18 +290,14 @@ sieve_action_reject (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
   char *addrtext;
   mu_address_t from, to;
   mu_header_t hdr;
+  char *text;
   
-  mu_sieve_value_t *val = mu_sieve_value_get (args, 0);
-  if (!val)
-    {
-      mu_sieve_error (mach, _("reject: cannot get text!"));
-      mu_sieve_abort (mach);
-    }
+  mu_sieve_value_get (mach, args, 0, SVT_STRING, &text);
   mu_sieve_log_action (mach, "REJECT", NULL);  
   if (mu_sieve_is_dry_run (mach))
     return 0;
 
-  rc = build_mime (&mime, mach->msg, val->v.string);
+  rc = build_mime (&mime, mach->msg, text);
 
   mu_mime_get_message (mime, &newmsg);
   mu_message_unref (newmsg);
@@ -413,25 +406,21 @@ sieve_action_redirect (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
   int rc;
   char *fromaddr, *p;
   mu_mailer_t mailer = mu_sieve_get_mailer (mach);
+  char *addrstr;
   
-  mu_sieve_value_t *val = mu_sieve_value_get (args, 0);
-  if (!val)
-    {
-      mu_sieve_error (mach, _("cannot get address!"));
-      mu_sieve_abort (mach);
-    }
+  mu_sieve_value_get (mach, args, 0, SVT_STRING, &addrstr);
 
-  rc = mu_address_create (&addr, val->v.string);
+  rc = mu_address_create (&addr, addrstr);
   if (rc)
     {
       mu_sieve_error (mach,
                      _("%lu: parsing recipient address `%s' failed: %s"),
                      (unsigned long) mu_sieve_get_message_num (mach),
-                     val->v.string, mu_strerror (rc));
+                     addrstr, mu_strerror (rc));
       return 1;
     }
   
-  mu_sieve_log_action (mach, "REDIRECT", _("to %s"), val->v.string);
+  mu_sieve_log_action (mach, "REDIRECT", _("to %s"), addrstr);
   if (mu_sieve_is_dry_run (mach))
     return 0;
 
diff --git a/libmu_sieve/comparator.c b/libmu_sieve/comparator.c
index d7be199..03fe403 100644
--- a/libmu_sieve/comparator.c
+++ b/libmu_sieve/comparator.c
@@ -288,8 +288,7 @@ mu_sieve_match_part_checker (mu_sieve_machine_t mach,
 
           matchtype = MU_SIEVE_MATCH_LAST; /* to not leave it undefined */
          compfun = comp_false;
-         val = mu_sieve_value_get (args, 1);
-         if (!val)
+         if (mu_list_get (args, 1, (void**) &val))
            return 1; /* shouldn't happen */
          /* NOTE: Type of v is always SVT_STRING_LIST */
          mu_list_count (val->v.list, &count);
diff --git a/libmu_sieve/extensions/editheader.c 
b/libmu_sieve/extensions/editheader.c
index ba4d0c0..4ec7c1d 100644
--- a/libmu_sieve/extensions/editheader.c
+++ b/libmu_sieve/extensions/editheader.c
@@ -33,32 +33,14 @@
 int
 sieve_addheader (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
 {
-  mu_sieve_value_t *val;
   const char *field_name;
   const char *field_value;
   mu_message_t msg;
   mu_header_t hdr;
   int rc;
   
-  val = mu_sieve_value_get (args, 0);
-  if (!val)
-    {
-      mu_sieve_error (mach, "%lu: %s",
-                     (unsigned long) mu_sieve_get_message_num (mach),
-                     _("cannot get field name"));
-      mu_sieve_abort (mach);
-    }
-  field_name = val->v.string;
-
-  val = mu_sieve_value_get (args, 1);
-  if (!val)
-    {
-      mu_sieve_error (mach, "%lu: %s",
-                     (unsigned long) mu_sieve_get_message_num (mach),
-                     _("cannot get field value"));
-      mu_sieve_abort (mach);
-    }
-  field_value = val->v.string;
+  mu_sieve_value_get (mach, args, 0, SVT_STRING, &field_name);
+  mu_sieve_value_get (mach, args, 1, SVT_STRING, &field_value);
 
   mu_sieve_log_action (mach, "ADDHEADER", "%s: %s", field_name, field_value);
 
@@ -76,7 +58,7 @@ sieve_addheader (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags)
       mu_sieve_abort (mach);
     }
 
-  rc = (mu_sieve_tag_lookup (tags, "last", NULL) ?
+  rc = (mu_sieve_tag_lookup (mach, tags, "last", SVT_VOID, NULL) ?
        mu_header_append : mu_header_prepend) (hdr, field_name, field_value);
   if (rc)
     {
@@ -105,19 +87,10 @@ sieve_deleteheader (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
   int rc;
   mu_sieve_comparator_t comp;
   mu_iterator_t itr;
-  unsigned long i, idx = 0;
+  size_t i, idx = 0;
   
-  val = mu_sieve_value_get (args, 0);
-  if (!val)
-    {
-      mu_sieve_error (mach, "%lu: %s",
-                     (unsigned long) mu_sieve_get_message_num (mach),
-                     _("cannot get field name"));
-      mu_sieve_abort (mach);
-    }
-  field_name = val->v.string;
-
-  val = mu_sieve_value_get (args, 1);
+  mu_sieve_value_get (mach, args, 0, SVT_STRING, &field_name);
+  val = mu_sieve_value_get_optional (mach, args, 1);
   if (!val)
     {
       field_pattern = NULL;
@@ -169,15 +142,14 @@ sieve_deleteheader (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
     }
 
   mu_header_get_iterator (hdr, &itr);
-  if (mu_sieve_tag_lookup (tags, "last", NULL))
+  if (mu_sieve_tag_lookup (mach, tags, "last", SVT_VOID, NULL))
     {
       int backwards = 1;
       mu_iterator_ctl (itr, mu_itrctl_set_direction, &backwards);
     }
   comp = mu_sieve_get_comparator (mach, tags);
 
-  if (mu_sieve_tag_lookup (tags, "index", &val))
-    idx = val->v.number;
+  mu_sieve_tag_lookup (mach, tags, "index", SVT_NUMBER, &idx);
   
   for (i = 0, mu_iterator_first (itr); !mu_iterator_is_done (itr);
        mu_iterator_next (itr))
diff --git a/libmu_sieve/extensions/list.c b/libmu_sieve/extensions/list.c
index ccde22d..fd18660 100644
--- a/libmu_sieve/extensions/list.c
+++ b/libmu_sieve/extensions/list.c
@@ -147,30 +147,17 @@ list_retrieve_header (void *item, void *data, int idx, 
char **pval)
 static int
 list_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
 {
-  mu_sieve_value_t *h, *v, *arg;
+  mu_sieve_value_t *h, *v;
   mu_sieve_comparator_t comp = mu_sieve_get_comparator (mach, tags);
   struct header_closure clos;
   int result;
 
   memset (&clos, 0, sizeof clos);
-  if (mu_sieve_tag_lookup (tags, "delim", &arg))
-    clos.delim = arg->v.string;
-  else
+  if (!mu_sieve_tag_lookup (mach, tags, "delim", SVT_STRING, &clos.delim))
     clos.delim = ",";
   
-  h = mu_sieve_value_get (args, 0);
-  if (!h)
-    {
-      mu_sieve_arg_error (mach, 1);
-      mu_sieve_abort (mach);
-    }
-  v = mu_sieve_value_get (args, 1);
-  if (!v)
-    {
-      mu_sieve_arg_error (mach, 2);
-      mu_sieve_abort (mach);
-    }
-
+  h = mu_sieve_value_get_untyped (mach, args, 0);
+  v = mu_sieve_value_get_untyped (mach, args, 1);
   mu_message_get_header (mu_sieve_get_message (mach), &clos.header);
   result = mu_sieve_vlist_compare (h, v, comp,
                                   mu_sieve_get_relcmp (mach, tags),
diff --git a/libmu_sieve/extensions/moderator.c 
b/libmu_sieve/extensions/moderator.c
index b19d0ed..7d16cef 100644
--- a/libmu_sieve/extensions/moderator.c
+++ b/libmu_sieve/extensions/moderator.c
@@ -80,9 +80,9 @@ moderator_filter_message (mu_sieve_machine_t mach, mu_list_t 
tags,
   int rc;
   mu_sieve_machine_t newmach;
   mu_attribute_t attr;
-  mu_sieve_value_t *arg;
+  char *arg;
   
-  if (mu_sieve_tag_lookup (tags, "source", &arg))
+  if (mu_sieve_tag_lookup (mach, tags, "source", SVT_STRING, &arg))
     {
       rc = mu_sieve_machine_inherit (mach, &newmach);
       if (rc)
@@ -97,11 +97,11 @@ moderator_filter_message (mu_sieve_machine_t mach, 
mu_list_t tags,
           ...
       */
       
-      rc = mu_sieve_compile (newmach, arg->v.string);
+      rc = mu_sieve_compile (newmach, arg);
       if (rc)
-       mu_sieve_error (mach, _("cannot compile source `%s'"), arg->v.string);
+       mu_sieve_error (mach, _("cannot compile source `%s'"), arg);
     }
-  else if (mu_sieve_tag_lookup (tags, "program", &arg))
+  else if (mu_sieve_tag_lookup (mach, tags, "program", SVT_STRING, &arg))
     {
       struct mu_locus locus;
       
@@ -114,7 +114,7 @@ moderator_filter_message (mu_sieve_machine_t mach, 
mu_list_t tags,
        }
       mu_sieve_get_locus (mach, &locus);
       rc = mu_sieve_compile_buffer (newmach,
-                                   arg->v.string, strlen (arg->v.string),
+                                   arg, strlen (arg),
                                    locus.mu_file, locus.mu_line);
       if (rc)
        mu_sieve_error (mach, _("cannot compile subprogram"));
@@ -303,7 +303,6 @@ moderator_action (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags)
     {
       mu_message_t request;
       char *from = NULL;
-      mu_sieve_value_t *arg;
       
       if ((rc = moderator_message_get_part (mach, msg, 3, &request)))
        {
@@ -312,14 +311,13 @@ moderator_action (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
          mu_sieve_abort (mach);
        }
 
-      if (mu_sieve_tag_lookup (tags, "address", &arg))
-       from = arg->v.string;
+      mu_sieve_tag_lookup (mach, tags, "address", SVT_STRING, &from);
       
       if (moderator_discard_message (mach, request, from))
        discard = 0;
       else
        {
-         if (!mu_sieve_tag_lookup (tags, "keep", NULL))
+         if (!mu_sieve_tag_lookup (mach, tags, "keep", SVT_VOID, NULL))
            {
              mu_attribute_t attr = 0;
 
diff --git a/libmu_sieve/extensions/pipe.c b/libmu_sieve/extensions/pipe.c
index 045c5a8..d7eaadd 100644
--- a/libmu_sieve/extensions/pipe.c
+++ b/libmu_sieve/extensions/pipe.c
@@ -87,7 +87,6 @@ sieve_pipe (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags, int test)
   int retval = 0;
   int rc, result;
   mu_message_t msg;
-  mu_sieve_value_t *val;
   char *cmd;
   mu_stream_t pstr;
   mu_envelope_t env;
@@ -95,15 +94,7 @@ sieve_pipe (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags, int test)
   const char *error_arg = NULL;
   int pipe_mask = 0;
   
-  val = mu_sieve_value_get (args, 0);
-  if (!val)
-    {
-      mu_sieve_error (mach, "%lu: %s",
-                     (unsigned long) mu_sieve_get_message_num (mach),
-                     _("cannot get command!"));
-      mu_sieve_abort (mach);
-    }
-  cmd = val->v.string;
+  mu_sieve_value_get (mach, args, 0, SVT_STRING, &cmd);
 
   if (mu_sieve_is_dry_run (mach))
     return 0;
@@ -111,11 +102,11 @@ sieve_pipe (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags, int test)
   msg = mu_sieve_get_message (mach);
   mu_message_get_envelope (msg, &env);
 
-  if (mu_sieve_tag_lookup (tags, "envelope", NULL))
+  if (mu_sieve_tag_lookup (mach, tags, "envelope", SVT_VOID, NULL))
     pipe_mask |= PIPE_ENVELOPE;
-  if (mu_sieve_tag_lookup (tags, "header", NULL))
+  if (mu_sieve_tag_lookup (mach, tags, "header", SVT_VOID, NULL))
     pipe_mask |= PIPE_HEADERS;
-  if (mu_sieve_tag_lookup (tags, "body", NULL))
+  if (mu_sieve_tag_lookup (mach, tags, "body", SVT_VOID, NULL))
     pipe_mask |= PIPE_BODY;
   if (pipe_mask == 0)
     pipe_mask = PIPE_ALL;
@@ -193,6 +184,7 @@ sieve_pipe (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags, int test)
     {
       int code = 0;
       int status;
+      size_t n;
       
       rc = mu_stream_ioctl (pstr, MU_IOCTL_PROGSTREAM,
                            MU_IOCTL_PROG_STATUS, &status);
@@ -202,8 +194,8 @@ sieve_pipe (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags, int test)
          mu_sieve_abort (mach);
        }
 
-      if (mu_sieve_tag_lookup (tags, "exit", &val))
-       code = val->v.number;
+      if (mu_sieve_tag_lookup (mach, tags, "exit", SVT_NUMBER, &n))
+       code = n;
       if (result == 0)
        retval = code == 0;
       else if (result == MU_ERR_PROCESS_EXITED)
@@ -211,8 +203,9 @@ sieve_pipe (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags, int test)
       else if (result == MU_ERR_PROCESS_SIGNALED)
        {
          int signo = WTERMSIG (status);
-         if (mu_sieve_tag_lookup (tags, "signal", &val))
-           retval = signo == val->v.number;
+         size_t n;
+         if (mu_sieve_tag_lookup (mach, tags, "signal", SVT_NUMBER, &n))
+           retval = signo == n;
          else
            {
              mu_stream_destroy (&pstr);
diff --git a/libmu_sieve/extensions/spamd.c b/libmu_sieve/extensions/spamd.c
index 290d8b8..4e5fea1 100644
--- a/libmu_sieve/extensions/spamd.c
+++ b/libmu_sieve/extensions/spamd.c
@@ -362,9 +362,10 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags)
   int result;
   long score, threshold, limit;
   mu_stream_t stream = NULL, null;
-  mu_sieve_value_t *arg;
   mu_message_t msg;
   char *host;
+  size_t num;
+  char *str;
   mu_header_t hdr;
   mu_debug_handle_t lev = 0;
   
@@ -380,15 +381,13 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags)
       mu_sieve_abort (mach);
     }
   
-  if (mu_sieve_tag_lookup (tags, "host", &arg))
-    host = arg->v.string;
-  else
+  if (!mu_sieve_tag_lookup (mach, tags, "host", SVT_STRING, &host))
     host = "127.0.0.1";
   
-  if (mu_sieve_tag_lookup (tags, "port", &arg))
-    result = spamd_connect_tcp (mach, &stream, host, arg->v.number);
-  else if (mu_sieve_tag_lookup (tags, "socket", &arg))
-    result = spamd_connect_socket (mach, &stream, arg->v.string);
+  if (mu_sieve_tag_lookup (mach, tags, "port", SVT_NUMBER, &num))
+    result = spamd_connect_tcp (mach, &stream, host, num);
+  else if (mu_sieve_tag_lookup (mach, tags, "socket", SVT_STRING, &str))
+    result = spamd_connect_socket (mach, &stream, str);
   else
     result = spamd_connect_tcp (mach, &stream, host, DEFAULT_SPAMD_PORT);
   if (result) /* spamd_connect_ already reported error */
@@ -422,8 +421,8 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags)
   spamd_send_command (stream, "SYMBOLS SPAMC/1.2");
   
   spamd_send_command (stream, "Content-length: %lu", (u_long) size);
-  if (mu_sieve_tag_lookup (tags, "user", &arg))
-    spamd_send_command (stream, "User: %s", arg);
+  if (mu_sieve_tag_lookup (mach, tags, "user", SVT_STRING, &str))
+    spamd_send_command (stream, "User: %s", str);
   else
     {
       struct mu_auth_data *auth = mu_get_auth_by_uid (geteuid ());
@@ -465,14 +464,14 @@ spamd_test (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags)
 
   if (!result)
     {
-      if (mu_sieve_tag_lookup (tags, "over", &arg))
+      if (mu_sieve_tag_lookup (mach, tags, "over", SVT_STRING, &str))
        {
-         decode_float (&limit, arg->v.string, 3, NULL);
+         decode_float (&limit, str, 3, NULL);
          result = score >= limit;
        }
-      else if (mu_sieve_tag_lookup (tags, "under", &arg))
+      else if (mu_sieve_tag_lookup (mach, tags, "under", SVT_STRING, &str))
        {
-         decode_float (&limit, arg->v.string, 3, NULL);
+         decode_float (&limit, str, 3, NULL);
          result = score <= limit;        
        }
     }
diff --git a/libmu_sieve/extensions/timestamp.c 
b/libmu_sieve/extensions/timestamp.c
index 56c12f2..dd29d1f 100644
--- a/libmu_sieve/extensions/timestamp.c
+++ b/libmu_sieve/extensions/timestamp.c
@@ -50,7 +50,8 @@
 static int
 timestamp_test (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags)
 {
-  mu_sieve_value_t *h, *v;
+  char const *hname;
+  char const *date;
   mu_header_t hdr;
   char *val;
   time_t now = time (NULL);
@@ -59,24 +60,14 @@ timestamp_test (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags)
   
   /* Retrieve required arguments: */
   /* First argument: header name */
-  h = mu_sieve_value_get (args, 0);
-  if (!h)
-    {
-      mu_sieve_arg_error (mach, 1);
-      mu_sieve_abort (mach);
-    }
+  mu_sieve_value_get (mach, args, 0, SVT_STRING, &hname);
   /* Second argument: date displacement */
-  v = mu_sieve_value_get (args, 1);
-  if (!v)
-    {
-      mu_sieve_arg_error (mach, 2);
-      mu_sieve_abort (mach);
-    }
+  mu_sieve_value_get (mach, args, 1, SVT_STRING, &date);
 
-  if (mu_parse_date (v->v.string, &tlimit, &now))
+  if (mu_parse_date (date, &tlimit, &now))
     {
       mu_sieve_error (mach, _("cannot parse date specification (%s)"),
-                  v->v.string);
+                     date);
       mu_sieve_abort (mach);
     }
 
@@ -87,7 +78,7 @@ timestamp_test (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags)
       mu_sieve_abort (mach);
     }
   
-  if (mu_header_aget_value (hdr, h->v.string, &val))
+  if (mu_header_aget_value (hdr, hname, &val))
     return 0;
 
   if (mu_parse_date (val, &tval, &now))
@@ -102,7 +93,7 @@ timestamp_test (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags)
 
   rc = tval > tlimit;
     
-  if (mu_sieve_tag_lookup (tags, "before", NULL))
+  if (mu_sieve_tag_lookup (mach, tags, "before", SVT_VOID, NULL))
     rc = !rc;  
 
   return rc;
diff --git a/libmu_sieve/extensions/vacation.c 
b/libmu_sieve/extensions/vacation.c
index 8b8fefc..a3a1fc3 100644
--- a/libmu_sieve/extensions/vacation.c
+++ b/libmu_sieve/extensions/vacation.c
@@ -78,7 +78,7 @@ build_mime (mu_sieve_machine_t mach, mu_list_t tags, 
mu_mime_t *pmime,
       return 1;
     }
 
-  if (mu_sieve_tag_lookup (tags, "mime", NULL))
+  if (mu_sieve_tag_lookup (mach, tags, "mime", SVT_VOID, NULL))
     {
       mu_stream_t fstr;
       rc = mu_filter_create (&fstr, input, "base64",
@@ -249,7 +249,7 @@ noreply_address_p (mu_sieve_machine_t mach, mu_list_t tags, 
char *email)
   for (i = 0; rc == 0 && noreply_sender[i]; i++)
     rc = regex_comparator (noreply_sender[i], &rd);
 
-  if (!rc && mu_sieve_tag_lookup (tags, "noreply", &arg))
+  if (!rc && mu_sieve_tag_lookup_untyped (mach, tags, "noreply", &arg))
     rc = mu_sieve_vlist_do (arg, regex_comparator, &rd);
   
   return rc;
@@ -341,24 +341,23 @@ check_db (mu_sieve_machine_t mach, mu_list_t tags, char 
*from)
 {
   mu_property_t prop;
   char *file;
-  mu_sieve_value_t *arg;
   unsigned int days;
   int rc;
   mu_stream_t str;
   mu_locker_t locker;
   const char *dbfile = "~/.vacation";
+  size_t n;
   
-  if (mu_sieve_tag_lookup (tags, "days", &arg))
+  if (mu_sieve_tag_lookup (mach, tags, "days", SVT_NUMBER, &n))
     {
-      days = arg->v.number;
+      days = n;
       if (days > DAYS_MAX)
        days = DAYS_MAX;
     }
   else
     days = DAYS_DEFAULT;
 
-  if (mu_sieve_tag_lookup (tags, "database", &arg))
-    dbfile = arg->v.string;
+  mu_sieve_tag_lookup (mach, tags, "database", SVT_STRING, &dbfile);
   
   file = mu_tilde_expansion (dbfile, MU_HIERARCHY_DELIMITER, NULL);
   if (!file)
@@ -433,13 +432,9 @@ static void
 re_subject (mu_sieve_machine_t mach, mu_list_t tags, char **psubject)
 {
   char *subject;
-  mu_sieve_value_t *arg;
   char *prefix = "Re";
   
-  if (mu_sieve_tag_lookup (tags, "reply_prefix", &arg))
-    {
-      prefix = arg->v.string;
-    }
+  mu_sieve_tag_lookup (mach, tags, "reply_prefix", SVT_STRING, &prefix);
 
   subject = malloc (strlen (*psubject) + strlen (prefix) + 3);
   if (!subject)
@@ -467,20 +462,19 @@ static void
 vacation_subject (mu_sieve_machine_t mach, mu_list_t tags,
                  mu_message_t msg, mu_header_t newhdr)
 {
-  mu_sieve_value_t *arg;
   char *value;
   char *subject;
   int subject_allocated = 0;
   mu_header_t hdr;
   
-  if (mu_sieve_tag_lookup (tags, "subject", &arg))
-    subject = arg->v.string;
+  if (mu_sieve_tag_lookup (mach, tags, "subject", SVT_STRING, &subject))
+    /* nothing */;
   else if (mu_message_get_header (msg, &hdr) == 0
           && mu_header_aget_value_unfold (hdr, MU_HEADER_SUBJECT,
                                           &value) == 0)
     {
       char *p;
-      
+
       int rc = mu_rfc2047_decode (MU_SIEVE_CHARSET, value, &p);
 
       subject_allocated = 1;
@@ -494,11 +488,11 @@ vacation_subject (mu_sieve_machine_t mach, mu_list_t tags,
          subject = p;
        }
 
-      if (mu_sieve_tag_lookup (tags, "reply_regex", &arg))
+      if (mu_sieve_tag_lookup (mach, tags, "reply_regex", SVT_STRING, &p))
        {
          char *err = NULL;
          
-         rc = mu_unre_set_regex (arg->v.string, 0, &err);
+         rc = mu_unre_set_regex (p, 0, &err);
          if (rc)
            {
              mu_sieve_error (mach,
@@ -619,7 +613,7 @@ vacation_reply (mu_sieve_machine_t mach, mu_list_t tags, 
mu_message_t msg,
   int rc;
   mu_sieve_value_t *val;
 
-  if (mu_sieve_tag_lookup (tags, "file", NULL))
+  if (mu_sieve_tag_lookup (mach, tags, "file", SVT_VOID, NULL))
     {
       mu_stream_t instr;
       
@@ -634,7 +628,7 @@ vacation_reply (mu_sieve_machine_t mach, mu_list_t tags, 
mu_message_t msg,
          return -1;
        }
       
-      if (mu_sieve_tag_lookup (tags, "rfc2822", NULL))
+      if (mu_sieve_tag_lookup (mach, tags, "rfc2822", SVT_VOID, NULL))
        {
          rc = mu_stream_to_message (instr, &newmsg);
          mu_stream_unref (instr);
@@ -722,7 +716,7 @@ vacation_reply (mu_sieve_machine_t mach, mu_list_t tags, 
mu_message_t msg,
     {
       mu_header_set_value (newhdr, MU_HEADER_TO, to, 0);
 
-      if (mu_sieve_tag_lookup (tags, "header", &val))
+      if (mu_sieve_tag_lookup_untyped (mach, tags, "header", &val))
        {
          struct header_closure hc;
          hc.mach = mach;
@@ -774,7 +768,6 @@ sieve_action_vacation (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
   int rc;
   char *text, *from = NULL;
   char const *return_address;
-  mu_sieve_value_t *val;
   mu_message_t msg;
   mu_header_t hdr;
   char *my_address;
@@ -782,22 +775,15 @@ sieve_action_vacation (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
   if (diag (mach))
     return 0;
   
-  val = mu_sieve_value_get (args, 0);
-  if (!val)
-    {
-      mu_sieve_error (mach, _("cannot get text!"));
-      mu_sieve_abort (mach);
-    }
-  else
-    text = val->v.string;
+  mu_sieve_value_get (mach, args, 0, SVT_STRING, &text);
 
   msg = mu_sieve_get_message (mach);
   mu_message_get_header (msg, &hdr);
 
-  if (mu_sieve_tag_lookup (tags, "sender", &val))
+  if (mu_sieve_tag_lookup (mach, tags, "sender", SVT_STRING, &from))
     {
       /* Debugging hook: :sender sets fake reply address */
-      from = strdup (val->v.string);
+      from = strdup (from);
       if (!from)
         {
           mu_sieve_error (mach, "%lu: %s",
@@ -817,12 +803,12 @@ sieve_action_vacation (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
 
   my_address = mu_get_user_email (NULL);
 
-  if (mu_sieve_tag_lookup (tags, "always_reply", NULL))
+  if (mu_sieve_tag_lookup (mach, tags, "always_reply", SVT_VOID, NULL))
     return_address = my_address;
   else
     {
-      val = NULL;
-      mu_sieve_tag_lookup (tags, "aliases", &val);
+      mu_sieve_value_t *val = NULL;
+      mu_sieve_tag_lookup_untyped (mach, tags, "aliases", &val);
       if (match_addresses (hdr, my_address, val, &return_address) == 0)
        {
          free (my_address);
@@ -839,8 +825,8 @@ sieve_action_vacation (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
       return 0;
     }
 
-  if (mu_sieve_tag_lookup (tags, "return_address", &val))
-    return_address = val->v.string;
+  mu_sieve_tag_lookup (mach, tags, "return_address", SVT_STRING,
+                      &return_address);
 
   rc = vacation_reply (mach, tags, msg, text, from, return_address);
   free (from);
diff --git a/libmu_sieve/relational.c b/libmu_sieve/relational.c
index 871d8e9..19c9eec 100644
--- a/libmu_sieve/relational.c
+++ b/libmu_sieve/relational.c
@@ -83,12 +83,12 @@ mu_sieve_str_to_relcmp (const char *str,
 mu_sieve_relcmp_t
 mu_sieve_get_relcmp (mu_sieve_machine_t mach, mu_list_t tags)
 {
-  mu_sieve_value_t *arg;
+  char *str;
   mu_sieve_relcmp_t test = NULL;
   
-  if (mu_sieve_tag_lookup (tags, "value", &arg) == 0)
+  if (mu_sieve_tag_lookup (mach, tags, "value", SVT_STRING, &str) == 0)
     return op_ne;
-  mu_sieve_str_to_relcmp (arg->v.string, &test, NULL);
+  mu_sieve_str_to_relcmp (str, &test, NULL);
   return test;
 }
 
diff --git a/libmu_sieve/sieve-priv.h b/libmu_sieve/sieve-priv.h
index 8aa4030..6c62255 100644
--- a/libmu_sieve/sieve-priv.h
+++ b/libmu_sieve/sieve-priv.h
@@ -35,6 +35,7 @@ typedef union
   size_t line;
   int inum;
   char *string;
+  unsigned unum;
 } sieve_op_t;
 
 struct mu_locus_range
diff --git a/libmu_sieve/sieve.l b/libmu_sieve/sieve.l
index f04d219..43edd6a 100644
--- a/libmu_sieve/sieve.l
+++ b/libmu_sieve/sieve.l
@@ -642,46 +642,32 @@ str_unescape (char *text, size_t len)
   return str;
 }
 
-enum
-  {
-    interp_encoded_character,
-    interp_variable
-  };
-
-#define MAXINTERP (interp_variable+1)
-mu_i_sv_interp_t interpreter[MAXINTERP];
+static mu_i_sv_interp_t string_interpreter;
 
 static void
 line_finish (void)
 {
-  int i;
   char *str;
   
   mu_opool_append_char (mu_sieve_machine->string_pool, 0);
   str = mu_opool_finish (mu_sieve_machine->string_pool, NULL);
-  for (i = 0; i < MAXINTERP; i++)
+  if (string_interpreter)
     {
-      if (interpreter[i])
+      char *exp;
+      int rc = mu_i_sv_string_expand (str, string_interpreter, NULL, &exp);
+      if (rc == 0)
+       {
+         mu_opool_free (mu_sieve_machine->string_pool, str);
+         mu_opool_appendz (mu_sieve_machine->string_pool, exp);
+         mu_opool_append_char (mu_sieve_machine->string_pool, 0);
+         free (exp);
+         str = mu_opool_finish (mu_sieve_machine->string_pool, NULL);
+       }
+      else if (rc != MU_ERR_CANCELED)
        {
-         char *exp;
-         int rc = mu_i_sv_string_expand (str, interpreter[i], NULL, &exp);
-         if (rc == 0)
-           {
-             mu_opool_free (mu_sieve_machine->string_pool, str);
-             mu_opool_appendz (mu_sieve_machine->string_pool, exp);
-             mu_opool_append_char (mu_sieve_machine->string_pool, 0);
-             free (exp);
-             str = mu_opool_finish (mu_sieve_machine->string_pool, NULL);
-           }
-         else if (rc == MU_ERR_CANCELED)
-           continue;
-         else
-           {
-             mu_diag_at_locus (MU_LOG_ERROR, &mu_sieve_locus,
-                               _("error expandind string: %s"),
-                               mu_strerror (rc));
-             break;
-           }
+         mu_diag_at_locus (MU_LOG_ERROR, &mu_sieve_locus,
+                           _("error expandind string: %s"),
+                           mu_strerror (rc));
        }
     }
   yylval.string = str;
@@ -691,6 +677,6 @@ int
 mu_sieve_require_encoded_character (mu_sieve_machine_t mach,
                                    const char *name)
 {
-  interpreter[interp_encoded_character] = mu_i_sv_expand_encoded_char;
+  string_interpreter = mu_i_sv_expand_encoded_char;
   return 0;
 }
diff --git a/libmu_sieve/sieve.y b/libmu_sieve/sieve.y
index eaa1cfc..22f0f20 100644
--- a/libmu_sieve/sieve.y
+++ b/libmu_sieve/sieve.y
@@ -539,12 +539,6 @@ mu_i_sv_valf (mu_stream_t str, mu_sieve_value_t *val)
       mu_stream_printf (str, "%s", val->v.string);
       break;
        
-    case SVT_VALUE_LIST:
-      mu_stream_printf (str, "[");
-      mu_i_sv_argf (str, val->v.list);
-      mu_stream_printf (str, "]");
-      break;
-      
     case SVT_POINTER:
       mu_stream_printf (str, "%p", val->v.ptr);
       break;
diff --git a/libmu_sieve/tests.c b/libmu_sieve/tests.c
index 88adbe6..03b40d7 100644
--- a/libmu_sieve/tests.c
+++ b/libmu_sieve/tests.c
@@ -64,22 +64,23 @@ struct address_closure
 };  
 
 static int
-do_count (mu_list_t args, mu_list_t tags, size_t count, int retval)
+do_count (mu_sieve_machine_t mach, mu_list_t args, mu_list_t tags,
+         size_t count, int retval)
 {
-  mu_sieve_value_t *arg;
+  char *relcmp;
   
-  if (mu_sieve_tag_lookup (tags, "count", &arg))
+  if (mu_sieve_tag_lookup (mach, tags, "count", SVT_STRING, &relcmp))
     {
       size_t limit;
       char *str;
-      mu_sieve_value_t *val;
+      mu_list_t list;
       mu_sieve_relcmpn_t stest;
       
-      val = mu_sieve_value_get (args, 1);
-      mu_list_get (val->v.list, 0, (void **) &str);
+      mu_sieve_value_get (mach, args, 1, SVT_STRING_LIST, &list);
+      mu_list_get (list, 0, (void **) &str);
       limit = strtoul (str, &str, 10);
 
-      mu_sieve_str_to_relcmp (arg->v.string, NULL, &stest);
+      mu_sieve_str_to_relcmp (relcmp, NULL, &stest);
       return stest (count, limit);
     }
   return retval;
@@ -119,18 +120,8 @@ sieve_test_address (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
   int rc;
   size_t count;
   
-  h = mu_sieve_value_get (args, 0);
-  if (!h)
-    {
-      mu_sieve_arg_error (mach, 1);
-      mu_sieve_abort (mach);
-    }
-  v = mu_sieve_value_get (args, 1);
-  if (!v)
-    {
-      mu_sieve_arg_error (mach, 2);
-      mu_sieve_abort (mach);
-    }
+  h = mu_sieve_value_get_untyped (mach, args, 0);
+  v = mu_sieve_value_get_untyped (mach, args, 1);
 
   mu_message_get_header (mu_sieve_get_message (mach), &header);
   clos.data = header;
@@ -139,10 +130,11 @@ sieve_test_address (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
   rc = mu_sieve_vlist_compare (h, v, comp, test, retrieve_address, &clos, 
&count);
   mu_address_destroy (&clos.addr);
   
-  return do_count (args, tags, count, rc);
+  return do_count (mach, args, tags, count, rc);
 }
 
-struct header_closure {
+struct header_closure
+{
   mu_header_t header;
   int index;
 };
@@ -180,20 +172,10 @@ sieve_test_header (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
   size_t count, mcount = 0;
   struct header_closure clos;
   
-  h = mu_sieve_value_get (args, 0);
-  if (!h)
-    {
-      mu_sieve_arg_error (mach, 1);
-      mu_sieve_abort (mach);
-    }
-  v = mu_sieve_value_get (args, 1);
-  if (!v)
-    {
-      mu_sieve_arg_error (mach, 2);
-      mu_sieve_abort (mach);
-    }
+  h = mu_sieve_value_get_untyped (mach, args, 0);
+  v = mu_sieve_value_get_untyped (mach, args, 1);
 
-  if (mu_sieve_tag_lookup (tags, "mime", NULL))
+  if (mu_sieve_tag_lookup (mach, tags, "mime", SVT_VOID, NULL))
     {
       int ismime = 0;
 
@@ -218,10 +200,11 @@ sieve_test_header (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
        }
     }
   mu_message_get_header (mach->msg, &clos.header);
-  if (mu_sieve_vlist_compare (h, v, comp, test, retrieve_header, &clos, 
&count))
+  if (mu_sieve_vlist_compare (h, v, comp, test, retrieve_header, &clos,
+                             &count))
     return 1;
 
-  return do_count (args, tags, count + mcount, 0);
+  return do_count (mach, args, tags, count + mcount, 0);
 }
 
 int
@@ -261,18 +244,8 @@ sieve_test_envelope (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
   int rc;
   size_t count;
   
-  h = mu_sieve_value_get (args, 0);
-  if (!h)
-    {
-      mu_sieve_arg_error (mach, 1);
-      mu_sieve_abort (mach);
-    }
-  v = mu_sieve_value_get (args, 1);
-  if (!v)
-    {
-      mu_sieve_arg_error (mach, 2);
-      mu_sieve_abort (mach);
-    }
+  h = mu_sieve_value_get_untyped (mach, args, 0);
+  v = mu_sieve_value_get_untyped (mach, args, 1);
 
   mu_message_get_envelope (mu_sieve_get_message (mach), 
                            (mu_envelope_t*)&clos.data);
@@ -281,7 +254,7 @@ sieve_test_envelope (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
   rc = mu_sieve_vlist_compare (h, v, comp, test, retrieve_envelope, &clos,
                            &count);
   mu_address_destroy (&clos.addr);
-  return do_count (args, tags, count, rc);
+  return do_count (mach, args, tags, count, rc);
 }
 
 int
@@ -290,22 +263,17 @@ sieve_test_size (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags)
   int rc = 1;
   mu_sieve_runtime_tag_t *tag = NULL;
   size_t size;
+  size_t arg;
   
-  mu_sieve_value_t *val = mu_sieve_value_get (args, 0);
-  if (!val)
-    {
-      mu_sieve_arg_error (mach, 1);
-      mu_sieve_abort (mach);
-    }
-
+  mu_sieve_value_get (mach, args, 0, SVT_NUMBER, &arg);
   mu_message_size (mu_sieve_get_message (mach), &size);
   mu_list_get (tags, 0, (void **)&tag);
   if (!tag)
-    rc = size == val->v.number;
+    rc = size == arg;
   else if (strcmp (tag->tag, "over") == 0)
-    rc = size > val->v.number;
+    rc = size > arg;
   else if (strcmp (tag->tag, "under") == 0)
-    rc = size < val->v.number;
+    rc = size < arg;
 
   return rc;
 }
@@ -326,13 +294,7 @@ sieve_test_exists (mu_sieve_machine_t mach, mu_list_t 
args, mu_list_t tags)
   mu_sieve_value_t *val;   
 
   mu_message_get_header (mu_sieve_get_message (mach), &header);
-  val = mu_sieve_value_get (args, 0);
-  if (!val)
-    {
-      mu_sieve_arg_error (mach, 1);
-      mu_sieve_abort (mach);
-    }
-
+  val = mu_sieve_value_get_untyped (mach, args, 0);
   return mu_sieve_vlist_do (val, _test_exists, header) == 0;
 }
 
diff --git a/libmu_sieve/util.c b/libmu_sieve/util.c
index 8b437c7..adc737e 100644
--- a/libmu_sieve/util.c
+++ b/libmu_sieve/util.c
@@ -156,7 +156,6 @@ mu_sieve_value_create (mu_sieve_data_type type, void *data)
       val->v.string = data;
       break;
       
-    case SVT_VALUE_LIST:
     case SVT_STRING_LIST:
       val->v.list = data;
       break;
@@ -178,13 +177,57 @@ mu_sieve_value_create (mu_sieve_data_type type, void 
*data)
 }
 
 mu_sieve_value_t *
-mu_sieve_value_get (mu_list_t vlist, size_t index)
+mu_sieve_value_get_untyped (mu_sieve_machine_t mach, mu_list_t vlist,
+                           size_t index)
 {
   mu_sieve_value_t *val = NULL;
-  mu_list_get (vlist, index, (void **)&val);
+  int rc = mu_list_get (vlist, index, (void **)&val);
+  if (rc)
+    {
+      mu_sieve_error (mach, _("can't get argument %zu: %s"),
+                     index, mu_strerror (rc));
+      mu_sieve_abort (mach);
+    }
   return val;
 }
 
+mu_sieve_value_t *
+mu_sieve_value_get_optional (mu_sieve_machine_t mach, mu_list_t vlist,
+                            size_t index)
+{
+  mu_sieve_value_t *val = NULL;
+  int rc = mu_list_get (vlist, index, (void **)&val);
+  if (rc == MU_ERR_NOENT)
+    return NULL;
+  else if (rc)
+    {
+      mu_sieve_error (mach, _("can't get argument %zu: %s"),
+                     index, mu_strerror (rc));
+      mu_sieve_abort (mach);
+    }
+  return val;
+}  
+
+int
+mu_sieve_value_get (mu_sieve_machine_t mach, mu_list_t vlist,
+                   size_t index,
+                   mu_sieve_data_type type, void *ret)
+{
+  mu_sieve_value_t *val = mu_sieve_value_get_untyped (mach, vlist, index);
+  if (val->type != type)
+    {
+      mu_sieve_error (mach,
+                   _("bad type for argument %zu: %s, instead of expected %s"),
+                     index,
+                     mu_sieve_type_str (val->type),
+                     mu_sieve_type_str (type));
+      mu_sieve_abort (mach);
+    }
+
+  *(union mu_sieve_value_storage *)ret = val->v;
+  return 0;
+}
+
 void
 mu_sieve_error (mu_sieve_machine_t mach, const char *fmt, ...)
 {
@@ -204,12 +247,6 @@ mu_sieve_error (mu_sieve_machine_t mach, const char *fmt, 
...)
   mu_stream_write (mach->errstream, "\n", 1, NULL);
   va_end (ap);
 }
-
-void
-mu_sieve_arg_error (mu_sieve_machine_t mach, int n)
-{
-  mu_sieve_error (mach, _("cannot retrieve argument %d"), n);
-}
 
 const char *
 mu_sieve_type_str (mu_sieve_data_type type)
@@ -234,9 +271,6 @@ mu_sieve_type_str (mu_sieve_data_type type)
     case SVT_IDENT:
       return "ident";
 
-    case SVT_VALUE_LIST:
-      return "value-list";
-
     case SVT_POINTER:
       return "pointer";
     }
@@ -367,26 +401,54 @@ tag_finder (void *item, void *data)
 }
 
 int
-mu_sieve_tag_lookup (mu_list_t taglist, char *name, mu_sieve_value_t **arg)
+mu_sieve_tag_lookup_untyped (mu_sieve_machine_t mach, mu_list_t taglist,
+                            char *name, mu_sieve_value_t **ret)
 {
   mu_sieve_runtime_tag_t t;
 
   t.tag = name;
   if (taglist && mu_list_foreach (taglist, tag_finder, &t))
     {
-      if (arg)
-       *arg = t.arg;
+      if (ret)
+       *ret = t.arg;
       return 1;
     }
   return 0;
 }
 
 int
+mu_sieve_tag_lookup (mu_sieve_machine_t mach, mu_list_t taglist,
+                    char *name, mu_sieve_data_type type,
+                    void *ret)
+{
+  mu_sieve_value_t *val;
+  int found = mu_sieve_tag_lookup_untyped (mach, taglist, name, &val);
+
+  if (found)
+    {
+      if (ret)
+       {
+         if (val->type != type)
+           {
+             mu_sieve_error (mach,
+                             _("bad type for tag %s: %s, instead of expected 
%s"),
+                             name,
+                             mu_sieve_type_str (val->type),
+                             mu_sieve_type_str (type));
+             mu_sieve_abort (mach);
+           }
+         *(union mu_sieve_value_storage *)ret = val->v;
+       }
+    }
+
+  return found;
+}
+
+int
 mu_sieve_vlist_do (mu_sieve_value_t *val, mu_list_action_t ac, void *data)
 {
   switch (val->type)
     {
-    case SVT_VALUE_LIST:
     case SVT_STRING_LIST:
       return mu_list_foreach (val->v.list, ac, data);
     case SVT_STRING:


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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