2 * File expr.c - expression handling for Wine internal debugger.
4 * Copyright (C) 1997, Eric Youngdale.
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.
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.
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
25 #include "wine/winbase16.h"
79 struct datatype
* cast
;
86 const char * element_name
;
98 const char * funcname
;
101 struct expr
* arg
[5];
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
120 static char expr_list
[4096];
121 static unsigned int next_expr_free
= 0;
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
128 #define VAL(_exp) DEBUG_GetExprValue(&_exp, NULL)
132 DEBUG_GetFreeExpr(void)
136 rtn
= (struct expr
*) &expr_list
[next_expr_free
];
138 next_expr_free
+= sizeof(struct expr
);
139 assert(next_expr_free
< sizeof(expr_list
));
145 DEBUG_FreeExprMem(void)
151 DEBUG_TypeCastExpr(struct datatype
* dt
, struct expr
* exp
)
155 ex
= DEBUG_GetFreeExpr();
157 ex
->type
= EXPR_TYPE_CAST
;
158 ex
->un
.cast
.cast
= dt
;
159 ex
->un
.cast
.expr
= exp
;
164 DEBUG_IntVarExpr(const char* name
)
168 ex
= DEBUG_GetFreeExpr();
170 ex
->type
= EXPR_TYPE_INTVAR
;
171 ex
->un
.intvar
.name
= name
;
176 DEBUG_SymbolExpr(const char * name
)
180 ex
= DEBUG_GetFreeExpr();
182 ex
->type
= EXPR_TYPE_SYMBOL
;
183 ex
->un
.symbol
.name
= name
;
188 DEBUG_ConstExpr(int value
)
192 ex
= DEBUG_GetFreeExpr();
194 ex
->type
= EXPR_TYPE_CONST
;
195 ex
->un
.constant
.value
= value
;
200 DEBUG_StringExpr(const char * str
)
204 ex
= DEBUG_GetFreeExpr();
206 ex
->type
= EXPR_TYPE_STRING
;
207 ex
->un
.string
.str
= str
+1;
208 pnt
= strrchr(ex
->un
.string
.str
, '"');
217 DEBUG_USConstExpr(unsigned int value
)
221 ex
= DEBUG_GetFreeExpr();
223 ex
->type
= EXPR_TYPE_CONST
;
224 ex
->un
.u_const
.value
= value
;
229 DEBUG_BinopExpr(int operator_type
, struct expr
* exp1
, struct expr
* exp2
)
233 ex
= DEBUG_GetFreeExpr();
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
;
243 DEBUG_UnopExpr(int operator_type
, struct expr
* exp1
)
247 ex
= DEBUG_GetFreeExpr();
249 ex
->type
= EXPR_TYPE_UNOP
;
250 ex
->un
.unop
.unop_type
= operator_type
;
251 ex
->un
.unop
.exp1
= exp1
;
256 DEBUG_StructExpr(struct expr
* exp
, const char * element
)
260 ex
= DEBUG_GetFreeExpr();
262 ex
->type
= EXPR_TYPE_STRUCT
;
263 ex
->un
.structure
.exp1
= exp
;
264 ex
->un
.structure
.element_name
= element
;
269 DEBUG_StructPExpr(struct expr
* exp
, const char * element
)
273 ex
= DEBUG_GetFreeExpr();
275 ex
->type
= EXPR_TYPE_PSTRUCT
;
276 ex
->un
.structure
.exp1
= exp
;
277 ex
->un
.structure
.element_name
= element
;
282 DEBUG_CallExpr(const char * funcname
, int nargs
, ...)
288 ex
= DEBUG_GetFreeExpr();
290 ex
->type
= EXPR_TYPE_CALL
;
291 ex
->un
.call
.funcname
= funcname
;
292 ex
->un
.call
.nargs
= nargs
;
295 for(i
=0; i
< nargs
; i
++)
297 ex
->un
.call
.arg
[i
] = va_arg(ap
, struct expr
*);
303 DBG_VALUE
DEBUG_EvalExpr(struct expr
* exp
)
309 unsigned int cexp
[5];
313 struct datatype
* type1
;
314 struct datatype
* type2
;
317 rtn
.cookie
= DV_INVALID
;
324 rtn
= DEBUG_EvalExpr(exp
->un
.cast
.expr
);
325 rtn
.type
= exp
->un
.cast
.cast
;
326 if (DEBUG_GetType(rtn
.type
) == DT_POINTER
)
327 rtn
.cookie
= DV_TARGET
;
329 case EXPR_TYPE_STRING
:
330 rtn
.type
= DEBUG_GetBasicType(DT_BASIC_STRING
);
331 rtn
.cookie
= DV_HOST
;
332 rtn
.addr
.off
= (unsigned int) &exp
->un
.string
.str
;
335 case EXPR_TYPE_CONST
:
336 rtn
.type
= DEBUG_GetBasicType(DT_BASIC_CONST_INT
);
337 rtn
.cookie
= DV_HOST
;
338 rtn
.addr
.off
= (unsigned int) &exp
->un
.constant
.value
;
341 case EXPR_TYPE_US_CONST
:
342 rtn
.type
= DEBUG_GetBasicType(DT_BASIC_USHORTINT
);
343 rtn
.cookie
= DV_HOST
;
344 rtn
.addr
.off
= (unsigned int) &exp
->un
.u_const
.value
;
347 case EXPR_TYPE_SYMBOL
:
348 if( !DEBUG_GetSymbolValue(exp
->un
.symbol
.name
, -1, &rtn
, FALSE
) )
350 DEBUG_Printf(DBG_CHN_MESG
, "%s\n", exp
->un
.symbol
.name
);
351 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
354 case EXPR_TYPE_PSTRUCT
:
355 exp1
= DEBUG_EvalExpr(exp
->un
.structure
.exp1
);
356 if( exp1
.type
== NULL
)
358 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
360 rtn
.cookie
= DV_TARGET
;
361 rtn
.addr
.off
= DEBUG_TypeDerefPointer(&exp1
, &rtn
.type
);
362 if( rtn
.type
== NULL
)
364 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
366 if (!DEBUG_FindStructElement(&rtn
, exp
->un
.structure
.element_name
,
367 &exp
->un
.structure
.result
))
369 DEBUG_Printf(DBG_CHN_MESG
, "%s\n", exp
->un
.structure
.element_name
);
370 RaiseException(DEBUG_STATUS_NO_FIELD
, 0, 0, NULL
);
374 case EXPR_TYPE_STRUCT
:
375 exp1
= DEBUG_EvalExpr(exp
->un
.structure
.exp1
);
376 if( exp1
.type
== NULL
)
378 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
381 if (!DEBUG_FindStructElement(&rtn
, exp
->un
.structure
.element_name
,
382 &exp
->un
.structure
.result
))
384 DEBUG_Printf(DBG_CHN_MESG
, "%s\n", exp
->un
.structure
.element_name
);
385 RaiseException(DEBUG_STATUS_NO_FIELD
, 0, 0, NULL
);
390 * First, evaluate all of the arguments. If any of them are not
391 * evaluable, then bail.
393 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
395 exp1
= DEBUG_EvalExpr(exp
->un
.call
.arg
[i
]);
396 if( exp1
.type
== NULL
)
400 cexp
[i
] = DEBUG_GetExprValue(&exp1
, NULL
);
404 * Now look up the address of the function itself.
406 if( !DEBUG_GetSymbolValue(exp
->un
.call
.funcname
, -1, &rtn
, FALSE
) )
408 RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
412 /* FIXME: NEWDBG NIY */
413 /* Anyway, I wonder how this could work depending on the calling order of
414 * the function (cdecl vs pascal for example)
418 fptr
= (int (*)()) rtn
.addr
.off
;
419 switch(exp
->un
.call
.nargs
)
422 exp
->un
.call
.result
= (*fptr
)();
425 exp
->un
.call
.result
= (*fptr
)(cexp
[0]);
428 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1]);
431 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2]);
434 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3]);
437 exp
->un
.call
.result
= (*fptr
)(cexp
[0], cexp
[1], cexp
[2], cexp
[3], cexp
[4]);
441 DEBUG_Printf(DBG_CHN_MESG
, "Function call no longer implemented\n");
442 /* would need to set up a call to this function, and then restore the current
443 * context afterwards...
445 exp
->un
.call
.result
= 0;
447 rtn
.type
= DEBUG_GetBasicType(DT_BASIC_INT
);
448 rtn
.cookie
= DV_HOST
;
449 rtn
.addr
.off
= (unsigned int) &exp
->un
.call
.result
;
452 case EXPR_TYPE_INTVAR
:
455 DBG_INTVAR
* div
= DEBUG_GetIntVar(exp
->un
.intvar
.name
);
457 if (!div
) RaiseException(DEBUG_STATUS_NO_SYMBOL
, 0, 0, NULL
);
458 rtn
.cookie
= DV_HOST
;
459 rtn
.type
= div
->type
;
460 rtn
.addr
.off
= (unsigned int)div
->pval
;
461 /* EPP FIXME rtn.addr.seg = ?? */
464 case EXPR_TYPE_BINOP
:
465 exp1
= DEBUG_EvalExpr(exp
->un
.binop
.exp1
);
466 exp2
= DEBUG_EvalExpr(exp
->un
.binop
.exp2
);
467 rtn
.cookie
= DV_HOST
;
468 if( exp1
.type
== NULL
|| exp2
.type
== NULL
)
470 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
472 if( exp1
.type
== DEBUG_GetBasicType(DT_BASIC_CONST_INT
) &&
473 exp2
.type
== DEBUG_GetBasicType(DT_BASIC_CONST_INT
) )
475 rtn
.type
= exp1
.type
;
479 rtn
.type
= DEBUG_GetBasicType(DT_BASIC_INT
);
482 rtn
.addr
.off
= (unsigned int) &exp
->un
.binop
.result
;
483 switch(exp
->un
.binop
.binop_type
)
486 type1
= DEBUG_GetPointerType(exp1
.type
);
487 type2
= DEBUG_GetPointerType(exp2
.type
);
490 if( type1
!= NULL
&& type2
!= NULL
)
492 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
494 else if( type1
!= NULL
)
496 scale2
= DEBUG_GetObjectSize(type1
);
497 rtn
.type
= exp1
.type
;
499 else if( type2
!= NULL
)
501 scale1
= DEBUG_GetObjectSize(type2
);
502 rtn
.type
= exp2
.type
;
504 exp
->un
.binop
.result
= (VAL(exp1
) * scale1
+ scale2
* VAL(exp2
));
507 type1
= DEBUG_GetPointerType(exp1
.type
);
508 type2
= DEBUG_GetPointerType(exp2
.type
);
512 if( type1
!= NULL
&& type2
!= NULL
)
516 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
518 scale3
= DEBUG_GetObjectSize(type1
);
520 else if( type1
!= NULL
)
522 scale2
= DEBUG_GetObjectSize(type1
);
523 rtn
.type
= exp1
.type
;
526 else if( type2
!= NULL
)
528 scale1
= DEBUG_GetObjectSize(type2
);
529 rtn
.type
= exp2
.type
;
531 exp
->un
.binop
.result
= (VAL(exp1
) - VAL(exp2
)) / scale3
;
534 rtn
.cookie
= DV_TARGET
;
536 rtn
.addr
.seg
= VAL(exp1
);
537 rtn
.addr
.off
= VAL(exp2
);
540 exp
->un
.binop
.result
= (VAL(exp1
) || VAL(exp2
));
543 exp
->un
.binop
.result
= (VAL(exp1
) && VAL(exp2
));
546 exp
->un
.binop
.result
= (VAL(exp1
) | VAL(exp2
));
549 exp
->un
.binop
.result
= (VAL(exp1
) & VAL(exp2
));
552 exp
->un
.binop
.result
= (VAL(exp1
) ^ VAL(exp2
));
555 exp
->un
.binop
.result
= (VAL(exp1
) == VAL(exp2
));
558 exp
->un
.binop
.result
= (VAL(exp1
) > VAL(exp2
));
561 exp
->un
.binop
.result
= (VAL(exp1
) < VAL(exp2
));
564 exp
->un
.binop
.result
= (VAL(exp1
) >= VAL(exp2
));
567 exp
->un
.binop
.result
= (VAL(exp1
) <= VAL(exp2
));
570 exp
->un
.binop
.result
= (VAL(exp1
) != VAL(exp2
));
573 exp
->un
.binop
.result
= ((unsigned) VAL(exp1
) << VAL(exp2
));
576 exp
->un
.binop
.result
= ((unsigned) VAL(exp1
) >> VAL(exp2
));
579 exp
->un
.binop
.result
= (VAL(exp1
) * VAL(exp2
));
584 RaiseException(DEBUG_STATUS_DIV_BY_ZERO
, 0, 0, NULL
);
586 exp
->un
.binop
.result
= (VAL(exp1
) / VAL(exp2
));
591 RaiseException(DEBUG_STATUS_DIV_BY_ZERO
, 0, 0, NULL
);
593 exp
->un
.binop
.result
= (VAL(exp1
) % VAL(exp2
));
596 DEBUG_ArrayIndex(&exp1
, &rtn
, VAL(exp2
));
599 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
604 exp1
= DEBUG_EvalExpr(exp
->un
.unop
.exp1
);
605 rtn
.cookie
= DV_HOST
;
606 if( exp1
.type
== NULL
)
608 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
611 rtn
.addr
.off
= (unsigned int) &exp
->un
.unop
.result
;
612 if( exp1
.type
== DEBUG_GetBasicType(DT_BASIC_CONST_INT
) )
614 rtn
.type
= exp1
.type
;
618 rtn
.type
= DEBUG_GetBasicType(DT_BASIC_INT
);
620 switch(exp
->un
.unop
.unop_type
)
623 exp
->un
.unop
.result
= -VAL(exp1
);
626 exp
->un
.unop
.result
= !VAL(exp1
);
629 exp
->un
.unop
.result
= ~VAL(exp1
);
632 /* FIXME: this is currently buggy.
633 * there is no way to tell were the deref:ed value is...
635 * x is a pointer to struct s, x being on the stack
636 * => exp1 is target, result is target
637 * x is a pointer to struct s, x being optimized into a reg
638 * => exp1 is host, result is target
639 * x is a pointer to internal variable x
640 * => exp1 is host, result is host
641 * so we force DV_TARGET, because dereferencing pointers to
642 * internal variables is very unlikely. a correct fix would be
645 rtn
.cookie
= DV_TARGET
;
646 rtn
.addr
.off
= (unsigned int) DEBUG_TypeDerefPointer(&exp1
, &rtn
.type
);
649 RaiseException(DEBUG_STATUS_BAD_TYPE
, 0, 0, NULL
);
652 case EXP_OP_FORCE_DEREF
:
653 rtn
.cookie
= exp1
.cookie
;
654 rtn
.addr
.seg
= exp1
.addr
.seg
;
655 if (exp1
.cookie
== DV_TARGET
)
656 DEBUG_READ_MEM((void*)exp1
.addr
.off
, &rtn
.addr
.off
, sizeof(rtn
.addr
.off
));
658 memcpy(&rtn
.addr
.off
, (void*)exp1
.addr
.off
, sizeof(rtn
.addr
.off
));
661 /* FIXME: even for a 16 bit entity ? */
662 rtn
.type
= DEBUG_FindOrMakePointerType(exp1
.type
);
663 exp
->un
.unop
.result
= exp1
.addr
.off
;
666 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
670 DEBUG_Printf(DBG_CHN_MESG
,"Unexpected expression (%d).\n", exp
->type
);
671 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
675 assert(rtn
.cookie
== DV_TARGET
|| rtn
.cookie
== DV_HOST
);
682 DEBUG_DisplayExpr(const struct expr
* exp
)
689 DEBUG_Printf(DBG_CHN_MESG
, "((");
690 DEBUG_PrintTypeCast(exp
->un
.cast
.cast
);
691 DEBUG_Printf(DBG_CHN_MESG
, ")");
692 DEBUG_DisplayExpr(exp
->un
.cast
.expr
);
693 DEBUG_Printf(DBG_CHN_MESG
, ")");
695 case EXPR_TYPE_INTVAR
:
696 DEBUG_Printf(DBG_CHN_MESG
, "$%s", exp
->un
.intvar
.name
);
698 case EXPR_TYPE_US_CONST
:
699 DEBUG_Printf(DBG_CHN_MESG
, "%ud", exp
->un
.u_const
.value
);
701 case EXPR_TYPE_CONST
:
702 DEBUG_Printf(DBG_CHN_MESG
, "%d", exp
->un
.u_const
.value
);
704 case EXPR_TYPE_STRING
:
705 DEBUG_Printf(DBG_CHN_MESG
, "\"%s\"", exp
->un
.string
.str
);
707 case EXPR_TYPE_SYMBOL
:
708 DEBUG_Printf(DBG_CHN_MESG
, "%s" , exp
->un
.symbol
.name
);
710 case EXPR_TYPE_PSTRUCT
:
711 DEBUG_DisplayExpr(exp
->un
.structure
.exp1
);
712 DEBUG_Printf(DBG_CHN_MESG
, "->%s", exp
->un
.structure
.element_name
);
714 case EXPR_TYPE_STRUCT
:
715 DEBUG_DisplayExpr(exp
->un
.structure
.exp1
);
716 DEBUG_Printf(DBG_CHN_MESG
, ".%s", exp
->un
.structure
.element_name
);
719 DEBUG_Printf(DBG_CHN_MESG
, "%s(",exp
->un
.call
.funcname
);
720 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
722 DEBUG_DisplayExpr(exp
->un
.call
.arg
[i
]);
723 if( i
!= exp
->un
.call
.nargs
- 1 )
725 DEBUG_Printf(DBG_CHN_MESG
, ", ");
728 DEBUG_Printf(DBG_CHN_MESG
, ")");
730 case EXPR_TYPE_BINOP
:
731 DEBUG_Printf(DBG_CHN_MESG
, "( ");
732 DEBUG_DisplayExpr(exp
->un
.binop
.exp1
);
733 switch(exp
->un
.binop
.binop_type
)
736 DEBUG_Printf(DBG_CHN_MESG
, " + ");
739 DEBUG_Printf(DBG_CHN_MESG
, " - ");
742 DEBUG_Printf(DBG_CHN_MESG
, ":");
745 DEBUG_Printf(DBG_CHN_MESG
, " || ");
748 DEBUG_Printf(DBG_CHN_MESG
, " && ");
751 DEBUG_Printf(DBG_CHN_MESG
, " | ");
754 DEBUG_Printf(DBG_CHN_MESG
, " & ");
757 DEBUG_Printf(DBG_CHN_MESG
, " ^ ");
760 DEBUG_Printf(DBG_CHN_MESG
, " == ");
763 DEBUG_Printf(DBG_CHN_MESG
, " > ");
766 DEBUG_Printf(DBG_CHN_MESG
, " < ");
769 DEBUG_Printf(DBG_CHN_MESG
, " >= ");
772 DEBUG_Printf(DBG_CHN_MESG
, " <= ");
775 DEBUG_Printf(DBG_CHN_MESG
, " != ");
778 DEBUG_Printf(DBG_CHN_MESG
, " << ");
781 DEBUG_Printf(DBG_CHN_MESG
, " >> ");
784 DEBUG_Printf(DBG_CHN_MESG
, " * ");
787 DEBUG_Printf(DBG_CHN_MESG
, " / ");
790 DEBUG_Printf(DBG_CHN_MESG
, " %% ");
793 DEBUG_Printf(DBG_CHN_MESG
, "[");
798 DEBUG_DisplayExpr(exp
->un
.binop
.exp2
);
799 if( exp
->un
.binop
.binop_type
== EXP_OP_ARR
)
801 DEBUG_Printf(DBG_CHN_MESG
, "]");
803 DEBUG_Printf(DBG_CHN_MESG
, " )");
806 switch(exp
->un
.unop
.unop_type
)
809 DEBUG_Printf(DBG_CHN_MESG
, "-");
812 DEBUG_Printf(DBG_CHN_MESG
, "!");
815 DEBUG_Printf(DBG_CHN_MESG
, "~");
818 DEBUG_Printf(DBG_CHN_MESG
, "*");
821 DEBUG_Printf(DBG_CHN_MESG
, "&");
824 DEBUG_DisplayExpr(exp
->un
.unop
.exp1
);
827 DEBUG_Printf(DBG_CHN_MESG
,"Unexpected expression.\n");
828 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
836 DEBUG_CloneExpr(const struct expr
* exp
)
841 rtn
= (struct expr
*) DBG_alloc(sizeof(struct expr
));
844 * First copy the contents of the expression itself.
852 rtn
->un
.cast
.expr
= DEBUG_CloneExpr(exp
->un
.cast
.expr
);
854 case EXPR_TYPE_INTVAR
:
855 rtn
->un
.intvar
.name
= DBG_strdup(exp
->un
.intvar
.name
);
857 case EXPR_TYPE_US_CONST
:
858 case EXPR_TYPE_CONST
:
860 case EXPR_TYPE_STRING
:
861 rtn
->un
.string
.str
= DBG_strdup(exp
->un
.string
.str
);
863 case EXPR_TYPE_SYMBOL
:
864 rtn
->un
.symbol
.name
= DBG_strdup(exp
->un
.symbol
.name
);
866 case EXPR_TYPE_PSTRUCT
:
867 case EXPR_TYPE_STRUCT
:
868 rtn
->un
.structure
.exp1
= DEBUG_CloneExpr(exp
->un
.structure
.exp1
);
869 rtn
->un
.structure
.element_name
= DBG_strdup(exp
->un
.structure
.element_name
);
872 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
874 rtn
->un
.call
.arg
[i
] = DEBUG_CloneExpr(exp
->un
.call
.arg
[i
]);
876 rtn
->un
.call
.funcname
= DBG_strdup(exp
->un
.call
.funcname
);
878 case EXPR_TYPE_BINOP
:
879 rtn
->un
.binop
.exp1
= DEBUG_CloneExpr(exp
->un
.binop
.exp1
);
880 rtn
->un
.binop
.exp2
= DEBUG_CloneExpr(exp
->un
.binop
.exp2
);
883 rtn
->un
.unop
.exp1
= DEBUG_CloneExpr(exp
->un
.unop
.exp1
);
886 DEBUG_Printf(DBG_CHN_MESG
,"Unexpected expression.\n");
887 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);
896 * Recursively go through an expression tree and free all memory associated
900 DEBUG_FreeExpr(struct expr
* exp
)
907 DEBUG_FreeExpr(exp
->un
.cast
.expr
);
909 case EXPR_TYPE_INTVAR
:
910 DBG_free((char *) exp
->un
.intvar
.name
);
912 case EXPR_TYPE_US_CONST
:
913 case EXPR_TYPE_CONST
:
915 case EXPR_TYPE_STRING
:
916 DBG_free((char *) exp
->un
.string
.str
);
918 case EXPR_TYPE_SYMBOL
:
919 DBG_free((char *) exp
->un
.symbol
.name
);
921 case EXPR_TYPE_PSTRUCT
:
922 case EXPR_TYPE_STRUCT
:
923 DEBUG_FreeExpr(exp
->un
.structure
.exp1
);
924 DBG_free((char *) exp
->un
.structure
.element_name
);
927 for(i
=0; i
< exp
->un
.call
.nargs
; i
++)
929 DEBUG_FreeExpr(exp
->un
.call
.arg
[i
]);
931 DBG_free((char *) exp
->un
.call
.funcname
);
933 case EXPR_TYPE_BINOP
:
934 DEBUG_FreeExpr(exp
->un
.binop
.exp1
);
935 DEBUG_FreeExpr(exp
->un
.binop
.exp2
);
938 DEBUG_FreeExpr(exp
->un
.unop
.exp1
);
941 DEBUG_Printf(DBG_CHN_MESG
,"Unexpected expression.\n");
942 RaiseException(DEBUG_STATUS_INTERNAL_ERROR
, 0, 0, NULL
);