Removed obsolete code.
[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 unsigned 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           /* FIXME: this is currently buggy.
611            * there is no way to tell were the deref:ed value is...
612            * for example:
613            *    x is a pointer to struct s, x being on the stack
614            *            => exp1 is target, result is target
615            *    x is a pointer to struct s, x being optimized into a reg
616            *            => exp1 is host, result is target
617            *    x is a pointer to internal variable x
618            *            => exp1 is host, result is host
619            * so we force DV_TARGET, because dereferencing pointers to 
620            * internal variables is very unlikely. a correct fix would be
621            * rather large.
622            */
623           rtn.cookie = DV_TARGET; 
624           rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
625           if (!rtn.type)
626             {
627               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
628             }
629           break;
630         case EXP_OP_FORCE_DEREF:
631           rtn.cookie = exp1.cookie;
632           rtn.addr.seg = exp1.addr.seg;
633           if (exp1.cookie == DV_TARGET)
634              DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
635           else
636              memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
637           break;
638         case EXP_OP_ADDR:
639           /* FIXME: even for a 16 bit entity ? */
640           rtn.cookie = DV_TARGET;
641           rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
642           exp->un.unop.result = exp1.addr.off;
643           break;
644         default:
645            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
646         }
647       break;
648     default:
649       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
650       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
651       break;
652     }
653
654   assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
655
656   return rtn;
657 }
658
659
660 int
661 DEBUG_DisplayExpr(const struct expr * exp)
662 {
663   int           i;
664
665   switch(exp->type)
666     {
667     case EXPR_TYPE_CAST:
668       DEBUG_Printf(DBG_CHN_MESG, "((");
669       DEBUG_PrintTypeCast(exp->un.cast.cast);
670       DEBUG_Printf(DBG_CHN_MESG, ")");
671       DEBUG_DisplayExpr(exp->un.cast.expr);
672       DEBUG_Printf(DBG_CHN_MESG, ")");
673       break;
674     case EXPR_TYPE_INTVAR:
675       DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
676       break;
677     case EXPR_TYPE_US_CONST:
678       DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
679       break;
680     case EXPR_TYPE_CONST:
681       DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
682       break;
683     case EXPR_TYPE_STRING:
684       DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str); 
685       break;
686     case EXPR_TYPE_SYMBOL:
687       DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
688       break;
689     case EXPR_TYPE_PSTRUCT:
690       DEBUG_DisplayExpr(exp->un.structure.exp1);
691       DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
692       break;
693     case EXPR_TYPE_STRUCT:
694       DEBUG_DisplayExpr(exp->un.structure.exp1);
695       DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
696       break;
697     case EXPR_TYPE_CALL:
698       DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
699       for(i=0; i < exp->un.call.nargs; i++)
700         {
701           DEBUG_DisplayExpr(exp->un.call.arg[i]);
702           if( i != exp->un.call.nargs - 1 )
703             {
704               DEBUG_Printf(DBG_CHN_MESG, ", ");
705             }
706         }
707       DEBUG_Printf(DBG_CHN_MESG, ")");
708       break;
709     case EXPR_TYPE_BINOP:
710       DEBUG_Printf(DBG_CHN_MESG, "( ");
711       DEBUG_DisplayExpr(exp->un.binop.exp1);
712       switch(exp->un.binop.binop_type)
713         {
714         case EXP_OP_ADD:
715           DEBUG_Printf(DBG_CHN_MESG, " + ");
716           break;
717         case EXP_OP_SUB:
718           DEBUG_Printf(DBG_CHN_MESG, " - ");
719           break;
720         case EXP_OP_SEG:
721           DEBUG_Printf(DBG_CHN_MESG, ":");
722           break;
723         case EXP_OP_LOR:
724           DEBUG_Printf(DBG_CHN_MESG, " || ");
725           break;
726         case EXP_OP_LAND:
727           DEBUG_Printf(DBG_CHN_MESG, " && ");
728           break;
729         case EXP_OP_OR:
730           DEBUG_Printf(DBG_CHN_MESG, " | ");
731           break;
732         case EXP_OP_AND:
733           DEBUG_Printf(DBG_CHN_MESG, " & ");
734           break;
735         case EXP_OP_XOR:
736           DEBUG_Printf(DBG_CHN_MESG, " ^ ");
737           break;
738         case EXP_OP_EQ:
739           DEBUG_Printf(DBG_CHN_MESG, " == ");
740           break;
741         case EXP_OP_GT:
742           DEBUG_Printf(DBG_CHN_MESG, " > ");
743           break;
744         case EXP_OP_LT:
745           DEBUG_Printf(DBG_CHN_MESG, " < ");
746           break;
747         case EXP_OP_GE:
748           DEBUG_Printf(DBG_CHN_MESG, " >= ");
749           break;
750         case EXP_OP_LE:
751           DEBUG_Printf(DBG_CHN_MESG, " <= ");
752           break;
753         case EXP_OP_NE:
754           DEBUG_Printf(DBG_CHN_MESG, " != ");
755           break;
756         case EXP_OP_SHL:
757           DEBUG_Printf(DBG_CHN_MESG, " << ");
758           break;
759         case EXP_OP_SHR:
760           DEBUG_Printf(DBG_CHN_MESG, " >> ");
761           break;
762         case EXP_OP_MUL:
763           DEBUG_Printf(DBG_CHN_MESG, " * ");
764           break;
765         case EXP_OP_DIV:
766           DEBUG_Printf(DBG_CHN_MESG, " / ");
767           break;
768         case EXP_OP_REM:
769           DEBUG_Printf(DBG_CHN_MESG, " %% ");
770           break;
771         case EXP_OP_ARR:
772           DEBUG_Printf(DBG_CHN_MESG, "[");
773           break;
774         default:
775           break;
776         }
777       DEBUG_DisplayExpr(exp->un.binop.exp2);
778       if( exp->un.binop.binop_type == EXP_OP_ARR )
779         {
780           DEBUG_Printf(DBG_CHN_MESG, "]");
781         }
782       DEBUG_Printf(DBG_CHN_MESG, " )");
783       break;
784     case EXPR_TYPE_UNOP:
785       switch(exp->un.unop.unop_type)
786         {
787         case EXP_OP_NEG:
788           DEBUG_Printf(DBG_CHN_MESG, "-");
789           break;
790         case EXP_OP_NOT:
791           DEBUG_Printf(DBG_CHN_MESG, "!");
792           break;
793         case EXP_OP_LNOT:
794           DEBUG_Printf(DBG_CHN_MESG, "~");
795           break;
796         case EXP_OP_DEREF:
797           DEBUG_Printf(DBG_CHN_MESG, "*");
798           break;
799         case EXP_OP_ADDR:
800           DEBUG_Printf(DBG_CHN_MESG, "&");
801           break;
802         }
803       DEBUG_DisplayExpr(exp->un.unop.exp1);
804       break;
805     default:
806       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
807       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
808       break;
809     }
810
811   return TRUE;
812 }
813
814 struct expr *
815 DEBUG_CloneExpr(const struct expr * exp)
816 {
817   int           i;
818   struct expr * rtn;
819
820   rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
821
822   /*
823    * First copy the contents of the expression itself.
824    */
825   *rtn = *exp;
826
827
828   switch(exp->type)
829     {
830     case EXPR_TYPE_CAST:
831       rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
832       break;
833     case EXPR_TYPE_INTVAR:
834       rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
835       break;
836     case EXPR_TYPE_US_CONST:
837     case EXPR_TYPE_CONST:
838       break;
839     case EXPR_TYPE_STRING:
840       rtn->un.string.str = DBG_strdup(exp->un.string.str);
841       break;
842     case EXPR_TYPE_SYMBOL:
843       rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
844       break;
845     case EXPR_TYPE_PSTRUCT:
846     case EXPR_TYPE_STRUCT:
847       rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
848       rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
849       break;
850     case EXPR_TYPE_CALL:
851       for(i=0; i < exp->un.call.nargs; i++)
852         {
853           rtn->un.call.arg[i]  = DEBUG_CloneExpr(exp->un.call.arg[i]);
854         }
855       rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
856       break;
857     case EXPR_TYPE_BINOP:
858       rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
859       rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
860       break;
861     case EXPR_TYPE_UNOP:
862       rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
863       break;
864     default:
865       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
866       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
867       break;
868     }
869
870   return rtn;
871 }
872
873
874 /*
875  * Recursively go through an expression tree and free all memory associated
876  * with it.
877  */
878 int
879 DEBUG_FreeExpr(struct expr * exp)
880 {
881   int i;
882
883   switch(exp->type)
884     {
885     case EXPR_TYPE_CAST:
886       DEBUG_FreeExpr(exp->un.cast.expr);
887       break;
888     case EXPR_TYPE_INTVAR:
889       DBG_free((char *) exp->un.intvar.name);
890       break;
891     case EXPR_TYPE_US_CONST:
892     case EXPR_TYPE_CONST:
893       break;
894     case EXPR_TYPE_STRING:
895       DBG_free((char *) exp->un.string.str);
896       break;
897     case EXPR_TYPE_SYMBOL:
898       DBG_free((char *) exp->un.symbol.name);
899       break;
900     case EXPR_TYPE_PSTRUCT:
901     case EXPR_TYPE_STRUCT:
902       DEBUG_FreeExpr(exp->un.structure.exp1);
903       DBG_free((char *) exp->un.structure.element_name);
904       break;
905     case EXPR_TYPE_CALL:
906       for(i=0; i < exp->un.call.nargs; i++)
907         {
908           DEBUG_FreeExpr(exp->un.call.arg[i]);
909         }
910       DBG_free((char *) exp->un.call.funcname);
911       break;
912     case EXPR_TYPE_BINOP:
913       DEBUG_FreeExpr(exp->un.binop.exp1);
914       DEBUG_FreeExpr(exp->un.binop.exp2);
915       break;
916     case EXPR_TYPE_UNOP:
917       DEBUG_FreeExpr(exp->un.unop.exp1);
918       break;
919     default:
920       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
921       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
922       break;
923     }
924
925   DBG_free(exp);
926   return TRUE;
927 }