xref: /minix3/minix/lib/libmagicrt/magic_eval.c (revision b2ed49a5d83e311ee0fa9e5ff613639b1bf77aaf)
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