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