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