1 /* Copyright (C) 2000-2015 Lavtech.com corp. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18 #include "udm_config.h"
19
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <errno.h>
25
26 #include "udm_common.h"
27 #include "udm_template.h"
28 #include "udm_server.h"
29 #include "udm_env.h"
30 #include "udm_conf.h"
31 #include "udm_db.h"
32 #include "udm_http.h"
33 #include "udm_parsehtml.h"
34 #include "udm_host.h"
35 #include "udm_contentencoding.h"
36 #include "udm_utils.h"
37 #include "udm_vars.h"
38 #include "udm_wild.h"
39 #include "udm_searchtool.h"
40 #include "udm_doc.h"
41 #include "udm_match.h"
42 #include "udm_sgml.h"
43 #include "udm_proto.h"
44 #include "udm_ctype.h"
45 #include "udm_lex.h"
46 #include "udm_prog.h"
47
48
49 void
UdmProgItemInit(UDM_PROG_ITEM * i)50 UdmProgItemInit(UDM_PROG_ITEM *i)
51 {
52 bzero((void*) i, sizeof(*i));
53 i->cmdnum= UDM_PROG_HANDLED;
54 }
55
56
57 static void
UdmProgItemFree(UDM_PROG_ITEM * it)58 UdmProgItemFree(UDM_PROG_ITEM *it)
59 {
60 UDM_FREE(it->comment);
61 }
62
63
UdmProgExecutorStateInitArgs(UDM_PROG_EXECUTOR_STATE * state)64 void UdmProgExecutorStateInitArgs(UDM_PROG_EXECUTOR_STATE *state)
65 {
66 UDM_BZERO(&state->vreg, sizeof(state->vreg));
67 }
68
69
PrintComment(UDM_PROG_ITEM * it)70 static void PrintComment(UDM_PROG_ITEM *it)
71 {
72 printf("%s%s", it->comment ? " # " : "",
73 it->comment ? it->comment : "");
74 }
75
76
PrintJmp(UDM_PROG_ITEM * it,const char * name,int add)77 static void PrintJmp(UDM_PROG_ITEM *it, const char *name, int add)
78 {
79 printf("%3s %04X", name, (int) it->cmdarg.jump);
80 }
81
82
UdmProgItemPrintArg(const UDM_PROG_ARG * arg)83 static void UdmProgItemPrintArg(const UDM_PROG_ARG *arg)
84 {
85 if (arg->handler)
86 printf(" handler=%s", arg->handler->type_name);
87 if (arg->stack_offset || arg->handler)
88 printf(" stack:%03X", (int) arg->stack_offset);
89 if (arg->textdata_addr.length || arg->textdata_addr.offset)
90 {
91 printf(" textdata: %d:%d",
92 (int) arg->textdata_addr.offset,
93 (int) arg->textdata_addr.length);
94 }
95 }
96
97
UdmProgItemPrintHandled(UDM_PROG_ITEM * it)98 static void UdmProgItemPrintHandled(UDM_PROG_ITEM *it)
99 {
100 printf("%s", it->cmd->name.str);
101 UdmProgItemPrintArg(&it->item_args);
102 }
103
104
UdmProgItemPrint(UDM_PROG_ITEM * it)105 static void UdmProgItemPrint(UDM_PROG_ITEM *it)
106 {
107 switch (it->cmdnum)
108 {
109 case UDM_PROG_JE: PrintJmp(it, "je", (int) it->cmdarg.jump); break;
110 case UDM_PROG_JNE: PrintJmp(it, "jne", (int) it->cmdarg.jump); break;
111 case UDM_PROG_JMP: PrintJmp(it, "jmp", (int) it->cmdarg.jump); break;
112 case UDM_PROG_NOT_IREG0: printf("not i0"); break;
113 case UDM_PROG_INC_IREG0: printf("inc i0"); break;
114 case UDM_PROG_DEC_IREG0: printf("dec i0"); break;
115 case UDM_PROG_INC_DREG0: printf("inc d0"); break;
116 case UDM_PROG_DEC_DREG0: printf("dec d0"); break;
117 case UDM_PROG_MOV_CHR_PTR_S0_IREG0: printf("mov CHR PTR s0, ireg0"); break;
118 case UDM_PROG_MOV_INT_PTR_S0_IREG0: printf("mov INT PTR s0, ireg0"); break;
119 case UDM_PROG_MOV_DBL_PTR_S0_DREG0: printf("mov DBL PTR s0, dreg0"); break;
120 case UDM_PROG_MOV_IREG0_INT_PTR_STACK_OFFSET:
121 printf("mov i0,INT PTR [stack:%d]", (int) it->item_args.stack_offset);
122 break;
123 case UDM_PROG_MOV_IREG1_INT_PTR_STACK_OFFSET:
124 printf("mov i1,INT PTR [stack:%d]", (int) it->item_args.stack_offset);
125 break;
126 case UDM_PROG_MOV_DREG0_DBL_PTR_STACK_OFFSET:
127 printf("mov d0,DBL PTR [stack:%d]", (int) it->item_args.stack_offset);
128 break;
129 case UDM_PROG_MOV_DREG1_DBL_PTR_STACK_OFFSET:
130 printf("mov d1,DBL PTR [stack:%d]", (int) it->item_args.stack_offset);
131 break;
132 case UDM_PROG_INC_CHR_PTR_STACK_OFFSET:
133 printf("inc CHR PTR [stack:%d]", (int) it->cmdarg.offset);
134 break;
135 case UDM_PROG_DEC_CHR_PTR_STACK_OFFSET:
136 printf("dec CHR PTR [stack:%d]", (int) it->cmdarg.offset);
137 break;
138 case UDM_PROG_INC_INT_PTR_STACK_OFFSET:
139 printf("inc INT PTR [stack:%d]", (int) it->cmdarg.offset);
140 break;
141 case UDM_PROG_DEC_INT_PTR_STACK_OFFSET:
142 printf("dec INT PTR [stack:%d]", (int) it->cmdarg.offset);
143 break;
144 case UDM_PROG_INC_DBL_PTR_STACK_OFFSET:
145 printf("inc DBL PTR [stack:%d]", (int) it->cmdarg.offset);
146 break;
147 case UDM_PROG_DEC_DBL_PTR_STACK_OFFSET:
148 printf("dec DBL PTR [stack:%d]", (int) it->cmdarg.offset);
149 break;
150 case UDM_PROG_MUL_IREG0_IREG1: printf("mul i0,i1"); break;
151 case UDM_PROG_ADD_IREG0_IREG1: printf("add i0,i1"); break;
152 case UDM_PROG_SUB_IREG0_IREG1: printf("sub i0,i1"); break;
153 case UDM_PROG_AND_IREG0_IREG1: printf("and i0,i1"); break;
154 case UDM_PROG_OR_IREG0_IREG1: printf("or i0,i1"); break;
155 case UDM_PROG_XOR_IREG0_IREG1: printf("xor i0,i1"); break;
156 case UDM_PROG_SHL_IREG0_IREG1: printf("shl i0,i1"); break;
157 case UDM_PROG_SHR_IREG0_IREG1: printf("shr i0,i1"); break;
158 case UDM_PROG_DIV_IREG0_IREG1: printf("div i0,i1"); break;
159 case UDM_PROG_REM_IREG0_IREG1: printf("rem i0,i1"); break;
160
161 case UDM_PROG_MUL_DREG0_DREG1: printf("mul d0,d1"); break;
162 case UDM_PROG_ADD_DREG0_DREG1: printf("add d0,d1"); break;
163 case UDM_PROG_SUB_DREG0_DREG1: printf("sub d0,d1"); break;
164 case UDM_PROG_DIV_DREG0_DREG1: printf("div d0,d1"); break;
165
166 case UDM_PROG_MOV_HREG0_0: printf("mov h0,0"); break;
167 case UDM_PROG_MOV_SREG0_0: printf("mov s0,0"); break;
168
169 case UDM_PROG_MOV_IREG0_0: printf("mov i0,0"); break;
170 case UDM_PROG_MOV_IREG1_0: printf("mov i1,0"); break;
171 case UDM_PROG_MOV_DREG0_0: printf("mov d0,0"); break;
172 case UDM_PROG_MOV_DREG1_0: printf("mov d1,0"); break;
173 case UDM_PROG_MOV_DREG0_IREG0: printf("mov d0,i0"); break;
174 case UDM_PROG_MOV_DREG1_IREG1: printf("mov d1,i1"); break;
175 case UDM_PROG_MOV_DREG1_DREG0: printf("mov d1,d0"); break;
176 case UDM_PROG_MOV_DREG1_IREG0: printf("mov d1,i0"); break;
177 case UDM_PROG_MOV_IREG1_DREG1: printf("mov i1,d1"); break;
178 case UDM_PROG_MOV_IREG0_DREG0: printf("mov i0,d0"); break;
179
180 case UDM_PROG_SWP_DREG0_DREG1: printf("swp d0,d1"); break;
181 case UDM_PROG_SWP_IREG0_IREG1: printf("swp i0,i1"); break;
182
183 case UDM_PROG_MOV_IREG1_IREG0: printf("mov i1,i0"); break;
184
185 case UDM_PROG_MOV_DREG0_DBL: printf("mov d0,%f", it->cmdarg.val_double); break;
186 case UDM_PROG_MOV_DREG1_DBL: printf("mov d1,%f", it->cmdarg.val_double); break;
187 case UDM_PROG_MOV_IREG0_INT: printf("mov i0,%d", it->cmdarg.val_int); break;
188 case UDM_PROG_MOV_IREG1_INT: printf("mov i1,%d", it->cmdarg.val_int); break;
189 case UDM_PROG_MOV_HREG0_PTR:
190 printf("mov h0, UdmValueHandler<%s>",
191 ((const UDM_VALUE_HANDLER *)it->cmdarg.val_const_ptr)->type_name);
192 break;
193 case UDM_PROG_MOV_SREG0_STACK_OFFSET: printf("mov s0,stack+%03X", (int) it->cmdarg.offset); break;
194 case UDM_PROG_MOV_VREG0_STACK_OFFSET: printf("mov v0,stack+%03X", (int) it->cmdarg.offset); break;
195 case UDM_PROG_MOV_VREG1_STACK_OFFSET: printf("mov v1,stack+%03X", (int) it->cmdarg.offset); break;
196 case UDM_PROG_MOV_VREG2_STACK_OFFSET: printf("mov v2,stack+%03X", (int) it->cmdarg.offset); break;
197 case UDM_PROG_MOV_VREG3_STACK_OFFSET: printf("mov v3,stack+%03X", (int) it->cmdarg.offset); break;
198 case UDM_PROG_MOV_VREG4_STACK_OFFSET: printf("mov v4,stack+%03X", (int) it->cmdarg.offset); break;
199 case UDM_PROG_CMP_DREG0_DREG1_EQ: printf("cmp d0,d1 [eq]"); break;
200 case UDM_PROG_CMP_DREG0_DREG1_LT: printf("cmp d0,d1 [lt]"); break;
201 case UDM_PROG_CMP_DREG0_DREG1_GT: printf("cmp d0,d1 [gt]"); break;
202 case UDM_PROG_CMP_DREG0_DREG1_LE: printf("cmp d0,d1 [le]"); break;
203 case UDM_PROG_CMP_DREG0_DREG1_GE: printf("cmp d0,d1 [ge]"); break;
204 case UDM_PROG_CMP_DREG0_DREG1_NE: printf("cmp d0,d1 [ne]"); break;
205
206 case UDM_PROG_CMP_IREG0_IREG1_EQ: printf("cmp i0,i1 [eq]"); break;
207 case UDM_PROG_CMP_IREG0_IREG1_LT: printf("cmp i0,i1 [lt]"); break;
208 case UDM_PROG_CMP_IREG0_IREG1_GT: printf("cmp i0,i1 [gt]"); break;
209 case UDM_PROG_CMP_IREG0_IREG1_LE: printf("cmp i0,i1 [le]"); break;
210 case UDM_PROG_CMP_IREG0_IREG1_GE: printf("cmp i0,i1 [ge]"); break;
211 case UDM_PROG_CMP_IREG0_IREG1_NE: printf("cmp i0,i1 [ne]"); break;
212
213 case UDM_PROG_CALL:
214 {
215 int i;
216 const UDM_FUNCTION *func= it->cmdarg.func;
217 printf("call %s %.*s(",
218 func->prototype.result.handler ?
219 func->prototype.result.handler->type_name :
220 "void",
221 (int) func->name.length,
222 func->name.str);
223 for (i= 0; i < func->prototype.nargs; i++)
224 {
225 printf("%s%s", i > 0 ? "," : "",
226 func->prototype.args[i].handler->type_name);
227 }
228 printf(")");
229 break;
230 }
231
232 case UDM_PROG_HANDLED:
233 UdmProgItemPrintHandled(it); break;
234 case UDM_PROG_NOP: printf("nop"); break;
235 case UDM_PROG_EXIT: printf("exit"); break;
236 }
237 PrintComment(it);
238 printf("\n");
239 }
240
241
UdmProgInit(UDM_PROG * prg)242 void UdmProgInit(UDM_PROG *prg)
243 {
244 bzero((void*)prg, sizeof(*prg));
245 UdmDSTRInit(&prg->textdata, 1024);
246 }
247
248
249 void
UdmProgPrint(const UDM_PROG * p)250 UdmProgPrint(const UDM_PROG *p)
251 {
252 size_t i;
253
254 for (i=0 ; i < p->nitems ; i++)
255 {
256 UDM_PROG_ITEM *it= &p->Items[i];
257 printf("%04X ", (int) i);
258 UdmProgItemPrint(it);
259 }
260 }
261
262
UdmProgFree(UDM_PROG * prg)263 void UdmProgFree(UDM_PROG *prg)
264 {
265 size_t i;
266 for (i=0 ; i < prg->nitems; i++)
267 UdmProgItemFree(&prg->Items[i]);
268 UDM_FREE(prg->Items);
269 UdmDSTRFree(&prg->textdata);
270 }
271
272
273 static int
UdmTemplateExecutorProcessOneCommand(UDM_PROG_EXECUTOR * executor,const UDM_PROG_ITEM * start,size_t nitems)274 UdmTemplateExecutorProcessOneCommand(UDM_PROG_EXECUTOR *executor,
275 const UDM_PROG_ITEM *start,
276 size_t nitems)
277 {
278 UDM_PROG_EXECUTOR_STATE *state= &executor->state;
279 const UDM_PROG_ITEM *it= executor->state.curr;
280 switch (it->cmdnum)
281 {
282 case UDM_PROG_JNE:
283 if (state->reg.i[0])
284 state->curr= start + it->cmdarg.jump;
285 else
286 state->curr++;
287 return 0;
288
289 case UDM_PROG_JE:
290 if (!state->reg.i[0])
291 state->curr= start + it->cmdarg.jump;
292 else
293 state->curr++;
294 return 0;
295
296 case UDM_PROG_JMP:
297 state->curr= start + it->cmdarg.jump;
298 return 0;
299
300 case UDM_PROG_NOT_IREG0: state->reg.i[0]= ~(state->reg.i[0]); break;
301 case UDM_PROG_INC_IREG0: state->reg.i[0]++; break;
302 case UDM_PROG_DEC_IREG0: state->reg.i[0]--; break;
303 case UDM_PROG_INC_DREG0: state->reg.d[0]++; break;
304 case UDM_PROG_DEC_DREG0: state->reg.d[0]--; break;
305 case UDM_PROG_MOV_IREG0_INT_PTR_STACK_OFFSET:
306 state->reg.i[0]= (((int *) (state->stack.Val.str + it->item_args.stack_offset))[0]);
307 break;
308 case UDM_PROG_MOV_IREG1_INT_PTR_STACK_OFFSET:
309 state->reg.i[1]= (((int *) (state->stack.Val.str + it->item_args.stack_offset))[0]);
310 break;
311 case UDM_PROG_MOV_DREG0_DBL_PTR_STACK_OFFSET:
312 state->reg.d[0]= (((double *) (state->stack.Val.str + it->item_args.stack_offset))[0]);
313 break;
314 case UDM_PROG_MOV_DREG1_DBL_PTR_STACK_OFFSET:
315 state->reg.d[1]= (((double *) (state->stack.Val.str + it->item_args.stack_offset))[0]);
316 break;
317 case UDM_PROG_MOV_CHR_PTR_S0_IREG0:
318 (((char *) (state->reg.s0))[0])= state->reg.i[0];
319 break;
320 case UDM_PROG_MOV_INT_PTR_S0_IREG0:
321 (((int *) (state->reg.s0))[0])= state->reg.i[0];
322 break;
323 case UDM_PROG_MOV_DBL_PTR_S0_DREG0:
324 (((double *) (state->reg.s0))[0])= state->reg.d[0];
325 break;
326 case UDM_PROG_INC_CHR_PTR_STACK_OFFSET:
327 (((char *) (state->stack.Val.str + it->item_args.stack_offset))[0])++;
328 break;
329 case UDM_PROG_DEC_CHR_PTR_STACK_OFFSET:
330 (((char *) (state->stack.Val.str + it->item_args.stack_offset))[0])--;
331 break;
332 case UDM_PROG_INC_DBL_PTR_STACK_OFFSET:
333 (((double *) (state->stack.Val.str + it->item_args.stack_offset))[0])++;
334 break;
335 case UDM_PROG_DEC_DBL_PTR_STACK_OFFSET:
336 (((double *) (state->stack.Val.str + it->item_args.stack_offset))[0])--;
337 break;
338 case UDM_PROG_INC_INT_PTR_STACK_OFFSET:
339 (((int *) (state->stack.Val.str + it->item_args.stack_offset))[0])++;
340 break;
341 case UDM_PROG_DEC_INT_PTR_STACK_OFFSET:
342 (((int *) (state->stack.Val.str + it->item_args.stack_offset))[0])--;
343 break;
344 case UDM_PROG_MOV_SREG0_STACK_OFFSET:
345 state->reg.s0= state->stack.Val.str + it->cmdarg.offset;
346 break;
347 case UDM_PROG_MOV_VREG0_STACK_OFFSET:
348 state->vreg[0].Data= state->stack.Val.str + it->cmdarg.offset;
349 break;
350 case UDM_PROG_MOV_VREG1_STACK_OFFSET:
351 state->vreg[1].Data= state->stack.Val.str + it->cmdarg.offset;
352 break;
353 case UDM_PROG_MOV_VREG2_STACK_OFFSET:
354 state->vreg[2].Data= state->stack.Val.str + it->cmdarg.offset;
355 break;
356 case UDM_PROG_MOV_VREG3_STACK_OFFSET:
357 state->vreg[3].Data= state->stack.Val.str + it->cmdarg.offset;
358 break;
359 case UDM_PROG_MOV_VREG4_STACK_OFFSET:
360 state->vreg[4].Data= state->stack.Val.str + it->cmdarg.offset;
361 break;
362 case UDM_PROG_MUL_IREG0_IREG1: state->reg.i[0]*= state->reg.i[1]; break;
363 case UDM_PROG_ADD_IREG0_IREG1: state->reg.i[0]+= state->reg.i[1]; break;
364 case UDM_PROG_SUB_IREG0_IREG1: state->reg.i[0]-= state->reg.i[1]; break;
365 case UDM_PROG_AND_IREG0_IREG1: state->reg.i[0]&= state->reg.i[1]; break;
366 case UDM_PROG_OR_IREG0_IREG1: state->reg.i[0]|= state->reg.i[1]; break;
367 case UDM_PROG_XOR_IREG0_IREG1: state->reg.i[0]^= state->reg.i[1]; break;
368 case UDM_PROG_SHL_IREG0_IREG1: state->reg.i[0]<<= state->reg.i[1]; break;
369 case UDM_PROG_SHR_IREG0_IREG1: state->reg.i[0]>>= state->reg.i[1]; break;
370
371 case UDM_PROG_DIV_IREG0_IREG1:
372 state->reg.i[0]= state->reg.i[1] ? state->reg.i[0] / state->reg.i[1] : 0;
373 break;
374 case UDM_PROG_REM_IREG0_IREG1:
375 state->reg.i[0]= state->reg.i[1] ? state->reg.i[0] % state->reg.i[1] : 0;
376 break;
377
378
379 case UDM_PROG_MUL_DREG0_DREG1: state->reg.d[0]*= state->reg.d[1]; break;
380 case UDM_PROG_ADD_DREG0_DREG1: state->reg.d[0]+= state->reg.d[1]; break;
381 case UDM_PROG_SUB_DREG0_DREG1: state->reg.d[0]-= state->reg.d[1]; break;
382 case UDM_PROG_DIV_DREG0_DREG1:
383 state->reg.d[0]= state->reg.d[1] ? state->reg.d[0] / state->reg.d[1] : 0;
384 break;
385
386 case UDM_PROG_MOV_HREG0_0: state->reg.h0= NULL; break;
387 case UDM_PROG_MOV_SREG0_0: state->reg.s0= NULL; break;
388 case UDM_PROG_MOV_IREG0_0: state->reg.i[0]= 0; break;
389 case UDM_PROG_MOV_IREG1_0: state->reg.i[1]= 0; break;
390 case UDM_PROG_MOV_DREG0_0: state->reg.d[0]= 0; break;
391 case UDM_PROG_MOV_DREG1_0: state->reg.d[1]= 0; break;
392 case UDM_PROG_MOV_DREG0_IREG0: state->reg.d[0]= state->reg.i[0]; break;
393 case UDM_PROG_MOV_DREG1_IREG1: state->reg.d[1]= state->reg.i[1]; break;
394 case UDM_PROG_MOV_DREG1_DREG0: state->reg.d[1]= state->reg.d[0]; break;
395 case UDM_PROG_MOV_DREG1_IREG0: state->reg.d[1]= state->reg.i[0]; break;
396 case UDM_PROG_MOV_IREG1_DREG1: state->reg.i[1]= state->reg.d[1]; break;
397 case UDM_PROG_MOV_IREG0_DREG0: state->reg.i[0]= state->reg.d[0]; break;
398
399 case UDM_PROG_SWP_DREG0_DREG1:
400 {
401 double tmp= state->reg.d[0];
402 state->reg.d[0]= state->reg.d[1];
403 state->reg.d[1]= tmp;
404 break;
405 }
406 case UDM_PROG_SWP_IREG0_IREG1:
407 {
408 int tmp= state->reg.i[0];
409 state->reg.i[0]= state->reg.i[1];
410 state->reg.i[1]= tmp;
411 break;
412 }
413 case UDM_PROG_MOV_IREG1_IREG0: state->reg.i[1]= state->reg.i[0]; break;
414 case UDM_PROG_MOV_IREG0_INT: state->reg.i[0]= it->cmdarg.val_int; break;
415 case UDM_PROG_MOV_IREG1_INT: state->reg.i[1]= it->cmdarg.val_int; break;
416 case UDM_PROG_MOV_DREG0_DBL: state->reg.d[0]= it->cmdarg.val_double; break;
417 case UDM_PROG_MOV_DREG1_DBL: state->reg.d[1]= it->cmdarg.val_double; break;
418 case UDM_PROG_MOV_HREG0_PTR: state->reg.h0= it->cmdarg.val_const_ptr; break;
419 case UDM_PROG_CMP_DREG0_DREG1_EQ:
420 state->reg.i[0]= (state->reg.d[0] == state->reg.d[1]);
421 break;
422 case UDM_PROG_CMP_DREG0_DREG1_NE:
423 state->reg.i[0]= (state->reg.d[0] != state->reg.d[1]);
424 break;
425
426 case UDM_PROG_CMP_DREG0_DREG1_LT:
427 state->reg.i[0]= (state->reg.d[0] < state->reg.d[1]);
428 break;
429
430 case UDM_PROG_CMP_DREG0_DREG1_GT:
431 state->reg.i[0]= (state->reg.d[0] > state->reg.d[1]);
432 break;
433
434 case UDM_PROG_CMP_DREG0_DREG1_LE:
435 state->reg.i[0]= (state->reg.d[0] <= state->reg.d[1]);
436 break;
437
438 case UDM_PROG_CMP_DREG0_DREG1_GE:
439 state->reg.i[0]= (state->reg.d[0] >= state->reg.d[1]);
440 break;
441
442 case UDM_PROG_CMP_IREG0_IREG1_EQ:
443 state->reg.i[0]= (state->reg.i[0] == state->reg.i[1]);
444 break;
445 case UDM_PROG_CMP_IREG0_IREG1_NE:
446 state->reg.i[0]= (state->reg.i[0] != state->reg.i[1]);
447 break;
448
449 case UDM_PROG_CMP_IREG0_IREG1_LT:
450 state->reg.i[0]= (state->reg.i[0] < state->reg.i[1]);
451 break;
452
453 case UDM_PROG_CMP_IREG0_IREG1_GT:
454 state->reg.i[0]= (state->reg.i[0] > state->reg.i[1]);
455 break;
456
457 case UDM_PROG_CMP_IREG0_IREG1_LE:
458 state->reg.i[0]= (state->reg.i[0] <= state->reg.i[1]);
459 break;
460
461 case UDM_PROG_CMP_IREG0_IREG1_GE:
462 state->reg.i[0]= (state->reg.i[0] >= state->reg.i[1]);
463 break;
464
465 case UDM_PROG_CALL:
466 it->cmdarg.func->func(state);
467 break;
468
469 case UDM_PROG_HANDLED:
470 it->cmd->exec(state);
471 break;
472 case UDM_PROG_NOP:
473 break;
474 case UDM_PROG_EXIT:
475 state->curr= start + nitems;
476 return state->reg.i[0];
477 }
478 state->curr++;
479 return 0;
480 }
481
482
483 int
UdmProgExecutorExec(UDM_PROG_EXECUTOR * tmpl,const UDM_PROG * prg)484 UdmProgExecutorExec(UDM_PROG_EXECUTOR *tmpl, const UDM_PROG *prg)
485 {
486 int rc= 0;
487 tmpl->state.prog= prg;
488 for (tmpl->state.curr= prg->Items;
489 tmpl->state.curr < &prg->Items[prg->nitems]; )
490 {
491 rc= UdmTemplateExecutorProcessOneCommand(tmpl, prg->Items, prg->nitems);
492 }
493 tmpl->state.prog= NULL;
494 return rc;
495 }
496
497
498 void
UdmProgExecutorInit(UDM_PROG_EXECUTOR * executor,FILE * stream,UDM_DSTR * dstr)499 UdmProgExecutorInit(UDM_PROG_EXECUTOR *executor,
500 FILE *stream, UDM_DSTR *dstr)
501 {
502 executor->state.reg.s0= NULL;
503 executor->state.reg.h0= NULL;
504 bzero(&executor->state.globals, sizeof(executor->state.globals));
505 executor->state.globals.stdout= stream;
506 executor->state.fatal_error= UDM_FALSE;
507 UdmProgExecutorStateInitArgs(&executor->state);
508 UdmDSTRInit(&executor->state.stack, 1024);
509 UdmDSTRAlloc(&executor->state.stack, 128*1024);
510 }
511
512
513 void
UdmProgExecutorFree(UDM_PROG_EXECUTOR * executor)514 UdmProgExecutorFree(UDM_PROG_EXECUTOR *executor)
515 {
516 UdmDSTRFree(&executor->state.stack);
517 }
518
519
CompileStackInit(UDM_PROG_COMPILE_STACK * st)520 static void CompileStackInit(UDM_PROG_COMPILE_STACK *st)
521 {
522 bzero((void*) st, sizeof(*st));
523 }
524
525
CompileStackFree(UDM_PROG_COMPILE_STACK * st)526 static void CompileStackFree(UDM_PROG_COMPILE_STACK *st)
527 {
528 UDM_FREE(st->Items);
529 }
530
531
UdmProgVarListInit(UDM_PROG_VARLIST * List)532 void UdmProgVarListInit(UDM_PROG_VARLIST *List)
533 {
534 UDM_BZERO(List, sizeof(*List));
535 }
536
537
UdmProgVarListFree(UDM_PROG_VARLIST * List)538 void UdmProgVarListFree(UDM_PROG_VARLIST *List)
539 {
540 size_t i;
541 for (i= 0 ; i < List->nitems; i++)
542 UdmFree(List->Item[i].name);
543 UdmFree(List->Item);
544 }
545
546
UdmProgVarListAdd(UDM_PROG_VARLIST * List,const char * name,const UDM_PROG_VAR_VALUE * Value)547 udm_rc_t UdmProgVarListAdd(UDM_PROG_VARLIST *List,
548 const char *name,
549 const UDM_PROG_VAR_VALUE *Value)
550 {
551 if (List->nitems >= List->mitems)
552 {
553 List->mitems+= 16;
554 if (!(List->Item= (UDM_PROG_VAR2 *) UdmRealloc(List->Item,
555 List->mitems *
556 sizeof(UDM_PROG_VAR2))))
557 return UDM_ERROR;
558 }
559 List->Item[List->nitems].name= UdmStrdup(name);
560 List->Item[List->nitems].value= Value[0];
561 List->nitems++;
562 return UDM_OK;
563 }
564
565
UdmProgVarListListInit(UDM_PROG_VARLISTLIST * List)566 void UdmProgVarListListInit(UDM_PROG_VARLISTLIST *List)
567 {
568 UDM_BZERO(List, sizeof(*List));
569 }
570
571
UdmProgVarListListFree(UDM_PROG_VARLISTLIST * List)572 void UdmProgVarListListFree(UDM_PROG_VARLISTLIST *List)
573 {
574 size_t i;
575 for (i= 0; i < List->nitems; i++)
576 UdmProgVarListFree(&List->Item[i]);
577 UdmFree(List->Item);
578 }
579
580
UdmProgVarListListAdd(UDM_PROG_VARLISTLIST * List,const UDM_PROG_VARLIST * Item)581 udm_rc_t UdmProgVarListListAdd(UDM_PROG_VARLISTLIST *List,
582 const UDM_PROG_VARLIST *Item)
583 {
584 if (List->nitems >= List->mitems)
585 {
586 List->mitems+= 16;
587 if (!(List->Item= (UDM_PROG_VARLIST *) UdmRealloc(List->Item,
588 List->mitems *
589 sizeof(UDM_PROG_VARLIST))))
590 return UDM_ERROR;
591 }
592 List->Item[List->nitems++]= Item[0];
593 return UDM_OK;
594 }
595
596
UdmProgVarListFind(const UDM_PROG_VARLIST * List,const char * name)597 const UDM_PROG_VAR2 *UdmProgVarListFind(const UDM_PROG_VARLIST *List,
598 const char *name)
599 {
600 size_t i;
601 for (i= 0; i < List->nitems; i++)
602 {
603 if (!strcmp(List->Item[i].name, name))
604 return &List->Item[i];
605 }
606 return NULL;
607 }
608
609
610 void
UdmProgCompilerInit(UDM_PROG_COMPILER * compiler,size_t lineno,UDM_PROG * prg,const char * src,size_t srclen)611 UdmProgCompilerInit(UDM_PROG_COMPILER *compiler,
612 size_t lineno, UDM_PROG *prg,
613 const char *src, size_t srclen)
614 {
615 const char *DebugProg= getenv("DebugProg");
616 compiler->prg= prg;
617 CompileStackInit(&compiler->st);
618 compiler->comment_type= COMMENT_NONE;
619 compiler->lineno= lineno;
620 compiler->start= src;
621 compiler->errstr[0]= '\0';
622 compiler->pi_count= 0;
623 compiler->current_loop_continue= 0;
624 compiler->generate_debug_info= DebugProg &&
625 udm_strntobool(DebugProg, strlen(DebugProg));
626 UdmLexScannerInit(&compiler->scanner, NULL, 0);
627 UdmProgVarListListInit(&compiler->Vars2);
628 }
629
630
631 void
UdmProgCompilerFree(UDM_PROG_COMPILER * compiler)632 UdmProgCompilerFree(UDM_PROG_COMPILER *compiler)
633 {
634 CompileStackFree(&compiler->st);
635 }
636
637
638 UDM_PROG *
UdmProgCompilerGetProg(UDM_PROG_COMPILER * tmpl)639 UdmProgCompilerGetProg(UDM_PROG_COMPILER *tmpl)
640 {
641 return tmpl->prg;
642 }
643
644
645 udm_rc_t
UdmProgAdd(UDM_PROG * prg,UDM_PROG_ITEM * item)646 UdmProgAdd(UDM_PROG *prg, UDM_PROG_ITEM *item)
647 {
648 if (prg->nitems >= prg->mitems)
649 {
650 prg->mitems+= 64;
651 prg->Items= (UDM_PROG_ITEM*) UdmRealloc(prg->Items,
652 prg->mitems*sizeof(*item));
653 if (!prg->Items)
654 return UDM_ERROR;
655 }
656 prg->Items[prg->nitems]= item[0];
657 prg->nitems++;
658 return UDM_OK;
659 }
660
661
662 udm_rc_t
UdmProgAddArg0SimpleOp(UDM_PROG * prog,udm_tmpl_cmd_t op)663 UdmProgAddArg0SimpleOp(UDM_PROG *prog, udm_tmpl_cmd_t op)
664 {
665 UDM_PROG_ITEM i;
666 UdmProgItemInit(&i);
667 i.cmdnum= op;
668 return UdmProgAdd(prog, &i);
669 }
670
671
672 udm_rc_t
UdmProgAddArg1SimpleOpDouble(UDM_PROG * prog,udm_tmpl_cmd_t op,double value)673 UdmProgAddArg1SimpleOpDouble(UDM_PROG *prog, udm_tmpl_cmd_t op, double value)
674 {
675 UDM_PROG_ITEM i;
676 UdmProgItemInit(&i);
677 i.cmdnum= op;
678 i.cmdarg.val_double= value;
679 return UdmProgAdd(prog, &i);
680 }
681
682
683 udm_rc_t
UdmProgAddArg1SimpleOpInt(UDM_PROG * prog,udm_tmpl_cmd_t op,int value)684 UdmProgAddArg1SimpleOpInt(UDM_PROG *prog, udm_tmpl_cmd_t op, int value)
685 {
686 UDM_PROG_ITEM i;
687 UdmProgItemInit(&i);
688 i.cmdnum= op;
689 i.cmdarg.val_int= value;
690 return UdmProgAdd(prog, &i);
691 }
692
693
694 udm_rc_t
UdmProgAddArg0Simple(UDM_PROG * prog,UDM_PROG_CMD * cmd)695 UdmProgAddArg0Simple(UDM_PROG *prog, UDM_PROG_CMD *cmd)
696 {
697 UDM_PROG_ITEM i;
698 UdmProgItemInit(&i);
699 i.cmd= cmd;
700 return UdmProgAdd(prog, &i);
701 }
702
703
704 udm_rc_t
UdmProgAddJmp(UDM_PROG * prog,udm_tmpl_cmd_t cmdnum,int addr)705 UdmProgAddJmp(UDM_PROG *prog, udm_tmpl_cmd_t cmdnum, int addr)
706 {
707 UDM_PROG_ITEM i;
708 UdmProgItemInit(&i);
709 i.cmdnum= cmdnum;
710 i.cmdarg.jump= addr;
711 return UdmProgAdd(prog, &i);
712 }
713
714
715 udm_rc_t
UdmProgAddValueHandler(UDM_PROG * prog,udm_tmpl_cmd_t cmdnum,const UDM_VALUE_HANDLER * handler)716 UdmProgAddValueHandler(UDM_PROG *prog, udm_tmpl_cmd_t cmdnum,
717 const UDM_VALUE_HANDLER *handler)
718 {
719 UDM_PROG_ITEM i;
720 UdmProgItemInit(&i);
721 i.cmdnum= cmdnum;
722 i.cmdarg.val_const_ptr= handler;
723 return UdmProgAdd(prog, &i);
724 }
725
726
727 void *
UdmProgExecutorStateSetupReturnValue(UDM_PROG_EXECUTOR_STATE * state,const UDM_VALUE_HANDLER * handler)728 UdmProgExecutorStateSetupReturnValue(UDM_PROG_EXECUTOR_STATE *state,
729 const UDM_VALUE_HANDLER *handler)
730 {
731 UDM_ASSERT(state->reg.s0);
732 UDM_ASSERT(state->reg.h0 == handler);
733 handler->Constructor(state->reg.s0, NULL, 0);
734 return state->reg.s0;
735 }
736
737
738 void
UdmProgExecutorStateReturnStrn(UDM_PROG_EXECUTOR_STATE * state,const char * str,size_t length)739 UdmProgExecutorStateReturnStrn(UDM_PROG_EXECUTOR_STATE *state,
740 const char *str, size_t length)
741 {
742 UDM_SECTION *ret= UdmProgExecutorStateSetupReturnValue(state, &UdmValueHandlerSimple);
743 UdmValueHandlerSimple.SetStrn((char *) ret, str, length);
744 }
745