1*b2ed49a5SDavid van Moolenbroek #include <magic_eval.h>
2*b2ed49a5SDavid van Moolenbroek #include <magic.h>
3*b2ed49a5SDavid van Moolenbroek #include <magic_eval_lib.h>
4*b2ed49a5SDavid van Moolenbroek
5*b2ed49a5SDavid van Moolenbroek #define DEBUG MAGIC_DEBUG_SET(0)
6*b2ed49a5SDavid van Moolenbroek
7*b2ed49a5SDavid van Moolenbroek #if DEBUG
8*b2ed49a5SDavid van Moolenbroek #define MAGIC_EVAL_PRINTF _magic_printf
9*b2ed49a5SDavid van Moolenbroek #else
10*b2ed49a5SDavid van Moolenbroek #define MAGIC_EVAL_PRINTF magic_null_printf
11*b2ed49a5SDavid van Moolenbroek #endif
12*b2ed49a5SDavid van Moolenbroek
13*b2ed49a5SDavid van Moolenbroek PRIVATE int magic_eval_print_style = MAGIC_EVAL_PRINT_STYLE_DEFAULT;
14*b2ed49a5SDavid van Moolenbroek
15*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
16*b2ed49a5SDavid van Moolenbroek * magic_eval_get_var_cb *
17*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_eval_get_var_cb(char * name,struct val * val)18*b2ed49a5SDavid van Moolenbroek PRIVATE struct val* magic_eval_get_var_cb(char* name, struct val* val)
19*b2ed49a5SDavid van Moolenbroek {
20*b2ed49a5SDavid van Moolenbroek _magic_selement_t selement;
21*b2ed49a5SDavid van Moolenbroek int ret;
22*b2ed49a5SDavid van Moolenbroek double dvalue;
23*b2ed49a5SDavid van Moolenbroek void *pvalue;
24*b2ed49a5SDavid van Moolenbroek unsigned long uvalue;
25*b2ed49a5SDavid van Moolenbroek long ivalue;
26*b2ed49a5SDavid van Moolenbroek char vvalue;
27*b2ed49a5SDavid van Moolenbroek struct _magic_dsentry dsentry_buff;
28*b2ed49a5SDavid van Moolenbroek MAGIC_EVAL_PRINTF("magic_eval_get_var_cb: %s requested\n", name);
29*b2ed49a5SDavid van Moolenbroek ret = magic_selement_lookup_by_name(name, &selement, &dsentry_buff);
30*b2ed49a5SDavid van Moolenbroek if(ret < 0) {
31*b2ed49a5SDavid van Moolenbroek return NULL;
32*b2ed49a5SDavid van Moolenbroek }
33*b2ed49a5SDavid van Moolenbroek val->type = T_INT;
34*b2ed49a5SDavid van Moolenbroek switch(selement.type->type_id) {
35*b2ed49a5SDavid van Moolenbroek case MAGIC_TYPE_FLOAT:
36*b2ed49a5SDavid van Moolenbroek dvalue = magic_selement_to_float(&selement);
37*b2ed49a5SDavid van Moolenbroek val->type = T_REAL;
38*b2ed49a5SDavid van Moolenbroek val->rval = dvalue;
39*b2ed49a5SDavid van Moolenbroek break;
40*b2ed49a5SDavid van Moolenbroek
41*b2ed49a5SDavid van Moolenbroek case MAGIC_TYPE_POINTER:
42*b2ed49a5SDavid van Moolenbroek pvalue = magic_selement_to_ptr(&selement);
43*b2ed49a5SDavid van Moolenbroek val->ival = (long) pvalue;
44*b2ed49a5SDavid van Moolenbroek break;
45*b2ed49a5SDavid van Moolenbroek
46*b2ed49a5SDavid van Moolenbroek case MAGIC_TYPE_INTEGER:
47*b2ed49a5SDavid van Moolenbroek case MAGIC_TYPE_ENUM:
48*b2ed49a5SDavid van Moolenbroek if(MAGIC_TYPE_FLAG(selement.type, MAGIC_TYPE_UNSIGNED)) {
49*b2ed49a5SDavid van Moolenbroek uvalue = magic_selement_to_unsigned(&selement);
50*b2ed49a5SDavid van Moolenbroek val->ival = (long) uvalue;
51*b2ed49a5SDavid van Moolenbroek }
52*b2ed49a5SDavid van Moolenbroek else {
53*b2ed49a5SDavid van Moolenbroek ivalue = magic_selement_to_int(&selement);
54*b2ed49a5SDavid van Moolenbroek val->ival = ivalue;
55*b2ed49a5SDavid van Moolenbroek }
56*b2ed49a5SDavid van Moolenbroek break;
57*b2ed49a5SDavid van Moolenbroek
58*b2ed49a5SDavid van Moolenbroek case MAGIC_TYPE_VOID:
59*b2ed49a5SDavid van Moolenbroek vvalue = *((char*) selement.address);
60*b2ed49a5SDavid van Moolenbroek val->ival = (long) vvalue;
61*b2ed49a5SDavid van Moolenbroek break;
62*b2ed49a5SDavid van Moolenbroek
63*b2ed49a5SDavid van Moolenbroek default:
64*b2ed49a5SDavid van Moolenbroek return NULL;
65*b2ed49a5SDavid van Moolenbroek break;
66*b2ed49a5SDavid van Moolenbroek }
67*b2ed49a5SDavid van Moolenbroek
68*b2ed49a5SDavid van Moolenbroek if(magic_eval_print_style & MAGIC_EVAL_PRINT_VAR_VALUES) {
69*b2ed49a5SDavid van Moolenbroek if(val->type == T_INT) {
70*b2ed49a5SDavid van Moolenbroek _magic_printf("VAR: %s = %ld\n", name, val->ival);
71*b2ed49a5SDavid van Moolenbroek }
72*b2ed49a5SDavid van Moolenbroek else {
73*b2ed49a5SDavid van Moolenbroek _magic_printf("VAR: %s = %g\n", name, val->rval);
74*b2ed49a5SDavid van Moolenbroek }
75*b2ed49a5SDavid van Moolenbroek }
76*b2ed49a5SDavid van Moolenbroek
77*b2ed49a5SDavid van Moolenbroek return val;
78*b2ed49a5SDavid van Moolenbroek }
79*b2ed49a5SDavid van Moolenbroek
80*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
81*b2ed49a5SDavid van Moolenbroek * magic_eval_get_func_result_cb *
82*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_eval_get_func_result_cb(char * name,struct val * arg,struct val * ret)83*b2ed49a5SDavid van Moolenbroek PRIVATE struct val* magic_eval_get_func_result_cb(char* name, struct val* arg,
84*b2ed49a5SDavid van Moolenbroek struct val* ret)
85*b2ed49a5SDavid van Moolenbroek {
86*b2ed49a5SDavid van Moolenbroek struct _magic_function *function;
87*b2ed49a5SDavid van Moolenbroek magic_eval_func_t magic_eval_func;
88*b2ed49a5SDavid van Moolenbroek long result, iarg;
89*b2ed49a5SDavid van Moolenbroek MAGIC_EVAL_PRINTF("magic_eval_get_func_result_cb: %s requested\n", name);
90*b2ed49a5SDavid van Moolenbroek if(strncmp(MAGIC_EVAL_FUNC_PREFIX, name, strlen(MAGIC_EVAL_FUNC_PREFIX))) {
91*b2ed49a5SDavid van Moolenbroek return NULL;
92*b2ed49a5SDavid van Moolenbroek }
93*b2ed49a5SDavid van Moolenbroek
94*b2ed49a5SDavid van Moolenbroek function = magic_function_lookup_by_name(NULL, name);
95*b2ed49a5SDavid van Moolenbroek if(!function) {
96*b2ed49a5SDavid van Moolenbroek return NULL;
97*b2ed49a5SDavid van Moolenbroek }
98*b2ed49a5SDavid van Moolenbroek magic_eval_func = (magic_eval_func_t) (long) function->address;
99*b2ed49a5SDavid van Moolenbroek iarg = arg->type == T_INT ? arg->ival : (long) arg->rval;
100*b2ed49a5SDavid van Moolenbroek result = magic_eval_func(iarg);
101*b2ed49a5SDavid van Moolenbroek ret->type = T_INT;
102*b2ed49a5SDavid van Moolenbroek ret->ival = result;
103*b2ed49a5SDavid van Moolenbroek
104*b2ed49a5SDavid van Moolenbroek if(magic_eval_print_style & MAGIC_EVAL_PRINT_FUNC_RESULTS) {
105*b2ed49a5SDavid van Moolenbroek _magic_printf("FUNCTION: %s(%ld) = %ld\n", name, iarg, result);
106*b2ed49a5SDavid van Moolenbroek }
107*b2ed49a5SDavid van Moolenbroek
108*b2ed49a5SDavid van Moolenbroek return ret;
109*b2ed49a5SDavid van Moolenbroek }
110*b2ed49a5SDavid van Moolenbroek
111*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
112*b2ed49a5SDavid van Moolenbroek * magic_eval_init *
113*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_eval_init()114*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_eval_init()
115*b2ed49a5SDavid van Moolenbroek {
116*b2ed49a5SDavid van Moolenbroek eval_set_cb_get_var(magic_eval_get_var_cb);
117*b2ed49a5SDavid van Moolenbroek eval_set_cb_get_func_result(magic_eval_get_func_result_cb);
118*b2ed49a5SDavid van Moolenbroek }
119*b2ed49a5SDavid van Moolenbroek
120*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
121*b2ed49a5SDavid van Moolenbroek * magic_eval *
122*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_eval(char * expr,struct val * result)123*b2ed49a5SDavid van Moolenbroek PRIVATE int magic_eval(char *expr, struct val* result)
124*b2ed49a5SDavid van Moolenbroek {
125*b2ed49a5SDavid van Moolenbroek int ret;
126*b2ed49a5SDavid van Moolenbroek MAGIC_EVAL_PRINTF("magic_eval: Evaluating expression %s\n", expr);
127*b2ed49a5SDavid van Moolenbroek ret = evaluate(expr, result, NULL);
128*b2ed49a5SDavid van Moolenbroek switch(ret) {
129*b2ed49a5SDavid van Moolenbroek case ERROR_SYNTAX:
130*b2ed49a5SDavid van Moolenbroek ret = MAGIC_EINVAL;
131*b2ed49a5SDavid van Moolenbroek break;
132*b2ed49a5SDavid van Moolenbroek case ERROR_FUNCNOTFOUND:
133*b2ed49a5SDavid van Moolenbroek case ERROR_VARNOTFOUND:
134*b2ed49a5SDavid van Moolenbroek ret = MAGIC_ENOENT;
135*b2ed49a5SDavid van Moolenbroek break;
136*b2ed49a5SDavid van Moolenbroek case ERROR_NOMEM:
137*b2ed49a5SDavid van Moolenbroek ret = MAGIC_ENOMEM;
138*b2ed49a5SDavid van Moolenbroek break;
139*b2ed49a5SDavid van Moolenbroek case ERROR_DIV0:
140*b2ed49a5SDavid van Moolenbroek ret = MAGIC_EBADMSTATE;
141*b2ed49a5SDavid van Moolenbroek break;
142*b2ed49a5SDavid van Moolenbroek case RESULT_OK:
143*b2ed49a5SDavid van Moolenbroek ret = 0;
144*b2ed49a5SDavid van Moolenbroek break;
145*b2ed49a5SDavid van Moolenbroek default:
146*b2ed49a5SDavid van Moolenbroek ret = MAGIC_EGENERIC;
147*b2ed49a5SDavid van Moolenbroek break;
148*b2ed49a5SDavid van Moolenbroek }
149*b2ed49a5SDavid van Moolenbroek
150*b2ed49a5SDavid van Moolenbroek return ret;
151*b2ed49a5SDavid van Moolenbroek }
152*b2ed49a5SDavid van Moolenbroek
153*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
154*b2ed49a5SDavid van Moolenbroek * magic_eval_int *
155*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_eval_int(char * expr,long * result)156*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_eval_int(char *expr, long *result)
157*b2ed49a5SDavid van Moolenbroek {
158*b2ed49a5SDavid van Moolenbroek struct val val_res;
159*b2ed49a5SDavid van Moolenbroek int ret;
160*b2ed49a5SDavid van Moolenbroek ret = magic_eval(expr, &val_res);
161*b2ed49a5SDavid van Moolenbroek if(ret < 0) {
162*b2ed49a5SDavid van Moolenbroek return ret;
163*b2ed49a5SDavid van Moolenbroek }
164*b2ed49a5SDavid van Moolenbroek *result = val_res.type == T_INT ? val_res.ival : (long) val_res.rval;
165*b2ed49a5SDavid van Moolenbroek return 0;
166*b2ed49a5SDavid van Moolenbroek }
167*b2ed49a5SDavid van Moolenbroek
168*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
169*b2ed49a5SDavid van Moolenbroek * magic_eval_bool *
170*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_eval_bool(char * expr,char * result)171*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_eval_bool(char *expr, char *result)
172*b2ed49a5SDavid van Moolenbroek {
173*b2ed49a5SDavid van Moolenbroek struct val val_res;
174*b2ed49a5SDavid van Moolenbroek int ret;
175*b2ed49a5SDavid van Moolenbroek ret = magic_eval(expr, &val_res);
176*b2ed49a5SDavid van Moolenbroek if(ret < 0) {
177*b2ed49a5SDavid van Moolenbroek return ret;
178*b2ed49a5SDavid van Moolenbroek }
179*b2ed49a5SDavid van Moolenbroek if(val_res.type != T_INT) {
180*b2ed49a5SDavid van Moolenbroek return MAGIC_EINVAL;
181*b2ed49a5SDavid van Moolenbroek }
182*b2ed49a5SDavid van Moolenbroek *result = val_res.ival == 0 ? 0 : 1;
183*b2ed49a5SDavid van Moolenbroek return 0;
184*b2ed49a5SDavid van Moolenbroek }
185*b2ed49a5SDavid van Moolenbroek
186*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
187*b2ed49a5SDavid van Moolenbroek * magic_eval_float *
188*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_eval_float(char * expr,double * result)189*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_eval_float(char *expr, double *result)
190*b2ed49a5SDavid van Moolenbroek {
191*b2ed49a5SDavid van Moolenbroek struct val val_res;
192*b2ed49a5SDavid van Moolenbroek int ret;
193*b2ed49a5SDavid van Moolenbroek ret = magic_eval(expr, &val_res);
194*b2ed49a5SDavid van Moolenbroek if(ret < 0) {
195*b2ed49a5SDavid van Moolenbroek return ret;
196*b2ed49a5SDavid van Moolenbroek }
197*b2ed49a5SDavid van Moolenbroek *result = val_res.type == T_INT ? (double) val_res.ival : val_res.rval;
198*b2ed49a5SDavid van Moolenbroek return 0;
199*b2ed49a5SDavid van Moolenbroek }
200*b2ed49a5SDavid van Moolenbroek
201*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
202*b2ed49a5SDavid van Moolenbroek * magic_eval_get_print_style *
203*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_eval_get_print_style()204*b2ed49a5SDavid van Moolenbroek PUBLIC int magic_eval_get_print_style()
205*b2ed49a5SDavid van Moolenbroek {
206*b2ed49a5SDavid van Moolenbroek return magic_eval_print_style;
207*b2ed49a5SDavid van Moolenbroek }
208*b2ed49a5SDavid van Moolenbroek
209*b2ed49a5SDavid van Moolenbroek /*===========================================================================*
210*b2ed49a5SDavid van Moolenbroek * magic_eval_set_print_style *
211*b2ed49a5SDavid van Moolenbroek *===========================================================================*/
magic_eval_set_print_style(int style)212*b2ed49a5SDavid van Moolenbroek PUBLIC void magic_eval_set_print_style(int style)
213*b2ed49a5SDavid van Moolenbroek {
214*b2ed49a5SDavid van Moolenbroek magic_eval_print_style = style;
215*b2ed49a5SDavid van Moolenbroek }
216*b2ed49a5SDavid van Moolenbroek
217