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