Verbose debugging.
(instr_branch, instr_brz): New functions. (sieve_get_data,sieve_get_message,sieve_get_message_num) (sieve_get_debug_level,sieve_disass,sieve_mailbox): New functions(sieve_vprintf_t): Removed.
Showing
1 changed file
with
168 additions
and
12 deletions
... | @@ -26,7 +26,8 @@ | ... | @@ -26,7 +26,8 @@ |
26 | #define SIEVE_ARG(m,n,t) ((m)->prog[(m)->pc+(n)].t) | 26 | #define SIEVE_ARG(m,n,t) ((m)->prog[(m)->pc+(n)].t) |
27 | #define SIEVE_ADJUST(m,n) (m)->pc+=(n) | 27 | #define SIEVE_ADJUST(m,n) (m)->pc+=(n) |
28 | 28 | ||
29 | #define INSTR_DEBUG(m) ((m)->debug_level == 100 && (m)->debug_printer) | 29 | #define INSTR_DEBUG(m) ((m)->debug_level > 90 && (m)->debug_printer) |
30 | #define INSTR_DISASS(m) ((m)->debug_level == 100) | ||
30 | 31 | ||
31 | static int | 32 | static int |
32 | instr_run (sieve_machine_t *mach) | 33 | instr_run (sieve_machine_t *mach) |
... | @@ -54,7 +55,9 @@ void | ... | @@ -54,7 +55,9 @@ void |
54 | instr_action (sieve_machine_t *mach) | 55 | instr_action (sieve_machine_t *mach) |
55 | { | 56 | { |
56 | if (INSTR_DEBUG (mach)) | 57 | if (INSTR_DEBUG (mach)) |
57 | sieve_debug (mach, "ACTION: %s\n", SIEVE_ARG (mach, 3, string)); | 58 | sieve_debug (mach, "%4lu: ACTION: %s\n", |
59 | (unsigned long) (mach->pc - 1), | ||
60 | SIEVE_ARG (mach, 3, string)); | ||
58 | instr_run (mach); | 61 | instr_run (mach); |
59 | } | 62 | } |
60 | 63 | ||
... | @@ -62,7 +65,9 @@ void | ... | @@ -62,7 +65,9 @@ void |
62 | instr_test (sieve_machine_t *mach) | 65 | instr_test (sieve_machine_t *mach) |
63 | { | 66 | { |
64 | if (INSTR_DEBUG (mach)) | 67 | if (INSTR_DEBUG (mach)) |
65 | sieve_debug (mach, "TEST: %s\n", SIEVE_ARG (mach, 3, string)); | 68 | sieve_debug (mach, "%4lu: TEST: %s\n", |
69 | (unsigned long) (mach->pc - 1), | ||
70 | SIEVE_ARG (mach, 3, string)); | ||
66 | mach->reg = instr_run (mach); | 71 | mach->reg = instr_run (mach); |
67 | } | 72 | } |
68 | 73 | ||
... | @@ -70,10 +75,15 @@ void | ... | @@ -70,10 +75,15 @@ void |
70 | instr_push (sieve_machine_t *mach) | 75 | instr_push (sieve_machine_t *mach) |
71 | { | 76 | { |
72 | if (INSTR_DEBUG (mach)) | 77 | if (INSTR_DEBUG (mach)) |
73 | sieve_debug (mach, "PUSH\n"); | 78 | { |
79 | sieve_debug (mach, "%4lu: PUSH\n", (unsigned long)(mach->pc - 1)); | ||
80 | if (INSTR_DISASS (mach)) | ||
81 | return; | ||
82 | } | ||
83 | |||
74 | if (!mach->stack && list_create (&mach->stack)) | 84 | if (!mach->stack && list_create (&mach->stack)) |
75 | { | 85 | { |
76 | sieve_error ("can't create stack"); | 86 | sieve_error (mach, "can't create stack"); |
77 | sieve_abort (mach); | 87 | sieve_abort (mach); |
78 | } | 88 | } |
79 | list_prepend (mach->stack, (void*) mach->reg); | 89 | list_prepend (mach->stack, (void*) mach->reg); |
... | @@ -83,10 +93,15 @@ void | ... | @@ -83,10 +93,15 @@ void |
83 | instr_pop (sieve_machine_t *mach) | 93 | instr_pop (sieve_machine_t *mach) |
84 | { | 94 | { |
85 | if (INSTR_DEBUG (mach)) | 95 | if (INSTR_DEBUG (mach)) |
86 | sieve_debug (mach, "POP\n"); | 96 | { |
97 | sieve_debug (mach, "%4lu: POP\n", (unsigned long)(mach->pc - 1)); | ||
98 | if (INSTR_DISASS (mach)) | ||
99 | return; | ||
100 | } | ||
101 | |||
87 | if (!mach->stack || list_is_empty (mach->stack)) | 102 | if (!mach->stack || list_is_empty (mach->stack)) |
88 | { | 103 | { |
89 | sieve_error ("stack underflow"); | 104 | sieve_error (mach, "stack underflow"); |
90 | sieve_abort (mach); | 105 | sieve_abort (mach); |
91 | } | 106 | } |
92 | list_get (mach->stack, 0, (void **)&mach->reg); | 107 | list_get (mach->stack, 0, (void **)&mach->reg); |
... | @@ -99,9 +114,16 @@ instr_allof (sieve_machine_t *mach) | ... | @@ -99,9 +114,16 @@ instr_allof (sieve_machine_t *mach) |
99 | int num = SIEVE_ARG (mach, 0, number); | 114 | int num = SIEVE_ARG (mach, 0, number); |
100 | int val = 1; | 115 | int val = 1; |
101 | 116 | ||
102 | if (INSTR_DEBUG (mach)) | ||
103 | sieve_debug (mach, "ALLOF %d\n", num); | ||
104 | SIEVE_ADJUST(mach, 1); | 117 | 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 | |||
105 | while (num-- > 0) | 127 | while (num-- > 0) |
106 | { | 128 | { |
107 | instr_pop (mach); | 129 | instr_pop (mach); |
... | @@ -116,9 +138,16 @@ instr_anyof (sieve_machine_t *mach) | ... | @@ -116,9 +138,16 @@ instr_anyof (sieve_machine_t *mach) |
116 | int num = SIEVE_ARG (mach, 0, number); | 138 | int num = SIEVE_ARG (mach, 0, number); |
117 | int val = 0; | 139 | int val = 0; |
118 | 140 | ||
119 | if (INSTR_DEBUG (mach)) | ||
120 | sieve_debug (mach, "ANYOF %d\n", num); | ||
121 | SIEVE_ADJUST(mach, 1); | 141 | 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 | |||
122 | while (num-- > 0) | 151 | while (num-- > 0) |
123 | { | 152 | { |
124 | instr_pop (mach); | 153 | instr_pop (mach); |
... | @@ -131,16 +160,83 @@ void | ... | @@ -131,16 +160,83 @@ void |
131 | instr_not (sieve_machine_t *mach) | 160 | instr_not (sieve_machine_t *mach) |
132 | { | 161 | { |
133 | if (INSTR_DEBUG (mach)) | 162 | if (INSTR_DEBUG (mach)) |
134 | sieve_debug (mach, "NOT"); | 163 | { |
164 | sieve_debug (mach, "%4lu: NOT\n", (unsigned long)(mach->pc - 1)); | ||
165 | if (INSTR_DISASS (mach)) | ||
166 | return; | ||
167 | } | ||
135 | mach->reg = !mach->reg; | 168 | mach->reg = !mach->reg; |
136 | } | 169 | } |
137 | 170 | ||
138 | void | 171 | 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 | ||
139 | sieve_abort (sieve_machine_t *mach) | 209 | sieve_abort (sieve_machine_t *mach) |
140 | { | 210 | { |
141 | longjmp (mach->errbuf, 1); | 211 | longjmp (mach->errbuf, 1); |
142 | } | 212 | } |
143 | 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 | |||
144 | int | 240 | int |
145 | sieve_run (sieve_machine_t *mach) | 241 | sieve_run (sieve_machine_t *mach) |
146 | { | 242 | { |
... | @@ -150,5 +246,65 @@ sieve_run (sieve_machine_t *mach) | ... | @@ -150,5 +246,65 @@ sieve_run (sieve_machine_t *mach) |
150 | for (mach->pc = 1; mach->prog[mach->pc].handler; ) | 246 | for (mach->pc = 1; mach->prog[mach->pc].handler; ) |
151 | (*mach->prog[mach->pc++].instr) (mach); | 247 | (*mach->prog[mach->pc++].instr) (mach); |
152 | 248 | ||
249 | if (INSTR_DEBUG (mach)) | ||
250 | sieve_debug (mach, "%4lu: STOP\n", mach->pc); | ||
251 | |||
252 | 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); | ||
153 | return 0; | 279 | return 0; |
154 | } | 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 | } | ... | ... |
-
Please register or sign in to post a comment