Link ttydrv and x11drv objects into their respective dll.
[wine/multimedia.git] / debugger / expr.c
blob298b62c4bc93c5c3a1c98fa0f7a5d5aa8edbfaf3
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 <stdio.h>
11 #include <string.h>
12 #include "winbase.h"
13 #include "wine/winbase16.h"
14 #include "task.h"
15 #include "debugger.h"
16 #include "expr.h"
18 #include <stdarg.h>
20 struct expr
22 unsigned int perm;
23 unsigned int type:31;
24 union
26 struct
28 int value;
29 } constant;
31 struct
33 const char * str;
34 } string;
36 struct
38 unsigned int value;
39 } u_const;
41 struct
43 const char * name;
44 } symbol;
46 struct
48 enum debug_regs reg;
49 int result;
50 } rgister;
52 struct
54 int unop_type;
55 struct expr * exp1;
56 int result;
57 } unop;
59 struct
61 int binop_type;
62 int result;
63 struct expr * exp1;
64 struct expr * exp2;
65 } binop;
67 struct
69 struct datatype * cast;
70 struct expr * expr;
71 } cast;
73 struct
75 struct expr * exp1;
76 const char * element_name;
77 int result;
78 } structure;
80 struct
82 struct expr * base;
83 struct expr * index;
84 } array;
86 struct
88 const char * funcname;
89 int nargs;
90 int result;
91 struct expr * arg[5];
92 } call;
94 } un;
97 #define EXPR_TYPE_CONST 0
98 #define EXPR_TYPE_US_CONST 1
99 #define EXPR_TYPE_SYMBOL 2
100 #define EXPR_TYPE_REGISTER 3
101 #define EXPR_TYPE_BINOP 4
102 #define EXPR_TYPE_UNOP 5
103 #define EXPR_TYPE_STRUCT 6
104 #define EXPR_TYPE_PSTRUCT 7
105 #define EXPR_TYPE_ARRAY 8
106 #define EXPR_TYPE_CALL 9
107 #define EXPR_TYPE_STRING 10
108 #define EXPR_TYPE_CAST 11
110 static char expr_list[4096];
111 static int next_expr_free = 0;
114 * This is how we turn an expression address into the actual value.
115 * This works well in the 32 bit domain - not sure at all about the
116 * 16 bit world.
118 #define VAL(_exp) DEBUG_GetExprValue(&_exp, NULL)
120 static
121 struct expr *
122 DEBUG_GetFreeExpr(void)
124 struct expr * rtn;
126 rtn = (struct expr *) &expr_list[next_expr_free];
128 next_expr_free += sizeof(struct expr);
129 assert(next_expr_free < sizeof(expr_list));
131 return rtn;
134 void
135 DEBUG_FreeExprMem(void)
137 next_expr_free = 0;
140 struct expr *
141 DEBUG_TypeCastExpr(struct datatype * dt, struct expr * exp)
143 struct expr * ex;
145 ex = DEBUG_GetFreeExpr();
147 ex->type = EXPR_TYPE_CAST;
148 ex->un.cast.cast = dt;
149 ex->un.cast.expr = exp;
150 return ex;
153 struct expr *
154 DEBUG_RegisterExpr(enum debug_regs regno)
156 struct expr * ex;
158 ex = DEBUG_GetFreeExpr();
160 ex->type = EXPR_TYPE_REGISTER;
161 ex->un.rgister.reg = regno;
162 return ex;
165 struct expr *
166 DEBUG_SymbolExpr(const char * name)
168 struct expr * ex;
170 ex = DEBUG_GetFreeExpr();
172 ex->type = EXPR_TYPE_SYMBOL;
173 ex->un.symbol.name = name;
174 return ex;
177 struct expr *
178 DEBUG_ConstExpr(int value)
180 struct expr * ex;
182 ex = DEBUG_GetFreeExpr();
184 ex->type = EXPR_TYPE_CONST;
185 ex->un.constant.value = value;
186 return ex;
189 struct expr *
190 DEBUG_StringExpr(const char * str)
192 struct expr * ex;
193 char * pnt;
194 ex = DEBUG_GetFreeExpr();
196 ex->type = EXPR_TYPE_STRING;
197 ex->un.string.str = str+1;
198 pnt = strrchr(ex->un.string.str, '"');
199 if( pnt != NULL )
201 *pnt = '\0';
203 return ex;
206 struct expr *
207 DEBUG_USConstExpr(unsigned int value)
209 struct expr * ex;
211 ex = DEBUG_GetFreeExpr();
213 ex->type = EXPR_TYPE_CONST;
214 ex->un.u_const.value = value;
215 return ex;
218 struct expr *
219 DEBUG_BinopExpr(int operator_type, struct expr * exp1, struct expr * exp2)
221 struct expr * ex;
223 ex = DEBUG_GetFreeExpr();
225 ex->type = EXPR_TYPE_BINOP;
226 ex->un.binop.binop_type = operator_type;
227 ex->un.binop.exp1 = exp1;
228 ex->un.binop.exp2 = exp2;
229 return ex;
232 struct expr *
233 DEBUG_UnopExpr(int operator_type, struct expr * exp1)
235 struct expr * ex;
237 ex = DEBUG_GetFreeExpr();
239 ex->type = EXPR_TYPE_UNOP;
240 ex->un.unop.unop_type = operator_type;
241 ex->un.unop.exp1 = exp1;
242 return ex;
245 struct expr *
246 DEBUG_StructExpr(struct expr * exp, const char * element)
248 struct expr * ex;
250 ex = DEBUG_GetFreeExpr();
252 ex->type = EXPR_TYPE_STRUCT;
253 ex->un.structure.exp1 = exp;
254 ex->un.structure.element_name = element;
255 return ex;
258 struct expr *
259 DEBUG_StructPExpr(struct expr * exp, const char * element)
261 struct expr * ex;
263 ex = DEBUG_GetFreeExpr();
265 ex->type = EXPR_TYPE_PSTRUCT;
266 ex->un.structure.exp1 = exp;
267 ex->un.structure.element_name = element;
268 return ex;
271 struct expr *
272 DEBUG_CallExpr(const char * funcname, int nargs, ...)
274 struct expr * ex;
275 va_list ap;
276 int i;
278 ex = DEBUG_GetFreeExpr();
280 ex->type = EXPR_TYPE_CALL;
281 ex->un.call.funcname = funcname;
282 ex->un.call.nargs = nargs;
284 va_start(ap, nargs);
285 for(i=0; i < nargs; i++)
287 ex->un.call.arg[i] = va_arg(ap, struct expr *);
289 va_end(ap);
290 return ex;
293 DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
295 DBG_VALUE rtn;
296 int i;
297 DBG_VALUE exp1;
298 DBG_VALUE exp2;
299 unsigned int cexp[5];
300 int scale1;
301 int scale2;
302 int scale3;
303 struct datatype * type1;
304 struct datatype * type2;
306 rtn.type = NULL;
307 rtn.addr.off = 0;
308 rtn.addr.seg = 0;
310 switch(exp->type)
312 case EXPR_TYPE_CAST:
313 rtn = DEBUG_EvalExpr(exp->un.cast.expr);
314 rtn.type = exp->un.cast.cast;
315 if (DEBUG_GetType(rtn.type) == DT_POINTER)
316 rtn.cookie = DV_TARGET;
317 break;
318 case EXPR_TYPE_STRING:
319 rtn.type = DEBUG_TypeString;
320 rtn.cookie = DV_HOST;
321 rtn.addr.off = (unsigned int) &exp->un.string.str;
322 rtn.addr.seg = 0;
323 break;
324 case EXPR_TYPE_CONST:
325 rtn.type = DEBUG_TypeIntConst;
326 rtn.cookie = DV_HOST;
327 rtn.addr.off = (unsigned int) &exp->un.constant.value;
328 rtn.addr.seg = 0;
329 break;
330 case EXPR_TYPE_US_CONST:
331 rtn.type = DEBUG_TypeUSInt;
332 rtn.cookie = DV_HOST;
333 rtn.addr.off = (unsigned int) &exp->un.u_const.value;
334 rtn.addr.seg = 0;
335 break;
336 case EXPR_TYPE_SYMBOL:
337 if( !DEBUG_GetSymbolValue(exp->un.symbol.name, -1, &rtn, FALSE) )
339 RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
341 break;
342 case EXPR_TYPE_PSTRUCT:
343 exp1 = DEBUG_EvalExpr(exp->un.structure.exp1);
344 if( exp1.type == NULL )
346 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
348 rtn.cookie = DV_TARGET;
349 rtn.addr.off = DEBUG_TypeDerefPointer(&exp1, &type1);
350 if( type1 == NULL )
352 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
354 rtn.type = type1;
355 DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
356 &exp->un.structure.result);
357 break;
358 case EXPR_TYPE_STRUCT:
359 exp1 = DEBUG_EvalExpr(exp->un.structure.exp1);
360 if( exp1.type == NULL )
362 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
364 rtn = exp1;
365 DEBUG_FindStructElement(&rtn, exp->un.structure.element_name,
366 &exp->un.structure.result);
367 break;
368 case EXPR_TYPE_CALL:
370 * First, evaluate all of the arguments. If any of them are not
371 * evaluable, then bail.
373 for(i=0; i < exp->un.call.nargs; i++)
375 exp1 = DEBUG_EvalExpr(exp->un.call.arg[i]);
376 if( exp1.type == NULL )
378 return rtn;
380 cexp[i] = DEBUG_GetExprValue(&exp1, NULL);
384 * Now look up the address of the function itself.
386 if( !DEBUG_GetSymbolValue(exp->un.call.funcname, -1, &rtn, FALSE ) )
388 RaiseException(DEBUG_STATUS_NO_SYMBOL, 0, 0, NULL);
391 #if 0
392 /* FIXME: NEWDBG NIY */
393 /* Anyway, I wonder how this could work depending on the calling order of
394 * the function (cdecl vs pascal for example)
396 int (*fptr)();
398 fptr = (int (*)()) rtn.addr.off;
399 switch(exp->un.call.nargs)
401 case 0:
402 exp->un.call.result = (*fptr)();
403 break;
404 case 1:
405 exp->un.call.result = (*fptr)(cexp[0]);
406 break;
407 case 2:
408 exp->un.call.result = (*fptr)(cexp[0], cexp[1]);
409 break;
410 case 3:
411 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2]);
412 break;
413 case 4:
414 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3]);
415 break;
416 case 5:
417 exp->un.call.result = (*fptr)(cexp[0], cexp[1], cexp[2], cexp[3], cexp[4]);
418 break;
420 #else
421 fprintf(stderr, "Function call no longer implemented\n");
422 /* would need to set up a call to this function, and then restore the current
423 * context afterwards...
425 exp->un.call.result = 0;
426 #endif
427 rtn.type = DEBUG_TypeInt;
428 rtn.cookie = DV_HOST;
429 rtn.addr.off = (unsigned int) &exp->un.call.result;
431 break;
432 case EXPR_TYPE_REGISTER:
433 rtn.type = DEBUG_TypeIntConst;
434 rtn.cookie = DV_HOST;
435 exp->un.rgister.result = DEBUG_GetRegister(exp->un.rgister.reg);
436 rtn.addr.off = (unsigned int) &exp->un.rgister.result;
437 #ifdef __i386__
438 if( exp->un.rgister.reg == REG_EIP )
439 rtn.addr.seg = DEBUG_context.SegCs;
440 else
441 rtn.addr.seg = DEBUG_context.SegDs;
442 #endif
443 DEBUG_FixAddress( &rtn.addr, 0 );
444 break;
445 case EXPR_TYPE_BINOP:
446 exp1 = DEBUG_EvalExpr(exp->un.binop.exp1);
447 exp2 = DEBUG_EvalExpr(exp->un.binop.exp2);
448 rtn.cookie = DV_HOST;
449 if( exp1.type == NULL || exp2.type == NULL )
451 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
453 if( exp1.type == DEBUG_TypeIntConst && exp2.type == DEBUG_TypeIntConst )
455 rtn.type = exp1.type;
457 else
459 rtn.type = DEBUG_TypeInt;
461 rtn.addr.seg = 0;
462 rtn.addr.off = (unsigned int) &exp->un.binop.result;
463 switch(exp->un.binop.binop_type)
465 case EXP_OP_ADD:
466 type1 = DEBUG_GetPointerType(exp1.type);
467 type2 = DEBUG_GetPointerType(exp2.type);
468 scale1 = 1;
469 scale2 = 1;
470 if( type1 != NULL && type2 != NULL )
472 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
474 else if( type1 != NULL )
476 scale2 = DEBUG_GetObjectSize(type1);
477 rtn.type = exp1.type;
479 else if( type2 != NULL )
481 scale1 = DEBUG_GetObjectSize(type2);
482 rtn.type = exp2.type;
484 exp->un.binop.result = (VAL(exp1) * scale1 + scale2 * VAL(exp2));
485 break;
486 case EXP_OP_SUB:
487 type1 = DEBUG_GetPointerType(exp1.type);
488 type2 = DEBUG_GetPointerType(exp2.type);
489 scale1 = 1;
490 scale2 = 1;
491 scale3 = 1;
492 if( type1 != NULL && type2 != NULL )
494 if( type1 != type2 )
496 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
498 scale3 = DEBUG_GetObjectSize(type1);
500 else if( type1 != NULL )
502 scale2 = DEBUG_GetObjectSize(type1);
503 rtn.type = exp1.type;
506 else if( type2 != NULL )
508 scale1 = DEBUG_GetObjectSize(type2);
509 rtn.type = exp2.type;
511 exp->un.binop.result = (VAL(exp1) - VAL(exp2)) / scale3;
512 break;
513 case EXP_OP_SEG:
514 rtn.cookie = DV_TARGET;
515 rtn.addr.seg = VAL(exp1);
516 exp->un.binop.result = VAL(exp2);
517 #ifdef __i386__
518 DEBUG_FixSegment(&rtn.addr);
519 #endif
520 break;
521 case EXP_OP_LOR:
522 exp->un.binop.result = (VAL(exp1) || VAL(exp2));
523 break;
524 case EXP_OP_LAND:
525 exp->un.binop.result = (VAL(exp1) && VAL(exp2));
526 break;
527 case EXP_OP_OR:
528 exp->un.binop.result = (VAL(exp1) | VAL(exp2));
529 break;
530 case EXP_OP_AND:
531 exp->un.binop.result = (VAL(exp1) & VAL(exp2));
532 break;
533 case EXP_OP_XOR:
534 exp->un.binop.result = (VAL(exp1) ^ VAL(exp2));
535 break;
536 case EXP_OP_EQ:
537 exp->un.binop.result = (VAL(exp1) == VAL(exp2));
538 break;
539 case EXP_OP_GT:
540 exp->un.binop.result = (VAL(exp1) > VAL(exp2));
541 break;
542 case EXP_OP_LT:
543 exp->un.binop.result = (VAL(exp1) < VAL(exp2));
544 break;
545 case EXP_OP_GE:
546 exp->un.binop.result = (VAL(exp1) >= VAL(exp2));
547 break;
548 case EXP_OP_LE:
549 exp->un.binop.result = (VAL(exp1) <= VAL(exp2));
550 break;
551 case EXP_OP_NE:
552 exp->un.binop.result = (VAL(exp1) != VAL(exp2));
553 break;
554 case EXP_OP_SHL:
555 exp->un.binop.result = ((unsigned) VAL(exp1) << VAL(exp2));
556 break;
557 case EXP_OP_SHR:
558 exp->un.binop.result = ((unsigned) VAL(exp1) >> VAL(exp2));
559 break;
560 case EXP_OP_MUL:
561 exp->un.binop.result = (VAL(exp1) * VAL(exp2));
562 break;
563 case EXP_OP_DIV:
564 if( VAL(exp2) == 0 )
566 RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
568 exp->un.binop.result = (VAL(exp1) / VAL(exp2));
569 break;
570 case EXP_OP_REM:
571 if( VAL(exp2) == 0 )
573 RaiseException(DEBUG_STATUS_DIV_BY_ZERO, 0, 0, NULL);
575 exp->un.binop.result = (VAL(exp1) % VAL(exp2));
576 break;
577 case EXP_OP_ARR:
578 DEBUG_ArrayIndex(&exp1, &rtn, VAL(exp2));
579 break;
580 default:
581 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
582 break;
584 break;
585 case EXPR_TYPE_UNOP:
586 exp1 = DEBUG_EvalExpr(exp->un.unop.exp1);
587 rtn.cookie = DV_HOST;
588 if( exp1.type == NULL )
590 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
592 rtn.addr.seg = 0;
593 rtn.addr.off = (unsigned int) &exp->un.unop.result;
594 if( exp1.type == DEBUG_TypeIntConst )
596 rtn.type = exp1.type;
598 else
600 rtn.type = DEBUG_TypeInt;
602 switch(exp->un.unop.unop_type)
604 case EXP_OP_NEG:
605 exp->un.unop.result = -VAL(exp1);
606 break;
607 case EXP_OP_NOT:
608 exp->un.unop.result = !VAL(exp1);
609 break;
610 case EXP_OP_LNOT:
611 exp->un.unop.result = ~VAL(exp1);
612 break;
613 case EXP_OP_DEREF:
614 rtn.cookie = exp1.cookie;
615 rtn.addr.off = (unsigned int) DEBUG_TypeDerefPointer(&exp1, &rtn.type);
616 if (!rtn.type)
618 RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
620 break;
621 case EXP_OP_FORCE_DEREF:
622 rtn.cookie = exp1.cookie;
623 rtn.addr.seg = exp1.addr.seg;
624 if (exp1.cookie == DV_TARGET)
625 DEBUG_READ_MEM((void*)exp1.addr.off, &rtn.addr.off, sizeof(rtn.addr.off));
626 else
627 memcpy(&rtn.addr.off, (void*)exp1.addr.off, sizeof(rtn.addr.off));
628 break;
629 case EXP_OP_ADDR:
630 /* FIXME: even for a 16 bit entity ? */
631 rtn.cookie = DV_TARGET;
632 rtn.type = DEBUG_FindOrMakePointerType(exp1.type);
633 exp->un.unop.result = exp1.addr.off;
634 break;
635 default:
636 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
638 break;
639 default:
640 fprintf(stderr,"Unexpected expression (%d).\n", exp->type);
641 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
642 break;
645 assert(rtn.cookie == DV_TARGET || rtn.cookie == DV_HOST);
647 return rtn;
652 DEBUG_DisplayExpr(const struct expr * exp)
654 int i;
656 switch(exp->type)
658 case EXPR_TYPE_CAST:
659 fprintf(stderr, "((");
660 DEBUG_PrintTypeCast(exp->un.cast.cast);
661 fprintf(stderr, ")");
662 DEBUG_DisplayExpr(exp->un.cast.expr);
663 fprintf(stderr, ")");
664 break;
665 case EXPR_TYPE_REGISTER:
666 DEBUG_PrintRegister(exp->un.rgister.reg);
667 break;
668 case EXPR_TYPE_US_CONST:
669 fprintf(stderr, "%ud", exp->un.u_const.value);
670 break;
671 case EXPR_TYPE_CONST:
672 fprintf(stderr, "%d", exp->un.u_const.value);
673 break;
674 case EXPR_TYPE_STRING:
675 fprintf(stderr, "\"%s\"", exp->un.string.str);
676 break;
677 case EXPR_TYPE_SYMBOL:
678 fprintf(stderr, "%s" , exp->un.symbol.name);
679 break;
680 case EXPR_TYPE_PSTRUCT:
681 DEBUG_DisplayExpr(exp->un.structure.exp1);
682 fprintf(stderr, "->%s", exp->un.structure.element_name);
683 break;
684 case EXPR_TYPE_STRUCT:
685 DEBUG_DisplayExpr(exp->un.structure.exp1);
686 fprintf(stderr, ".%s", exp->un.structure.element_name);
687 break;
688 case EXPR_TYPE_CALL:
689 fprintf(stderr, "%s(",exp->un.call.funcname);
690 for(i=0; i < exp->un.call.nargs; i++)
692 DEBUG_DisplayExpr(exp->un.call.arg[i]);
693 if( i != exp->un.call.nargs - 1 )
695 fprintf(stderr, ", ");
698 fprintf(stderr, ")");
699 break;
700 case EXPR_TYPE_BINOP:
701 fprintf(stderr, "( ");
702 DEBUG_DisplayExpr(exp->un.binop.exp1);
703 switch(exp->un.binop.binop_type)
705 case EXP_OP_ADD:
706 fprintf(stderr, " + ");
707 break;
708 case EXP_OP_SUB:
709 fprintf(stderr, " - ");
710 break;
711 case EXP_OP_SEG:
712 fprintf(stderr, ":");
713 break;
714 case EXP_OP_LOR:
715 fprintf(stderr, " || ");
716 break;
717 case EXP_OP_LAND:
718 fprintf(stderr, " && ");
719 break;
720 case EXP_OP_OR:
721 fprintf(stderr, " | ");
722 break;
723 case EXP_OP_AND:
724 fprintf(stderr, " & ");
725 break;
726 case EXP_OP_XOR:
727 fprintf(stderr, " ^ ");
728 break;
729 case EXP_OP_EQ:
730 fprintf(stderr, " == ");
731 break;
732 case EXP_OP_GT:
733 fprintf(stderr, " > ");
734 break;
735 case EXP_OP_LT:
736 fprintf(stderr, " < ");
737 break;
738 case EXP_OP_GE:
739 fprintf(stderr, " >= ");
740 break;
741 case EXP_OP_LE:
742 fprintf(stderr, " <= ");
743 break;
744 case EXP_OP_NE:
745 fprintf(stderr, " != ");
746 break;
747 case EXP_OP_SHL:
748 fprintf(stderr, " << ");
749 break;
750 case EXP_OP_SHR:
751 fprintf(stderr, " >> ");
752 break;
753 case EXP_OP_MUL:
754 fprintf(stderr, " * ");
755 break;
756 case EXP_OP_DIV:
757 fprintf(stderr, " / ");
758 break;
759 case EXP_OP_REM:
760 fprintf(stderr, " %% ");
761 break;
762 case EXP_OP_ARR:
763 fprintf(stderr, "[");
764 break;
765 default:
766 break;
768 DEBUG_DisplayExpr(exp->un.binop.exp2);
769 if( exp->un.binop.binop_type == EXP_OP_ARR )
771 fprintf(stderr, "]");
773 fprintf(stderr, " )");
774 break;
775 case EXPR_TYPE_UNOP:
776 switch(exp->un.unop.unop_type)
778 case EXP_OP_NEG:
779 fprintf(stderr, "-");
780 break;
781 case EXP_OP_NOT:
782 fprintf(stderr, "!");
783 break;
784 case EXP_OP_LNOT:
785 fprintf(stderr, "~");
786 break;
787 case EXP_OP_DEREF:
788 fprintf(stderr, "*");
789 break;
790 case EXP_OP_ADDR:
791 fprintf(stderr, "&");
792 break;
794 DEBUG_DisplayExpr(exp->un.unop.exp1);
795 break;
796 default:
797 fprintf(stderr,"Unexpected expression.\n");
798 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
799 break;
802 return TRUE;
805 struct expr *
806 DEBUG_CloneExpr(const struct expr * exp)
808 int i;
809 struct expr * rtn;
811 rtn = (struct expr *) DBG_alloc(sizeof(struct expr));
814 * First copy the contents of the expression itself.
816 *rtn = *exp;
819 switch(exp->type)
821 case EXPR_TYPE_CAST:
822 rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
823 break;
824 case EXPR_TYPE_REGISTER:
825 case EXPR_TYPE_US_CONST:
826 case EXPR_TYPE_CONST:
827 break;
828 case EXPR_TYPE_STRING:
829 rtn->un.string.str = DBG_strdup(exp->un.string.str);
830 break;
831 case EXPR_TYPE_SYMBOL:
832 rtn->un.symbol.name = DBG_strdup(exp->un.symbol.name);
833 break;
834 case EXPR_TYPE_PSTRUCT:
835 case EXPR_TYPE_STRUCT:
836 rtn->un.structure.exp1 = DEBUG_CloneExpr(exp->un.structure.exp1);
837 rtn->un.structure.element_name = DBG_strdup(exp->un.structure.element_name);
838 break;
839 case EXPR_TYPE_CALL:
840 for(i=0; i < exp->un.call.nargs; i++)
842 rtn->un.call.arg[i] = DEBUG_CloneExpr(exp->un.call.arg[i]);
844 rtn->un.call.funcname = DBG_strdup(exp->un.call.funcname);
845 break;
846 case EXPR_TYPE_BINOP:
847 rtn->un.binop.exp1 = DEBUG_CloneExpr(exp->un.binop.exp1);
848 rtn->un.binop.exp2 = DEBUG_CloneExpr(exp->un.binop.exp2);
849 break;
850 case EXPR_TYPE_UNOP:
851 rtn->un.unop.exp1 = DEBUG_CloneExpr(exp->un.unop.exp1);
852 break;
853 default:
854 fprintf(stderr,"Unexpected expression.\n");
855 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
856 break;
859 return rtn;
864 * Recursively go through an expression tree and free all memory associated
865 * with it.
868 DEBUG_FreeExpr(struct expr * exp)
870 int i;
872 switch(exp->type)
874 case EXPR_TYPE_CAST:
875 DEBUG_FreeExpr(exp->un.cast.expr);
876 break;
877 case EXPR_TYPE_REGISTER:
878 case EXPR_TYPE_US_CONST:
879 case EXPR_TYPE_CONST:
880 break;
881 case EXPR_TYPE_STRING:
882 DBG_free((char *) exp->un.string.str);
883 break;
884 case EXPR_TYPE_SYMBOL:
885 DBG_free((char *) exp->un.symbol.name);
886 break;
887 case EXPR_TYPE_PSTRUCT:
888 case EXPR_TYPE_STRUCT:
889 DEBUG_FreeExpr(exp->un.structure.exp1);
890 DBG_free((char *) exp->un.structure.element_name);
891 break;
892 case EXPR_TYPE_CALL:
893 for(i=0; i < exp->un.call.nargs; i++)
895 DEBUG_FreeExpr(exp->un.call.arg[i]);
897 DBG_free((char *) exp->un.call.funcname);
898 break;
899 case EXPR_TYPE_BINOP:
900 DEBUG_FreeExpr(exp->un.binop.exp1);
901 DEBUG_FreeExpr(exp->un.binop.exp2);
902 break;
903 case EXPR_TYPE_UNOP:
904 DEBUG_FreeExpr(exp->un.unop.exp1);
905 break;
906 default:
907 fprintf(stderr,"Unexpected expression.\n");
908 RaiseException(DEBUG_STATUS_INTERNAL_ERROR, 0, 0, NULL);
909 break;
912 DBG_free(exp);
913 return TRUE;