Added atfork support.
[wine/multimedia.git] / debugger / expr.c
bloba083fb3cdc1480f59fea925eceebee7ab9d041f2
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.addr.off = 0;
306 rtn.addr.seg = 0;
308 switch(exp->type)
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) )
337 RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
339 break;
340 case EXPR_TYPE_PSTRUCT:
341 exp1 = DEBUG_EvalExpr(exp->un.structure.exp1);
342 if( exp1.type == NULL )
344 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
346 rtn.cookie = DV_TARGET;
347 rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &type1);
348 if( type1 == NULL )
350 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
352 rtn.type = type1;
353 DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
354 &exp->un.structure.result);
355 break;
356 case EXPR_TYPE_STRUCT:
357 exp1 = DEBUG_EvalExpr(exp->un.structure.exp1);
358 if( exp1.type == NULL )
360 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
362 rtn = exp1;
363 DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
364 &exp->un.structure.result);
365 break;
366 case EXPR_TYPE_CALL:
368 * First, evaluate all of the arguments. If any of them are not
369 * evaluable, then bail.
371 for(i=0; i < exp->un.call.nargs; i++)
373 exp1 = DEBUG_EvalExpr(exp->un.call.arg[i]);
374 if( exp1.type == NULL )
376 return rtn;
378 cexp[i] = DEBUG_GetExprValue(&exp1, NULL);
382 * Now look up the address of the function itself.
384 if( !DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ) )
386 RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
389 #if 0
390 /* FIXME: NEWDBG NIY */
391 /* Anyway, I wonder how this could work depending on the calling order of
392 * the function (cdecl vs pascal for example)
394 int (*fptr)();
396 fptr = (int (*)()) rtn.addr.off;
397 switch(exp->un.call.nargs)
399 case 0:
400 exp->un.call.result = (*fptr)();
401 break;
402 case 1:
403 exp->un.call.result = (*fptr)(cexp[0]);
404 break;
405 case 2:
406 exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
407 break;
408 case 3:
409 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
410 break;
411 case 4:
412 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
413 break;
414 case 5:
415 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
416 break;
418 #else
419 DEBUG_Printf(DBG_CHN_MESG, "Function call no longer implemented\n");
420 /* would need to set up a call to this function, and then restore the current
421 * context afterwards...
423 exp->un.call.result = 0;
424 #endif
425 rtn.type = DEBUG_TypeInt;
426 rtn.cookie = DV_HOST;
427 rtn.addr.off = (unsigned int) &exp->un.call.result;
429 break;
430 case EXPR_TYPE_INTVAR:
433 DBG_INTVAR* div = DEBUG_GetIntVar(exp->un.intvar.name);
435 if (!div) RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
436 rtn.cookie = DV_HOST;
437 rtn.type = div->type;
438 rtn.addr.off = (unsigned int)div->pval;
439 /* EPP FIXME rtn.addr.seg = ?? */
441 break;
442 case EXPR_TYPE_BINOP:
443 exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
444 exp2 = DEBUG_EvalExpr(exp->un.binop.exp2);
445 rtn.cookie = DV_HOST;
446 if( exp1.type == NULL || exp2.type == NULL )
448 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
450 if( exp1.type == DEBUG_TypeIntConst && exp2.type == DEBUG_TypeIntConst )
452 rtn.type = exp1.type;
454 else
456 rtn.type = DEBUG_TypeInt;
458 rtn.addr.seg = 0;
459 rtn.addr.off = (unsigned int) &exp->un.binop.result;
460 switch(exp->un.binop.binop_type)
462 case EXP_OP_ADD:
463 type1 = DEBUG_GetPointerType(exp1.type);
464 type2 = DEBUG_GetPointerType(exp2.type);
465 scale1 = 1;
466 scale2 = 1;
467 if( type1 != NULL && type2 != NULL )
469 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
471 else if( type1 != NULL )
473 scale2 = DEBUG_GetObjectSize(type1);
474 rtn.type = exp1.type;
476 else if( type2 != NULL )
478 scale1 = DEBUG_GetObjectSize(type2);
479 rtn.type = exp2.type;
481 exp->un.binop.result = (VAL(exp1) * scale1 + scale2 * VAL(exp2));
482 break;
483 case EXP_OP_SUB:
484 type1 = DEBUG_GetPointerType(exp1.type);
485 type2 = DEBUG_GetPointerType(exp2.type);
486 scale1 = 1;
487 scale2 = 1;
488 scale3 = 1;
489 if( type1 != NULL && type2 != NULL )
491 if( type1 != type2 )
493 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
495 scale3 = DEBUG_GetObjectSize(type1);
497 else if( type1 != NULL )
499 scale2 = DEBUG_GetObjectSize(type1);
500 rtn.type = exp1.type;
503 else if( type2 != NULL )
505 scale1 = DEBUG_GetObjectSize(type2);
506 rtn.type = exp2.type;
508 exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
509 break;
510 case EXP_OP_SEG:
511 rtn.cookie = DV_TARGET;
512 rtn.addr.seg = VAL(exp1);
513 exp->un.binop.result = VAL(exp2);
514 #ifdef __i386__
515 DEBUG_FixSegment(&rtn.addr);
516 #endif
517 break;
518 case EXP_OP_LOR:
519 exp->un.binop.result = (VAL(exp1) || VAL(exp2));
520 break;
521 case EXP_OP_LAND:
522 exp->un.binop.result = (VAL(exp1) && VAL(exp2));
523 break;
524 case EXP_OP_OR:
525 exp->un.binop.result = (VAL(exp1) | VAL(exp2));
526 break;
527 case EXP_OP_AND:
528 exp->un.binop.result = (VAL(exp1) & VAL(exp2));
529 break;
530 case EXP_OP_XOR:
531 exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
532 break;
533 case EXP_OP_EQ:
534 exp->un.binop.result = (VAL(exp1) == VAL(exp2));
535 break;
536 case EXP_OP_GT:
537 exp->un.binop.result = (VAL(exp1) > VAL(exp2));
538 break;
539 case EXP_OP_LT:
540 exp->un.binop.result = (VAL(exp1) < VAL(exp2));
541 break;
542 case EXP_OP_GE:
543 exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
544 break;
545 case EXP_OP_LE:
546 exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
547 break;
548 case EXP_OP_NE:
549 exp->un.binop.result = (VAL(exp1) != VAL(exp2));
550 break;
551 case EXP_OP_SHL:
552 exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
553 break;
554 case EXP_OP_SHR:
555 exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
556 break;
557 case EXP_OP_MUL:
558 exp->un.binop.result = (VAL(exp1) * VAL(exp2));
559 break;
560 case EXP_OP_DIV:
561 if( VAL(exp2) == 0 )
563 RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
565 exp->un.binop.result = (VAL(exp1) / VAL(exp2));
566 break;
567 case EXP_OP_REM:
568 if( VAL(exp2) == 0 )
570 RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
572 exp->un.binop.result = (VAL(exp1) % VAL(exp2));
573 break;
574 case EXP_OP_ARR:
575 DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
576 break;
577 default:
578 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
579 break;
581 break;
582 case EXPR_TYPE_UNOP:
583 exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
584 rtn.cookie = DV_HOST;
585 if( exp1.type == NULL )
587 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
589 rtn.addr.seg = 0;
590 rtn.addr.off = (unsigned int) &exp->un.unop.result;
591 if( exp1.type == DEBUG_TypeIntConst )
593 rtn.type = exp1.type;
595 else
597 rtn.type = DEBUG_TypeInt;
599 switch(exp->un.unop.unop_type)
601 case EXP_OP_NEG:
602 exp->un.unop.result = -VAL(exp1);
603 break;
604 case EXP_OP_NOT:
605 exp->un.unop.result = !VAL(exp1);
606 break;
607 case EXP_OP_LNOT:
608 exp->un.unop.result = ~VAL(exp1);
609 break;
610 case EXP_OP_DEREF:
611 rtn.cookie = exp1.cookie;
612 rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
613 if (!rtn.type)
615 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
617 break;
618 case EXP_OP_FORCE_DEREF:
619 rtn.cookie = exp1.cookie;
620 rtn.addr.seg = exp1.addr.seg;
621 if (exp1.cookie == DV_TARGET)
622 DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
623 else
624 memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
625 break;
626 case EXP_OP_ADDR:
627 /* FIXME: even for a 16 bit entity ? */
628 rtn.cookie = DV_TARGET;
629 rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
630 exp->un.unop.result = exp1.addr.off;
631 break;
632 default:
633 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
635 break;
636 default:
637 DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression (%d).\n", exp->type);
638 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
639 break;
642 assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
644 return rtn;
649 DEBUG_DisplayExpr(const struct expr * exp)
651 int i;
653 switch(exp->type)
655 case EXPR_TYPE_CAST:
656 DEBUG_Printf(DBG_CHN_MESG, "((");
657 DEBUG_PrintTypeCast(exp->un.cast.cast);
658 DEBUG_Printf(DBG_CHN_MESG, ")");
659 DEBUG_DisplayExpr(exp->un.cast.expr);
660 DEBUG_Printf(DBG_CHN_MESG, ")");
661 break;
662 case EXPR_TYPE_INTVAR:
663 DEBUG_Printf(DBG_CHN_MESG, "$%s", exp->un.intvar.name);
664 break;
665 case EXPR_TYPE_US_CONST:
666 DEBUG_Printf(DBG_CHN_MESG, "%ud", exp->un.u_const.value);
667 break;
668 case EXPR_TYPE_CONST:
669 DEBUG_Printf(DBG_CHN_MESG, "%d", exp->un.u_const.value);
670 break;
671 case EXPR_TYPE_STRING:
672 DEBUG_Printf(DBG_CHN_MESG, "\"%s\"", exp->un.string.str);
673 break;
674 case EXPR_TYPE_SYMBOL:
675 DEBUG_Printf(DBG_CHN_MESG, "%s" , exp->un.symbol.name);
676 break;
677 case EXPR_TYPE_PSTRUCT:
678 DEBUG_DisplayExpr(exp->un.structure.exp1);
679 DEBUG_Printf(DBG_CHN_MESG, "->%s", exp->un.structure.element_name);
680 break;
681 case EXPR_TYPE_STRUCT:
682 DEBUG_DisplayExpr(exp->un.structure.exp1);
683 DEBUG_Printf(DBG_CHN_MESG, ".%s", exp->un.structure.element_name);
684 break;
685 case EXPR_TYPE_CALL:
686 DEBUG_Printf(DBG_CHN_MESG, "%s(",exp->un.call.funcname);
687 for(i=0; i < exp->un.call.nargs; i++)
689 DEBUG_DisplayExpr(exp->un.call.arg[i]);
690 if( i != exp->un.call.nargs - 1 )
692 DEBUG_Printf(DBG_CHN_MESG, ", ");
695 DEBUG_Printf(DBG_CHN_MESG, ")");
696 break;
697 case EXPR_TYPE_BINOP:
698 DEBUG_Printf(DBG_CHN_MESG, "( ");
699 DEBUG_DisplayExpr(exp->un.binop.exp1);
700 switch(exp->un.binop.binop_type)
702 case EXP_OP_ADD:
703 DEBUG_Printf(DBG_CHN_MESG, " + ");
704 break;
705 case EXP_OP_SUB:
706 DEBUG_Printf(DBG_CHN_MESG, " - ");
707 break;
708 case EXP_OP_SEG:
709 DEBUG_Printf(DBG_CHN_MESG, ":");
710 break;
711 case EXP_OP_LOR:
712 DEBUG_Printf(DBG_CHN_MESG, " || ");
713 break;
714 case EXP_OP_LAND:
715 DEBUG_Printf(DBG_CHN_MESG, " && ");
716 break;
717 case EXP_OP_OR:
718 DEBUG_Printf(DBG_CHN_MESG, " | ");
719 break;
720 case EXP_OP_AND:
721 DEBUG_Printf(DBG_CHN_MESG, " & ");
722 break;
723 case EXP_OP_XOR:
724 DEBUG_Printf(DBG_CHN_MESG, " ^ ");
725 break;
726 case EXP_OP_EQ:
727 DEBUG_Printf(DBG_CHN_MESG, " == ");
728 break;
729 case EXP_OP_GT:
730 DEBUG_Printf(DBG_CHN_MESG, " > ");
731 break;
732 case EXP_OP_LT:
733 DEBUG_Printf(DBG_CHN_MESG, " < ");
734 break;
735 case EXP_OP_GE:
736 DEBUG_Printf(DBG_CHN_MESG, " >= ");
737 break;
738 case EXP_OP_LE:
739 DEBUG_Printf(DBG_CHN_MESG, " <= ");
740 break;
741 case EXP_OP_NE:
742 DEBUG_Printf(DBG_CHN_MESG, " != ");
743 break;
744 case EXP_OP_SHL:
745 DEBUG_Printf(DBG_CHN_MESG, " << ");
746 break;
747 case EXP_OP_SHR:
748 DEBUG_Printf(DBG_CHN_MESG, " >> ");
749 break;
750 case EXP_OP_MUL:
751 DEBUG_Printf(DBG_CHN_MESG, " * ");
752 break;
753 case EXP_OP_DIV:
754 DEBUG_Printf(DBG_CHN_MESG, " / ");
755 break;
756 case EXP_OP_REM:
757 DEBUG_Printf(DBG_CHN_MESG, " %% ");
758 break;
759 case EXP_OP_ARR:
760 DEBUG_Printf(DBG_CHN_MESG, "[");
761 break;
762 default:
763 break;
765 DEBUG_DisplayExpr(exp->un.binop.exp2);
766 if( exp->un.binop.binop_type == EXP_OP_ARR )
768 DEBUG_Printf(DBG_CHN_MESG, "]");
770 DEBUG_Printf(DBG_CHN_MESG, " )");
771 break;
772 case EXPR_TYPE_UNOP:
773 switch(exp->un.unop.unop_type)
775 case EXP_OP_NEG:
776 DEBUG_Printf(DBG_CHN_MESG, "-");
777 break;
778 case EXP_OP_NOT:
779 DEBUG_Printf(DBG_CHN_MESG, "!");
780 break;
781 case EXP_OP_LNOT:
782 DEBUG_Printf(DBG_CHN_MESG, "~");
783 break;
784 case EXP_OP_DEREF:
785 DEBUG_Printf(DBG_CHN_MESG, "*");
786 break;
787 case EXP_OP_ADDR:
788 DEBUG_Printf(DBG_CHN_MESG, "&");
789 break;
791 DEBUG_DisplayExpr(exp->un.unop.exp1);
792 break;
793 default:
794 DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
795 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
796 break;
799 return TRUE;
802 struct expr *
803 DEBUG_CloneExpr(const struct expr * exp)
805 int i;
806 struct expr * rtn;
808 rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
811 * First copy the contents of the expression itself.
813 *rtn = *exp;
816 switch(exp->type)
818 case EXPR_TYPE_CAST:
819 rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
820 break;
821 case EXPR_TYPE_INTVAR:
822 rtn->un.intvar.name = DBG_strdup(exp->un.intvar.name);
823 break;
824 case EXPR_TYPE_US_CONST:
825 case EXPR_TYPE_CONST:
826 break;
827 case EXPR_TYPE_STRING:
828 rtn->un.string.str = DBG_strdup(exp->un.string.str);
829 break;
830 case EXPR_TYPE_SYMBOL:
831 rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
832 break;
833 case EXPR_TYPE_PSTRUCT:
834 case EXPR_TYPE_STRUCT:
835 rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
836 rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
837 break;
838 case EXPR_TYPE_CALL:
839 for(i=0; i < exp->un.call.nargs; i++)
841 rtn->un.call.arg[i] = DEBUG_CloneExpr(exp->un.call.arg[i]);
843 rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
844 break;
845 case EXPR_TYPE_BINOP:
846 rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
847 rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
848 break;
849 case EXPR_TYPE_UNOP:
850 rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
851 break;
852 default:
853 DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
854 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
855 break;
858 return rtn;
863 * Recursively go through an expression tree and free all memory associated
864 * with it.
867 DEBUG_FreeExpr(struct expr * exp)
869 int i;
871 switch(exp->type)
873 case EXPR_TYPE_CAST:
874 DEBUG_FreeExpr(exp->un.cast.expr);
875 break;
876 case EXPR_TYPE_INTVAR:
877 DBG_free((char *) exp->un.intvar.name);
878 break;
879 case EXPR_TYPE_US_CONST:
880 case EXPR_TYPE_CONST:
881 break;
882 case EXPR_TYPE_STRING:
883 DBG_free((char *) exp->un.string.str);
884 break;
885 case EXPR_TYPE_SYMBOL:
886 DBG_free((char *) exp->un.symbol.name);
887 break;
888 case EXPR_TYPE_PSTRUCT:
889 case EXPR_TYPE_STRUCT:
890 DEBUG_FreeExpr(exp->un.structure.exp1);
891 DBG_free((char *) exp->un.structure.element_name);
892 break;
893 case EXPR_TYPE_CALL:
894 for(i=0; i < exp->un.call.nargs; i++)
896 DEBUG_FreeExpr(exp->un.call.arg[i]);
898 DBG_free((char *) exp->un.call.funcname);
899 break;
900 case EXPR_TYPE_BINOP:
901 DEBUG_FreeExpr(exp->un.binop.exp1);
902 DEBUG_FreeExpr(exp->un.binop.exp2);
903 break;
904 case EXPR_TYPE_UNOP:
905 DEBUG_FreeExpr(exp->un.unop.exp1);
906 break;
907 default:
908 DEBUG_Printf(DBG_CHN_MESG,"Unexpected expression.\n");
909 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
910 break;
913 DBG_free(exp);
914 return TRUE;