Uses Xrender extension to allow client side font rendering.
[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_GetBasicType(DT_BASIC_STRING);
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_GetBasicType(DT_BASIC_CONST_INT);
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_GetBasicType(DT_BASIC_USHORTINT);
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_GetBasicType(DT_BASIC_INT);
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_GetBasicType(DT_BASIC_CONST_INT) && 
460           exp2.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) )
461         {
462           rtn.type = exp1.type;
463         }
464       else
465         {
466           rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
467         }
468       rtn.addr.seg = 0;
469       rtn.addr.off = (unsigned int) &exp->un.binop.result;
470       switch(exp->un.binop.binop_type)
471         {
472         case EXP_OP_ADD:
473           type1 = DEBUG_GetPointerType(exp1.type);
474           type2 = DEBUG_GetPointerType(exp2.type);
475           scale1 = 1;
476           scale2 = 1;
477           if( type1 != NULL && type2 != NULL )
478             {
479               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
480             }
481           else if( type1 != NULL )
482             {
483               scale2 = DEBUG_GetObjectSize(type1);
484               rtn.type = exp1.type;
485             }
486           else if( type2 != NULL )
487             {
488               scale1 = DEBUG_GetObjectSize(type2);
489               rtn.type = exp2.type;
490             }
491           exp->un.binop.result = (VAL(exp1) * scale1  + scale2 * VAL(exp2));
492           break;
493         case EXP_OP_SUB:
494           type1 = DEBUG_GetPointerType(exp1.type);
495           type2 = DEBUG_GetPointerType(exp2.type);
496           scale1 = 1;
497           scale2 = 1;
498           scale3 = 1;
499           if( type1 != NULL && type2 != NULL )
500             {
501               if( type1 != type2 )
502                 {
503                   RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
504                 }
505               scale3 = DEBUG_GetObjectSize(type1);
506             }
507           else if( type1 != NULL )
508             {
509               scale2 = DEBUG_GetObjectSize(type1);
510               rtn.type = exp1.type;
511             }
512
513           else if( type2 != NULL )
514             {
515               scale1 = DEBUG_GetObjectSize(type2);
516               rtn.type = exp2.type;
517             }
518           exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
519           break;
520         case EXP_OP_SEG:
521           rtn.cookie = DV_TARGET;
522           rtn.type = NULL;
523           rtn.addr.seg = VAL(exp1);
524           rtn.addr.off = VAL(exp2);
525           break;
526         case EXP_OP_LOR:
527           exp->un.binop.result = (VAL(exp1) || VAL(exp2));
528           break;
529         case EXP_OP_LAND:
530           exp->un.binop.result = (VAL(exp1) && VAL(exp2));
531           break;
532         case EXP_OP_OR:
533           exp->un.binop.result = (VAL(exp1) | VAL(exp2));
534           break;
535         case EXP_OP_AND:
536           exp->un.binop.result = (VAL(exp1) & VAL(exp2));
537           break;
538         case EXP_OP_XOR:
539           exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
540           break;
541         case EXP_OP_EQ:
542           exp->un.binop.result = (VAL(exp1) == VAL(exp2));
543           break;
544         case EXP_OP_GT:
545           exp->un.binop.result = (VAL(exp1) > VAL(exp2));
546           break;
547         case EXP_OP_LT:
548           exp->un.binop.result = (VAL(exp1) < VAL(exp2));
549           break;
550         case EXP_OP_GE:
551           exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
552           break;
553         case EXP_OP_LE:
554           exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
555           break;
556         case EXP_OP_NE:
557           exp->un.binop.result = (VAL(exp1) != VAL(exp2));
558           break;
559         case EXP_OP_SHL:
560           exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
561           break;
562         case EXP_OP_SHR:
563           exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
564           break;
565         case EXP_OP_MUL:
566           exp->un.binop.result = (VAL(exp1) * VAL(exp2));
567           break;
568         case EXP_OP_DIV:
569           if( VAL(exp2) == 0 )
570             {
571                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
572             }
573           exp->un.binop.result = (VAL(exp1) / VAL(exp2));
574           break;
575         case EXP_OP_REM:
576           if( VAL(exp2) == 0 )
577             {
578                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
579             }
580           exp->un.binop.result = (VAL(exp1) % VAL(exp2));
581           break;
582         case EXP_OP_ARR:
583           DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
584           break;
585         default:
586           RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
587           break;
588         }
589       break;
590     case EXPR_TYPE_UNOP:
591       exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
592       rtn.cookie = DV_HOST;
593       if( exp1.type == NULL )
594         {
595           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
596         }
597       rtn.addr.seg = 0;
598       rtn.addr.off = (unsigned int) &exp->un.unop.result;
599       if( exp1.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) )
600         {
601           rtn.type = exp1.type;
602         }
603       else
604         {
605           rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
606         }
607       switch(exp->un.unop.unop_type)
608         {
609         case EXP_OP_NEG:
610           exp->un.unop.result = -VAL(exp1);
611           break;
612         case EXP_OP_NOT:
613           exp->un.unop.result = !VAL(exp1);
614           break;
615         case EXP_OP_LNOT:
616           exp->un.unop.result = ~VAL(exp1);
617           break;
618         case EXP_OP_DEREF:
619           /* FIXME: this is currently buggy.
620            * there is no way to tell were the deref:ed value is...
621            * for example:
622            *    x is a pointer to struct s, x being on the stack
623            *            => exp1 is target, result is target
624            *    x is a pointer to struct s, x being optimized into a reg
625            *            => exp1 is host, result is target
626            *    x is a pointer to internal variable x
627            *            => exp1 is host, result is host
628            * so we force DV_TARGET, because dereferencing pointers to 
629            * internal variables is very unlikely. a correct fix would be
630            * rather large.
631            */
632           rtn.cookie = DV_TARGET; 
633           rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
634           if (!rtn.type)
635             {
636               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
637             }
638           break;
639         case EXP_OP_FORCE_DEREF:
640           rtn.cookie = exp1.cookie;
641           rtn.addr.seg = exp1.addr.seg;
642           if (exp1.cookie == DV_TARGET)
643              DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
644           else
645              memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
646           break;
647         case EXP_OP_ADDR:
648           /* FIXME: even for a 16 bit entity ? */
649           rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
650           exp->un.unop.result = exp1.addr.off;
651           break;
652         default:
653            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
654         }
655       break;
656     default:
657       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
658       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
659       break;
660     }
661
662   assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
663
664   return rtn;
665 }
666
667
668 int
669 DEBUG_DisplayExpr(const struct expr * exp)
670 {
671   int           i;
672
673   switch(exp->type)
674     {
675     case EXPR_TYPE_CAST:
676       DEBUG_Printf(DBG_CHN_MESG, "((");
677       DEBUG_PrintTypeCast(exp->un.cast.cast);
678       DEBUG_Printf(DBG_CHN_MESG, ")");
679       DEBUG_DisplayExpr(exp->un.cast.expr);
680       DEBUG_Printf(DBG_CHN_MESG, ")");
681       break;
682     case EXPR_TYPE_INTVAR:
683       DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
684       break;
685     case EXPR_TYPE_US_CONST:
686       DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
687       break;
688     case EXPR_TYPE_CONST:
689       DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
690       break;
691     case EXPR_TYPE_STRING:
692       DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str); 
693       break;
694     case EXPR_TYPE_SYMBOL:
695       DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
696       break;
697     case EXPR_TYPE_PSTRUCT:
698       DEBUG_DisplayExpr(exp->un.structure.exp1);
699       DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
700       break;
701     case EXPR_TYPE_STRUCT:
702       DEBUG_DisplayExpr(exp->un.structure.exp1);
703       DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
704       break;
705     case EXPR_TYPE_CALL:
706       DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
707       for(i=0; i < exp->un.call.nargs; i++)
708         {
709           DEBUG_DisplayExpr(exp->un.call.arg[i]);
710           if( i != exp->un.call.nargs - 1 )
711             {
712               DEBUG_Printf(DBG_CHN_MESG, ", ");
713             }
714         }
715       DEBUG_Printf(DBG_CHN_MESG, ")");
716       break;
717     case EXPR_TYPE_BINOP:
718       DEBUG_Printf(DBG_CHN_MESG, "( ");
719       DEBUG_DisplayExpr(exp->un.binop.exp1);
720       switch(exp->un.binop.binop_type)
721         {
722         case EXP_OP_ADD:
723           DEBUG_Printf(DBG_CHN_MESG, " + ");
724           break;
725         case EXP_OP_SUB:
726           DEBUG_Printf(DBG_CHN_MESG, " - ");
727           break;
728         case EXP_OP_SEG:
729           DEBUG_Printf(DBG_CHN_MESG, ":");
730           break;
731         case EXP_OP_LOR:
732           DEBUG_Printf(DBG_CHN_MESG, " || ");
733           break;
734         case EXP_OP_LAND:
735           DEBUG_Printf(DBG_CHN_MESG, " && ");
736           break;
737         case EXP_OP_OR:
738           DEBUG_Printf(DBG_CHN_MESG, " | ");
739           break;
740         case EXP_OP_AND:
741           DEBUG_Printf(DBG_CHN_MESG, " & ");
742           break;
743         case EXP_OP_XOR:
744           DEBUG_Printf(DBG_CHN_MESG, " ^ ");
745           break;
746         case EXP_OP_EQ:
747           DEBUG_Printf(DBG_CHN_MESG, " == ");
748           break;
749         case EXP_OP_GT:
750           DEBUG_Printf(DBG_CHN_MESG, " > ");
751           break;
752         case EXP_OP_LT:
753           DEBUG_Printf(DBG_CHN_MESG, " < ");
754           break;
755         case EXP_OP_GE:
756           DEBUG_Printf(DBG_CHN_MESG, " >= ");
757           break;
758         case EXP_OP_LE:
759           DEBUG_Printf(DBG_CHN_MESG, " <= ");
760           break;
761         case EXP_OP_NE:
762           DEBUG_Printf(DBG_CHN_MESG, " != ");
763           break;
764         case EXP_OP_SHL:
765           DEBUG_Printf(DBG_CHN_MESG, " << ");
766           break;
767         case EXP_OP_SHR:
768           DEBUG_Printf(DBG_CHN_MESG, " >> ");
769           break;
770         case EXP_OP_MUL:
771           DEBUG_Printf(DBG_CHN_MESG, " * ");
772           break;
773         case EXP_OP_DIV:
774           DEBUG_Printf(DBG_CHN_MESG, " / ");
775           break;
776         case EXP_OP_REM:
777           DEBUG_Printf(DBG_CHN_MESG, " %% ");
778           break;
779         case EXP_OP_ARR:
780           DEBUG_Printf(DBG_CHN_MESG, "[");
781           break;
782         default:
783           break;
784         }
785       DEBUG_DisplayExpr(exp->un.binop.exp2);
786       if( exp->un.binop.binop_type == EXP_OP_ARR )
787         {
788           DEBUG_Printf(DBG_CHN_MESG, "]");
789         }
790       DEBUG_Printf(DBG_CHN_MESG, " )");
791       break;
792     case EXPR_TYPE_UNOP:
793       switch(exp->un.unop.unop_type)
794         {
795         case EXP_OP_NEG:
796           DEBUG_Printf(DBG_CHN_MESG, "-");
797           break;
798         case EXP_OP_NOT:
799           DEBUG_Printf(DBG_CHN_MESG, "!");
800           break;
801         case EXP_OP_LNOT:
802           DEBUG_Printf(DBG_CHN_MESG, "~");
803           break;
804         case EXP_OP_DEREF:
805           DEBUG_Printf(DBG_CHN_MESG, "*");
806           break;
807         case EXP_OP_ADDR:
808           DEBUG_Printf(DBG_CHN_MESG, "&");
809           break;
810         }
811       DEBUG_DisplayExpr(exp->un.unop.exp1);
812       break;
813     default:
814       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
815       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
816       break;
817     }
818
819   return TRUE;
820 }
821
822 struct expr *
823 DEBUG_CloneExpr(const struct expr * exp)
824 {
825   int           i;
826   struct expr * rtn;
827
828   rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
829
830   /*
831    * First copy the contents of the expression itself.
832    */
833   *rtn = *exp;
834
835
836   switch(exp->type)
837     {
838     case EXPR_TYPE_CAST:
839       rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
840       break;
841     case EXPR_TYPE_INTVAR:
842       rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
843       break;
844     case EXPR_TYPE_US_CONST:
845     case EXPR_TYPE_CONST:
846       break;
847     case EXPR_TYPE_STRING:
848       rtn->un.string.str = DBG_strdup(exp->un.string.str);
849       break;
850     case EXPR_TYPE_SYMBOL:
851       rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
852       break;
853     case EXPR_TYPE_PSTRUCT:
854     case EXPR_TYPE_STRUCT:
855       rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
856       rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
857       break;
858     case EXPR_TYPE_CALL:
859       for(i=0; i < exp->un.call.nargs; i++)
860         {
861           rtn->un.call.arg[i]  = DEBUG_CloneExpr(exp->un.call.arg[i]);
862         }
863       rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
864       break;
865     case EXPR_TYPE_BINOP:
866       rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
867       rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
868       break;
869     case EXPR_TYPE_UNOP:
870       rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
871       break;
872     default:
873       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
874       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
875       break;
876     }
877
878   return rtn;
879 }
880
881
882 /*
883  * Recursively go through an expression tree and free all memory associated
884  * with it.
885  */
886 int
887 DEBUG_FreeExpr(struct expr * exp)
888 {
889   int i;
890
891   switch(exp->type)
892     {
893     case EXPR_TYPE_CAST:
894       DEBUG_FreeExpr(exp->un.cast.expr);
895       break;
896     case EXPR_TYPE_INTVAR:
897       DBG_free((char *) exp->un.intvar.name);
898       break;
899     case EXPR_TYPE_US_CONST:
900     case EXPR_TYPE_CONST:
901       break;
902     case EXPR_TYPE_STRING:
903       DBG_free((char *) exp->un.string.str);
904       break;
905     case EXPR_TYPE_SYMBOL:
906       DBG_free((char *) exp->un.symbol.name);
907       break;
908     case EXPR_TYPE_PSTRUCT:
909     case EXPR_TYPE_STRUCT:
910       DEBUG_FreeExpr(exp->un.structure.exp1);
911       DBG_free((char *) exp->un.structure.element_name);
912       break;
913     case EXPR_TYPE_CALL:
914       for(i=0; i < exp->un.call.nargs; i++)
915         {
916           DEBUG_FreeExpr(exp->un.call.arg[i]);
917         }
918       DBG_free((char *) exp->un.call.funcname);
919       break;
920     case EXPR_TYPE_BINOP:
921       DEBUG_FreeExpr(exp->un.binop.exp1);
922       DEBUG_FreeExpr(exp->un.binop.exp2);
923       break;
924     case EXPR_TYPE_UNOP:
925       DEBUG_FreeExpr(exp->un.unop.exp1);
926       break;
927     default:
928       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
929       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
930       break;
931     }
932
933   DBG_free(exp);
934   return TRUE;
935 }