/[mailutils]/mailutils/libsieve/runtime.c
ViewVC logotype

Diff of /mailutils/libsieve/runtime.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by gray, Tue Nov 12 16:26:45 2002 UTC revision 1.2 by gray, Wed Nov 13 13:36:38 2002 UTC
# Line 26  Line 26 
26  #define SIEVE_ARG(m,n,t) ((m)->prog[(m)->pc+(n)].t)  #define SIEVE_ARG(m,n,t) ((m)->prog[(m)->pc+(n)].t)
27  #define SIEVE_ADJUST(m,n) (m)->pc+=(n)  #define SIEVE_ADJUST(m,n) (m)->pc+=(n)
28    
29  #define INSTR_DEBUG(m) ((m)->debug_level == 100 && (m)->debug_printer)  #define INSTR_DEBUG(m) ((m)->debug_level > 90 && (m)->debug_printer)
30    #define INSTR_DISASS(m) ((m)->debug_level == 100)
31    
32  static int  static int
33  instr_run (sieve_machine_t *mach)  instr_run (sieve_machine_t *mach)
# Line 54  void Line 55  void
55  instr_action (sieve_machine_t *mach)  instr_action (sieve_machine_t *mach)
56  {  {
57    if (INSTR_DEBUG (mach))    if (INSTR_DEBUG (mach))
58      sieve_debug (mach, "ACTION: %s\n", SIEVE_ARG (mach, 3, string));      sieve_debug (mach, "%4lu: ACTION: %s\n",
59                     (unsigned long) (mach->pc - 1),
60                     SIEVE_ARG (mach, 3, string));
61    instr_run (mach);    instr_run (mach);
62  }  }
63    
# Line 62  void Line 65  void
65  instr_test (sieve_machine_t *mach)  instr_test (sieve_machine_t *mach)
66  {  {
67    if (INSTR_DEBUG (mach))    if (INSTR_DEBUG (mach))
68      sieve_debug (mach, "TEST: %s\n", SIEVE_ARG (mach, 3, string));      sieve_debug (mach, "%4lu: TEST: %s\n",
69                     (unsigned long) (mach->pc - 1),
70                     SIEVE_ARG (mach, 3, string));
71    mach->reg = instr_run (mach);    mach->reg = instr_run (mach);
72  }  }
73    
# Line 70  void Line 75  void
75  instr_push (sieve_machine_t *mach)  instr_push (sieve_machine_t *mach)
76  {  {
77    if (INSTR_DEBUG (mach))    if (INSTR_DEBUG (mach))
78      sieve_debug (mach, "PUSH\n");      {
79          sieve_debug (mach, "%4lu: PUSH\n", (unsigned long)(mach->pc - 1));
80          if (INSTR_DISASS (mach))
81            return;
82        }
83      
84    if (!mach->stack && list_create (&mach->stack))    if (!mach->stack && list_create (&mach->stack))
85      {      {
86        sieve_error ("can't create stack");        sieve_error (mach, "can't create stack");
87        sieve_abort (mach);        sieve_abort (mach);
88      }      }
89    list_prepend (mach->stack, (void*) mach->reg);    list_prepend (mach->stack, (void*) mach->reg);
# Line 83  void Line 93  void
93  instr_pop (sieve_machine_t *mach)  instr_pop (sieve_machine_t *mach)
94  {  {
95    if (INSTR_DEBUG (mach))    if (INSTR_DEBUG (mach))
96      sieve_debug (mach, "POP\n");      {
97          sieve_debug (mach, "%4lu: POP\n", (unsigned long)(mach->pc - 1));
98          if (INSTR_DISASS (mach))
99            return;
100        }
101    
102    if (!mach->stack || list_is_empty (mach->stack))    if (!mach->stack || list_is_empty (mach->stack))
103      {      {
104        sieve_error ("stack underflow");        sieve_error (mach, "stack underflow");
105        sieve_abort (mach);        sieve_abort (mach);
106      }      }
107    list_get (mach->stack, 0, (void **)&mach->reg);    list_get (mach->stack, 0, (void **)&mach->reg);
# Line 99  instr_allof (sieve_machine_t *mach) Line 114  instr_allof (sieve_machine_t *mach)
114    int num = SIEVE_ARG (mach, 0, number);    int num = SIEVE_ARG (mach, 0, number);
115    int val = 1;    int val = 1;
116    
   if (INSTR_DEBUG (mach))  
     sieve_debug (mach, "ALLOF %d\n", num);  
117    SIEVE_ADJUST(mach, 1);    SIEVE_ADJUST(mach, 1);
118    
119      if (INSTR_DEBUG (mach))
120        {
121          sieve_debug (mach, "%4lu: ALLOF %d\n", (unsigned long)(mach->pc - 2),
122                       num);
123          if (INSTR_DISASS (mach))
124            return;
125        }
126      
127    while (num-- > 0)    while (num-- > 0)
128      {      {
129        instr_pop (mach);        instr_pop (mach);
# Line 116  instr_anyof (sieve_machine_t *mach) Line 138  instr_anyof (sieve_machine_t *mach)
138    int num = SIEVE_ARG (mach, 0, number);    int num = SIEVE_ARG (mach, 0, number);
139    int val = 0;    int val = 0;
140    
   if (INSTR_DEBUG (mach))  
     sieve_debug (mach, "ANYOF %d\n", num);  
141    SIEVE_ADJUST(mach, 1);    SIEVE_ADJUST(mach, 1);
142    
143      if (INSTR_DEBUG (mach))
144        {
145          sieve_debug (mach, "%4lu: ANYOF %d\n", (unsigned long)(mach->pc - 2),
146                       num);
147          if (INSTR_DISASS (mach))
148            return;
149        }
150    
151    while (num-- > 0)    while (num-- > 0)
152      {      {
153        instr_pop (mach);        instr_pop (mach);
# Line 131  void Line 160  void
160  instr_not (sieve_machine_t *mach)  instr_not (sieve_machine_t *mach)
161  {  {
162    if (INSTR_DEBUG (mach))    if (INSTR_DEBUG (mach))
163      sieve_debug (mach, "NOT");      {
164          sieve_debug (mach, "%4lu: NOT\n", (unsigned long)(mach->pc - 1));
165          if (INSTR_DISASS (mach))
166            return;
167        }
168    mach->reg = !mach->reg;    mach->reg = !mach->reg;
169  }  }
170    
171  void  void
172    instr_branch (sieve_machine_t *mach)
173    {
174      long num = SIEVE_ARG (mach, 0, number);
175    
176      SIEVE_ADJUST (mach, 1);
177      if (INSTR_DEBUG (mach))
178        {
179          sieve_debug (mach, "%4lu: BRANCH %lu\n",
180                       (unsigned long)(mach->pc-2),
181                       (unsigned long)(mach->pc + num));
182          if (INSTR_DISASS (mach))
183            return;
184        }
185    
186      mach->pc += num;
187    }
188    
189    void
190    instr_brz (sieve_machine_t *mach)
191    {
192      long num = SIEVE_ARG (mach, 0, number);
193      SIEVE_ADJUST (mach, 1);
194    
195      if (INSTR_DEBUG (mach))
196        {
197          sieve_debug (mach, "%4lu: BRZ %lu\n",
198                       (unsigned long)(mach->pc-2),
199                       (unsigned long)(mach->pc + num));
200          if (INSTR_DISASS (mach))
201            return;
202        }
203      
204      if (mach->reg)
205        mach->pc += num;
206    }
207      
208    void
209  sieve_abort (sieve_machine_t *mach)  sieve_abort (sieve_machine_t *mach)
210  {  {
211    longjmp (mach->errbuf, 1);    longjmp (mach->errbuf, 1);
212  }  }
213    
214    void *
215    sieve_get_data (sieve_machine_t *mach)
216    {
217      return mach->data;
218    }
219    
220    message_t
221    sieve_get_message (sieve_machine_t *mach)
222    {
223      if (!mach->msg)
224        mailbox_get_message (mach->mailbox, mach->msgno, &mach->msg);
225      return mach->msg;
226    }
227    
228    size_t
229    sieve_get_message_num (sieve_machine_t *mach)
230    {
231      return mach->msgno;
232    }
233    
234    int
235    sieve_get_debug_level (sieve_machine_t *mach)
236    {
237      return mach->debug_level;
238    }
239    
240  int  int
241  sieve_run (sieve_machine_t *mach)  sieve_run (sieve_machine_t *mach)
242  {  {
# Line 150  sieve_run (sieve_machine_t *mach) Line 246  sieve_run (sieve_machine_t *mach)
246    for (mach->pc = 1; mach->prog[mach->pc].handler; )    for (mach->pc = 1; mach->prog[mach->pc].handler; )
247      (*mach->prog[mach->pc++].instr) (mach);      (*mach->prog[mach->pc++].instr) (mach);
248    
249      if (INSTR_DEBUG (mach))
250        sieve_debug (mach, "%4lu: STOP\n", mach->pc);
251      
252    return 0;    return 0;
253  }  }
254    
255    int
256    sieve_disass (sieve_machine_t *mach)
257    {
258      int level = mach->debug_level;
259      int rc;
260    
261      mach->debug_level = 100;
262      rc = sieve_run (mach);
263      mach->debug_level = level;
264      return rc;
265    }
266      
267    static int
268    _sieve_action (observer_t obs, size_t type)
269    {
270      sieve_machine_t *mach;
271      
272      if (type != MU_EVT_MESSAGE_ADD)
273        return 0;
274    
275      mach = observer_get_owner (obs);
276      mach->msgno++;
277      mailbox_get_message (mach->mailbox, mach->msgno, &mach->msg);
278      sieve_run (mach);
279      return 0;
280    }
281    
282    int
283    sieve_mailbox (sieve_machine_t *mach, mailbox_t mbox)
284    {
285      int rc;
286      size_t total;
287      observer_t observer;
288      observable_t observable;
289      
290      if (!mach || !mbox)
291        return EINVAL;
292    
293      observer_create (&observer, mach);
294      observer_set_action (observer, _sieve_action, mbox);
295      mailbox_get_observable (mbox, &observable);
296      observable_attach (observable, MU_EVT_MESSAGE_ADD, observer);
297      
298      mach->mailbox = mbox;
299      mach->msgno = 0;
300      rc = mailbox_scan (mbox, 1, &total);
301      if (rc)
302        sieve_error (mach, "mailbox_scan: %s", mu_errstring (errno));
303    
304      observable_detach (observable, observer);
305      observer_destroy (&observer, mach);
306    
307      mach->mailbox = NULL;
308      
309      return rc;
310    }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26