fixed a number of long standing bugs:
[wine.git] / debugger / expr.c
blob29262ef7ced81fc82da78a96fe23c394b4577b39
1 /*
2 * File expr.c - expression handling for Wine internal debugger.
4 * Copyright (C) 1997, Eric Youngdale.
6 */
8 #include "config.h"
9 #include <stdlib.h>
10 #include <string.h>
11 #include "winbase.h"
12 #include "wine/winbase16.h"
13 #include "task.h"
14 #include "debugger.h"
15 #include "expr.h"
17 #include <stdarg.h>
19 struct expr
21 unsigned int perm;
22 unsigned int type:31;
23 union
25 struct
27 int value;
28 } constant;
30 struct
32 const char * str;
33 } string;
35 struct
37 unsigned int value;
38 } u_const;
40 struct
42 const char * name;
43 } symbol;
45 struct
47 const char * name;
48 } intvar;
50 struct
52 int unop_type;
53 struct expr * exp1;
54 int result;
55 } unop;
57 struct
59 int binop_type;
60 int result;
61 struct expr * exp1;
62 struct expr * exp2;
63 } binop;
65 struct
67 struct datatype * cast;
68 struct expr * expr;
69 } cast;
71 struct
73 struct expr * exp1;
74 const char * element_name;
75 int result;
76 } structure;
78 struct
80 struct expr * base;
81 struct expr * index;
82 } array;
84 struct
86 const char * funcname;
87 int nargs;
88 int result;
89 struct expr * arg[5];
90 } call;
92 } un;
95 #define EXPR_TYPE_CONST 0
96 #define EXPR_TYPE_US_CONST 1
97 #define EXPR_TYPE_SYMBOL 2
98 #define EXPR_TYPE_INTVAR 3
99 #define EXPR_TYPE_BINOP 4
100 #define EXPR_TYPE_UNOP 5
101 #define EXPR_TYPE_STRUCT 6
102 #define EXPR_TYPE_PSTRUCT 7
103 #define EXPR_TYPE_ARRAY 8
104 #define EXPR_TYPE_CALL 9
105 #define EXPR_TYPE_STRING 10
106 #define EXPR_TYPE_CAST 11
108 static char expr_list[4096];
109 static int next_expr_free = 0;
112 * This is how we turn an expression address into the actual value.
113 * This works well in the 32 bit domain - not sure at all about the
114 * 16 bit world.
116 #define VAL(_exp) DEBUG_GetExprValue(&_exp, NULL)
118 static
119 struct expr *
120 DEBUG_GetFreeExpr(void)
122 struct expr * rtn;
124 rtn = (struct expr *) &expr_list[next_expr_free];
126 next_expr_free += sizeof(struct expr);
127 assert(next_expr_free < sizeof(expr_list));
129 return rtn;
132 void
133 DEBUG_FreeExprMem(void)
135 next_expr_free = 0;
138 struct expr *
139 DEBUG_TypeCastExpr(struct datatype * dt, struct expr * exp)
141 struct expr * ex;
143 ex = DEBUG_GetFreeExpr();
145 ex->type = EXPR_TYPE_CAST;
146 ex->un.cast.cast = dt;
147 ex->un.cast.expr = exp;
148 return ex;
151 struct expr *
152 DEBUG_IntVarExpr(const char* name)
154 struct expr * ex;
156 ex = DEBUG_GetFreeExpr();
158 ex->type = EXPR_TYPE_INTVAR;
159 ex->un.intvar.name = name;
160 return ex;
163 struct expr *
164 DEBUG_SymbolExpr(const char * name)
166 struct expr * ex;
168 ex = DEBUG_GetFreeExpr();
170 ex->type = EXPR_TYPE_SYMBOL;
171 ex->un.symbol.name = name;
172 return ex;
175 struct expr *
176 DEBUG_ConstExpr(int value)
178 struct expr * ex;
180 ex = DEBUG_GetFreeExpr();
182 ex->type = EXPR_TYPE_CONST;
183 ex->un.constant.value = value;
184 return ex;
187 struct expr *
188 DEBUG_StringExpr(const char * str)
190 struct expr * ex;
191 char * pnt;
192 ex = DEBUG_GetFreeExpr();
194 ex->type = EXPR_TYPE_STRING;
195 ex->un.string.str = str+1;
196 pnt = strrchr(ex->un.string.str, '"');
197 if( pnt != NULL )
199 *pnt = '\0';
201 return ex;
204 struct expr *
205 DEBUG_USConstExpr(unsigned int value)
207 struct expr * ex;
209 ex = DEBUG_GetFreeExpr();
211 ex->type = EXPR_TYPE_CONST;
212 ex->un.u_const.value = value;
213 return ex;
216 struct expr *
217 DEBUG_BinopExpr(int operator_type, struct expr * exp1, struct expr * exp2)
219 struct expr * ex;
221 ex = DEBUG_GetFreeExpr();
223 ex->type = EXPR_TYPE_BINOP;
224 ex->un.binop.binop_type = operator_type;
225 ex->un.binop.exp1 = exp1;
226 ex->un.binop.exp2 = exp2;
227 return ex;
230 struct expr *
231 DEBUG_UnopExpr(int operator_type, struct expr * exp1)
233 struct expr * ex;
235 ex = DEBUG_GetFreeExpr();
237 ex->type = EXPR_TYPE_UNOP;
238 ex->un.unop.unop_type = operator_type;
239 ex->un.unop.exp1 = exp1;
240 return ex;
243 struct expr *
244 DEBUG_StructExpr(struct expr * exp, const char * element)
246 struct expr * ex;
248 ex = DEBUG_GetFreeExpr();
250 ex->type = EXPR_TYPE_STRUCT;
251 ex->un.structure.exp1 = exp;
252 ex->un.structure.element_name = element;
253 return ex;
256 struct expr *
257 DEBUG_StructPExpr(struct expr * exp, const char * element)
259 struct expr * ex;
261 ex = DEBUG_GetFreeExpr();
263 ex->type = EXPR_TYPE_PSTRUCT;
264 ex->un.structure.exp1 = exp;
265 ex->un.structure.element_name = element;
266 return ex;
269 struct expr *
270 DEBUG_CallExpr(const char * funcname, int nargs, ...)
272 struct expr * ex;
273 va_list ap;
274 int i;
276 ex = DEBUG_GetFreeExpr();
278 ex->type = EXPR_TYPE_CALL;
279 ex->un.call.funcname = funcname;
280 ex->un.call.nargs = nargs;
282 va_start(ap, nargs);
283 for(i=0; i < nargs; i++)
285 ex->un.call.arg[i] = va_arg(ap, struct expr *);
287 va_end(ap);
288 return ex;
291 DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
293 DBG_VALUE rtn;
294 int i;
295 DBG_VALUE exp1;
296 DBG_VALUE exp2;
297 unsigned int cexp[5];
298 int scale1;
299 int scale2;
300 int scale3;
301 struct datatype * type1;
302 struct datatype * type2;
304 rtn.type = NULL;
305 rtn.cookie = DV_INVALID;
306 rtn.addr.off = 0;
307 rtn.addr.seg = 0;
309 switch(exp->type)
311 case EXPR_TYPE_CAST:
312 rtn = DEBUG_EvalExpr(exp->un.cast.expr);
313 rtn.type = exp->un.cast.cast;
314 if (DEBUG_GetType(rtn.type) == DT_POINTER)
315 rtn.cookie = DV_TARGET;
316 break;
317 case EXPR_TYPE_STRING:
318 rtn.type = DEBUG_TypeString;
319 rtn.cookie = DV_HOST;
320 rtn.addr.off = (unsigned int) &exp->un.string.str;
321 rtn.addr.seg = 0;
322 break;
323 case EXPR_TYPE_CONST:
324 rtn.type = DEBUG_TypeIntConst;
325 rtn.cookie = DV_HOST;
326 rtn.addr.off = (unsigned int) &exp->un.constant.value;
327 rtn.addr.seg = 0;
328 break;
329 case EXPR_TYPE_US_CONST:
330 rtn.type = DEBUG_TypeUSInt;
331 rtn.cookie = DV_HOST;
332 rtn.addr.off = (unsigned int) &exp->un.u_const.value;
333 rtn.addr.seg = 0;
334 break;
335 case EXPR_TYPE_SYMBOL:
336 if( !DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE) )
338 RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
340 break;
341 case EXPR_TYPE_PSTRUCT:
342 exp1 = DEBUG_EvalExpr(exp->un.structure.exp1);
343 if( exp1.type == NULL )
345 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
347 rtn.cookie = DV_TARGET;
348 rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &type1);
349 if( type1 == NULL )
351 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
353 rtn.type = type1;
354 DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
355 &exp->un.structure.result);
356 break;
357 case EXPR_TYPE_STRUCT:
358 exp1 = DEBUG_EvalExpr(exp->un.structure.exp1);
359 if( exp1.type == NULL )
361 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
363 rtn = exp1;
364 DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
365 &exp->un.structure.result);
366 break;
367 case EXPR_TYPE_CALL:
369 * First, evaluate all of the arguments. If any of them are not
370 * evaluable, then bail.
372 for(i=0; i < exp->un.call.nargs; i++)
374 exp1 = DEBUG_EvalExpr(exp->un.call.arg[i]);
375 if( exp1.type == NULL )
377 return rtn;
379 cexp[i] = DEBUG_GetExprValue(&exp1, NULL);
383 * Now look up the address of the function itself.
385 if( !DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ) )
387 RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
390 #if 0
391 /* FIXME: NEWDBG NIY */
392 /* Anyway, I wonder how this could work depending on the calling order of
393 * the function (cdecl vs pascal for example)
395 int (*fptr)();
397 fptr = (int (*)()) rtn.addr.off;
398 switch(exp->un.call.nargs)
400 case 0:
401 exp->un.call.result = (*fptr)();
402 break;
403 case 1:
404 exp->un.call.result = (*fptr)(cexp[0]);
405 break;
406 case 2:
407 exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
408 break;
409 case 3:
410 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
411 break;
412 case 4:
413 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
414 break;
415 case 5:
416 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
417 break;
419 #else
420 DEBUG_Printf(DBG_CHN_MESG, "Function call no longer implemented\n");
421 /* would need to set up a call to this function, and then restore the current
422 * context afterwards...
424 exp->un.call.result = 0;
425 #endif
426 rtn.type = DEBUG_TypeInt;
427 rtn.cookie = DV_HOST;
428 rtn.addr.off = (unsigned int) &exp->un.call.result;
430 break;
431 case EXPR_TYPE_INTVAR:
434 DBG_INTVAR* div = DEBUG_GetIntVar(exp->un.intvar.name);
436 if (!div) RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
437 rtn.cookie = DV_HOST;
438 rtn.type = div->type;
439 rtn.addr.off = (unsigned int)div->pval;
440 /* EPP FIXME rtn.addr.seg = ?? */
442 break;
443 case EXPR_TYPE_BINOP:
444 exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
445 exp2 = DEBUG_EvalExpr(exp->un.binop.exp2);
446 rtn.cookie = DV_HOST;
447 if( exp1.type == NULL || exp2.type == NULL )
449 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
451 if( exp1.type == DEBUG_TypeIntConst && exp2.type == DEBUG_TypeIntConst )
453 rtn.type = exp1.type;
455 else
457 rtn.type = DEBUG_TypeInt;
459 rtn.addr.seg = 0;
460 rtn.addr.off = (unsigned int) &exp->un.binop.result;
461 switch(exp->un.binop.binop_type)
463 case EXP_OP_ADD:
464 type1 = DEBUG_GetPointerType(exp1.type);
465 type2 = DEBUG_GetPointerType(exp2.type);
466 scale1 = 1;
467 scale2 = 1;
468 if( type1 != NULL && type2 != NULL )
470 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
472 else if( type1 != NULL )
474 scale2 = DEBUG_GetObjectSize(type1);
475 rtn.type = exp1.type;
477 else if( type2 != NULL )
479 scale1 = DEBUG_GetObjectSize(type2);
480 rtn.type = exp2.type;
482 exp->un.binop.result = (VAL(exp1) * scale1 + scale2 * VAL(exp2));
483 break;
484 case EXP_OP_SUB:
485 type1 = DEBUG_GetPointerType(exp1.type);
486 type2 = DEBUG_GetPointerType(exp2.type);
487 scale1 = 1;
488 scale2 = 1;
489 scale3 = 1;
490 if( type1 != NULL && type2 != NULL )
492 if( type1 != type2 )
494 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
496 scale3 = DEBUG_GetObjectSize(type1);
498 else if( type1 != NULL )
500 scale2 = DEBUG_GetObjectSize(type1);
501 rtn.type = exp1.type;
504 else if( type2 != NULL )
506 scale1 = DEBUG_GetObjectSize(type2);
507 rtn.type = exp2.type;
509 exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
510 break;
511 case EXP_OP_SEG:
512 rtn.cookie = DV_TARGET;
513 rtn.type = NULL;
514 rtn.addr.seg = VAL(exp1);
515 rtn.addr.off = VAL(exp2);
516 #ifdef __i386__
517 DEBUG_FixSegment(&rtn.addr);
518 #endif
519 break;
520 case EXP_OP_LOR:
521 exp->un.binop.result = (VAL(exp1) || VAL(exp2));
522 break;
523 case EXP_OP_LAND:
524 exp->un.binop.result = (VAL(exp1) && VAL(exp2));
525 break;
526 case EXP_OP_OR:
527 exp->un.binop.result = (VAL(exp1) | VAL(exp2));
528 break;
529 case EXP_OP_AND:
530 exp->un.binop.result = (VAL(exp1) & VAL(exp2));
531 break;
532 case EXP_OP_XOR:
533 exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
534 break;
535 case EXP_OP_EQ:
536 exp->un.binop.result = (VAL(exp1) == VAL(exp2));
537 break;
538 case EXP_OP_GT:
539 exp->un.binop.result = (VAL(exp1) > VAL(exp2));
540 break;
541 case EXP_OP_LT:
542 exp->un.binop.result = (VAL(exp1) < VAL(exp2));
543 break;
544 case EXP_OP_GE:
545 exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
546 break;
547 case EXP_OP_LE:
548 exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
549 break;
550 case EXP_OP_NE:
551 exp->un.binop.result = (VAL(exp1) != VAL(exp2));
552 break;
553 case EXP_OP_SHL:
554 exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
555 break;
556 case EXP_OP_SHR:
557 exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
558 break;
559 case EXP_OP_MUL:
560 exp->un.binop.result = (VAL(exp1) * VAL(exp2));
561 break;
562 case EXP_OP_DIV:
563 if( VAL(exp2) == 0 )
565 RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
567 exp->un.binop.result = (VAL(exp1) / VAL(exp2));
568 break;
569 case EXP_OP_REM:
570 if( VAL(exp2) == 0 )
572 RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
574 exp->un.binop.result = (VAL(exp1) % VAL(exp2));
575 break;
576 case EXP_OP_ARR:
577 DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
578 break;
579 default:
580 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
581 break;
583 break;
584 case EXPR_TYPE_UNOP:
585 exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
586 rtn.cookie = DV_HOST;
587 if( exp1.type == NULL )
589 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
591 rtn.addr.seg = 0;
592 rtn.addr.off = (unsigned int) &exp->un.unop.result;
593 if( exp1.type == DEBUG_TypeIntConst )
595 rtn.type = exp1.type;
597 else
599 rtn.type = DEBUG_TypeInt;
601 switch(exp->un.unop.unop_type)
603 case EXP_OP_NEG:
604 exp->un.unop.result = -VAL(exp1);
605 break;
606 case EXP_OP_NOT:
607 exp->un.unop.result = !VAL(exp1);
608 break;
609 case EXP_OP_LNOT:
610 exp->un.unop.result = ~VAL(exp1);
611 break;
612 case EXP_OP_DEREF:
613 rtn.cookie = exp1.cookie;
614 rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
615 if (!rtn.type)
617 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
619 break;
620 case EXP_OP_FORCE_DEREF:
621 rtn.cookie = exp1.cookie;
622 rtn.addr.seg = exp1.addr.seg;
623 if (exp1.cookie == DV_TARGET)
624 DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
625 else
626 memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
627 break;
628 case EXP_OP_ADDR:
629 /* FIXME: even for a 16 bit entity ? */
630 rtn.cookie = DV_TARGET;
631 rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
632 exp->un.unop.result = exp1.addr.off;
633 break;
634 default:
635 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
637 break;
638 default:
639 DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
640 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
641 break;
644 assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
646 return rtn;
651 DEBUG_DisplayExpr(const struct expr * exp)
653 int i;
655 switch(exp->type)
657 case EXPR_TYPE_CAST:
658 DEBUG_Printf(DBG_CHN_MESG, "((");
659 DEBUG_PrintTypeCast(exp->un.cast.cast);
660 DEBUG_Printf(DBG_CHN_MESG, ")");
661 DEBUG_DisplayExpr(exp->un.cast.expr);
662 DEBUG_Printf(DBG_CHN_MESG, ")");
663 break;
664 case EXPR_TYPE_INTVAR:
665 DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
666 break;
667 case EXPR_TYPE_US_CONST:
668 DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
669 break;
670 case EXPR_TYPE_CONST:
671 DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
672 break;
673 case EXPR_TYPE_STRING:
674 DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str);
675 break;
676 case EXPR_TYPE_SYMBOL:
677 DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
678 break;
679 case EXPR_TYPE_PSTRUCT:
680 DEBUG_DisplayExpr(exp->un.structure.exp1);
681 DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
682 break;
683 case EXPR_TYPE_STRUCT:
684 DEBUG_DisplayExpr(exp->un.structure.exp1);
685 DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
686 break;
687 case EXPR_TYPE_CALL:
688 DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
689 for(i=0; i < exp->un.call.nargs; i++)
691 DEBUG_DisplayExpr(exp->un.call.arg[i]);
692 if( i != exp->un.call.nargs - 1 )
694 DEBUG_Printf(DBG_CHN_MESG, ", ");
697 DEBUG_Printf(DBG_CHN_MESG, ")");
698 break;
699 case EXPR_TYPE_BINOP:
700 DEBUG_Printf(DBG_CHN_MESG, "( ");
701 DEBUG_DisplayExpr(exp->un.binop.exp1);
702 switch(exp->un.binop.binop_type)
704 case EXP_OP_ADD:
705 DEBUG_Printf(DBG_CHN_MESG, " + ");
706 break;
707 case EXP_OP_SUB:
708 DEBUG_Printf(DBG_CHN_MESG, " - ");
709 break;
710 case EXP_OP_SEG:
711 DEBUG_Printf(DBG_CHN_MESG, ":");
712 break;
713 case EXP_OP_LOR:
714 DEBUG_Printf(DBG_CHN_MESG, " || ");
715 break;
716 case EXP_OP_LAND:
717 DEBUG_Printf(DBG_CHN_MESG, " && ");
718 break;
719 case EXP_OP_OR:
720 DEBUG_Printf(DBG_CHN_MESG, " | ");
721 break;
722 case EXP_OP_AND:
723 DEBUG_Printf(DBG_CHN_MESG, " & ");
724 break;
725 case EXP_OP_XOR:
726 DEBUG_Printf(DBG_CHN_MESG, " ^ ");
727 break;
728 case EXP_OP_EQ:
729 DEBUG_Printf(DBG_CHN_MESG, " == ");
730 break;
731 case EXP_OP_GT:
732 DEBUG_Printf(DBG_CHN_MESG, " > ");
733 break;
734 case EXP_OP_LT:
735 DEBUG_Printf(DBG_CHN_MESG, " < ");
736 break;
737 case EXP_OP_GE:
738 DEBUG_Printf(DBG_CHN_MESG, " >= ");
739 break;
740 case EXP_OP_LE:
741 DEBUG_Printf(DBG_CHN_MESG, " <= ");
742 break;
743 case EXP_OP_NE:
744 DEBUG_Printf(DBG_CHN_MESG, " != ");
745 break;
746 case EXP_OP_SHL:
747 DEBUG_Printf(DBG_CHN_MESG, " << ");
748 break;
749 case EXP_OP_SHR:
750 DEBUG_Printf(DBG_CHN_MESG, " >> ");
751 break;
752 case EXP_OP_MUL:
753 DEBUG_Printf(DBG_CHN_MESG, " * ");
754 break;
755 case EXP_OP_DIV:
756 DEBUG_Printf(DBG_CHN_MESG, " / ");
757 break;
758 case EXP_OP_REM:
759 DEBUG_Printf(DBG_CHN_MESG, " %% ");
760 break;
761 case EXP_OP_ARR:
762 DEBUG_Printf(DBG_CHN_MESG, "[");
763 break;
764 default:
765 break;
767 DEBUG_DisplayExpr(exp->un.binop.exp2);
768 if( exp->un.binop.binop_type == EXP_OP_ARR )
770 DEBUG_Printf(DBG_CHN_MESG, "]");
772 DEBUG_Printf(DBG_CHN_MESG, " )");
773 break;
774 case EXPR_TYPE_UNOP:
775 switch(exp->un.unop.unop_type)
777 case EXP_OP_NEG:
778 DEBUG_Printf(DBG_CHN_MESG, "-");
779 break;
780 case EXP_OP_NOT:
781 DEBUG_Printf(DBG_CHN_MESG, "!");
782 break;
783 case EXP_OP_LNOT:
784 DEBUG_Printf(DBG_CHN_MESG, "~");
785 break;
786 case EXP_OP_DEREF:
787 DEBUG_Printf(DBG_CHN_MESG, "*");
788 break;
789 case EXP_OP_ADDR:
790 DEBUG_Printf(DBG_CHN_MESG, "&");
791 break;
793 DEBUG_DisplayExpr(exp->un.unop.exp1);
794 break;
795 default:
796 DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
797 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
798 break;
801 return TRUE;
804 struct expr *
805 DEBUG_CloneExpr(const struct expr * exp)
807 int i;
808 struct expr * rtn;
810 rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
813 * First copy the contents of the expression itself.
815 *rtn = *exp;
818 switch(exp->type)
820 case EXPR_TYPE_CAST:
821 rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
822 break;
823 case EXPR_TYPE_INTVAR:
824 rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
825 break;
826 case EXPR_TYPE_US_CONST:
827 case EXPR_TYPE_CONST:
828 break;
829 case EXPR_TYPE_STRING:
830 rtn->un.string.str = DBG_strdup(exp->un.string.str);
831 break;
832 case EXPR_TYPE_SYMBOL:
833 rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
834 break;
835 case EXPR_TYPE_PSTRUCT:
836 case EXPR_TYPE_STRUCT:
837 rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
838 rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
839 break;
840 case EXPR_TYPE_CALL:
841 for(i=0; i < exp->un.call.nargs; i++)
843 rtn->un.call.arg[i] = DEBUG_CloneExpr(exp->un.call.arg[i]);
845 rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
846 break;
847 case EXPR_TYPE_BINOP:
848 rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
849 rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
850 break;
851 case EXPR_TYPE_UNOP:
852 rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
853 break;
854 default:
855 DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
856 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
857 break;
860 return rtn;
865 * Recursively go through an expression tree and free all memory associated
866 * with it.
869 DEBUG_FreeExpr(struct expr * exp)
871 int i;
873 switch(exp->type)
875 case EXPR_TYPE_CAST:
876 DEBUG_FreeExpr(exp->un.cast.expr);
877 break;
878 case EXPR_TYPE_INTVAR:
879 DBG_free((char *) exp->un.intvar.name);
880 break;
881 case EXPR_TYPE_US_CONST:
882 case EXPR_TYPE_CONST:
883 break;
884 case EXPR_TYPE_STRING:
885 DBG_free((char *) exp->un.string.str);
886 break;
887 case EXPR_TYPE_SYMBOL:
888 DBG_free((char *) exp->un.symbol.name);
889 break;
890 case EXPR_TYPE_PSTRUCT:
891 case EXPR_TYPE_STRUCT:
892 DEBUG_FreeExpr(exp->un.structure.exp1);
893 DBG_free((char *) exp->un.structure.element_name);
894 break;
895 case EXPR_TYPE_CALL:
896 for(i=0; i < exp->un.call.nargs; i++)
898 DEBUG_FreeExpr(exp->un.call.arg[i]);
900 DBG_free((char *) exp->un.call.funcname);
901 break;
902 case EXPR_TYPE_BINOP:
903 DEBUG_FreeExpr(exp->un.binop.exp1);
904 DEBUG_FreeExpr(exp->un.binop.exp2);
905 break;
906 case EXPR_TYPE_UNOP:
907 DEBUG_FreeExpr(exp->un.unop.exp1);
908 break;
909 default:
910 DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
911 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
912 break;
915 DBG_free(exp);
916 return TRUE;