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