Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

eval.cc

Go to the documentation of this file.
00001 /*
00002  *      HT Editor
00003  *      eval.cc
00004  *
00005  *      Copyright (C) 1999, 2000, 2001 Stefan Weyergraf (stefan@weyergraf.de)
00006  *
00007  *      This program is free software; you can redistribute it and/or modify
00008  *      it under the terms of the GNU General Public License version 2 as
00009  *      published by the Free Software Foundation.
00010  *
00011  *      This program is distributed in the hope that it will be useful,
00012  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *      GNU General Public License for more details.
00015  *
00016  *      You should have received a copy of the GNU General Public License
00017  *      along with this program; if not, write to the Free Software
00018  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #include "evaltype.h"
00022 #include "evalparse.h"
00023 #include "eval.h"
00024 #include "snprintf.h"
00025 
00026 #ifdef EVAL_DEBUG
00027 
00028 int debug_dump_ident;
00029 
00030 #endif
00031 
00032 #define MIN(a, b) ((a) < (b) ? (a) : (b))
00033 #define MAX(a, b) ((a) > (b) ? (a) : (b))
00034 
00035 /*
00036  *
00037  */
00038 
00039 static eval_func_handler g_eval_func_handler;
00040 static eval_symbol_handler g_eval_symbol_handler;
00041 static void *eval_context;
00042 static int helpmode = 0;
00043 static eval_scalar helpstring;
00044 static char helpname[MAX_FUNCNAME_LEN+1];
00045 
00046 qword f2i(double f)
00047 {
00048         int r;
00049         if (f>0) r = (int)(f+.5); else r = (int)(f-.5);
00050         // FIXME
00051         return to_qword(r);
00052 }
00053 
00054 void set_helpmode(int flag, char *name)
00055 {
00056         helpmode = flag;
00057         int l = name ? strlen(name) : (MAX_FUNCNAME_LEN+1);
00058         if (l>MAX_FUNCNAME_LEN) {
00059                 *helpname = 0;
00060                 return;
00061         }
00062         strcpy(helpname, name);
00063 }
00064 
00065 static qword ipow(qword a, qword b)
00066 {
00067         qword r = to_qword(1);
00068         qword m = to_qword(1) << 63;
00069         while (m != to_qword(0)) {
00070                 r *= r;
00071                 if ((b & m) != to_qword(0)) {
00072                         r *= a;
00073                 }
00074                 m = m >> 1;
00075         }
00076         return r;
00077 }
00078 
00079 /*
00080 static int sprint_basen(char *buffer, int base, qword q)
00081 {
00082         static char *chars="0123456789abcdef";
00083         if ((base<2) || (base>16)) return 0;
00084         int n = 0;
00085         char *b = buffer;
00086         while (q != to_qword(0)) {
00087                 int c = QWORD_GET_INT(q % to_qword(base));
00088                 *buffer++ = chars[c];
00089                 n++;
00090                 q /= to_qword(base);
00091         }
00092         for (int i=0; i < n/2; i++) {
00093                 char t = b[i];
00094                 b[i] = b[n-i-1];
00095                 b[n-i-1] = t;
00096         }
00097         b[n] = 0;
00098         return n;
00099 }
00100 */
00101 
00102 static int hexdigit(char a)
00103 {
00104         if ((a>='0') && (a<='9')) {
00105                 return a-'0';
00106         } else if ((a>='a') && (a<='f')) {
00107                 return a-'a'+10;
00108         } else if ((a>='A') && (a<='F')) {
00109                 return a-'A'+10;
00110         }
00111         return -1;
00112 }
00113 
00114 static void str2int(char *str, qword *q, int base)
00115 {
00116         *q = to_qword(0);
00117         qword qbase = to_qword(base);
00118         while (*str) {
00119                 int c = hexdigit(*str);
00120                 if ((c == -1) || (c >= base)) break;
00121                 *q *= qbase;
00122                 *q += to_qword(c);
00123                 str++;
00124         }
00125 }
00126 
00127 char *binstr2cstr(char *s, int len)
00128 {
00129         char *x=(char*)malloc(len+1);
00130         memmove(x, s, len);
00131         x[len]=0;
00132         return x;
00133 }
00134         
00135 int bin2str(char *result, void *S, int len)
00136 {
00137         unsigned char *s = (unsigned char*)S;
00138         while (len--) {
00139                 if (*s==0) *result=' '; else *result=*s;
00140                 result++;
00141                 s++;
00142         }
00143         *result=0;
00144         return len;
00145 }
00146 
00147 /*
00148  *      ERROR HANDLING
00149  */
00150 
00151 static int eval_error;
00152 static int eval_error_pos;
00153 static char eval_errstr[MAX_ERRSTR_LEN];
00154 
00155 void clear_eval_error()
00156 {
00157         eval_error=0;
00158 }
00159 
00160 int get_eval_error(char **str, int *pos)
00161 {
00162         if (eval_error) {
00163                 if (str) *str=eval_errstr;
00164                 if (pos) *pos=eval_error_pos;
00165                 return eval_error;
00166         }
00167         if (str) *str="?";
00168         if (pos) *pos=0;
00169         return 0;
00170 }
00171 
00172 void set_eval_error(char *format,...)
00173 {
00174         va_list vargs;
00175         
00176         va_start(vargs, format);
00177         ht_vsnprintf(eval_errstr, sizeof eval_errstr, format, vargs);
00178         va_end(vargs);
00179         eval_error_pos=lex_current_buffer_pos();
00180         eval_error=1;
00181 }
00182 
00183 void set_eval_error_ex(int pos, char *format, ...)
00184 {
00185         va_list vargs;
00186         
00187         va_start(vargs, format);
00188         ht_vsnprintf(eval_errstr, sizeof eval_errstr, format, vargs);
00189         va_end(vargs);
00190         eval_error_pos=pos;
00191         eval_error=1;
00192 }
00193 
00194 /*
00195  *
00196  */
00197 
00198 #ifdef EVAL_DEBUG
00199 
00200 void integer_dump(eval_int *i)
00201 {
00202         printf("%d", i->value);
00203 }
00204 
00205 void float_dump(eval_float *f)
00206 {
00207         printf("%f", f->value);
00208 }
00209 
00210 void string_dump(eval_str *s)
00211 {
00212         int i;
00213         for (i=0; i<s->len; i++) {
00214                 if ((unsigned)s->value[i]<32) {
00215                         printf("\\x%x", s->value[i]);
00216                 } else {
00217                         printf("%c", s->value[i]);
00218                 }
00219         }
00220 }
00221 
00222 #endif
00223 
00224 void string_destroy(eval_str *s)
00225 {
00226         if (s->value) free(s->value);
00227 }
00228 
00229 /*
00230  *      SCALARLIST
00231  */
00232 
00233 void scalarlist_set(eval_scalarlist *l, eval_scalar *s)
00234 {
00235         l->count=1;
00236         l->scalars=(eval_scalar*)malloc(sizeof (eval_scalar) * l->count);
00237         l->scalars[0]=*s;
00238 }
00239 
00240 void scalarlist_concat(eval_scalarlist *l, eval_scalarlist *a, eval_scalarlist *b)
00241 {
00242         l->count=a->count+b->count;
00243         l->scalars=(eval_scalar*)malloc(sizeof (eval_scalar) * l->count);
00244         memmove(l->scalars, a->scalars, sizeof (eval_scalar) * a->count);
00245         memmove(l->scalars+a->count, b->scalars, sizeof (eval_scalar) * b->count);
00246 }
00247 
00248 void scalarlist_destroy(eval_scalarlist *l)
00249 {
00250         int i;
00251         if (l && l->scalars) {
00252                 for (i=0; i < l->count; i++) {
00253                         scalar_destroy(&l->scalars[i]);
00254                 }
00255                 free(l->scalars);
00256         }               
00257 }
00258 
00259 void scalarlist_destroy_gentle(eval_scalarlist *l)
00260 {
00261         if (l && l->scalars) free(l->scalars);
00262 }
00263 
00264 #ifdef EVAL_DEBUG
00265 
00266 void scalarlist_dump(eval_scalarlist *l)
00267 {
00268         int i;
00269         for (i=0; i<l->count; i++) {
00270                 scalar_dump(&l->scalars[i]);
00271                 if (i!=l->count-1) {
00272                         printf(", ");
00273                 }
00274         }
00275 }
00276 
00277 #endif
00278 
00279 /*
00280  *      SCALAR
00281  */
00282 
00283 void scalar_setint(eval_scalar *s, eval_int *i)
00284 {
00285         s->type=SCALAR_INT;
00286         s->scalar.integer=*i;
00287 }
00288 
00289 void scalar_setstr(eval_scalar *s, eval_str *t)
00290 {
00291         s->type=SCALAR_STR;
00292         s->scalar.str=*t;
00293 }
00294 
00295 #ifdef EVAL_DEBUG
00296 
00297 void scalar_dump(eval_scalar *s)
00298 {
00299         switch (s->type) {
00300                 case SCALAR_STR: {
00301                         string_dump(&s->scalar.str);
00302                         break;
00303                 }
00304                 case SCALAR_INT: {
00305                         integer_dump(&s->scalar.integer);
00306                         break;
00307                 }
00308                 case SCALAR_FLOAT: {
00309                         float_dump(&s->scalar.floatnum);
00310                         break;
00311                 }
00312                 default:
00313                         break;
00314         }
00315 }
00316 
00317 #endif
00318 
00319 void scalar_create_int(eval_scalar *s, const eval_int *t)
00320 {
00321         s->type=SCALAR_INT;
00322         s->scalar.integer=*t;
00323 }
00324 
00325 void scalar_create_int_c(eval_scalar *s, const int i)
00326 {
00327         s->type=SCALAR_INT;
00328         s->scalar.integer.value=to_uint64(to_sint64(i));
00329         s->scalar.integer.type=TYPE_UNKNOWN;
00330 }
00331 
00332 void scalar_create_int_q(eval_scalar *s, const qword q)
00333 {
00334         s->type=SCALAR_INT;
00335         s->scalar.integer.value=q;
00336         s->scalar.integer.type=TYPE_UNKNOWN;
00337 }
00338 
00339 void scalar_create_str(eval_scalar *s, const eval_str *t)
00340 {
00341         s->type=SCALAR_STR;
00342         s->scalar.str.value=(char*)malloc(t->len ? t->len : 1);
00343         memmove(s->scalar.str.value, t->value, t->len);
00344         s->scalar.str.len=t->len;
00345 }
00346 
00347 void scalar_create_str_c(eval_scalar *s, const char *cstr)
00348 {
00349         eval_str t;
00350         t.value = (char*)cstr;
00351         t.len = strlen(cstr);
00352         scalar_create_str(s, &t);
00353 }
00354 
00355 void scalar_create_float(eval_scalar *s, const eval_float *t)
00356 {
00357         s->type=SCALAR_FLOAT;
00358         s->scalar.floatnum=*t;
00359 }
00360 
00361 void scalar_create_float_c(eval_scalar *s, const double f)
00362 {
00363         s->type=SCALAR_FLOAT;
00364         s->scalar.floatnum.value=f;
00365 }
00366 
00367 void scalar_context_str(const eval_scalar *s, eval_str *t)
00368 {
00369         switch (s->type) {
00370                 case SCALAR_INT: {
00371                         char buf[64];
00372                         ht_snprintf(buf, sizeof buf, "%qd",
00373                                 /* FIXME: by reference*/ &s->scalar.integer.value);
00374                         t->value = (char*)strdup(buf);
00375                         t->len = strlen(buf);
00376                         break;
00377                 }
00378                 case SCALAR_STR: {
00379                         t->value = (char*)malloc(s->scalar.str.len ? s->scalar.str.len : 1);
00380                         t->len = s->scalar.str.len;
00381                         memmove(t->value, s->scalar.str.value, t->len);
00382                         break;
00383                 }                       
00384                 case SCALAR_FLOAT: {
00385                         char buf[64];
00386                         ht_snprintf(buf, sizeof buf, "%f", s->scalar.floatnum.value);
00387                         t->value = (char*)strdup(buf);
00388                         t->len = strlen(buf);
00389                         break;
00390                 }
00391                 default:
00392                         break;
00393         }                                       
00394 }
00395 
00396 void scalar_context_int(const eval_scalar *s, eval_int *t)
00397 {
00398         switch (s->type) {
00399                 case SCALAR_INT: {
00400                         *t=s->scalar.integer;
00401                         break;
00402                 }
00403                 case SCALAR_STR: {
00404                         char *x = binstr2cstr(s->scalar.str.value, s->scalar.str.len);
00405                         str2int(x, &t->value, 10);
00406                         t->type = TYPE_UNKNOWN;
00407                         free(x);
00408                         break;
00409                 }                       
00410                 case SCALAR_FLOAT: {
00411                         t->value=f2i(s->scalar.floatnum.value);
00412                         t->type=TYPE_UNKNOWN;
00413                         break;
00414                 }
00415                 default:
00416                         break;
00417         }                                       
00418 }
00419 
00420 void scalar_context_float(const eval_scalar *s, eval_float *t)
00421 {
00422         switch (s->type) {
00423                 case SCALAR_INT: {
00424                         t->value = QWORD_GET_FLOAT(s->scalar.integer.value);
00425                         break;
00426                 }
00427                 case SCALAR_STR:  {
00428                         char *x = binstr2cstr(s->scalar.str.value, s->scalar.str.len);
00429                         t->value = strtod(x, (char**)NULL);
00430                         free(x);
00431                         break;
00432                 }                       
00433                 case SCALAR_FLOAT: {
00434                         *t = s->scalar.floatnum;
00435                         break;
00436                 }
00437                 default:
00438                         break;
00439         }                                       
00440 }
00441 
00442 void string_concat(eval_str *s, eval_str *a, eval_str *b)
00443 {
00444         s->value=(char*)malloc(a->len+b->len ? a->len+b->len : 1);
00445         memmove(s->value, a->value, a->len);
00446         memmove(s->value+a->len, b->value, b->len);
00447         s->len=a->len+b->len;
00448         
00449         free(a->value);
00450         a->len=0;
00451         free(b->value);
00452         b->len=0;
00453 }
00454 
00455 void scalar_clone(eval_scalar *result, const eval_scalar *s)
00456 {
00457         switch (s->type) {
00458                 case SCALAR_INT: {
00459                         *result = *s;
00460                         break;
00461                 }
00462                 case SCALAR_STR:  {
00463                         *result = *s;
00464                         result->scalar.str.value = (char*)malloc(result->scalar.str.len);
00465                         memmove(result->scalar.str.value, s->scalar.str.value, result->scalar.str.len);
00466                         break;
00467                 }                       
00468                 case SCALAR_FLOAT: {
00469                         *result = *s;
00470                         break;
00471                 }
00472                 default:
00473                         break;
00474         }
00475 }
00476 
00477 void scalar_concat(eval_scalar *s, const eval_scalar *a, const eval_scalar *b)
00478 {
00479         eval_str as, bs, rs;
00480         scalar_context_str(a, &as);
00481         scalar_context_str(b, &bs);
00482         string_concat(&rs, &as, &bs);
00483         s->type=SCALAR_STR;
00484         s->scalar.str=rs;
00485 }
00486 
00487 void scalar_destroy(eval_scalar *s)
00488 {
00489         switch (s->type) {
00490                 case SCALAR_STR:
00491                         string_destroy(&s->scalar.str);
00492                         break;
00493                 default:
00494                         break;
00495         }
00496 }
00497 
00498 int string_compare(const eval_str *a, const eval_str *b)
00499 {
00500         if (a->len==b->len) {
00501                 return memcmp(a->value, b->value, a->len);
00502         }
00503         return a->len-b->len;
00504 }
00505 
00506 int scalar_strop(eval_scalar *xr, const eval_scalar *xa, const eval_scalar *xb, int op)
00507 {
00508         eval_str as, bs;
00509         int r;
00510         int c;
00511         scalar_context_str(xa, &as);
00512         scalar_context_str(xb, &bs);
00513         
00514         c=string_compare(&as, &bs);
00515         switch (op) {
00516                 case EVAL_STR_EQ: r=(c==0); break;
00517                 case EVAL_STR_NE: r=(c!=0); break;
00518                 case EVAL_STR_GT: r=(c>0); break;
00519                 case EVAL_STR_GE: r=(c>=0); break;
00520                 case EVAL_STR_LT: r=(c<0); break;
00521                 case EVAL_STR_LE: r=(c>=0); break;
00522                 default: 
00523                         return 0;
00524         }
00525         xr->type=SCALAR_INT;
00526         xr->scalar.integer.value=to_qword(r);
00527         xr->scalar.integer.type=TYPE_UNKNOWN;
00528         return 1;
00529 }
00530 
00531 int scalar_float_op(eval_scalar *xr, const eval_scalar *xa, const eval_scalar *xb, int op)
00532 {
00533         eval_float ai, bi;
00534         float a, b, r;
00535         scalar_context_float(xa, &ai);
00536         scalar_context_float(xb, &bi);
00537 
00538         a = ai.value;
00539         b = bi.value;
00540         switch (op) {
00541                 case '*': r = a*b; break;
00542                 case '/': {
00543                     if (!b) {
00544                             set_eval_error("division by zero");
00545                             return 0;
00546                     }
00547                     r = a/b;
00548                     break;
00549                 }                           
00550                 case '+': r = a+b; break;
00551                 case '-': r = a-b; break;
00552                 case EVAL_POW: r = pow(a,b); break;
00553                 default: {
00554                         uint64 ri;
00555                         switch (op) {
00556                                 case EVAL_EQ: ri=to_qword(a==b); break;
00557                                 case EVAL_NE: ri=to_qword(a!=b); break;
00558                                 case EVAL_GT: ri=to_qword(a>b); break;
00559                                 case EVAL_GE: ri=to_qword(a>=b); break;
00560                                 case EVAL_LT: ri=to_qword(a<b); break;
00561                                 case EVAL_LE: ri=to_qword(a<=b); break;
00562                                 case EVAL_LAND: ri=to_qword(a && b); break;
00563                                 case EVAL_LXOR: ri=to_qword((a && !b) || (!a && b)); break;
00564                                 case EVAL_LOR: ri=to_qword(a||b); break;
00565                                 default:
00566                                         set_eval_error("invalid operator");
00567                                         return 0;
00568                         }
00569                         xr->type = SCALAR_INT;
00570                         xr->scalar.integer.value = ri;
00571                         xr->scalar.integer.type = TYPE_UNKNOWN;
00572                         return 1;
00573                 }
00574         }
00575         xr->type = SCALAR_FLOAT;
00576         xr->scalar.floatnum.value = r;
00577         return 1;
00578 }
00579 
00580 int scalar_int_op(eval_scalar *xr, const eval_scalar *xa, const eval_scalar *xb, int op)
00581 {
00582         eval_int ai, bi;
00583         qword a, b, r;
00584         scalar_context_int(xa, &ai);
00585         scalar_context_int(xb, &bi);
00586 
00587         a = ai.value;
00588         b = bi.value;
00589         switch (op) {
00590                 case '*': r = a*b; break;
00591                 case '/': {
00592                     if (!b) {
00593                             set_eval_error("division by zero");
00594                             return 0;
00595                     }
00596                     r = a/b;
00597                     break;
00598                 }                           
00599                 case '%': {
00600                     if (!b) {
00601                             set_eval_error("division by zero");
00602                             return 0;
00603                     }
00604                     r = a%b;
00605                     break;
00606                 }                           
00607                 case '+': r=a+b; break;
00608                 case '-': r=a-b; break;
00609                 case '&': r=a&b; break;
00610                 case '|': r=a|b; break;
00611                 case '^': r=a^b; break;
00612                 // FIXME
00613                 case EVAL_POW: r=ipow(a, b); break;
00614 //              case EVAL_POW: r=to_qword((int)pow(QWORD_GET_INT(a),QWORD_GET_INT(b))); break;
00615                 case EVAL_SHL: r=a<<QWORD_GET_LO(b); break;
00616                 case EVAL_SHR: r=a>>QWORD_GET_LO(b); break;
00617                 case EVAL_EQ: r=to_qword(a==b); break;
00618                 case EVAL_NE: r=to_qword(a!=b); break;
00619                 case EVAL_GT: r=to_qword(a>b); break;
00620                 case EVAL_GE: r=to_qword(a>=b); break;
00621                 case EVAL_LT: r=to_qword(a<b); break;
00622                 case EVAL_LE: r=to_qword(a<=b); break;
00623                 case EVAL_LAND: r=to_qword(qword_cmp(a, to_qword(0)) && qword_cmp(b, to_qword(0))); break;
00624                 case EVAL_LXOR: r=to_qword((qword_cmp(a,to_qword(0)) && !qword_cmp(b,to_qword(0))) || (!qword_cmp(a,to_qword(0)) && qword_cmp(b,to_qword(0)))); break;
00625                 case EVAL_LOR: r=to_qword(qword_cmp(a,to_qword(0)) || qword_cmp(b,to_qword(0))); break;
00626                 default: 
00627                         set_eval_error("invalid operator");
00628                         return 0;
00629         }
00630         xr->type = SCALAR_INT;
00631         xr->scalar.integer.value = r;
00632         xr->scalar.integer.type = TYPE_UNKNOWN;
00633         return 1;
00634 }
00635 
00636 int scalar_op(eval_scalar *xr, eval_scalar *xa, eval_scalar *xb, int op)
00637 {
00638         int r;
00639         if ((xa->type==SCALAR_FLOAT) || (xb->type==SCALAR_FLOAT)) {
00640                 r=scalar_float_op(xr, xa, xb, op);
00641         } else {
00642                 r=scalar_int_op(xr, xa, xb, op);
00643         }
00644         scalar_destroy(xa);
00645         scalar_destroy(xb);
00646         return r;
00647 }
00648         
00649 void scalar_negset(eval_scalar *xr, eval_scalar *xa)
00650 {
00651         if (xa->type==SCALAR_FLOAT) {
00652                 eval_float a;
00653                 a=xa->scalar.floatnum;
00654         
00655                 xr->type=SCALAR_FLOAT;
00656                 xr->scalar.floatnum.value=-a.value;
00657         } else {
00658                 eval_int a;
00659                 scalar_context_int(xa, &a);
00660         
00661                 xr->type=SCALAR_INT;
00662                 xr->scalar.integer.value=-a.value;
00663                 xr->scalar.integer.type=TYPE_UNKNOWN;
00664         }
00665         scalar_destroy(xa);
00666 }
00667 
00668 void scalar_notset(eval_scalar *xr, eval_scalar *xa)
00669 {
00670         eval_int a;
00671         scalar_context_int(xa, &a);
00672 
00673         xr->type=SCALAR_INT;
00674         xr->scalar.integer.value=~a.value;
00675         xr->scalar.integer.type=TYPE_UNKNOWN;
00676 
00677         scalar_destroy(xa);
00678 }
00679 
00680 void scalar_lnotset(eval_scalar *xr, eval_scalar *xa)
00681 {
00682         eval_int a;
00683         scalar_context_int(xa, &a);
00684 
00685         xr->type=SCALAR_INT;
00686         xr->scalar.integer.value=to_qword(!a.value);
00687         xr->scalar.integer.type=TYPE_UNKNOWN;
00688 
00689         scalar_destroy(xa);
00690 }
00691 
00692 void scalar_miniif(eval_scalar *xr, eval_scalar *xa, eval_scalar *xb, eval_scalar *xc)
00693 {
00694         eval_int a;
00695         scalar_context_int(xa, &a);
00696         if (a.value != to_qword(0)) {
00697                 *xr = *xb;
00698         } else {
00699                 *xr = *xc;
00700         }
00701         scalar_destroy(xa);
00702 }
00703 
00704 /*
00705  *      BUILTIN FUNCTIONS
00706  */
00707 
00708 int func_typeof(eval_scalar *r, eval_scalar *s)
00709 {
00710         switch (s->type) {
00711                 case SCALAR_INT:
00712                         scalar_create_str_c(r, "int");
00713                         break;
00714                 case SCALAR_STR:
00715                         scalar_create_str_c(r, "string");
00716                         break;
00717                 case SCALAR_FLOAT:
00718                         scalar_create_str_c(r, "float");
00719                         break;
00720                 default:
00721 // FIXME: should never happen
00722                         scalar_create_str_c(r, "unknown");
00723                         break;
00724         }
00725         return 1;
00726 }
00727 
00728 int func_is_int(eval_scalar *r, eval_scalar *s)
00729 {
00730         if (s->type == SCALAR_INT) {
00731                 scalar_create_int_c(r, 1);
00732         } else {
00733                 scalar_create_int_c(r, 0);
00734         }
00735         return 1;
00736 }
00737 
00738 int func_is_string(eval_scalar *r, eval_scalar *s)
00739 {
00740         if (s->type == SCALAR_STR) {
00741                 scalar_create_int_c(r, 1);
00742         } else {
00743                 scalar_create_int_c(r, 0);
00744         }
00745         return 1;
00746 }
00747 
00748 int func_is_float(eval_scalar *r, eval_scalar *s)
00749 {
00750         if (s->type == SCALAR_FLOAT) {
00751                 scalar_create_int_c(r, 1);
00752         } else {
00753                 scalar_create_int_c(r, 0);
00754         }
00755         return 1;
00756 }
00757 
00758 int func_char(eval_scalar *r, eval_int *i)
00759 {
00760         eval_str s;
00761         char c = QWORD_GET_LO(i->value);
00762         s.value=&c;
00763         s.len=1;
00764         scalar_create_str(r, &s);
00765         return 1;
00766 }
00767 
00768 int func_byte(eval_scalar *r, eval_int *i)
00769 {
00770         UINT c = QWORD_GET_LO(i->value);
00771         scalar_create_int_c(r, c&0xff);
00772         return 1;
00773 }
00774 
00775 int func_word(eval_scalar *r, eval_int *i)
00776 {
00777         UINT c = QWORD_GET_LO(i->value);
00778         scalar_create_int_c(r, c&0xffff);
00779         return 1;
00780 }
00781 
00782 int func_dword(eval_scalar *r, eval_int *i)
00783 {
00784         UINT c = QWORD_GET_LO(i->value);
00785         scalar_create_int_q(r, to_qword(c));
00786         return 1;
00787 }
00788 
00789 int func_sbyte(eval_scalar *r, eval_int *i)
00790 {
00791         UINT c = QWORD_GET_LO(i->value);
00792         scalar_create_int_c(r, (signed char)c);
00793         return 1;
00794 }
00795 
00796 int func_short(eval_scalar *r, eval_int *i)
00797 {
00798         UINT c = QWORD_GET_LO(i->value);
00799         scalar_create_int_c(r, (short)c);
00800         return 1;
00801 }
00802 
00803 int func_long(eval_scalar *r, eval_int *i)
00804 {
00805         int c = QWORD_GET_LO(i->value);
00806         scalar_create_int_c(r, c);
00807         return 1;
00808 }
00809 
00810 int func_float(eval_scalar *r, eval_float *p)
00811 {
00812         scalar_create_float(r, p);
00813         return 1;
00814 }
00815 
00816 int func_fmax(eval_scalar *r, eval_float *p1, eval_float *p2)
00817 {
00818         r->type=SCALAR_FLOAT;
00819         r->scalar.floatnum.value=(p1->value>p2->value) ? p1->value : p2->value;
00820         return 1;
00821 }
00822 
00823 int func_fmin(eval_scalar *r, eval_float *p1, eval_float *p2)
00824 {
00825         r->type=SCALAR_FLOAT;
00826         r->scalar.floatnum.value=(p1->value<p2->value) ? p1->value : p2->value;
00827         return 1;
00828 }
00829 
00830 int func_int(eval_scalar *r, eval_int *p)
00831 {
00832         scalar_create_int(r, p);
00833         return 1;
00834 }
00835 
00836 int func_ord(eval_scalar *r, eval_str *s)
00837 {
00838         if (s->len>=1) {
00839                 scalar_create_int_c(r, s->value[0]);
00840                 return 1;
00841         }
00842         set_eval_error("string must at least contain one character");
00843         return 0;               
00844 }
00845 
00846 int func_max(eval_scalar *r, eval_int *p1, eval_int *p2)
00847 {
00848         scalar_create_int(r, (p1->value>p2->value) ? p1 : p2);
00849         return 1;
00850 }
00851 
00852 int func_min(eval_scalar *r, eval_int *p1, eval_int *p2)
00853 {
00854         scalar_create_int(r, (p1->value<p2->value) ? p1 : p2);
00855         return 1;
00856 }
00857 
00858 int func_random(eval_scalar *r, eval_int *p1)
00859 {
00860         qword d = to_qword(rand());
00861         scalar_create_int_q(r, (p1->value != to_qword(0)) ? (d % p1->value):to_qword(0));
00862         return 1;
00863 }
00864 
00865 int func_rnd(eval_scalar *r)
00866 {
00867         scalar_create_int_c(r, rand() % 2);
00868         return 1;
00869 }
00870 
00871 int func_round(eval_scalar *r, eval_float *p)
00872 {
00873         r->type=SCALAR_INT;
00874         r->scalar.integer.value=f2i(p->value+0.5);
00875         r->scalar.integer.type=TYPE_UNKNOWN;
00876         return 1;
00877 }
00878 
00879 int func_strchr(eval_scalar *r, eval_str *p1, eval_str *p2)
00880 {
00881         if (p2->len) {
00882                 if (p1->len) {
00883                         char *pos = (char *)memchr(p1->value, *p2->value, p1->len);
00884                         if (pos) {
00885                                 scalar_create_int_c(r, pos-p1->value);
00886                         } else {
00887                                 scalar_create_int_c(r, -1);
00888                         }
00889                 } else {
00890                         scalar_create_int_c(r, -1);
00891                 }
00892                 return 1;
00893         } else {
00894                 return 0;
00895         }
00896 }
00897 
00898 int func_strcmp(eval_scalar *r, eval_str *p1, eval_str *p2)
00899 {
00900         int r2=memcmp(p1->value, p2->value, MIN(p1->len, p2->len));
00901         if (r2) {
00902                 scalar_create_int_c(r, r2);
00903         } else {
00904                 if (p1->len > p2->len) {
00905                         scalar_create_int_c(r, 1);
00906                 } else if (p1->len < p2->len) {
00907                         scalar_create_int_c(r, -1);
00908                 } else {
00909                         scalar_create_int_c(r, 0);
00910                 }
00911         }
00912         return 1;     
00913 }
00914 
00915 int func_string(eval_scalar *r, eval_str *p)
00916 {
00917         scalar_create_str(r, p);
00918         return 1;
00919 }
00920 
00921 int func_strlen(eval_scalar *r, eval_str *p1)
00922 {
00923         scalar_create_int_c(r, p1->len);
00924         return 1;
00925 }
00926 
00927 int func_strncmp(eval_scalar *r, eval_str *p1, eval_str *p2, eval_int *p3)
00928 {
00929         return 1;
00930 }
00931 
00932 int func_strrchr(eval_scalar *r, eval_str *p1, eval_str *p2)
00933 {
00934         return 1;
00935 }
00936 
00937 int func_strstr(eval_scalar *r, eval_str *p1, eval_str *p2)
00938 {
00939 
00940         return 1;
00941 }
00942 
00943 int func_substr(eval_scalar *r, eval_str *p1, eval_int *p2, eval_int *p3)
00944 {
00945         if (p2->value >= to_qword(0) && p3->value > to_qword(0)) {
00946                 if (p2->value < to_qword(p1->len)) {
00947                         eval_str s;
00948                         s.len = QWORD_GET_LO(MIN(p3->value, to_qword(p1->len)-p2->value));
00949                         s.value = &p1->value[QWORD_GET_LO(p2->value)];
00950                         scalar_create_str(r, &s);
00951                 } else {
00952                         scalar_create_str_c(r, "");
00953                 }
00954         } else {
00955                 scalar_create_str_c(r, "");
00956         }
00957         return 1;
00958 }
00959 
00960 int func_trunc(eval_scalar *r, eval_float *p)
00961 {
00962         r->type=SCALAR_INT;
00963         r->scalar.integer.value=f2i(p->value);
00964         r->scalar.integer.type=TYPE_UNKNOWN;
00965         return 1;
00966 }
00967 
00968 #define EVALFUNC_FMATH1(name) int func_##name(eval_scalar *r, eval_float *p)\
00969 {\
00970         r->type=SCALAR_FLOAT;\
00971         r->scalar.floatnum.value=name(p->value);\
00972         return 1;\
00973 }
00974 
00975 #define EVALFUNC_FMATH1i(name) int func_##name(eval_scalar *r, eval_float *p)\
00976 {\
00977         r->type=SCALAR_INT;\
00978         r->scalar.integer.value=f2i(name(p->value));\
00979         r->scalar.integer.type=TYPE_UNKNOWN;\
00980         return 1;\
00981 }
00982 
00983 #define EVALFUNC_FMATH2(name) int func_##name(eval_scalar *r, eval_float *p1, eval_float *p2)\
00984 {\
00985         r->type=SCALAR_FLOAT;\
00986         r->scalar.floatnum.value=name(p1->value, p2->value);\
00987         return 1;\
00988 }
00989 
00990 EVALFUNC_FMATH2(pow)
00991 
00992 EVALFUNC_FMATH1(sqrt)
00993 
00994 EVALFUNC_FMATH1(exp)
00995 EVALFUNC_FMATH1(log)
00996 
00997 EVALFUNC_FMATH1i(ceil)
00998 EVALFUNC_FMATH1i(floor)
00999 
01000 EVALFUNC_FMATH1(sin)
01001 EVALFUNC_FMATH1(cos)
01002 EVALFUNC_FMATH1(tan)
01003 
01004 EVALFUNC_FMATH1(asin)
01005 EVALFUNC_FMATH1(acos)
01006 EVALFUNC_FMATH1(atan)
01007 
01008 EVALFUNC_FMATH1(sinh)
01009 EVALFUNC_FMATH1(cosh)
01010 EVALFUNC_FMATH1(tanh)
01011 
01012 #ifdef HAVE_ASINH
01013 EVALFUNC_FMATH1(asinh)
01014 #endif
01015 
01016 #ifdef HAVE_ACOSH
01017 EVALFUNC_FMATH1(acosh)
01018 #endif
01019 
01020 #ifdef HAVE_ATANH
01021 EVALFUNC_FMATH1(atanh)
01022 #endif
01023 
01024 void sprintf_puts(char **b, char *blimit, char *buf)
01025 {
01026         while ((*b<blimit) && (*buf)) {
01027                 **b=*(buf++);
01028                 (*b)++;
01029         }
01030 }
01031 
01032 int sprintf_percent(char **fmt, int *fmtl, char **b, char *blimit, eval_scalar *s)
01033 {
01034         char cfmt[32];
01035         char buf[512];
01036         int ci=1;
01037         cfmt[0]='%';
01038         while ((*fmtl) && (ci<32-1)) {
01039                 cfmt[ci]=(*fmt)[0];
01040                 cfmt[ci+1]=0;
01041                 switch ((*fmt)[0]) {
01042                         case 'd':
01043                         case 'i':
01044                         case 'o':
01045                         case 'u':
01046                         case 'x':
01047                         case 'X':
01048                         case 'c': {
01049                                 eval_int i;
01050                                 scalar_context_int(s, &i);
01051                                 
01052                                 sprintf(buf, cfmt, i.value);
01053                                 sprintf_puts(b, blimit, buf);
01054                                 
01055                                 return 1;
01056                         }
01057                         case 's': {
01058                                 char *q=cfmt+1;
01059                                 eval_str t;
01060 /*                              int l;*/
01061                                 scalar_context_str(s, &t);
01062                                 
01063                                 while (*q!='s') {
01064                                         if ((*q>='0') && (*q<='9')) {
01065                                                 unsigned int sl=strtol(q, NULL, 10);
01066                                                 if (sl>sizeof buf-1) sl=sizeof buf-1;
01067                                                 sprintf(q, "%ds", sl);
01068                                                 break;
01069                                         } else {
01070                                                 switch (*q) {
01071                                                         case '+':
01072                                                         case '-':
01073                                                         case '#':
01074                                                         case ' ':
01075                                                                 break;
01076                                                         default:
01077                                                         /* FIXME: invalid format */
01078                                                                 break;
01079                                                 }
01080                                         }
01081                                         q++;
01082                                 }
01083                                 
01084                                 if ((unsigned int)t.len>sizeof buf-1) t.len=sizeof buf-1;
01085                                 t.value[t.len]=0;
01086                                 
01087                                 sprintf(buf, cfmt, t.value);
01088                                 
01089 /*                              l=t.len;
01090                                 if (l > (sizeof buf)-1) l=(sizeof buf)-1;
01091 
01092                                 memmove(buf, t.value, l);
01093                                 buf[l]=0;*/
01094                                 sprintf_puts(b, blimit, buf);
01095                                 
01096                                 string_destroy(&t);
01097                                 return 1;
01098                         }
01099                         case 'e':
01100                         case 'E':
01101                         case 'f':
01102                         case 'F':
01103                         case 'g':
01104                         case 'G': {
01105                                 eval_float f;
01106                                 scalar_context_float(s, &f);
01107                                 
01108                                 sprintf(buf, cfmt, f.value);
01109                                 sprintf_puts(b, blimit, buf);
01110                                 
01111                                 return 1;
01112                         }
01113                         case '%':
01114                                 sprintf_puts(b, blimit, "%");
01115                                 return 1;
01116                 }
01117                 (*fmt)++;
01118                 (*fmtl)--;
01119                 ci++;
01120         }
01121         return 0;
01122 }
01123 
01124 int func_sprintf(eval_scalar *r, const eval_str *format, const eval_scalarlist *scalars)
01125 {
01126         char buf[512];          /* FIXME: possible buffer overflow */
01127         char *b=buf;
01128         char *fmt;
01129         int fmtl;
01130         eval_scalar *s=scalars->scalars;
01131         
01132         fmt=format->value;
01133         fmtl=format->len;
01134         
01135         while (fmtl) {
01136                 if (fmt[0]=='%') {
01137                         fmt++;
01138                         fmtl--;
01139                         if (!fmtl) break;
01140                         if (fmt[0]!='%') {
01141                                 if (s-scalars->scalars >= scalars->count) {
01142                                         DEBUG_DUMP("too few parameters");
01143                                         return 0;
01144                                 }                                       
01145                                 if (!sprintf_percent(&fmt, &fmtl, &b, buf+sizeof buf, s)) return 0;
01146                                 s++;
01147                         } else {
01148                                 *b++=fmt[0];
01149                                 if (b-buf>=512) break;
01150                         }
01151                 } else {
01152                         *b++=fmt[0];
01153                         if (b-buf>=512) break;
01154                 }
01155                 fmt++;
01156                 fmtl--;
01157         }
01158         *b=0;
01159         r->type=SCALAR_STR;
01160         r->scalar.str.value=(char*)strdup(buf);
01161         r->scalar.str.len=strlen(r->scalar.str.value);
01162         return 1;
01163 }
01164 
01165 /*
01166  *      FUNCTIONS
01167  */
01168 
01169 int func_eval(eval_scalar *r, eval_str *p)
01170 {
01171         char *q=(char*)malloc(p->len+1);
01172         int x;
01173         memmove(q, p->value, p->len);
01174         q[p->len]=0;
01175         x=eval(r, q, g_eval_func_handler, g_eval_symbol_handler, eval_context);
01176         free(q);
01177 /*     if (get_eval_error(NULL, NULL)) {
01178                 eval_error_pos+=lex_current_buffer_pos();
01179         }*/
01180         return x;
01181 }
01182 
01183 int func_error(eval_scalar *r, eval_str *s)
01184 {
01185         char c[1024];
01186         bin2str(c, s->value, MIN((unsigned int)s->len, sizeof c));
01187         set_eval_error(c);
01188         return 0;
01189 }
01190 
01191 int func_help_helper(eval_scalar *r, eval_str *s)
01192 {
01193         if (s->len > MAX_FUNCNAME_LEN) return 0;
01194         char b[MAX_FUNCNAME_LEN+1];
01195         bin2str(b, s->value, s->len);
01196         set_helpmode(1, b);
01197         eval_scalar str;
01198         scalar_create_str_c(&str, "NaF()");
01199         scalar_create_str_c(&helpstring, "");
01200         func_eval(r, &str.scalar.str);
01201         *r = helpstring;
01202         scalar_destroy(&str);
01203         set_helpmode(0, NULL);
01204         return 1;
01205 }
01206 
01207 int func_whatis(eval_scalar *r, eval_str *s)
01208 {
01209         int t = 0;
01210         if (s->len != 0) t = func_help_helper(r, s);
01211         if ((s->len == 0) || (r->scalar.str.len == 0)) {
01212                 char n[MAX_FUNCNAME_LEN+1];
01213                 bin2str(n, s->value, s->len);
01214                 set_eval_error("no such function \"%s\"", n);
01215                 return 0;
01216         }
01217         return t;
01218 }
01219 
01220 int func_help(eval_scalar *r)
01221 {
01222         eval_scalar str;
01223         scalar_create_str_c(&str, "");
01224         int t = func_help_helper(r, &str.scalar.str);
01225         scalar_destroy(&str);
01226         return t;
01227 }
01228 
01229 eval_func builtin_evalfuncs[]=  {
01230 /* eval */
01231         { "eval", (void*)&func_eval, {SCALAR_STR}, "evaluate string" },
01232 /* help */
01233         { "help", (void*)&func_help, {}, "get help on all functions"},
01234         { "whatis", (void*)&func_whatis, {SCALAR_STR}, "get help on specific function"},
01235 /* type juggling */
01236         { "int", (void*)&func_int, {SCALAR_INT}, "converts to integer" },
01237         { "string", (void*)&func_string, {SCALAR_STR}, "converts to string" },
01238         { "float", (void*)&func_float, {SCALAR_FLOAT}, "converts to float" },
01239         { "byte", (void*)&func_byte, {SCALAR_INT}, "converts to byte (1 bytes)" },
01240         { "word", (void*)&func_word, {SCALAR_INT}, "converts to word (2 bytes unsigned)" },
01241         { "dword", (void*)&func_dword, {SCALAR_INT}, "converts to dword (4 bytes unsigned)" },
01242         { "sbyte", (void*)&func_sbyte, {SCALAR_INT}, "converts to signed byte (1 bytes signed)" },
01243         { "short", (void*)&func_short, {SCALAR_INT}, "converts to short (2 bytes signed)" },
01244         { "long", (void*)&func_long, {SCALAR_INT}, "converts to long (4 bytes signed)" },
01245         { "typeof", (void*)&func_typeof, {SCALAR_ANY}, "returns \"int\", \"string\" or \"float\"" },
01246         { "is_int", (void*)&func_is_int, {SCALAR_ANY}, "returns non-zero if param is an integer" },
01247         { "is_string", (void*)&func_is_string, {SCALAR_ANY}, "returns non-zero if param is a string" },
01248         { "is_float", (void*)&func_is_float, {SCALAR_ANY}, "returns non-zero if param is a float" },
01249 
01250 /* general */
01251         { "error", (void*)&func_error, {SCALAR_STR}, "abort with error" },
01252 /* string functions */
01253         { "char", (void*)&func_char, {SCALAR_INT}, "return the ascii character (1-char string) specified by p1" },
01254         { "ord", (void*)&func_ord, {SCALAR_STR}, "return the ordinal value of p1" },
01255         { "sprintf", (void*)&func_sprintf, {SCALAR_STR, SCALAR_VARARGS}, "returns formatted string" },
01256         { "strchr", (void*)&func_strchr, {SCALAR_STR, SCALAR_STR}, "returns position of first occurrence of character param2 in param1" },
01257         { "strcmp", (void*)&func_strcmp, {SCALAR_STR, SCALAR_STR}, "returns zero for equality, positive number for str1 > str2 and negative number for str1 < str2" },
01258         { "strlen", (void*)&func_strlen, {SCALAR_STR}, "returns length of string" },
01259         { "strncmp", (void*)&func_strncmp, {SCALAR_STR, SCALAR_STR, SCALAR_INT}, "like strcmp, but considers a maximum of param3 characters" },
01260         { "strstr", (void*)&func_strchr, {SCALAR_STR, SCALAR_STR}, "returns position of first occurrence of string param2 in param1" },
01261         { "substr", (void*)&func_substr, {SCALAR_STR, SCALAR_INT, SCALAR_INT}, "returns substring from param1, start param2, length param3" },
01262 /*      { "stricmp", (void*)&func_stricmp, {SCALAR_STR, SCALAR_STR}, "like strcmp but case-insensitive" },
01263         { "strnicmp", (void*)&func_strnicmp, {SCALAR_STR, SCALAR_STR}, "" }, */
01264 /* math */      
01265         { "pow", (void*)&func_pow, {SCALAR_FLOAT, SCALAR_FLOAT}, 0 },
01266         { "sqrt", (void*)&func_sqrt, {SCALAR_FLOAT}, 0 },
01267         
01268         { "fmin", (void*)&func_fmin, {SCALAR_FLOAT, SCALAR_FLOAT}, 0 },
01269         { "fmax", (void*)&func_fmax, {SCALAR_FLOAT, SCALAR_FLOAT}, 0 },
01270         { "min", (void*)&func_min, {SCALAR_INT, SCALAR_INT}, 0 },
01271         { "max", (void*)&func_max, {SCALAR_INT, SCALAR_INT}, 0 },
01272         
01273         { "random", (void*)&func_random, {SCALAR_INT}, "returns a random integer between 0 and param1-1" },
01274         { "rnd", (void*)&func_rnd, {}, "returns a random bit as integer (0 or 1)" },
01275 
01276         { "exp", (void*)&func_exp, {SCALAR_FLOAT}, 0 },
01277         { "log", (void*)&func_log, {SCALAR_FLOAT}, 0 },
01278         
01279         { "ceil", (void*)&func_ceil, {SCALAR_FLOAT}, 0 },
01280         { "floor", (void*)&func_floor, {SCALAR_FLOAT}, 0 },
01281         { "round", (void*)&func_round, {SCALAR_FLOAT}, 0 },
01282         { "trunc", (void*)&func_trunc, {SCALAR_FLOAT}, 0 },
01283         
01284         { "sin", (void*)&func_sin, {SCALAR_FLOAT}, 0 },
01285         { "cos", (void*)&func_cos, {SCALAR_FLOAT}, 0 },
01286         { "tan", (void*)&func_tan, {SCALAR_FLOAT}, 0 },
01287         
01288         { "asin", (void*)&func_asin, {SCALAR_FLOAT}, 0 },
01289         { "acos", (void*)&func_acos, {SCALAR_FLOAT}, 0 },
01290         { "atan", (void*)&func_atan, {SCALAR_FLOAT}, 0 },
01291         
01292         { "sinh", (void*)&func_sinh, {SCALAR_FLOAT}, 0 },
01293         { "cosh", (void*)&func_cosh, {SCALAR_FLOAT}, 0 },
01294         { "tanh", (void*)&func_tanh, {SCALAR_FLOAT}, 0 },
01295         
01296 #ifdef HAVE_ASINH
01297         { "asinh", (void*)&func_asinh, {SCALAR_FLOAT}, 0 },
01298 #endif
01299 
01300 #ifdef HAVE_ACOSH
01301         { "acosh", (void*)&func_acosh, {SCALAR_FLOAT}, 0 },
01302 #endif
01303 
01304 #ifdef HAVE_ATANH
01305         { "atanh", (void*)&func_atanh, {SCALAR_FLOAT}, 0 },
01306 #endif
01307         
01308         { NULL, NULL }
01309 };
01310 
01311 eval_protomatch match_evalfunc_proto(char *name, eval_scalarlist *params, eval_func *proto)
01312 {
01313         int j;
01314         int protoparams=0;
01315         
01316         if (strcmp(name, proto->name)!=0) return PROTOMATCH_NAME_FAIL;
01317         
01318         for (j=0; j<MAX_EVALFUNC_PARAMS; j++) {
01319                 if (proto->ptype[j]==SCALAR_NULL) break;
01320                 if (proto->ptype[j]==SCALAR_VARARGS) {
01321                         if (params->count > protoparams) protoparams=params->count;
01322                         break;
01323                 }
01324                 protoparams++;
01325         }
01326         return (protoparams==params->count) ? PROTOMATCH_OK : PROTOMATCH_PARAM_FAIL;
01327 }
01328 
01329 int exec_evalfunc(eval_scalar *r, eval_scalarlist *params, eval_func *proto)
01330 {
01331         int j;
01332         int retv;
01333         eval_scalar sc[MAX_EVALFUNC_PARAMS];
01334         void *pptrs[MAX_EVALFUNC_PARAMS];
01335         int protoparams=0;
01336         eval_scalarlist *sclist=0;
01337         char *errmsg;
01338         int errpos;
01339 
01340         for (j=0; j<MAX_EVALFUNC_PARAMS; j++) {
01341                 sc[j].type=SCALAR_NULL;
01342                 pptrs[j]=NULL;
01343         }                                       
01344         
01345         DEBUG_DUMP("%s:", proto->name);
01346         
01347         for (j=0; j<MAX_EVALFUNC_PARAMS; j++) {
01348                 int term=0;
01349                 if (proto->ptype[j]==SCALAR_NULL) break;
01350                 switch (proto->ptype[j]) {
01351                         case SCALAR_INT:
01352                                 protoparams++;
01353                                 if (params->count<protoparams) return 0;
01354                                 sc[j].type=SCALAR_INT;
01355                                 scalar_context_int(&params->scalars[j], &sc[j].scalar.integer);
01356                                 pptrs[j]=&sc[j].scalar.integer;
01357 
01358                                 DEBUG_DUMP_SCALAR(&sc[j], "param %d: int=", j);
01359                                 break;
01360                         case SCALAR_STR:
01361                                 protoparams++;
01362                                 if (params->count<protoparams) return 0;
01363                                 sc[j].type=SCALAR_STR;
01364                                 scalar_context_str(&params->scalars[j], &sc[j].scalar.str);
01365                                 pptrs[j]=&sc[j].scalar.str;
01366                                 
01367                                 DEBUG_DUMP_SCALAR(&sc[j], "param %d: str=", j);
01368                                 break;
01369                         case SCALAR_FLOAT:
01370                                 protoparams++;
01371                                 if (params->count<protoparams) return 0;
01372                                 sc[j].type=SCALAR_FLOAT;
01373                                 scalar_context_float(&params->scalars[j], &sc[j].scalar.floatnum);
01374                                 pptrs[j]=&sc[j].scalar.floatnum;
01375 
01376                                 DEBUG_DUMP_SCALAR(&sc[j], "param %d: float=", j);
01377                                 break;
01378                         case SCALAR_ANY: {
01379                                 protoparams++;
01380                                 if (params->count<protoparams) return 0;
01381                                 scalar_clone(&sc[j], &params->scalars[j]);
01382                                 pptrs[j] = &sc[j];
01383 
01384                                 DEBUG_DUMP_SCALAR(&sc[j], "param %d: vararg=", j);
01385                                 break;
01386                         }
01387                         case SCALAR_VARARGS: {
01388                                 sclist=(eval_scalarlist*)malloc(sizeof (eval_scalarlist));
01389                                 sclist->count=params->count-j;
01390                                 if (sclist->count) {
01391                                         sclist->scalars=(eval_scalar*)malloc(sizeof (eval_scalar) * sclist->count);
01392                                         memmove(sclist->scalars, &params->scalars[j], sizeof (eval_scalar) * sclist->count);
01393                                 } else {
01394                                         sclist->scalars=NULL;
01395                                 }                                       
01396                                 pptrs[j]=sclist;
01397                                 protoparams = params->count;
01398                                 term=1;
01399                                 
01400                                 DEBUG_DUMP_SCALARLIST(params, "param %d: varargs=", j);
01401                                 break;
01402                         }                                                               
01403                         default:
01404                                 set_eval_error("internal error (%s:%d)", __FILE__, __LINE__);
01405                                 return 0;
01406                 }
01407                 if (term) break;
01408         }
01409         if (params->count == protoparams) {
01410                 DEBUG_DUMP_INDENT_IN;
01411                 retv=((int(*)(eval_scalar*,void*,void*,void*,void*,void*,void*,void*,void*))proto->func)(r, pptrs[0], pptrs[1], pptrs[2], pptrs[3], pptrs[4], pptrs[5], pptrs[6], pptrs[7]);
01412                 DEBUG_DUMP_INDENT_OUT;
01413         } else {
01414                 retv=0;
01415         }               
01416         if (retv) {
01417                 DEBUG_DUMP_SCALAR(r, "returns ");
01418         } else {
01419                 DEBUG_DUMP("fails...");
01420         }
01421 
01422         if (sclist) {   
01423                 scalarlist_destroy_gentle(sclist);
01424                 free(sclist);
01425         }               
01426         
01427         for (j=0; j<MAX_EVALFUNC_PARAMS; j++) {
01428                 if (sc[j].type!=SCALAR_NULL) {
01429                         scalar_destroy(&sc[j]);
01430                 }
01431         }
01432         
01433         if (!get_eval_error(NULL, NULL) && !retv) {
01434                 set_eval_error("?");
01435         }
01436         
01437         if (get_eval_error(&errmsg, &errpos)) {
01438                 char ee[MAX_ERRSTR_LEN+1];
01439                 ee[MAX_ERRSTR_LEN]=0;
01440                 strncpy(ee, proto->name, sizeof ee);
01441                 strncat(ee, "(): ", sizeof ee);
01442                 strncat(ee, errmsg, sizeof ee);
01443                 set_eval_error_ex(errpos, "%s", ee);
01444         }
01445         return retv;
01446 }
01447 
01448 int evalsymbol(eval_scalar *r, char *sname)
01449 {
01450         int s=0;
01451         if (g_eval_symbol_handler) s = g_eval_symbol_handler(r, sname);
01452         if (!get_eval_error(NULL, NULL) && !s) {
01453                 char sname_short[MAX_SYMBOLNAME_LEN+1];
01454                 sname_short[MAX_SYMBOLNAME_LEN]=0;
01455                 strncpy(sname_short, sname, MAX_SYMBOLNAME_LEN);
01456                 set_eval_error("unknown symbol: %s", sname_short);
01457         }
01458         return s;
01459 }
01460 
01461 static void proto_dump(char *buf, int bufsize, eval_func *proto, int full, const char *separator)
01462 {
01463 // FIXME: buffer safety/possible buffer overflow
01464         strcpy(buf, proto->name);
01465         int term = 0;
01466         strcat(buf, "(");
01467         for (int j=0; j<MAX_EVALFUNC_PARAMS; j++) {
01468                 if (proto->ptype[j]==SCALAR_NULL) break;
01469                 if (j) strcat(buf, ", ");
01470                 switch (proto->ptype[j]) {
01471                         case SCALAR_INT:
01472                                 strcat(buf, "INT");
01473                                 break;
01474                         case SCALAR_STR:
01475                                 strcat(buf, "STRING");
01476                                 break;
01477                         case SCALAR_FLOAT:
01478                                 strcat(buf, "FLOAT");
01479                                 break;
01480                         case SCALAR_ANY:
01481                                 strcat(buf, "ANY");
01482                                 break;
01483                         case SCALAR_VARARGS:
01484                                 strcat(buf, "...");
01485                                 term = 1;
01486                                 break;
01487                         default:
01488                                 break;
01489                 }
01490                 if (term) break;
01491         }
01492         strcat(buf, ")");
01493         if (full && proto->desc) {
01494                 strcat(buf, separator);
01495                 strcat(buf, proto->desc);
01496         }
01497 }
01498 
01499 int std_eval_func_handler(eval_scalar *result, char *fname, eval_scalarlist *params, eval_func *protos)
01500 {
01501         if (strlen(fname) > MAX_FUNCNAME_LEN) {
01502                 set_eval_error("invalid function, function name too long");
01503                 return 0;
01504         }
01505         
01506         if (helpmode) {
01507                 while (protos->name) {
01508                         char buf[256];
01509                         if ((!*helpname) || (*helpname && (strcmp(helpname, protos->name)==0))) {
01510                                 proto_dump(buf, sizeof buf, protos, 1, "\n");
01511                                 strcat(buf, "\n\n");
01512                                 eval_scalar s;
01513                                 scalar_create_str_c(&s, buf);
01514                                 eval_scalar r;
01515                                 scalar_concat(&r, &helpstring, &s);
01516                                 scalar_destroy(&helpstring);
01517                                 helpstring = r;
01518                         }
01519 
01520                         protos++;
01521                 }
01522         } else {
01523                 while (protos->name) {
01524                         switch (match_evalfunc_proto(fname, params, protos)) {
01525                                 case PROTOMATCH_OK:
01526                                         return exec_evalfunc(result, params, protos);
01527                                 case PROTOMATCH_PARAM_FAIL: {
01528                                         char b[256];
01529                                         proto_dump(b, sizeof b, protos, 0, "");
01530                                         set_eval_error("invalid params to function %s, declaration is: %s", protos->name, b);
01531                                         return 0;
01532                                 }
01533                                 default: {}
01534                         }
01535                         protos++;
01536                 }
01537         }
01538         return 0;
01539 }
01540 
01541 int evalfunc(eval_scalar *r, char *fname, eval_scalarlist *params)
01542 {
01543         if (strlen(fname) > MAX_FUNCNAME_LEN) {
01544                 set_eval_error("invalid function, function name too long");
01545                 return 0;
01546         }
01547         
01548         int s;
01549         if (g_eval_func_handler) {
01550                 s = g_eval_func_handler(r, fname, params);
01551                 if (get_eval_error(NULL, NULL)) return 0;
01552                 if (s) return s;
01553         }
01554         
01555         s = std_eval_func_handler(r, fname, params, builtin_evalfuncs);
01556         if (get_eval_error(NULL, NULL)) return 0;
01557         if (s) return s;
01558         
01559         if (!helpmode) {
01560                 set_eval_error("unknown function %s", fname);
01561                 return 0;
01562         } else return 1;
01563 }
01564 
01565 void *eval_get_context()
01566 {
01567         return eval_context;
01568 }
01569 
01570 void eval_set_context(void *context)
01571 {
01572         eval_context = context;
01573 }
01574 
01575 void eval_set_func_handler(eval_func_handler func_handler)
01576 {
01577         g_eval_func_handler = func_handler;
01578 }
01579 
01580 void eval_set_symbol_handler(eval_symbol_handler symbol_handler)
01581 {
01582         g_eval_symbol_handler = symbol_handler;
01583 }
01584 

Generated on Fri May 7 21:15:30 2004 by doxygen 1.3.5