Fixed some places where whitespace was not handled correctly.
[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           DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.symbol.name);
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, &rtn.type);
349       if( rtn.type == NULL )
350         {
351           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
352         }
353       if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
354                                    &exp->un.structure.result))
355       {
356           DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
357           RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
358       }
359
360       break;
361     case EXPR_TYPE_STRUCT:
362       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
363       if( exp1.type == NULL )
364       {
365           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
366       }
367       rtn = exp1;
368       if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
369                                    &exp->un.structure.result))
370       {
371           DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
372           RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
373       }
374       break;
375     case EXPR_TYPE_CALL:
376       /*
377        * First, evaluate all of the arguments.  If any of them are not
378        * evaluable, then bail.
379        */
380       for(i=0; i < exp->un.call.nargs; i++)
381         {
382           exp1  = DEBUG_EvalExpr(exp->un.call.arg[i]);
383           if( exp1.type == NULL )
384             {
385               return rtn;
386             }
387           cexp[i] = DEBUG_GetExprValue(&exp1, NULL);
388         }
389
390       /*
391        * Now look up the address of the function itself.
392        */
393       if( !DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ) )
394         {
395           RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
396         }
397
398 #if 0
399       /* FIXME: NEWDBG NIY */
400       /* Anyway, I wonder how this could work depending on the calling order of
401        * the function (cdecl vs pascal for example)
402        */
403       int               (*fptr)();
404
405       fptr = (int (*)()) rtn.addr.off;
406       switch(exp->un.call.nargs)
407         {
408         case 0:
409           exp->un.call.result = (*fptr)();
410           break;
411         case 1:
412           exp->un.call.result = (*fptr)(cexp[0]);
413           break;
414         case 2:
415           exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
416           break;
417         case 3:
418           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
419           break;
420         case 4:
421           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
422           break;
423         case 5:
424           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
425           break;
426         }
427 #else
428       DEBUG_Printf(DBG_CHN_MESG, "Function call no longer implemented\n");
429       /* would need to set up a call to this function, and then restore the current
430        * context afterwards...
431        */
432       exp->un.call.result = 0;
433 #endif
434       rtn.type = DEBUG_TypeInt;
435       rtn.cookie = DV_HOST;
436       rtn.addr.off = (unsigned int) &exp->un.call.result;
437
438       break;
439     case EXPR_TYPE_INTVAR:
440       {
441
442          DBG_INTVAR*    div = DEBUG_GetIntVar(exp->un.intvar.name);
443
444          if (!div) RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
445          rtn.cookie = DV_HOST;
446          rtn.type = div->type;
447          rtn.addr.off = (unsigned int)div->pval;
448          /* EPP FIXME rtn.addr.seg = ?? */
449       }
450       break;
451     case EXPR_TYPE_BINOP:
452       exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
453       exp2 = DEBUG_EvalExpr(exp->un.binop.exp2);
454       rtn.cookie = DV_HOST;
455       if( exp1.type == NULL || exp2.type == NULL )
456         {
457           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
458         }
459       if( exp1.type == DEBUG_TypeIntConst && exp2.type == DEBUG_TypeIntConst )
460         {
461           rtn.type = exp1.type;
462         }
463       else
464         {
465           rtn.type = DEBUG_TypeInt;
466         }
467       rtn.addr.seg = 0;
468       rtn.addr.off = (unsigned int) &exp->un.binop.result;
469       switch(exp->un.binop.binop_type)
470         {
471         case EXP_OP_ADD:
472           type1 = DEBUG_GetPointerType(exp1.type);
473           type2 = DEBUG_GetPointerType(exp2.type);
474           scale1 = 1;
475           scale2 = 1;
476           if( type1 != NULL && type2 != NULL )
477             {
478               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
479             }
480           else if( type1 != NULL )
481             {
482               scale2 = DEBUG_GetObjectSize(type1);
483               rtn.type = exp1.type;
484             }
485           else if( type2 != NULL )
486             {
487               scale1 = DEBUG_GetObjectSize(type2);
488               rtn.type = exp2.type;
489             }
490           exp->un.binop.result = (VAL(exp1) * scale1  + scale2 * VAL(exp2));
491           break;
492         case EXP_OP_SUB:
493           type1 = DEBUG_GetPointerType(exp1.type);
494           type2 = DEBUG_GetPointerType(exp2.type);
495           scale1 = 1;
496           scale2 = 1;
497           scale3 = 1;
498           if( type1 != NULL && type2 != NULL )
499             {
500               if( type1 != type2 )
501                 {
502                   RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
503                 }
504               scale3 = DEBUG_GetObjectSize(type1);
505             }
506           else if( type1 != NULL )
507             {
508               scale2 = DEBUG_GetObjectSize(type1);
509               rtn.type = exp1.type;
510             }
511
512           else if( type2 != NULL )
513             {
514               scale1 = DEBUG_GetObjectSize(type2);
515               rtn.type = exp2.type;
516             }
517           exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
518           break;
519         case EXP_OP_SEG:
520           rtn.cookie = DV_TARGET;
521           rtn.type = NULL;
522           rtn.addr.seg = VAL(exp1);
523           rtn.addr.off = VAL(exp2);
524           break;
525         case EXP_OP_LOR:
526           exp->un.binop.result = (VAL(exp1) || VAL(exp2));
527           break;
528         case EXP_OP_LAND:
529           exp->un.binop.result = (VAL(exp1) && VAL(exp2));
530           break;
531         case EXP_OP_OR:
532           exp->un.binop.result = (VAL(exp1) | VAL(exp2));
533           break;
534         case EXP_OP_AND:
535           exp->un.binop.result = (VAL(exp1) & VAL(exp2));
536           break;
537         case EXP_OP_XOR:
538           exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
539           break;
540         case EXP_OP_EQ:
541           exp->un.binop.result = (VAL(exp1) == VAL(exp2));
542           break;
543         case EXP_OP_GT:
544           exp->un.binop.result = (VAL(exp1) > VAL(exp2));
545           break;
546         case EXP_OP_LT:
547           exp->un.binop.result = (VAL(exp1) < VAL(exp2));
548           break;
549         case EXP_OP_GE:
550           exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
551           break;
552         case EXP_OP_LE:
553           exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
554           break;
555         case EXP_OP_NE:
556           exp->un.binop.result = (VAL(exp1) != VAL(exp2));
557           break;
558         case EXP_OP_SHL:
559           exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
560           break;
561         case EXP_OP_SHR:
562           exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
563           break;
564         case EXP_OP_MUL:
565           exp->un.binop.result = (VAL(exp1) * VAL(exp2));
566           break;
567         case EXP_OP_DIV:
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_REM:
575           if( VAL(exp2) == 0 )
576             {
577                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
578             }
579           exp->un.binop.result = (VAL(exp1) % VAL(exp2));
580           break;
581         case EXP_OP_ARR:
582           DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
583           break;
584         default:
585           RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
586           break;
587         }
588       break;
589     case EXPR_TYPE_UNOP:
590       exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
591       rtn.cookie = DV_HOST;
592       if( exp1.type == NULL )
593         {
594           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
595         }
596       rtn.addr.seg = 0;
597       rtn.addr.off = (unsigned int) &exp->un.unop.result;
598       if( exp1.type == DEBUG_TypeIntConst )
599         {
600           rtn.type = exp1.type;
601         }
602       else
603         {
604           rtn.type = DEBUG_TypeInt;
605         }
606       switch(exp->un.unop.unop_type)
607         {
608         case EXP_OP_NEG:
609           exp->un.unop.result = -VAL(exp1);
610           break;
611         case EXP_OP_NOT:
612           exp->un.unop.result = !VAL(exp1);
613           break;
614         case EXP_OP_LNOT:
615           exp->un.unop.result = ~VAL(exp1);
616           break;
617         case EXP_OP_DEREF:
618           /* FIXME: this is currently buggy.
619            * there is no way to tell were the deref:ed value is...
620            * for example:
621            *    x is a pointer to struct s, x being on the stack
622            *            => exp1 is target, result is target
623            *    x is a pointer to struct s, x being optimized into a reg
624            *            => exp1 is host, result is target
625            *    x is a pointer to internal variable x
626            *            => exp1 is host, result is host
627            * so we force DV_TARGET, because dereferencing pointers to 
628            * internal variables is very unlikely. a correct fix would be
629            * rather large.
630            */
631           rtn.cookie = DV_TARGET; 
632           rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
633           if (!rtn.type)
634             {
635               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
636             }
637           break;
638         case EXP_OP_FORCE_DEREF:
639           rtn.cookie = exp1.cookie;
640           rtn.addr.seg = exp1.addr.seg;
641           if (exp1.cookie == DV_TARGET)
642              DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
643           else
644              memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
645           break;
646         case EXP_OP_ADDR:
647           /* FIXME: even for a 16 bit entity ? */
648           rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
649           exp->un.unop.result = exp1.addr.off;
650           break;
651         default:
652            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
653         }
654       break;
655     default:
656       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
657       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
658       break;
659     }
660
661   assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
662
663   return rtn;
664 }
665
666
667 int
668 DEBUG_DisplayExpr(const struct expr * exp)
669 {
670   int           i;
671
672   switch(exp->type)
673     {
674     case EXPR_TYPE_CAST:
675       DEBUG_Printf(DBG_CHN_MESG, "((");
676       DEBUG_PrintTypeCast(exp->un.cast.cast);
677       DEBUG_Printf(DBG_CHN_MESG, ")");
678       DEBUG_DisplayExpr(exp->un.cast.expr);
679       DEBUG_Printf(DBG_CHN_MESG, ")");
680       break;
681     case EXPR_TYPE_INTVAR:
682       DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
683       break;
684     case EXPR_TYPE_US_CONST:
685       DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
686       break;
687     case EXPR_TYPE_CONST:
688       DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
689       break;
690     case EXPR_TYPE_STRING:
691       DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str); 
692       break;
693     case EXPR_TYPE_SYMBOL:
694       DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
695       break;
696     case EXPR_TYPE_PSTRUCT:
697       DEBUG_DisplayExpr(exp->un.structure.exp1);
698       DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
699       break;
700     case EXPR_TYPE_STRUCT:
701       DEBUG_DisplayExpr(exp->un.structure.exp1);
702       DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
703       break;
704     case EXPR_TYPE_CALL:
705       DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
706       for(i=0; i < exp->un.call.nargs; i++)
707         {
708           DEBUG_DisplayExpr(exp->un.call.arg[i]);
709           if( i != exp->un.call.nargs - 1 )
710             {
711               DEBUG_Printf(DBG_CHN_MESG, ", ");
712             }
713         }
714       DEBUG_Printf(DBG_CHN_MESG, ")");
715       break;
716     case EXPR_TYPE_BINOP:
717       DEBUG_Printf(DBG_CHN_MESG, "( ");
718       DEBUG_DisplayExpr(exp->un.binop.exp1);
719       switch(exp->un.binop.binop_type)
720         {
721         case EXP_OP_ADD:
722           DEBUG_Printf(DBG_CHN_MESG, " + ");
723           break;
724         case EXP_OP_SUB:
725           DEBUG_Printf(DBG_CHN_MESG, " - ");
726           break;
727         case EXP_OP_SEG:
728           DEBUG_Printf(DBG_CHN_MESG, ":");
729           break;
730         case EXP_OP_LOR:
731           DEBUG_Printf(DBG_CHN_MESG, " || ");
732           break;
733         case EXP_OP_LAND:
734           DEBUG_Printf(DBG_CHN_MESG, " && ");
735           break;
736         case EXP_OP_OR:
737           DEBUG_Printf(DBG_CHN_MESG, " | ");
738           break;
739         case EXP_OP_AND:
740           DEBUG_Printf(DBG_CHN_MESG, " & ");
741           break;
742         case EXP_OP_XOR:
743           DEBUG_Printf(DBG_CHN_MESG, " ^ ");
744           break;
745         case EXP_OP_EQ:
746           DEBUG_Printf(DBG_CHN_MESG, " == ");
747           break;
748         case EXP_OP_GT:
749           DEBUG_Printf(DBG_CHN_MESG, " > ");
750           break;
751         case EXP_OP_LT:
752           DEBUG_Printf(DBG_CHN_MESG, " < ");
753           break;
754         case EXP_OP_GE:
755           DEBUG_Printf(DBG_CHN_MESG, " >= ");
756           break;
757         case EXP_OP_LE:
758           DEBUG_Printf(DBG_CHN_MESG, " <= ");
759           break;
760         case EXP_OP_NE:
761           DEBUG_Printf(DBG_CHN_MESG, " != ");
762           break;
763         case EXP_OP_SHL:
764           DEBUG_Printf(DBG_CHN_MESG, " << ");
765           break;
766         case EXP_OP_SHR:
767           DEBUG_Printf(DBG_CHN_MESG, " >> ");
768           break;
769         case EXP_OP_MUL:
770           DEBUG_Printf(DBG_CHN_MESG, " * ");
771           break;
772         case EXP_OP_DIV:
773           DEBUG_Printf(DBG_CHN_MESG, " / ");
774           break;
775         case EXP_OP_REM:
776           DEBUG_Printf(DBG_CHN_MESG, " %% ");
777           break;
778         case EXP_OP_ARR:
779           DEBUG_Printf(DBG_CHN_MESG, "[");
780           break;
781         default:
782           break;
783         }
784       DEBUG_DisplayExpr(exp->un.binop.exp2);
785       if( exp->un.binop.binop_type == EXP_OP_ARR )
786         {
787           DEBUG_Printf(DBG_CHN_MESG, "]");
788         }
789       DEBUG_Printf(DBG_CHN_MESG, " )");
790       break;
791     case EXPR_TYPE_UNOP:
792       switch(exp->un.unop.unop_type)
793         {
794         case EXP_OP_NEG:
795           DEBUG_Printf(DBG_CHN_MESG, "-");
796           break;
797         case EXP_OP_NOT:
798           DEBUG_Printf(DBG_CHN_MESG, "!");
799           break;
800         case EXP_OP_LNOT:
801           DEBUG_Printf(DBG_CHN_MESG, "~");
802           break;
803         case EXP_OP_DEREF:
804           DEBUG_Printf(DBG_CHN_MESG, "*");
805           break;
806         case EXP_OP_ADDR:
807           DEBUG_Printf(DBG_CHN_MESG, "&");
808           break;
809         }
810       DEBUG_DisplayExpr(exp->un.unop.exp1);
811       break;
812     default:
813       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
814       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
815       break;
816     }
817
818   return TRUE;
819 }
820
821 struct expr *
822 DEBUG_CloneExpr(const struct expr * exp)
823 {
824   int           i;
825   struct expr * rtn;
826
827   rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
828
829   /*
830    * First copy the contents of the expression itself.
831    */
832   *rtn = *exp;
833
834
835   switch(exp->type)
836     {
837     case EXPR_TYPE_CAST:
838       rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
839       break;
840     case EXPR_TYPE_INTVAR:
841       rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
842       break;
843     case EXPR_TYPE_US_CONST:
844     case EXPR_TYPE_CONST:
845       break;
846     case EXPR_TYPE_STRING:
847       rtn->un.string.str = DBG_strdup(exp->un.string.str);
848       break;
849     case EXPR_TYPE_SYMBOL:
850       rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
851       break;
852     case EXPR_TYPE_PSTRUCT:
853     case EXPR_TYPE_STRUCT:
854       rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
855       rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
856       break;
857     case EXPR_TYPE_CALL:
858       for(i=0; i < exp->un.call.nargs; i++)
859         {
860           rtn->un.call.arg[i]  = DEBUG_CloneExpr(exp->un.call.arg[i]);
861         }
862       rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
863       break;
864     case EXPR_TYPE_BINOP:
865       rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
866       rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
867       break;
868     case EXPR_TYPE_UNOP:
869       rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
870       break;
871     default:
872       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
873       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
874       break;
875     }
876
877   return rtn;
878 }
879
880
881 /*
882  * Recursively go through an expression tree and free all memory associated
883  * with it.
884  */
885 int
886 DEBUG_FreeExpr(struct expr * exp)
887 {
888   int i;
889
890   switch(exp->type)
891     {
892     case EXPR_TYPE_CAST:
893       DEBUG_FreeExpr(exp->un.cast.expr);
894       break;
895     case EXPR_TYPE_INTVAR:
896       DBG_free((char *) exp->un.intvar.name);
897       break;
898     case EXPR_TYPE_US_CONST:
899     case EXPR_TYPE_CONST:
900       break;
901     case EXPR_TYPE_STRING:
902       DBG_free((char *) exp->un.string.str);
903       break;
904     case EXPR_TYPE_SYMBOL:
905       DBG_free((char *) exp->un.symbol.name);
906       break;
907     case EXPR_TYPE_PSTRUCT:
908     case EXPR_TYPE_STRUCT:
909       DEBUG_FreeExpr(exp->un.structure.exp1);
910       DBG_free((char *) exp->un.structure.element_name);
911       break;
912     case EXPR_TYPE_CALL:
913       for(i=0; i < exp->un.call.nargs; i++)
914         {
915           DEBUG_FreeExpr(exp->un.call.arg[i]);
916         }
917       DBG_free((char *) exp->un.call.funcname);
918       break;
919     case EXPR_TYPE_BINOP:
920       DEBUG_FreeExpr(exp->un.binop.exp1);
921       DEBUG_FreeExpr(exp->un.binop.exp2);
922       break;
923     case EXPR_TYPE_UNOP:
924       DEBUG_FreeExpr(exp->un.unop.exp1);
925       break;
926     default:
927       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
928       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
929       break;
930     }
931
932   DBG_free(exp);
933   return TRUE;
934 }