Removed extraneous trace message.
[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.addr.seg = VAL(exp1);
514           exp->un.binop.result = VAL(exp2);
515 #ifdef __i386__
516           DEBUG_FixSegment(&rtn.addr);
517 #endif
518           break;
519         case EXP_OP_LOR:
520           exp->un.binop.result = (VAL(exp1) || VAL(exp2));
521           break;
522         case EXP_OP_LAND:
523           exp->un.binop.result = (VAL(exp1) && VAL(exp2));
524           break;
525         case EXP_OP_OR:
526           exp->un.binop.result = (VAL(exp1) | VAL(exp2));
527           break;
528         case EXP_OP_AND:
529           exp->un.binop.result = (VAL(exp1) & VAL(exp2));
530           break;
531         case EXP_OP_XOR:
532           exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
533           break;
534         case EXP_OP_EQ:
535           exp->un.binop.result = (VAL(exp1) == VAL(exp2));
536           break;
537         case EXP_OP_GT:
538           exp->un.binop.result = (VAL(exp1) > VAL(exp2));
539           break;
540         case EXP_OP_LT:
541           exp->un.binop.result = (VAL(exp1) < VAL(exp2));
542           break;
543         case EXP_OP_GE:
544           exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
545           break;
546         case EXP_OP_LE:
547           exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
548           break;
549         case EXP_OP_NE:
550           exp->un.binop.result = (VAL(exp1) != VAL(exp2));
551           break;
552         case EXP_OP_SHL:
553           exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
554           break;
555         case EXP_OP_SHR:
556           exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
557           break;
558         case EXP_OP_MUL:
559           exp->un.binop.result = (VAL(exp1) * VAL(exp2));
560           break;
561         case EXP_OP_DIV:
562           if( VAL(exp2) == 0 )
563             {
564                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
565             }
566           exp->un.binop.result = (VAL(exp1) / VAL(exp2));
567           break;
568         case EXP_OP_REM:
569           if( VAL(exp2) == 0 )
570             {
571                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
572             }
573           exp->un.binop.result = (VAL(exp1) % VAL(exp2));
574           break;
575         case EXP_OP_ARR:
576           DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
577           break;
578         default:
579           RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
580           break;
581         }
582       break;
583     case EXPR_TYPE_UNOP:
584       exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
585       rtn.cookie = DV_HOST;
586       if( exp1.type == NULL )
587         {
588           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
589         }
590       rtn.addr.seg = 0;
591       rtn.addr.off = (unsigned int) &exp->un.unop.result;
592       if( exp1.type == DEBUG_TypeIntConst )
593         {
594           rtn.type = exp1.type;
595         }
596       else
597         {
598           rtn.type = DEBUG_TypeInt;
599         }
600       switch(exp->un.unop.unop_type)
601         {
602         case EXP_OP_NEG:
603           exp->un.unop.result = -VAL(exp1);
604           break;
605         case EXP_OP_NOT:
606           exp->un.unop.result = !VAL(exp1);
607           break;
608         case EXP_OP_LNOT:
609           exp->un.unop.result = ~VAL(exp1);
610           break;
611         case EXP_OP_DEREF:
612           rtn.cookie = exp1.cookie;
613           rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
614           if (!rtn.type)
615             {
616               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
617             }
618           break;
619         case EXP_OP_FORCE_DEREF:
620           rtn.cookie = exp1.cookie;
621           rtn.addr.seg = exp1.addr.seg;
622           if (exp1.cookie == DV_TARGET)
623              DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
624           else
625              memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
626           break;
627         case EXP_OP_ADDR:
628           /* FIXME: even for a 16 bit entity ? */
629           rtn.cookie = DV_TARGET;
630           rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
631           exp->un.unop.result = exp1.addr.off;
632           break;
633         default:
634            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
635         }
636       break;
637     default:
638       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
639       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
640       break;
641     }
642
643   assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
644
645   return rtn;
646 }
647
648
649 int
650 DEBUG_DisplayExpr(const struct expr * exp)
651 {
652   int           i;
653
654   switch(exp->type)
655     {
656     case EXPR_TYPE_CAST:
657       DEBUG_Printf(DBG_CHN_MESG, "((");
658       DEBUG_PrintTypeCast(exp->un.cast.cast);
659       DEBUG_Printf(DBG_CHN_MESG, ")");
660       DEBUG_DisplayExpr(exp->un.cast.expr);
661       DEBUG_Printf(DBG_CHN_MESG, ")");
662       break;
663     case EXPR_TYPE_INTVAR:
664       DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
665       break;
666     case EXPR_TYPE_US_CONST:
667       DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
668       break;
669     case EXPR_TYPE_CONST:
670       DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
671       break;
672     case EXPR_TYPE_STRING:
673       DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str); 
674       break;
675     case EXPR_TYPE_SYMBOL:
676       DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
677       break;
678     case EXPR_TYPE_PSTRUCT:
679       DEBUG_DisplayExpr(exp->un.structure.exp1);
680       DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
681       break;
682     case EXPR_TYPE_STRUCT:
683       DEBUG_DisplayExpr(exp->un.structure.exp1);
684       DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
685       break;
686     case EXPR_TYPE_CALL:
687       DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
688       for(i=0; i < exp->un.call.nargs; i++)
689         {
690           DEBUG_DisplayExpr(exp->un.call.arg[i]);
691           if( i != exp->un.call.nargs - 1 )
692             {
693               DEBUG_Printf(DBG_CHN_MESG, ", ");
694             }
695         }
696       DEBUG_Printf(DBG_CHN_MESG, ")");
697       break;
698     case EXPR_TYPE_BINOP:
699       DEBUG_Printf(DBG_CHN_MESG, "( ");
700       DEBUG_DisplayExpr(exp->un.binop.exp1);
701       switch(exp->un.binop.binop_type)
702         {
703         case EXP_OP_ADD:
704           DEBUG_Printf(DBG_CHN_MESG, " + ");
705           break;
706         case EXP_OP_SUB:
707           DEBUG_Printf(DBG_CHN_MESG, " - ");
708           break;
709         case EXP_OP_SEG:
710           DEBUG_Printf(DBG_CHN_MESG, ":");
711           break;
712         case EXP_OP_LOR:
713           DEBUG_Printf(DBG_CHN_MESG, " || ");
714           break;
715         case EXP_OP_LAND:
716           DEBUG_Printf(DBG_CHN_MESG, " && ");
717           break;
718         case EXP_OP_OR:
719           DEBUG_Printf(DBG_CHN_MESG, " | ");
720           break;
721         case EXP_OP_AND:
722           DEBUG_Printf(DBG_CHN_MESG, " & ");
723           break;
724         case EXP_OP_XOR:
725           DEBUG_Printf(DBG_CHN_MESG, " ^ ");
726           break;
727         case EXP_OP_EQ:
728           DEBUG_Printf(DBG_CHN_MESG, " == ");
729           break;
730         case EXP_OP_GT:
731           DEBUG_Printf(DBG_CHN_MESG, " > ");
732           break;
733         case EXP_OP_LT:
734           DEBUG_Printf(DBG_CHN_MESG, " < ");
735           break;
736         case EXP_OP_GE:
737           DEBUG_Printf(DBG_CHN_MESG, " >= ");
738           break;
739         case EXP_OP_LE:
740           DEBUG_Printf(DBG_CHN_MESG, " <= ");
741           break;
742         case EXP_OP_NE:
743           DEBUG_Printf(DBG_CHN_MESG, " != ");
744           break;
745         case EXP_OP_SHL:
746           DEBUG_Printf(DBG_CHN_MESG, " << ");
747           break;
748         case EXP_OP_SHR:
749           DEBUG_Printf(DBG_CHN_MESG, " >> ");
750           break;
751         case EXP_OP_MUL:
752           DEBUG_Printf(DBG_CHN_MESG, " * ");
753           break;
754         case EXP_OP_DIV:
755           DEBUG_Printf(DBG_CHN_MESG, " / ");
756           break;
757         case EXP_OP_REM:
758           DEBUG_Printf(DBG_CHN_MESG, " %% ");
759           break;
760         case EXP_OP_ARR:
761           DEBUG_Printf(DBG_CHN_MESG, "[");
762           break;
763         default:
764           break;
765         }
766       DEBUG_DisplayExpr(exp->un.binop.exp2);
767       if( exp->un.binop.binop_type == EXP_OP_ARR )
768         {
769           DEBUG_Printf(DBG_CHN_MESG, "]");
770         }
771       DEBUG_Printf(DBG_CHN_MESG, " )");
772       break;
773     case EXPR_TYPE_UNOP:
774       switch(exp->un.unop.unop_type)
775         {
776         case EXP_OP_NEG:
777           DEBUG_Printf(DBG_CHN_MESG, "-");
778           break;
779         case EXP_OP_NOT:
780           DEBUG_Printf(DBG_CHN_MESG, "!");
781           break;
782         case EXP_OP_LNOT:
783           DEBUG_Printf(DBG_CHN_MESG, "~");
784           break;
785         case EXP_OP_DEREF:
786           DEBUG_Printf(DBG_CHN_MESG, "*");
787           break;
788         case EXP_OP_ADDR:
789           DEBUG_Printf(DBG_CHN_MESG, "&");
790           break;
791         }
792       DEBUG_DisplayExpr(exp->un.unop.exp1);
793       break;
794     default:
795       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
796       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
797       break;
798     }
799
800   return TRUE;
801 }
802
803 struct expr *
804 DEBUG_CloneExpr(const struct expr * exp)
805 {
806   int           i;
807   struct expr * rtn;
808
809   rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
810
811   /*
812    * First copy the contents of the expression itself.
813    */
814   *rtn = *exp;
815
816
817   switch(exp->type)
818     {
819     case EXPR_TYPE_CAST:
820       rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
821       break;
822     case EXPR_TYPE_INTVAR:
823       rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
824       break;
825     case EXPR_TYPE_US_CONST:
826     case EXPR_TYPE_CONST:
827       break;
828     case EXPR_TYPE_STRING:
829       rtn->un.string.str = DBG_strdup(exp->un.string.str);
830       break;
831     case EXPR_TYPE_SYMBOL:
832       rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
833       break;
834     case EXPR_TYPE_PSTRUCT:
835     case EXPR_TYPE_STRUCT:
836       rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
837       rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
838       break;
839     case EXPR_TYPE_CALL:
840       for(i=0; i < exp->un.call.nargs; i++)
841         {
842           rtn->un.call.arg[i]  = DEBUG_CloneExpr(exp->un.call.arg[i]);
843         }
844       rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
845       break;
846     case EXPR_TYPE_BINOP:
847       rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
848       rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
849       break;
850     case EXPR_TYPE_UNOP:
851       rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
852       break;
853     default:
854       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
855       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
856       break;
857     }
858
859   return rtn;
860 }
861
862
863 /*
864  * Recursively go through an expression tree and free all memory associated
865  * with it.
866  */
867 int
868 DEBUG_FreeExpr(struct expr * exp)
869 {
870   int i;
871
872   switch(exp->type)
873     {
874     case EXPR_TYPE_CAST:
875       DEBUG_FreeExpr(exp->un.cast.expr);
876       break;
877     case EXPR_TYPE_INTVAR:
878       DBG_free((char *) exp->un.intvar.name);
879       break;
880     case EXPR_TYPE_US_CONST:
881     case EXPR_TYPE_CONST:
882       break;
883     case EXPR_TYPE_STRING:
884       DBG_free((char *) exp->un.string.str);
885       break;
886     case EXPR_TYPE_SYMBOL:
887       DBG_free((char *) exp->un.symbol.name);
888       break;
889     case EXPR_TYPE_PSTRUCT:
890     case EXPR_TYPE_STRUCT:
891       DEBUG_FreeExpr(exp->un.structure.exp1);
892       DBG_free((char *) exp->un.structure.element_name);
893       break;
894     case EXPR_TYPE_CALL:
895       for(i=0; i < exp->un.call.nargs; i++)
896         {
897           DEBUG_FreeExpr(exp->un.call.arg[i]);
898         }
899       DBG_free((char *) exp->un.call.funcname);
900       break;
901     case EXPR_TYPE_BINOP:
902       DEBUG_FreeExpr(exp->un.binop.exp1);
903       DEBUG_FreeExpr(exp->un.binop.exp2);
904       break;
905     case EXPR_TYPE_UNOP:
906       DEBUG_FreeExpr(exp->un.unop.exp1);
907       break;
908     default:
909       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
910       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
911       break;
912     }
913
914   DBG_free(exp);
915   return TRUE;
916 }