Moved standard syslevel APIs declaration to winbase.h.
[wine] / debugger / expr.c
1 /*
2  * File expr.c - expression handling for Wine internal debugger.
3  *
4  * Copyright (C) 1997, Eric Youngdale.
5  *
6  */
7
8 #include "config.h"
9 #include <stdlib.h>
10 #include <string.h>
11 #include "winbase.h"
12 #include "wine/winbase16.h"
13 #include "task.h"
14 #include "debugger.h"
15 #include "expr.h"
16
17 #include <stdarg.h>
18
19 struct expr
20 {
21   unsigned int  perm;
22   unsigned int  type:31;
23   union
24   {
25     struct
26     {
27       int value;
28     } constant;
29
30     struct
31     {
32       const char * str;
33     } string;
34
35     struct
36     {
37       unsigned int value;
38     } u_const;
39
40     struct
41     {
42       const char * name;
43     } symbol;
44
45     struct
46     {
47       const char * name;
48     } intvar;
49
50     struct
51     {
52       int unop_type;
53       struct expr * exp1;
54       int             result;
55     } unop;
56
57     struct
58     {
59       int binop_type;
60       int result;
61       struct expr * exp1;
62       struct expr * exp2;
63     } binop;
64
65     struct
66     {
67       struct datatype * cast;
68       struct expr     * expr;
69     } cast;
70
71     struct
72     {
73       struct expr * exp1;
74       const char * element_name;
75       int result;
76     } structure;
77
78     struct
79     {
80       struct expr * base;
81       struct expr * index;
82     } array;
83
84     struct
85     {
86       const char  * funcname;
87       int           nargs;
88       int           result;
89       struct expr * arg[5];
90     } call;
91
92   } un;
93 };
94
95 #define EXPR_TYPE_CONST         0
96 #define EXPR_TYPE_US_CONST      1
97 #define EXPR_TYPE_SYMBOL        2
98 #define EXPR_TYPE_INTVAR        3
99 #define EXPR_TYPE_BINOP         4
100 #define EXPR_TYPE_UNOP          5
101 #define EXPR_TYPE_STRUCT        6
102 #define EXPR_TYPE_PSTRUCT       7
103 #define EXPR_TYPE_ARRAY         8
104 #define EXPR_TYPE_CALL          9
105 #define EXPR_TYPE_STRING        10
106 #define EXPR_TYPE_CAST          11
107
108 static char expr_list[4096];
109 static int next_expr_free = 0;
110
111 /*
112  * This is how we turn an expression address into the actual value.
113  * This works well in the 32 bit domain - not sure at all about the
114  * 16 bit world.
115  */
116 #define VAL(_exp)       DEBUG_GetExprValue(&_exp, NULL)
117
118 static
119 struct expr *
120 DEBUG_GetFreeExpr(void)
121 {
122   struct expr * rtn;
123
124   rtn =  (struct expr *) &expr_list[next_expr_free];
125
126   next_expr_free += sizeof(struct expr);
127   assert(next_expr_free < sizeof(expr_list));
128
129   return rtn;
130 }
131
132 void
133 DEBUG_FreeExprMem(void)
134 {
135   next_expr_free = 0;
136 }
137
138 struct expr *
139 DEBUG_TypeCastExpr(struct datatype * dt, struct expr * exp)
140 {
141   struct expr * ex;
142
143   ex = DEBUG_GetFreeExpr();
144
145   ex->type        = EXPR_TYPE_CAST;
146   ex->un.cast.cast = dt;
147   ex->un.cast.expr = exp;
148   return ex;
149 }
150
151 struct expr *
152 DEBUG_IntVarExpr(const char* name)
153 {
154   struct expr * ex;
155
156   ex = DEBUG_GetFreeExpr();
157
158   ex->type        = EXPR_TYPE_INTVAR;
159   ex->un.intvar.name = name;
160   return ex;
161 }
162
163 struct expr *
164 DEBUG_SymbolExpr(const char * name)
165 {
166   struct expr * ex;
167
168   ex = DEBUG_GetFreeExpr();
169
170   ex->type        = EXPR_TYPE_SYMBOL;
171   ex->un.symbol.name = name;
172   return ex;
173 }
174
175 struct expr *
176 DEBUG_ConstExpr(int value)
177 {
178   struct expr * ex;
179
180   ex = DEBUG_GetFreeExpr();
181
182   ex->type        = EXPR_TYPE_CONST;
183   ex->un.constant.value = value;
184   return ex;
185 }
186
187 struct expr *
188 DEBUG_StringExpr(const char * str)
189 {
190   struct expr * ex;
191   char * pnt;
192   ex = DEBUG_GetFreeExpr();
193
194   ex->type        = EXPR_TYPE_STRING;
195   ex->un.string.str = str+1;
196   pnt = strrchr(ex->un.string.str, '"');
197   if( pnt != NULL )
198     {
199       *pnt =  '\0';
200     }
201   return ex;
202 }
203
204 struct expr *
205 DEBUG_USConstExpr(unsigned int value)
206 {
207   struct expr * ex;
208
209   ex = DEBUG_GetFreeExpr();
210
211   ex->type           = EXPR_TYPE_CONST;
212   ex->un.u_const.value = value;
213   return ex;
214 }
215
216 struct expr *
217 DEBUG_BinopExpr(int operator_type, struct expr * exp1, struct expr * exp2)
218 {
219   struct expr * ex;
220
221   ex = DEBUG_GetFreeExpr();
222
223   ex->type           = EXPR_TYPE_BINOP;
224   ex->un.binop.binop_type = operator_type;
225   ex->un.binop.exp1     = exp1;
226   ex->un.binop.exp2     = exp2;
227   return ex;
228 }
229
230 struct expr *
231 DEBUG_UnopExpr(int operator_type, struct expr * exp1)
232 {
233   struct expr * ex;
234
235   ex = DEBUG_GetFreeExpr();
236
237   ex->type           = EXPR_TYPE_UNOP;
238   ex->un.unop.unop_type = operator_type;
239   ex->un.unop.exp1      = exp1;
240   return ex;
241 }
242
243 struct expr *
244 DEBUG_StructExpr(struct expr * exp, const char * element)
245 {
246   struct expr * ex;
247
248   ex = DEBUG_GetFreeExpr();
249
250   ex->type           = EXPR_TYPE_STRUCT;
251   ex->un.structure.exp1 = exp;
252   ex->un.structure.element_name = element;
253   return ex;
254 }
255
256 struct expr *
257 DEBUG_StructPExpr(struct expr * exp, const char * element)
258 {
259   struct expr * ex;
260
261   ex = DEBUG_GetFreeExpr();
262
263   ex->type           = EXPR_TYPE_PSTRUCT;
264   ex->un.structure.exp1 = exp;
265   ex->un.structure.element_name = element;
266   return ex;
267 }
268
269 struct expr *
270 DEBUG_CallExpr(const char * funcname, int nargs, ...)
271 {
272   struct expr * ex;
273   va_list ap;
274   int i;
275
276   ex = DEBUG_GetFreeExpr();
277
278   ex->type           = EXPR_TYPE_CALL;
279   ex->un.call.funcname = funcname;
280   ex->un.call.nargs = nargs;
281
282   va_start(ap, nargs);
283   for(i=0; i < nargs; i++)
284     {
285       ex->un.call.arg[i] = va_arg(ap, struct expr *);
286     }
287   va_end(ap);
288   return ex;
289 }
290
291 DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
292 {
293   DBG_VALUE     rtn;
294   int           i;
295   DBG_VALUE     exp1;
296   DBG_VALUE     exp2;
297   unsigned int  cexp[5];
298   int               scale1;
299   int               scale2;
300   int               scale3;
301   struct datatype * type1;
302   struct datatype * type2;
303
304   rtn.type = NULL;
305   rtn.cookie = DV_INVALID;
306   rtn.addr.off = 0;
307   rtn.addr.seg = 0;
308
309   switch(exp->type)
310     {
311     case EXPR_TYPE_CAST:
312       rtn = DEBUG_EvalExpr(exp->un.cast.expr);
313       rtn.type = exp->un.cast.cast;
314       if (DEBUG_GetType(rtn.type) == DT_POINTER)
315          rtn.cookie = DV_TARGET;
316       break;
317     case EXPR_TYPE_STRING:
318       rtn.type = DEBUG_TypeString;
319       rtn.cookie = DV_HOST;
320       rtn.addr.off = (unsigned int) &exp->un.string.str;
321       rtn.addr.seg = 0;
322       break;
323     case EXPR_TYPE_CONST:
324       rtn.type = DEBUG_TypeIntConst;
325       rtn.cookie = DV_HOST;
326       rtn.addr.off = (unsigned int) &exp->un.constant.value;
327       rtn.addr.seg = 0;
328       break;
329     case EXPR_TYPE_US_CONST:
330       rtn.type = DEBUG_TypeUSInt;
331       rtn.cookie = DV_HOST;
332       rtn.addr.off = (unsigned int) &exp->un.u_const.value;
333       rtn.addr.seg = 0;
334       break;
335     case EXPR_TYPE_SYMBOL:
336       if( !DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE) )
337         {    
338            RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
339         }
340       break;
341     case EXPR_TYPE_PSTRUCT:
342       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
343       if( exp1.type == NULL )
344         {
345            RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
346         }
347       rtn.cookie = DV_TARGET;
348       rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &type1);
349       if( type1 == NULL )
350         {
351           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
352         }
353       rtn.type = type1;
354       DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
355                               &exp->un.structure.result);
356       break;
357     case EXPR_TYPE_STRUCT:
358       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
359       if( exp1.type == NULL )
360         {
361           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
362         }
363       rtn = exp1;
364       DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
365                               &exp->un.structure.result);
366       break;
367     case EXPR_TYPE_CALL:
368       /*
369        * First, evaluate all of the arguments.  If any of them are not
370        * evaluable, then bail.
371        */
372       for(i=0; i < exp->un.call.nargs; i++)
373         {
374           exp1  = DEBUG_EvalExpr(exp->un.call.arg[i]);
375           if( exp1.type == NULL )
376             {
377               return rtn;
378             }
379           cexp[i] = DEBUG_GetExprValue(&exp1, NULL);
380         }
381
382       /*
383        * Now look up the address of the function itself.
384        */
385       if( !DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ) )
386         {
387           RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
388         }
389
390 #if 0
391       /* FIXME: NEWDBG NIY */
392       /* Anyway, I wonder how this could work depending on the calling order of
393        * the function (cdecl vs pascal for example)
394        */
395       int               (*fptr)();
396
397       fptr = (int (*)()) rtn.addr.off;
398       switch(exp->un.call.nargs)
399         {
400         case 0:
401           exp->un.call.result = (*fptr)();
402           break;
403         case 1:
404           exp->un.call.result = (*fptr)(cexp[0]);
405           break;
406         case 2:
407           exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
408           break;
409         case 3:
410           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
411           break;
412         case 4:
413           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
414           break;
415         case 5:
416           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
417           break;
418         }
419 #else
420       DEBUG_Printf(DBG_CHN_MESG, "Function call no longer implemented\n");
421       /* would need to set up a call to this function, and then restore the current
422        * context afterwards...
423        */
424       exp->un.call.result = 0;
425 #endif
426       rtn.type = DEBUG_TypeInt;
427       rtn.cookie = DV_HOST;
428       rtn.addr.off = (unsigned int) &exp->un.call.result;
429
430       break;
431     case EXPR_TYPE_INTVAR:
432       {
433
434          DBG_INTVAR*    div = DEBUG_GetIntVar(exp->un.intvar.name);
435
436          if (!div) RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
437          rtn.cookie = DV_HOST;
438          rtn.type = div->type;
439          rtn.addr.off = (unsigned int)div->pval;
440          /* EPP FIXME rtn.addr.seg = ?? */
441       }
442       break;
443     case EXPR_TYPE_BINOP:
444       exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
445       exp2 = DEBUG_EvalExpr(exp->un.binop.exp2);
446       rtn.cookie = DV_HOST;
447       if( exp1.type == NULL || exp2.type == NULL )
448         {
449           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
450         }
451       if( exp1.type == DEBUG_TypeIntConst && exp2.type == DEBUG_TypeIntConst )
452         {
453           rtn.type = exp1.type;
454         }
455       else
456         {
457           rtn.type = DEBUG_TypeInt;
458         }
459       rtn.addr.seg = 0;
460       rtn.addr.off = (unsigned int) &exp->un.binop.result;
461       switch(exp->un.binop.binop_type)
462         {
463         case EXP_OP_ADD:
464           type1 = DEBUG_GetPointerType(exp1.type);
465           type2 = DEBUG_GetPointerType(exp2.type);
466           scale1 = 1;
467           scale2 = 1;
468           if( type1 != NULL && type2 != NULL )
469             {
470               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
471             }
472           else if( type1 != NULL )
473             {
474               scale2 = DEBUG_GetObjectSize(type1);
475               rtn.type = exp1.type;
476             }
477           else if( type2 != NULL )
478             {
479               scale1 = DEBUG_GetObjectSize(type2);
480               rtn.type = exp2.type;
481             }
482           exp->un.binop.result = (VAL(exp1) * scale1  + scale2 * VAL(exp2));
483           break;
484         case EXP_OP_SUB:
485           type1 = DEBUG_GetPointerType(exp1.type);
486           type2 = DEBUG_GetPointerType(exp2.type);
487           scale1 = 1;
488           scale2 = 1;
489           scale3 = 1;
490           if( type1 != NULL && type2 != NULL )
491             {
492               if( type1 != type2 )
493                 {
494                   RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
495                 }
496               scale3 = DEBUG_GetObjectSize(type1);
497             }
498           else if( type1 != NULL )
499             {
500               scale2 = DEBUG_GetObjectSize(type1);
501               rtn.type = exp1.type;
502             }
503
504           else if( type2 != NULL )
505             {
506               scale1 = DEBUG_GetObjectSize(type2);
507               rtn.type = exp2.type;
508             }
509           exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
510           break;
511         case EXP_OP_SEG:
512           rtn.cookie = DV_TARGET;
513           rtn.type = NULL;
514           rtn.addr.seg = VAL(exp1);
515           rtn.addr.off = VAL(exp2);
516           break;
517         case EXP_OP_LOR:
518           exp->un.binop.result = (VAL(exp1) || VAL(exp2));
519           break;
520         case EXP_OP_LAND:
521           exp->un.binop.result = (VAL(exp1) && VAL(exp2));
522           break;
523         case EXP_OP_OR:
524           exp->un.binop.result = (VAL(exp1) | VAL(exp2));
525           break;
526         case EXP_OP_AND:
527           exp->un.binop.result = (VAL(exp1) & VAL(exp2));
528           break;
529         case EXP_OP_XOR:
530           exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
531           break;
532         case EXP_OP_EQ:
533           exp->un.binop.result = (VAL(exp1) == VAL(exp2));
534           break;
535         case EXP_OP_GT:
536           exp->un.binop.result = (VAL(exp1) > VAL(exp2));
537           break;
538         case EXP_OP_LT:
539           exp->un.binop.result = (VAL(exp1) < VAL(exp2));
540           break;
541         case EXP_OP_GE:
542           exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
543           break;
544         case EXP_OP_LE:
545           exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
546           break;
547         case EXP_OP_NE:
548           exp->un.binop.result = (VAL(exp1) != VAL(exp2));
549           break;
550         case EXP_OP_SHL:
551           exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
552           break;
553         case EXP_OP_SHR:
554           exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
555           break;
556         case EXP_OP_MUL:
557           exp->un.binop.result = (VAL(exp1) * VAL(exp2));
558           break;
559         case EXP_OP_DIV:
560           if( VAL(exp2) == 0 )
561             {
562                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
563             }
564           exp->un.binop.result = (VAL(exp1) / VAL(exp2));
565           break;
566         case EXP_OP_REM:
567           if( VAL(exp2) == 0 )
568             {
569                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
570             }
571           exp->un.binop.result = (VAL(exp1) % VAL(exp2));
572           break;
573         case EXP_OP_ARR:
574           DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
575           break;
576         default:
577           RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
578           break;
579         }
580       break;
581     case EXPR_TYPE_UNOP:
582       exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
583       rtn.cookie = DV_HOST;
584       if( exp1.type == NULL )
585         {
586           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
587         }
588       rtn.addr.seg = 0;
589       rtn.addr.off = (unsigned int) &exp->un.unop.result;
590       if( exp1.type == DEBUG_TypeIntConst )
591         {
592           rtn.type = exp1.type;
593         }
594       else
595         {
596           rtn.type = DEBUG_TypeInt;
597         }
598       switch(exp->un.unop.unop_type)
599         {
600         case EXP_OP_NEG:
601           exp->un.unop.result = -VAL(exp1);
602           break;
603         case EXP_OP_NOT:
604           exp->un.unop.result = !VAL(exp1);
605           break;
606         case EXP_OP_LNOT:
607           exp->un.unop.result = ~VAL(exp1);
608           break;
609         case EXP_OP_DEREF:
610           rtn.cookie = exp1.cookie;
611           rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
612           if (!rtn.type)
613             {
614               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
615             }
616           break;
617         case EXP_OP_FORCE_DEREF:
618           rtn.cookie = exp1.cookie;
619           rtn.addr.seg = exp1.addr.seg;
620           if (exp1.cookie == DV_TARGET)
621              DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
622           else
623              memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
624           break;
625         case EXP_OP_ADDR:
626           /* FIXME: even for a 16 bit entity ? */
627           rtn.cookie = DV_TARGET;
628           rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
629           exp->un.unop.result = exp1.addr.off;
630           break;
631         default:
632            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
633         }
634       break;
635     default:
636       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
637       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
638       break;
639     }
640
641   assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
642
643   return rtn;
644 }
645
646
647 int
648 DEBUG_DisplayExpr(const struct expr * exp)
649 {
650   int           i;
651
652   switch(exp->type)
653     {
654     case EXPR_TYPE_CAST:
655       DEBUG_Printf(DBG_CHN_MESG, "((");
656       DEBUG_PrintTypeCast(exp->un.cast.cast);
657       DEBUG_Printf(DBG_CHN_MESG, ")");
658       DEBUG_DisplayExpr(exp->un.cast.expr);
659       DEBUG_Printf(DBG_CHN_MESG, ")");
660       break;
661     case EXPR_TYPE_INTVAR:
662       DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
663       break;
664     case EXPR_TYPE_US_CONST:
665       DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
666       break;
667     case EXPR_TYPE_CONST:
668       DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
669       break;
670     case EXPR_TYPE_STRING:
671       DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str); 
672       break;
673     case EXPR_TYPE_SYMBOL:
674       DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
675       break;
676     case EXPR_TYPE_PSTRUCT:
677       DEBUG_DisplayExpr(exp->un.structure.exp1);
678       DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
679       break;
680     case EXPR_TYPE_STRUCT:
681       DEBUG_DisplayExpr(exp->un.structure.exp1);
682       DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
683       break;
684     case EXPR_TYPE_CALL:
685       DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
686       for(i=0; i < exp->un.call.nargs; i++)
687         {
688           DEBUG_DisplayExpr(exp->un.call.arg[i]);
689           if( i != exp->un.call.nargs - 1 )
690             {
691               DEBUG_Printf(DBG_CHN_MESG, ", ");
692             }
693         }
694       DEBUG_Printf(DBG_CHN_MESG, ")");
695       break;
696     case EXPR_TYPE_BINOP:
697       DEBUG_Printf(DBG_CHN_MESG, "( ");
698       DEBUG_DisplayExpr(exp->un.binop.exp1);
699       switch(exp->un.binop.binop_type)
700         {
701         case EXP_OP_ADD:
702           DEBUG_Printf(DBG_CHN_MESG, " + ");
703           break;
704         case EXP_OP_SUB:
705           DEBUG_Printf(DBG_CHN_MESG, " - ");
706           break;
707         case EXP_OP_SEG:
708           DEBUG_Printf(DBG_CHN_MESG, ":");
709           break;
710         case EXP_OP_LOR:
711           DEBUG_Printf(DBG_CHN_MESG, " || ");
712           break;
713         case EXP_OP_LAND:
714           DEBUG_Printf(DBG_CHN_MESG, " && ");
715           break;
716         case EXP_OP_OR:
717           DEBUG_Printf(DBG_CHN_MESG, " | ");
718           break;
719         case EXP_OP_AND:
720           DEBUG_Printf(DBG_CHN_MESG, " & ");
721           break;
722         case EXP_OP_XOR:
723           DEBUG_Printf(DBG_CHN_MESG, " ^ ");
724           break;
725         case EXP_OP_EQ:
726           DEBUG_Printf(DBG_CHN_MESG, " == ");
727           break;
728         case EXP_OP_GT:
729           DEBUG_Printf(DBG_CHN_MESG, " > ");
730           break;
731         case EXP_OP_LT:
732           DEBUG_Printf(DBG_CHN_MESG, " < ");
733           break;
734         case EXP_OP_GE:
735           DEBUG_Printf(DBG_CHN_MESG, " >= ");
736           break;
737         case EXP_OP_LE:
738           DEBUG_Printf(DBG_CHN_MESG, " <= ");
739           break;
740         case EXP_OP_NE:
741           DEBUG_Printf(DBG_CHN_MESG, " != ");
742           break;
743         case EXP_OP_SHL:
744           DEBUG_Printf(DBG_CHN_MESG, " << ");
745           break;
746         case EXP_OP_SHR:
747           DEBUG_Printf(DBG_CHN_MESG, " >> ");
748           break;
749         case EXP_OP_MUL:
750           DEBUG_Printf(DBG_CHN_MESG, " * ");
751           break;
752         case EXP_OP_DIV:
753           DEBUG_Printf(DBG_CHN_MESG, " / ");
754           break;
755         case EXP_OP_REM:
756           DEBUG_Printf(DBG_CHN_MESG, " %% ");
757           break;
758         case EXP_OP_ARR:
759           DEBUG_Printf(DBG_CHN_MESG, "[");
760           break;
761         default:
762           break;
763         }
764       DEBUG_DisplayExpr(exp->un.binop.exp2);
765       if( exp->un.binop.binop_type == EXP_OP_ARR )
766         {
767           DEBUG_Printf(DBG_CHN_MESG, "]");
768         }
769       DEBUG_Printf(DBG_CHN_MESG, " )");
770       break;
771     case EXPR_TYPE_UNOP:
772       switch(exp->un.unop.unop_type)
773         {
774         case EXP_OP_NEG:
775           DEBUG_Printf(DBG_CHN_MESG, "-");
776           break;
777         case EXP_OP_NOT:
778           DEBUG_Printf(DBG_CHN_MESG, "!");
779           break;
780         case EXP_OP_LNOT:
781           DEBUG_Printf(DBG_CHN_MESG, "~");
782           break;
783         case EXP_OP_DEREF:
784           DEBUG_Printf(DBG_CHN_MESG, "*");
785           break;
786         case EXP_OP_ADDR:
787           DEBUG_Printf(DBG_CHN_MESG, "&");
788           break;
789         }
790       DEBUG_DisplayExpr(exp->un.unop.exp1);
791       break;
792     default:
793       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
794       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
795       break;
796     }
797
798   return TRUE;
799 }
800
801 struct expr *
802 DEBUG_CloneExpr(const struct expr * exp)
803 {
804   int           i;
805   struct expr * rtn;
806
807   rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
808
809   /*
810    * First copy the contents of the expression itself.
811    */
812   *rtn = *exp;
813
814
815   switch(exp->type)
816     {
817     case EXPR_TYPE_CAST:
818       rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
819       break;
820     case EXPR_TYPE_INTVAR:
821       rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
822       break;
823     case EXPR_TYPE_US_CONST:
824     case EXPR_TYPE_CONST:
825       break;
826     case EXPR_TYPE_STRING:
827       rtn->un.string.str = DBG_strdup(exp->un.string.str);
828       break;
829     case EXPR_TYPE_SYMBOL:
830       rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
831       break;
832     case EXPR_TYPE_PSTRUCT:
833     case EXPR_TYPE_STRUCT:
834       rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
835       rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
836       break;
837     case EXPR_TYPE_CALL:
838       for(i=0; i < exp->un.call.nargs; i++)
839         {
840           rtn->un.call.arg[i]  = DEBUG_CloneExpr(exp->un.call.arg[i]);
841         }
842       rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
843       break;
844     case EXPR_TYPE_BINOP:
845       rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
846       rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
847       break;
848     case EXPR_TYPE_UNOP:
849       rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
850       break;
851     default:
852       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
853       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
854       break;
855     }
856
857   return rtn;
858 }
859
860
861 /*
862  * Recursively go through an expression tree and free all memory associated
863  * with it.
864  */
865 int
866 DEBUG_FreeExpr(struct expr * exp)
867 {
868   int i;
869
870   switch(exp->type)
871     {
872     case EXPR_TYPE_CAST:
873       DEBUG_FreeExpr(exp->un.cast.expr);
874       break;
875     case EXPR_TYPE_INTVAR:
876       DBG_free((char *) exp->un.intvar.name);
877       break;
878     case EXPR_TYPE_US_CONST:
879     case EXPR_TYPE_CONST:
880       break;
881     case EXPR_TYPE_STRING:
882       DBG_free((char *) exp->un.string.str);
883       break;
884     case EXPR_TYPE_SYMBOL:
885       DBG_free((char *) exp->un.symbol.name);
886       break;
887     case EXPR_TYPE_PSTRUCT:
888     case EXPR_TYPE_STRUCT:
889       DEBUG_FreeExpr(exp->un.structure.exp1);
890       DBG_free((char *) exp->un.structure.element_name);
891       break;
892     case EXPR_TYPE_CALL:
893       for(i=0; i < exp->un.call.nargs; i++)
894         {
895           DEBUG_FreeExpr(exp->un.call.arg[i]);
896         }
897       DBG_free((char *) exp->un.call.funcname);
898       break;
899     case EXPR_TYPE_BINOP:
900       DEBUG_FreeExpr(exp->un.binop.exp1);
901       DEBUG_FreeExpr(exp->un.binop.exp2);
902       break;
903     case EXPR_TYPE_UNOP:
904       DEBUG_FreeExpr(exp->un.unop.exp1);
905       break;
906     default:
907       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
908       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
909       break;
910     }
911
912   DBG_free(exp);
913   return TRUE;
914 }