- Improve LVM_GETITEMRECT values for LVS_ICON style. Now mostly
[wine] / debugger / expr.c
1 /*
2  * File expr.c - expression handling for Wine internal debugger.
3  *
4  * Copyright (C) 1997, Eric Youngdale.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "config.h"
22 #include <stdlib.h>
23 #include <string.h>
24 #include "winbase.h"
25 #include "wine/winbase16.h"
26 #include "debugger.h"
27 #include "expr.h"
28
29 #include <stdarg.h>
30
31 struct expr
32 {
33   unsigned int  perm;
34   unsigned int  type:31;
35   union
36   {
37     struct
38     {
39       int value;
40     } constant;
41
42     struct
43     {
44       const char * str;
45     } string;
46
47     struct
48     {
49       unsigned int value;
50     } u_const;
51
52     struct
53     {
54       const char * name;
55     } symbol;
56
57     struct
58     {
59       const char * name;
60     } intvar;
61
62     struct
63     {
64       int unop_type;
65       struct expr * exp1;
66       int             result;
67     } unop;
68
69     struct
70     {
71       int binop_type;
72       int result;
73       struct expr * exp1;
74       struct expr * exp2;
75     } binop;
76
77     struct
78     {
79       struct datatype * cast;
80       struct expr     * expr;
81     } cast;
82
83     struct
84     {
85       struct expr * exp1;
86       const char * element_name;
87       int result;
88     } structure;
89
90     struct
91     {
92       struct expr * base;
93       struct expr * index;
94     } array;
95
96     struct
97     {
98       const char  * funcname;
99       int           nargs;
100       int           result;
101       struct expr * arg[5];
102     } call;
103
104   } un;
105 };
106
107 #define EXPR_TYPE_CONST         0
108 #define EXPR_TYPE_US_CONST      1
109 #define EXPR_TYPE_SYMBOL        2
110 #define EXPR_TYPE_INTVAR        3
111 #define EXPR_TYPE_BINOP         4
112 #define EXPR_TYPE_UNOP          5
113 #define EXPR_TYPE_STRUCT        6
114 #define EXPR_TYPE_PSTRUCT       7
115 #define EXPR_TYPE_ARRAY         8
116 #define EXPR_TYPE_CALL          9
117 #define EXPR_TYPE_STRING        10
118 #define EXPR_TYPE_CAST          11
119
120 static char expr_list[4096];
121 static unsigned int next_expr_free = 0;
122
123 /*
124  * This is how we turn an expression address into the actual value.
125  * This works well in the 32 bit domain - not sure at all about the
126  * 16 bit world.
127  */
128 #define VAL(_exp)       DEBUG_GetExprValue(&_exp, NULL)
129
130 static
131 struct expr *
132 DEBUG_GetFreeExpr(void)
133 {
134   struct expr * rtn;
135
136   rtn =  (struct expr *) &expr_list[next_expr_free];
137
138   next_expr_free += sizeof(struct expr);
139   assert(next_expr_free < sizeof(expr_list));
140
141   return rtn;
142 }
143
144 void
145 DEBUG_FreeExprMem(void)
146 {
147   next_expr_free = 0;
148 }
149
150 struct expr *
151 DEBUG_TypeCastExpr(struct datatype * dt, struct expr * exp)
152 {
153   struct expr * ex;
154
155   ex = DEBUG_GetFreeExpr();
156
157   ex->type        = EXPR_TYPE_CAST;
158   ex->un.cast.cast = dt;
159   ex->un.cast.expr = exp;
160   return ex;
161 }
162
163 struct expr *
164 DEBUG_IntVarExpr(const char* name)
165 {
166   struct expr * ex;
167
168   ex = DEBUG_GetFreeExpr();
169
170   ex->type        = EXPR_TYPE_INTVAR;
171   ex->un.intvar.name = name;
172   return ex;
173 }
174
175 struct expr *
176 DEBUG_SymbolExpr(const char * name)
177 {
178   struct expr * ex;
179
180   ex = DEBUG_GetFreeExpr();
181
182   ex->type        = EXPR_TYPE_SYMBOL;
183   ex->un.symbol.name = name;
184   return ex;
185 }
186
187 struct expr *
188 DEBUG_ConstExpr(int value)
189 {
190   struct expr * ex;
191
192   ex = DEBUG_GetFreeExpr();
193
194   ex->type        = EXPR_TYPE_CONST;
195   ex->un.constant.value = value;
196   return ex;
197 }
198
199 struct expr *
200 DEBUG_StringExpr(const char * str)
201 {
202   struct expr * ex;
203   char * pnt;
204   ex = DEBUG_GetFreeExpr();
205
206   ex->type        = EXPR_TYPE_STRING;
207   ex->un.string.str = str+1;
208   pnt = strrchr(ex->un.string.str, '"');
209   if( pnt != NULL )
210     {
211       *pnt =  '\0';
212     }
213   return ex;
214 }
215
216 struct expr *
217 DEBUG_USConstExpr(unsigned int value)
218 {
219   struct expr * ex;
220
221   ex = DEBUG_GetFreeExpr();
222
223   ex->type           = EXPR_TYPE_CONST;
224   ex->un.u_const.value = value;
225   return ex;
226 }
227
228 struct expr *
229 DEBUG_BinopExpr(int operator_type, struct expr * exp1, struct expr * exp2)
230 {
231   struct expr * ex;
232
233   ex = DEBUG_GetFreeExpr();
234
235   ex->type           = EXPR_TYPE_BINOP;
236   ex->un.binop.binop_type = operator_type;
237   ex->un.binop.exp1     = exp1;
238   ex->un.binop.exp2     = exp2;
239   return ex;
240 }
241
242 struct expr *
243 DEBUG_UnopExpr(int operator_type, struct expr * exp1)
244 {
245   struct expr * ex;
246
247   ex = DEBUG_GetFreeExpr();
248
249   ex->type           = EXPR_TYPE_UNOP;
250   ex->un.unop.unop_type = operator_type;
251   ex->un.unop.exp1      = exp1;
252   return ex;
253 }
254
255 struct expr *
256 DEBUG_StructExpr(struct expr * exp, const char * element)
257 {
258   struct expr * ex;
259
260   ex = DEBUG_GetFreeExpr();
261
262   ex->type           = EXPR_TYPE_STRUCT;
263   ex->un.structure.exp1 = exp;
264   ex->un.structure.element_name = element;
265   return ex;
266 }
267
268 struct expr *
269 DEBUG_StructPExpr(struct expr * exp, const char * element)
270 {
271   struct expr * ex;
272
273   ex = DEBUG_GetFreeExpr();
274
275   ex->type           = EXPR_TYPE_PSTRUCT;
276   ex->un.structure.exp1 = exp;
277   ex->un.structure.element_name = element;
278   return ex;
279 }
280
281 struct expr *
282 DEBUG_CallExpr(const char * funcname, int nargs, ...)
283 {
284   struct expr * ex;
285   va_list ap;
286   int i;
287
288   ex = DEBUG_GetFreeExpr();
289
290   ex->type           = EXPR_TYPE_CALL;
291   ex->un.call.funcname = funcname;
292   ex->un.call.nargs = nargs;
293
294   va_start(ap, nargs);
295   for(i=0; i < nargs; i++)
296     {
297       ex->un.call.arg[i] = va_arg(ap, struct expr *);
298     }
299   va_end(ap);
300   return ex;
301 }
302
303 DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
304 {
305   DBG_VALUE     rtn;
306   int           i;
307   DBG_VALUE     exp1;
308   DBG_VALUE     exp2;
309   unsigned int  cexp[5];
310   int               scale1;
311   int               scale2;
312   int               scale3;
313   struct datatype * type1;
314   struct datatype * type2;
315
316   rtn.type = NULL;
317   rtn.cookie = DV_INVALID;
318   rtn.addr.off = 0;
319   rtn.addr.seg = 0;
320
321   switch(exp->type)
322     {
323     case EXPR_TYPE_CAST:
324       rtn = DEBUG_EvalExpr(exp->un.cast.expr);
325       rtn.type = exp->un.cast.cast;
326       if (!rtn.type)
327       {
328           DEBUG_Printf(DBG_CHN_MESG, "Can't cast to unknown type\n");
329           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
330       }
331       if (DEBUG_GetType(rtn.type) == DT_POINTER)
332          rtn.cookie = DV_TARGET;
333       break;
334     case EXPR_TYPE_STRING:
335       rtn.type = DEBUG_GetBasicType(DT_BASIC_STRING);
336       rtn.cookie = DV_HOST;
337       rtn.addr.off = (unsigned int) &exp->un.string.str;
338       rtn.addr.seg = 0;
339       break;
340     case EXPR_TYPE_CONST:
341       rtn.type = DEBUG_GetBasicType(DT_BASIC_CONST_INT);
342       rtn.cookie = DV_HOST;
343       rtn.addr.off = (unsigned int) &exp->un.constant.value;
344       rtn.addr.seg = 0;
345       break;
346     case EXPR_TYPE_US_CONST:
347       rtn.type = DEBUG_GetBasicType(DT_BASIC_USHORTINT);
348       rtn.cookie = DV_HOST;
349       rtn.addr.off = (unsigned int) &exp->un.u_const.value;
350       rtn.addr.seg = 0;
351       break;
352     case EXPR_TYPE_SYMBOL:
353       if( !DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE) )
354       {
355           DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.symbol.name);
356           RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
357       }
358       break;
359     case EXPR_TYPE_PSTRUCT:
360       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
361       if( exp1.type == NULL )
362         {
363            RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
364         }
365       rtn.cookie = DV_TARGET;
366       rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &rtn.type);
367       if( rtn.type == NULL )
368         {
369           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
370         }
371       if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
372                                    &exp->un.structure.result))
373       {
374           DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
375           RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
376       }
377
378       break;
379     case EXPR_TYPE_STRUCT:
380       exp1 =  DEBUG_EvalExpr(exp->un.structure.exp1);
381       if( exp1.type == NULL )
382       {
383           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
384       }
385       rtn = exp1;
386       if (!DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
387                                    &exp->un.structure.result))
388       {
389           DEBUG_Printf(DBG_CHN_MESG, "%s\n", exp->un.structure.element_name);
390           RaiseException(DEBUG_STATUS_NO_FIELD, 0, 0, NULL);
391       }
392       break;
393     case EXPR_TYPE_CALL:
394       /*
395        * First, evaluate all of the arguments.  If any of them are not
396        * evaluable, then bail.
397        */
398       for(i=0; i < exp->un.call.nargs; i++)
399         {
400           exp1  = DEBUG_EvalExpr(exp->un.call.arg[i]);
401           if( exp1.type == NULL )
402             {
403               return rtn;
404             }
405           cexp[i] = DEBUG_GetExprValue(&exp1, NULL);
406         }
407
408       /*
409        * Now look up the address of the function itself.
410        */
411       if( !DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ) )
412         {
413           RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
414         }
415
416 #if 0
417       /* FIXME: NEWDBG NIY */
418       /* Anyway, I wonder how this could work depending on the calling order of
419        * the function (cdecl vs pascal for example)
420        */
421       int               (*fptr)();
422
423       fptr = (int (*)()) rtn.addr.off;
424       switch(exp->un.call.nargs)
425         {
426         case 0:
427           exp->un.call.result = (*fptr)();
428           break;
429         case 1:
430           exp->un.call.result = (*fptr)(cexp[0]);
431           break;
432         case 2:
433           exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
434           break;
435         case 3:
436           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
437           break;
438         case 4:
439           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
440           break;
441         case 5:
442           exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
443           break;
444         }
445 #else
446       DEBUG_Printf(DBG_CHN_MESG, "Function call no longer implemented\n");
447       /* would need to set up a call to this function, and then restore the current
448        * context afterwards...
449        */
450       exp->un.call.result = 0;
451 #endif
452       rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
453       rtn.cookie = DV_HOST;
454       rtn.addr.off = (unsigned int) &exp->un.call.result;
455
456       break;
457     case EXPR_TYPE_INTVAR:
458       {
459
460          DBG_INTVAR*    div = DEBUG_GetIntVar(exp->un.intvar.name);
461
462          if (!div) RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
463          rtn.cookie = DV_HOST;
464          rtn.type = div->type;
465          rtn.addr.off = (unsigned int)div->pval;
466          /* EPP FIXME rtn.addr.seg = ?? */
467       }
468       break;
469     case EXPR_TYPE_BINOP:
470       exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
471       exp2 = DEBUG_EvalExpr(exp->un.binop.exp2);
472       rtn.cookie = DV_HOST;
473       if( exp1.type == NULL || exp2.type == NULL )
474         {
475           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
476         }
477       if( exp1.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) &&
478           exp2.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) )
479         {
480           rtn.type = exp1.type;
481         }
482       else
483         {
484           rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
485         }
486       rtn.addr.seg = 0;
487       rtn.addr.off = (unsigned int) &exp->un.binop.result;
488       switch(exp->un.binop.binop_type)
489         {
490         case EXP_OP_ADD:
491           type1 = DEBUG_GetPointerType(exp1.type);
492           type2 = DEBUG_GetPointerType(exp2.type);
493           scale1 = 1;
494           scale2 = 1;
495           if( type1 != NULL && type2 != NULL )
496             {
497               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
498             }
499           else if( type1 != NULL )
500             {
501               scale2 = DEBUG_GetObjectSize(type1);
502               rtn.type = exp1.type;
503             }
504           else if( type2 != NULL )
505             {
506               scale1 = DEBUG_GetObjectSize(type2);
507               rtn.type = exp2.type;
508             }
509           exp->un.binop.result = (VAL(exp1) * scale1  + scale2 * VAL(exp2));
510           break;
511         case EXP_OP_SUB:
512           type1 = DEBUG_GetPointerType(exp1.type);
513           type2 = DEBUG_GetPointerType(exp2.type);
514           scale1 = 1;
515           scale2 = 1;
516           scale3 = 1;
517           if( type1 != NULL && type2 != NULL )
518             {
519               if( type1 != type2 )
520                 {
521                   RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
522                 }
523               scale3 = DEBUG_GetObjectSize(type1);
524             }
525           else if( type1 != NULL )
526             {
527               scale2 = DEBUG_GetObjectSize(type1);
528               rtn.type = exp1.type;
529             }
530
531           else if( type2 != NULL )
532             {
533               scale1 = DEBUG_GetObjectSize(type2);
534               rtn.type = exp2.type;
535             }
536           exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
537           break;
538         case EXP_OP_SEG:
539           rtn.cookie = DV_TARGET;
540           rtn.type = NULL;
541           rtn.addr.seg = VAL(exp1);
542           rtn.addr.off = VAL(exp2);
543           break;
544         case EXP_OP_LOR:
545           exp->un.binop.result = (VAL(exp1) || VAL(exp2));
546           break;
547         case EXP_OP_LAND:
548           exp->un.binop.result = (VAL(exp1) && VAL(exp2));
549           break;
550         case EXP_OP_OR:
551           exp->un.binop.result = (VAL(exp1) | VAL(exp2));
552           break;
553         case EXP_OP_AND:
554           exp->un.binop.result = (VAL(exp1) & VAL(exp2));
555           break;
556         case EXP_OP_XOR:
557           exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
558           break;
559         case EXP_OP_EQ:
560           exp->un.binop.result = (VAL(exp1) == VAL(exp2));
561           break;
562         case EXP_OP_GT:
563           exp->un.binop.result = (VAL(exp1) > VAL(exp2));
564           break;
565         case EXP_OP_LT:
566           exp->un.binop.result = (VAL(exp1) < VAL(exp2));
567           break;
568         case EXP_OP_GE:
569           exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
570           break;
571         case EXP_OP_LE:
572           exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
573           break;
574         case EXP_OP_NE:
575           exp->un.binop.result = (VAL(exp1) != VAL(exp2));
576           break;
577         case EXP_OP_SHL:
578           exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
579           break;
580         case EXP_OP_SHR:
581           exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
582           break;
583         case EXP_OP_MUL:
584           exp->un.binop.result = (VAL(exp1) * VAL(exp2));
585           break;
586         case EXP_OP_DIV:
587           if( VAL(exp2) == 0 )
588             {
589                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
590             }
591           exp->un.binop.result = (VAL(exp1) / VAL(exp2));
592           break;
593         case EXP_OP_REM:
594           if( VAL(exp2) == 0 )
595             {
596                RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
597             }
598           exp->un.binop.result = (VAL(exp1) % VAL(exp2));
599           break;
600         case EXP_OP_ARR:
601           DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
602           break;
603         default:
604           RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
605           break;
606         }
607       break;
608     case EXPR_TYPE_UNOP:
609       exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
610       rtn.cookie = DV_HOST;
611       if( exp1.type == NULL )
612         {
613           RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
614         }
615       rtn.addr.seg = 0;
616       rtn.addr.off = (unsigned int) &exp->un.unop.result;
617       if( exp1.type == DEBUG_GetBasicType(DT_BASIC_CONST_INT) )
618         {
619           rtn.type = exp1.type;
620         }
621       else
622         {
623           rtn.type = DEBUG_GetBasicType(DT_BASIC_INT);
624         }
625       switch(exp->un.unop.unop_type)
626         {
627         case EXP_OP_NEG:
628           exp->un.unop.result = -VAL(exp1);
629           break;
630         case EXP_OP_NOT:
631           exp->un.unop.result = !VAL(exp1);
632           break;
633         case EXP_OP_LNOT:
634           exp->un.unop.result = ~VAL(exp1);
635           break;
636         case EXP_OP_DEREF:
637           /* FIXME: this is currently buggy.
638            * there is no way to tell were the deref:ed value is...
639            * for example:
640            *    x is a pointer to struct s, x being on the stack
641            *            => exp1 is target, result is target
642            *    x is a pointer to struct s, x being optimized into a reg
643            *            => exp1 is host, result is target
644            *    x is a pointer to internal variable x
645            *            => exp1 is host, result is host
646            * so we force DV_TARGET, because dereferencing pointers to
647            * internal variables is very unlikely. a correct fix would be
648            * rather large.
649            */
650           rtn.cookie = DV_TARGET;
651           rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
652           if (!rtn.type)
653             {
654               RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
655             }
656           break;
657         case EXP_OP_FORCE_DEREF:
658           rtn.cookie = exp1.cookie;
659           rtn.addr.seg = exp1.addr.seg;
660           if (exp1.cookie == DV_TARGET)
661              DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
662           else
663              memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
664           break;
665         case EXP_OP_ADDR:
666           /* FIXME: even for a 16 bit entity ? */
667           rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
668           exp->un.unop.result = exp1.addr.off;
669           break;
670         default:
671            RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
672         }
673       break;
674     default:
675       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
676       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
677       break;
678     }
679
680   assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
681
682   return rtn;
683 }
684
685
686 int
687 DEBUG_DisplayExpr(const struct expr * exp)
688 {
689   int           i;
690
691   switch(exp->type)
692     {
693     case EXPR_TYPE_CAST:
694       DEBUG_Printf(DBG_CHN_MESG, "((");
695       DEBUG_PrintTypeCast(exp->un.cast.cast);
696       DEBUG_Printf(DBG_CHN_MESG, ")");
697       DEBUG_DisplayExpr(exp->un.cast.expr);
698       DEBUG_Printf(DBG_CHN_MESG, ")");
699       break;
700     case EXPR_TYPE_INTVAR:
701       DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
702       break;
703     case EXPR_TYPE_US_CONST:
704       DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
705       break;
706     case EXPR_TYPE_CONST:
707       DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
708       break;
709     case EXPR_TYPE_STRING:
710       DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str);
711       break;
712     case EXPR_TYPE_SYMBOL:
713       DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
714       break;
715     case EXPR_TYPE_PSTRUCT:
716       DEBUG_DisplayExpr(exp->un.structure.exp1);
717       DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
718       break;
719     case EXPR_TYPE_STRUCT:
720       DEBUG_DisplayExpr(exp->un.structure.exp1);
721       DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
722       break;
723     case EXPR_TYPE_CALL:
724       DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
725       for(i=0; i < exp->un.call.nargs; i++)
726         {
727           DEBUG_DisplayExpr(exp->un.call.arg[i]);
728           if( i != exp->un.call.nargs - 1 )
729             {
730               DEBUG_Printf(DBG_CHN_MESG, ", ");
731             }
732         }
733       DEBUG_Printf(DBG_CHN_MESG, ")");
734       break;
735     case EXPR_TYPE_BINOP:
736       DEBUG_Printf(DBG_CHN_MESG, "( ");
737       DEBUG_DisplayExpr(exp->un.binop.exp1);
738       switch(exp->un.binop.binop_type)
739         {
740         case EXP_OP_ADD:
741           DEBUG_Printf(DBG_CHN_MESG, " + ");
742           break;
743         case EXP_OP_SUB:
744           DEBUG_Printf(DBG_CHN_MESG, " - ");
745           break;
746         case EXP_OP_SEG:
747           DEBUG_Printf(DBG_CHN_MESG, ":");
748           break;
749         case EXP_OP_LOR:
750           DEBUG_Printf(DBG_CHN_MESG, " || ");
751           break;
752         case EXP_OP_LAND:
753           DEBUG_Printf(DBG_CHN_MESG, " && ");
754           break;
755         case EXP_OP_OR:
756           DEBUG_Printf(DBG_CHN_MESG, " | ");
757           break;
758         case EXP_OP_AND:
759           DEBUG_Printf(DBG_CHN_MESG, " & ");
760           break;
761         case EXP_OP_XOR:
762           DEBUG_Printf(DBG_CHN_MESG, " ^ ");
763           break;
764         case EXP_OP_EQ:
765           DEBUG_Printf(DBG_CHN_MESG, " == ");
766           break;
767         case EXP_OP_GT:
768           DEBUG_Printf(DBG_CHN_MESG, " > ");
769           break;
770         case EXP_OP_LT:
771           DEBUG_Printf(DBG_CHN_MESG, " < ");
772           break;
773         case EXP_OP_GE:
774           DEBUG_Printf(DBG_CHN_MESG, " >= ");
775           break;
776         case EXP_OP_LE:
777           DEBUG_Printf(DBG_CHN_MESG, " <= ");
778           break;
779         case EXP_OP_NE:
780           DEBUG_Printf(DBG_CHN_MESG, " != ");
781           break;
782         case EXP_OP_SHL:
783           DEBUG_Printf(DBG_CHN_MESG, " << ");
784           break;
785         case EXP_OP_SHR:
786           DEBUG_Printf(DBG_CHN_MESG, " >> ");
787           break;
788         case EXP_OP_MUL:
789           DEBUG_Printf(DBG_CHN_MESG, " * ");
790           break;
791         case EXP_OP_DIV:
792           DEBUG_Printf(DBG_CHN_MESG, " / ");
793           break;
794         case EXP_OP_REM:
795           DEBUG_Printf(DBG_CHN_MESG, " %% ");
796           break;
797         case EXP_OP_ARR:
798           DEBUG_Printf(DBG_CHN_MESG, "[");
799           break;
800         default:
801           break;
802         }
803       DEBUG_DisplayExpr(exp->un.binop.exp2);
804       if( exp->un.binop.binop_type == EXP_OP_ARR )
805         {
806           DEBUG_Printf(DBG_CHN_MESG, "]");
807         }
808       DEBUG_Printf(DBG_CHN_MESG, " )");
809       break;
810     case EXPR_TYPE_UNOP:
811       switch(exp->un.unop.unop_type)
812         {
813         case EXP_OP_NEG:
814           DEBUG_Printf(DBG_CHN_MESG, "-");
815           break;
816         case EXP_OP_NOT:
817           DEBUG_Printf(DBG_CHN_MESG, "!");
818           break;
819         case EXP_OP_LNOT:
820           DEBUG_Printf(DBG_CHN_MESG, "~");
821           break;
822         case EXP_OP_DEREF:
823           DEBUG_Printf(DBG_CHN_MESG, "*");
824           break;
825         case EXP_OP_ADDR:
826           DEBUG_Printf(DBG_CHN_MESG, "&");
827           break;
828         }
829       DEBUG_DisplayExpr(exp->un.unop.exp1);
830       break;
831     default:
832       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
833       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
834       break;
835     }
836
837   return TRUE;
838 }
839
840 struct expr *
841 DEBUG_CloneExpr(const struct expr * exp)
842 {
843   int           i;
844   struct expr * rtn;
845
846   rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
847
848   /*
849    * First copy the contents of the expression itself.
850    */
851   *rtn = *exp;
852
853
854   switch(exp->type)
855     {
856     case EXPR_TYPE_CAST:
857       rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
858       break;
859     case EXPR_TYPE_INTVAR:
860       rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
861       break;
862     case EXPR_TYPE_US_CONST:
863     case EXPR_TYPE_CONST:
864       break;
865     case EXPR_TYPE_STRING:
866       rtn->un.string.str = DBG_strdup(exp->un.string.str);
867       break;
868     case EXPR_TYPE_SYMBOL:
869       rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
870       break;
871     case EXPR_TYPE_PSTRUCT:
872     case EXPR_TYPE_STRUCT:
873       rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
874       rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
875       break;
876     case EXPR_TYPE_CALL:
877       for(i=0; i < exp->un.call.nargs; i++)
878         {
879           rtn->un.call.arg[i]  = DEBUG_CloneExpr(exp->un.call.arg[i]);
880         }
881       rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
882       break;
883     case EXPR_TYPE_BINOP:
884       rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
885       rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
886       break;
887     case EXPR_TYPE_UNOP:
888       rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
889       break;
890     default:
891       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
892       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
893       break;
894     }
895
896   return rtn;
897 }
898
899
900 /*
901  * Recursively go through an expression tree and free all memory associated
902  * with it.
903  */
904 int
905 DEBUG_FreeExpr(struct expr * exp)
906 {
907   int i;
908
909   switch(exp->type)
910     {
911     case EXPR_TYPE_CAST:
912       DEBUG_FreeExpr(exp->un.cast.expr);
913       break;
914     case EXPR_TYPE_INTVAR:
915       DBG_free((char *) exp->un.intvar.name);
916       break;
917     case EXPR_TYPE_US_CONST:
918     case EXPR_TYPE_CONST:
919       break;
920     case EXPR_TYPE_STRING:
921       DBG_free((char *) exp->un.string.str);
922       break;
923     case EXPR_TYPE_SYMBOL:
924       DBG_free((char *) exp->un.symbol.name);
925       break;
926     case EXPR_TYPE_PSTRUCT:
927     case EXPR_TYPE_STRUCT:
928       DEBUG_FreeExpr(exp->un.structure.exp1);
929       DBG_free((char *) exp->un.structure.element_name);
930       break;
931     case EXPR_TYPE_CALL:
932       for(i=0; i < exp->un.call.nargs; i++)
933         {
934           DEBUG_FreeExpr(exp->un.call.arg[i]);
935         }
936       DBG_free((char *) exp->un.call.funcname);
937       break;
938     case EXPR_TYPE_BINOP:
939       DEBUG_FreeExpr(exp->un.binop.exp1);
940       DEBUG_FreeExpr(exp->un.binop.exp2);
941       break;
942     case EXPR_TYPE_UNOP:
943       DEBUG_FreeExpr(exp->un.unop.exp1);
944       break;
945     default:
946       DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
947       RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
948       break;
949     }
950
951   DBG_free(exp);
952   return TRUE;
953 }