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