xref: /minix3/minix/lib/libmagicrt/magic_eval.c (revision d2532d3d42d764c9ef9816851cdb17eda7e08d36)
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  *===========================================================================*/
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  *===========================================================================*/
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  *===========================================================================*/
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  *===========================================================================*/
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  *===========================================================================*/
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  *===========================================================================*/
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  *===========================================================================*/
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  *===========================================================================*/
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  *===========================================================================*/
212 PUBLIC void magic_eval_set_print_style(int style)
213 {
214     magic_eval_print_style = style;
215 }
216 
217