summaryrefslogtreecommitdiff
path: root/libsieve/runtime.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2002-11-12 16:26:45 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2002-11-12 16:26:45 +0000
commit6ac08c6e173f9b49fc5432f31482ed3e559d626c (patch)
treef530d944c0d7621b822198b34fba7a6e2caf61a5 /libsieve/runtime.c
parente4d186ff991138c8834950ebb1320a35fa2b7357 (diff)
downloadmailutils-6ac08c6e173f9b49fc5432f31482ed3e559d626c.tar.gz
mailutils-6ac08c6e173f9b49fc5432f31482ed3e559d626c.tar.bz2
Runtime support.
Diffstat (limited to 'libsieve/runtime.c')
-rw-r--r--libsieve/runtime.c154
1 files changed, 154 insertions, 0 deletions
diff --git a/libsieve/runtime.c b/libsieve/runtime.c
new file mode 100644
index 000000000..d593de069
--- /dev/null
+++ b/libsieve/runtime.c
@@ -0,0 +1,154 @@
+/* GNU mailutils - a suite of utilities for electronic mail
+ Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <sieve.h>
+
+#define SIEVE_ARG(m,n,t) ((m)->prog[(m)->pc+(n)].t)
+#define SIEVE_ADJUST(m,n) (m)->pc+=(n)
+
+#define INSTR_DEBUG(m) ((m)->debug_level == 100 && (m)->debug_printer)
+
+static int
+instr_run (sieve_machine_t *mach)
+{
+ sieve_handler_t han = SIEVE_ARG (mach, 0, handler);
+ list_t arg_list = SIEVE_ARG (mach, 1, list);
+ list_t tag_list = SIEVE_ARG (mach, 2, list);
+ int rc;
+
+ if (INSTR_DEBUG (mach))
+ {
+ sieve_debug (mach, "Arguments: ");
+ sieve_print_value_list (arg_list, mach->debug_printer, mach->data);
+ sieve_debug (mach, "\nTags:");
+ sieve_print_tag_list (tag_list, mach->debug_printer, mach->data);
+ sieve_debug (mach, "\n");
+ }
+
+ rc = han (mach, arg_list, tag_list);
+ SIEVE_ADJUST(mach, 4);
+ return rc;
+}
+
+void
+instr_action (sieve_machine_t *mach)
+{
+ if (INSTR_DEBUG (mach))
+ sieve_debug (mach, "ACTION: %s\n", SIEVE_ARG (mach, 3, string));
+ instr_run (mach);
+}
+
+void
+instr_test (sieve_machine_t *mach)
+{
+ if (INSTR_DEBUG (mach))
+ sieve_debug (mach, "TEST: %s\n", SIEVE_ARG (mach, 3, string));
+ mach->reg = instr_run (mach);
+}
+
+void
+instr_push (sieve_machine_t *mach)
+{
+ if (INSTR_DEBUG (mach))
+ sieve_debug (mach, "PUSH\n");
+ if (!mach->stack && list_create (&mach->stack))
+ {
+ sieve_error ("can't create stack");
+ sieve_abort (mach);
+ }
+ list_prepend (mach->stack, (void*) mach->reg);
+}
+
+void
+instr_pop (sieve_machine_t *mach)
+{
+ if (INSTR_DEBUG (mach))
+ sieve_debug (mach, "POP\n");
+ if (!mach->stack || list_is_empty (mach->stack))
+ {
+ sieve_error ("stack underflow");
+ sieve_abort (mach);
+ }
+ list_get (mach->stack, 0, (void **)&mach->reg);
+ list_remove (mach->stack, (void *)mach->reg);
+}
+
+void
+instr_allof (sieve_machine_t *mach)
+{
+ int num = SIEVE_ARG (mach, 0, number);
+ int val = 1;
+
+ if (INSTR_DEBUG (mach))
+ sieve_debug (mach, "ALLOF %d\n", num);
+ SIEVE_ADJUST(mach, 1);
+ while (num-- > 0)
+ {
+ instr_pop (mach);
+ val &= mach->reg;
+ }
+ mach->reg = val;
+}
+
+void
+instr_anyof (sieve_machine_t *mach)
+{
+ int num = SIEVE_ARG (mach, 0, number);
+ int val = 0;
+
+ if (INSTR_DEBUG (mach))
+ sieve_debug (mach, "ANYOF %d\n", num);
+ SIEVE_ADJUST(mach, 1);
+ while (num-- > 0)
+ {
+ instr_pop (mach);
+ val &= mach->reg;
+ }
+ mach->reg = val;
+}
+
+void
+instr_not (sieve_machine_t *mach)
+{
+ if (INSTR_DEBUG (mach))
+ sieve_debug (mach, "NOT");
+ mach->reg = !mach->reg;
+}
+
+void
+sieve_abort (sieve_machine_t *mach)
+{
+ longjmp (mach->errbuf, 1);
+}
+
+int
+sieve_run (sieve_machine_t *mach)
+{
+ if (setjmp (mach->errbuf))
+ return 1;
+
+ for (mach->pc = 1; mach->prog[mach->pc].handler; )
+ (*mach->prog[mach->pc++].instr) (mach);
+
+ return 0;
+}

Return to:

Send suggestions and report system problems to the System administrator.