summaryrefslogtreecommitdiff
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
parente4d186ff991138c8834950ebb1320a35fa2b7357 (diff)
downloadmailutils-6ac08c6e173f9b49fc5432f31482ed3e559d626c.tar.gz
mailutils-6ac08c6e173f9b49fc5432f31482ed3e559d626c.tar.bz2
Runtime support.
-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 @@
1/* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18#ifdef HAVE_CONFIG_H
19# include <config.h>
20#endif
21#include <stdio.h>
22#include <stdlib.h>
23#include <assert.h>
24#include <sieve.h>
25
26#define SIEVE_ARG(m,n,t) ((m)->prog[(m)->pc+(n)].t)
27#define SIEVE_ADJUST(m,n) (m)->pc+=(n)
28
29#define INSTR_DEBUG(m) ((m)->debug_level == 100 && (m)->debug_printer)
30
31static int
32instr_run (sieve_machine_t *mach)
33{
34 sieve_handler_t han = SIEVE_ARG (mach, 0, handler);
35 list_t arg_list = SIEVE_ARG (mach, 1, list);
36 list_t tag_list = SIEVE_ARG (mach, 2, list);
37 int rc;
38
39 if (INSTR_DEBUG (mach))
40 {
41 sieve_debug (mach, "Arguments: ");
42 sieve_print_value_list (arg_list, mach->debug_printer, mach->data);
43 sieve_debug (mach, "\nTags:");
44 sieve_print_tag_list (tag_list, mach->debug_printer, mach->data);
45 sieve_debug (mach, "\n");
46 }
47
48 rc = han (mach, arg_list, tag_list);
49 SIEVE_ADJUST(mach, 4);
50 return rc;
51}
52
53void
54instr_action (sieve_machine_t *mach)
55{
56 if (INSTR_DEBUG (mach))
57 sieve_debug (mach, "ACTION: %s\n", SIEVE_ARG (mach, 3, string));
58 instr_run (mach);
59}
60
61void
62instr_test (sieve_machine_t *mach)
63{
64 if (INSTR_DEBUG (mach))
65 sieve_debug (mach, "TEST: %s\n", SIEVE_ARG (mach, 3, string));
66 mach->reg = instr_run (mach);
67}
68
69void
70instr_push (sieve_machine_t *mach)
71{
72 if (INSTR_DEBUG (mach))
73 sieve_debug (mach, "PUSH\n");
74 if (!mach->stack && list_create (&mach->stack))
75 {
76 sieve_error ("can't create stack");
77 sieve_abort (mach);
78 }
79 list_prepend (mach->stack, (void*) mach->reg);
80}
81
82void
83instr_pop (sieve_machine_t *mach)
84{
85 if (INSTR_DEBUG (mach))
86 sieve_debug (mach, "POP\n");
87 if (!mach->stack || list_is_empty (mach->stack))
88 {
89 sieve_error ("stack underflow");
90 sieve_abort (mach);
91 }
92 list_get (mach->stack, 0, (void **)&mach->reg);
93 list_remove (mach->stack, (void *)mach->reg);
94}
95
96void
97instr_allof (sieve_machine_t *mach)
98{
99 int num = SIEVE_ARG (mach, 0, number);
100 int val = 1;
101
102 if (INSTR_DEBUG (mach))
103 sieve_debug (mach, "ALLOF %d\n", num);
104 SIEVE_ADJUST(mach, 1);
105 while (num-- > 0)
106 {
107 instr_pop (mach);
108 val &= mach->reg;
109 }
110 mach->reg = val;
111}
112
113void
114instr_anyof (sieve_machine_t *mach)
115{
116 int num = SIEVE_ARG (mach, 0, number);
117 int val = 0;
118
119 if (INSTR_DEBUG (mach))
120 sieve_debug (mach, "ANYOF %d\n", num);
121 SIEVE_ADJUST(mach, 1);
122 while (num-- > 0)
123 {
124 instr_pop (mach);
125 val &= mach->reg;
126 }
127 mach->reg = val;
128}
129
130void
131instr_not (sieve_machine_t *mach)
132{
133 if (INSTR_DEBUG (mach))
134 sieve_debug (mach, "NOT");
135 mach->reg = !mach->reg;
136}
137
138void
139sieve_abort (sieve_machine_t *mach)
140{
141 longjmp (mach->errbuf, 1);
142}
143
144int
145sieve_run (sieve_machine_t *mach)
146{
147 if (setjmp (mach->errbuf))
148 return 1;
149
150 for (mach->pc = 1; mach->prog[mach->pc].handler; )
151 (*mach->prog[mach->pc++].instr) (mach);
152
153 return 0;
154}

Return to:

Send suggestions and report system problems to the System administrator.