1 /*
2  *	HT Editor
3  *	eval.cc
4  *
5  *	Copyright (C) 1999, 2000, 2001 Stefan Weyergraf
6  *
7  *	This program is free software; you can redistribute it and/or modify
8  *	it under the terms of the GNU General Public License version 2 as
9  *	published by the Free Software Foundation.
10  *
11  *	This program is distributed in the hope that it will be useful,
12  *	but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *	GNU General Public License for more details.
15  *
16  *	You should have received a copy of the GNU General Public License
17  *	along with this program; if not, write to the Free Software
18  *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */
20 
21 #include "evaltype.h"
22 #include "evalparse.h"
23 #include "eval.h"
24 #include "snprintf.h"
25 #include "strtools.h"
26 
27 #ifdef EVAL_DEBUG
28 
29 int debug_dump_ident;
30 
31 #endif
32 
33 #define MIN(a, b) ((a) < (b) ? (a) : (b))
34 #define MAX(a, b) ((a) > (b) ? (a) : (b))
35 
36 /*
37  *
38  */
39 
40 static eval_func_handler g_eval_func_handler;
41 static eval_symbol_handler g_eval_symbol_handler;
42 static void *eval_context;
43 static int helpmode = 0;
44 static eval_scalar helpstring;
45 static char helpname[MAX_FUNCNAME_LEN+1];
46 
f2i(double f)47 uint64 f2i(double f)
48 {
49 	uint64 r;
50 	if (f>0) r = (sint64)(f+.5); else r = (sint64)(f-.5);
51 	return r;
52 }
53 
set_helpmode(int flag,char * name)54 void set_helpmode(int flag, char *name)
55 {
56 	helpmode = flag;
57 	int l = name ? strlen(name) : (MAX_FUNCNAME_LEN+1);
58 	if (l>MAX_FUNCNAME_LEN) {
59 		*helpname = 0;
60 		return;
61 	}
62 	strcpy(helpname, name);
63 }
64 
ipow(uint64 a,uint64 b)65 static uint64 ipow(uint64 a, uint64 b)
66 {
67 	uint64 r = 1ULL;
68 	uint64 m = 1ULL << 63;
69 	while (m != 0) {
70 		r *= r;
71 		if ((b & m) != 0) {
72 			r *= a;
73 		}
74 		m = m >> 1;
75 	}
76 	return r;
77 }
78 
79 /*
80 static int sprint_basen(char *buffer, int base, uint64 q)
81 {
82 	static char *chars="0123456789abcdef";
83 	if ((base<2) || (base>16)) return 0;
84 	int n = 0;
85 	char *b = buffer;
86 	while (q != to_qword(0)) {
87 		int c = QWORD_GET_INT(q % to_qword(base));
88 		*buffer++ = chars[c];
89 		n++;
90 		q /= to_qword(base);
91 	}
92 	for (int i=0; i < n/2; i++) {
93 		char t = b[i];
94 		b[i] = b[n-i-1];
95 		b[n-i-1] = t;
96 	}
97 	b[n] = 0;
98 	return n;
99 }
100 */
101 
str2int(char * str,uint64 * q,int base)102 static void str2int(char *str, uint64 *q, int base)
103 {
104 	*q = 0;
105 	uint64 qbase = base;
106 	while (*str) {
107 		int c = hexdigit(*str);
108 		if ((c == -1) || (c >= base)) break;
109 		*q *= qbase;
110 		*q += c;
111 		str++;
112 	}
113 }
114 
binstr2cstr(char * s,int len)115 char *binstr2cstr(char *s, int len)
116 {
117 	char *x = ht_malloc(len+1);
118 	memcpy(x, s, len);
119 	x[len]=0;
120 	return x;
121 }
122 
bin2str(char * result,void * S,int len)123 int bin2str(char *result, void *S, int len)
124 {
125 	unsigned char *s = (unsigned char*)S;
126 	while (len--) {
127 		if (*s==0) *result=' '; else *result=*s;
128 		result++;
129 		s++;
130 	}
131 	*result=0;
132 	return len;
133 }
134 
135 /*
136  *	ERROR HANDLING
137  */
138 
139 static int eval_error;
140 static int eval_error_pos;
141 static char eval_errstr[MAX_ERRSTR_LEN];
142 
clear_eval_error()143 void clear_eval_error()
144 {
145 	eval_error=0;
146 }
147 
get_eval_error(const char ** str,int * pos)148 int get_eval_error(const char **str, int *pos)
149 {
150 	if (eval_error) {
151 		if (str) *str = eval_errstr;
152 		if (pos) *pos = eval_error_pos;
153 		return eval_error;
154 	}
155 	if (str) *str = "?";
156 	if (pos) *pos = 0;
157 	return 0;
158 }
159 
set_eval_error(const char * format,...)160 void set_eval_error(const char *format,...)
161 {
162 	va_list vargs;
163 
164 	va_start(vargs, format);
165 	ht_vsnprintf(eval_errstr, sizeof eval_errstr, format, vargs);
166 	va_end(vargs);
167 	eval_error_pos = lex_current_buffer_pos();
168 	eval_error = 1;
169 }
170 
set_eval_error_ex(int pos,const char * format,...)171 void set_eval_error_ex(int pos, const char *format, ...)
172 {
173 	va_list vargs;
174 
175 	va_start(vargs, format);
176 	ht_vsnprintf(eval_errstr, sizeof eval_errstr, format, vargs);
177 	va_end(vargs);
178 	eval_error_pos = pos;
179 	eval_error = 1;
180 }
181 
182 /*
183  *
184  */
185 
186 #ifdef EVAL_DEBUG
187 
integer_dump(eval_int * i)188 void integer_dump(eval_int *i)
189 {
190 	printf("%d", i->value);
191 }
192 
float_dump(eval_float * f)193 void float_dump(eval_float *f)
194 {
195 	printf("%f", f->value);
196 }
197 
string_dump(eval_str * s)198 void string_dump(eval_str *s)
199 {
200 	int i;
201 	for (i=0; i<s->len; i++) {
202 		if ((unsigned)s->value[i]<32) {
203 			printf("\\x%x", s->value[i]);
204 		} else {
205 			printf("%c", s->value[i]);
206 		}
207 	}
208 }
209 
210 #endif
211 
string_destroy(eval_str * s)212 void string_destroy(eval_str *s)
213 {
214 	if (s->value) free(s->value);
215 }
216 
217 /*
218  *	SCALARLIST
219  */
220 
scalarlist_set(eval_scalarlist * l,eval_scalar * s)221 void scalarlist_set(eval_scalarlist *l, eval_scalar *s)
222 {
223 	l->count = 1;
224 	l->scalars = ht_malloc(sizeof (eval_scalar) * l->count);
225 	l->scalars[0] = *s;
226 }
227 
scalarlist_concat(eval_scalarlist * l,eval_scalarlist * a,eval_scalarlist * b)228 void scalarlist_concat(eval_scalarlist *l, eval_scalarlist *a, eval_scalarlist *b)
229 {
230 	l->count = a->count+b->count;
231 	l->scalars = ht_malloc(sizeof (eval_scalar) * l->count);
232 	memcpy(l->scalars, a->scalars, sizeof (eval_scalar) * a->count);
233 	memcpy(l->scalars + a->count, b->scalars, sizeof (eval_scalar) * b->count);
234 }
235 
scalarlist_destroy(eval_scalarlist * l)236 void scalarlist_destroy(eval_scalarlist *l)
237 {
238 	int i;
239 	if (l && l->scalars) {
240 		for (i=0; i < l->count; i++) {
241 			scalar_destroy(&l->scalars[i]);
242 		}
243 		free(l->scalars);
244 	}
245 }
246 
scalarlist_destroy_gentle(eval_scalarlist * l)247 void scalarlist_destroy_gentle(eval_scalarlist *l)
248 {
249 	if (l && l->scalars) free(l->scalars);
250 }
251 
252 #ifdef EVAL_DEBUG
253 
scalarlist_dump(eval_scalarlist * l)254 void scalarlist_dump(eval_scalarlist *l)
255 {
256 	int i;
257 	for (i=0; i<l->count; i++) {
258 		scalar_dump(&l->scalars[i]);
259 		if (i!=l->count-1) {
260 			printf(", ");
261 		}
262 	}
263 }
264 
265 #endif
266 
267 /*
268  *	SCALAR
269  */
270 
scalar_setint(eval_scalar * s,eval_int * i)271 void scalar_setint(eval_scalar *s, eval_int *i)
272 {
273 	s->type=SCALAR_INT;
274 	s->scalar.integer=*i;
275 }
276 
scalar_setstr(eval_scalar * s,eval_str * t)277 void scalar_setstr(eval_scalar *s, eval_str *t)
278 {
279 	s->type=SCALAR_STR;
280 	s->scalar.str=*t;
281 }
282 
283 #ifdef EVAL_DEBUG
284 
scalar_dump(eval_scalar * s)285 void scalar_dump(eval_scalar *s)
286 {
287 	switch (s->type) {
288 		case SCALAR_STR: {
289 			string_dump(&s->scalar.str);
290 			break;
291 		}
292 		case SCALAR_INT: {
293 			integer_dump(&s->scalar.integer);
294 			break;
295 		}
296 		case SCALAR_FLOAT: {
297 			float_dump(&s->scalar.floatnum);
298 			break;
299 		}
300 		default:
301 			break;
302 	}
303 }
304 
305 #endif
306 
scalar_create_int(eval_scalar * s,const eval_int * t)307 void scalar_create_int(eval_scalar *s, const eval_int *t)
308 {
309 	s->type = SCALAR_INT;
310 	s->scalar.integer=*t;
311 }
312 
scalar_create_int_c(eval_scalar * s,const int i)313 void scalar_create_int_c(eval_scalar *s, const int i)
314 {
315 	s->type = SCALAR_INT;
316 	s->scalar.integer.value = (sint64)i;
317 	s->scalar.integer.type = TYPE_UNKNOWN;
318 }
319 
scalar_create_int_q(eval_scalar * s,const uint64 q)320 void scalar_create_int_q(eval_scalar *s, const uint64 q)
321 {
322 	s->type = SCALAR_INT;
323 	s->scalar.integer.value = q;
324 	s->scalar.integer.type = TYPE_UNKNOWN;
325 }
326 
scalar_create_str(eval_scalar * s,const eval_str * t)327 void scalar_create_str(eval_scalar *s, const eval_str *t)
328 {
329 	s->type = SCALAR_STR;
330 	s->scalar.str.value = ht_malloc(t->len ? t->len : 1);
331 	memcpy(s->scalar.str.value, t->value, t->len);
332 	s->scalar.str.len = t->len;
333 }
334 
scalar_create_str_c(eval_scalar * s,const char * cstr)335 void scalar_create_str_c(eval_scalar *s, const char *cstr)
336 {
337 	eval_str t;
338 	t.value = (char*)cstr;
339 	t.len = strlen(cstr);
340 	scalar_create_str(s, &t);
341 }
342 
scalar_create_float(eval_scalar * s,const eval_float * t)343 void scalar_create_float(eval_scalar *s, const eval_float *t)
344 {
345 	s->type=SCALAR_FLOAT;
346 	s->scalar.floatnum=*t;
347 }
348 
scalar_create_float_c(eval_scalar * s,const double f)349 void scalar_create_float_c(eval_scalar *s, const double f)
350 {
351 	s->type=SCALAR_FLOAT;
352 	s->scalar.floatnum.value=f;
353 }
354 
scalar_context_str(const eval_scalar * s,eval_str * t)355 void scalar_context_str(const eval_scalar *s, eval_str *t)
356 {
357 	switch (s->type) {
358 		case SCALAR_INT: {
359 			char buf[64];
360 			ht_snprintf(buf, sizeof buf, "%qd",
361 				/* FIXME: by reference*/ &s->scalar.integer.value);
362 			t->value = (char*)strdup(buf);
363 			t->len = strlen(buf);
364 			break;
365 		}
366 		case SCALAR_STR: {
367 			t->value = ht_malloc(s->scalar.str.len ? s->scalar.str.len : 1);
368 			t->len = s->scalar.str.len;
369 			memcpy(t->value, s->scalar.str.value, t->len);
370 			break;
371 		}
372 		case SCALAR_FLOAT: {
373 			char buf[64];
374 			ht_snprintf(buf, sizeof buf, "%f", s->scalar.floatnum.value);
375 			t->value = (char*)strdup(buf);
376 			t->len = strlen(buf);
377 			break;
378 		}
379 		default:
380 			break;
381 	}
382 }
383 
scalar_context_int(const eval_scalar * s,eval_int * t)384 void scalar_context_int(const eval_scalar *s, eval_int *t)
385 {
386 	switch (s->type) {
387 		case SCALAR_INT: {
388 			*t=s->scalar.integer;
389 			break;
390 		}
391 		case SCALAR_STR: {
392 			char *x = binstr2cstr(s->scalar.str.value, s->scalar.str.len);
393 			str2int(x, &t->value, 10);
394 			t->type = TYPE_UNKNOWN;
395 			free(x);
396 			break;
397 		}
398 		case SCALAR_FLOAT: {
399 			t->value=f2i(s->scalar.floatnum.value);
400 			t->type=TYPE_UNKNOWN;
401 			break;
402 		}
403 		default:
404 			break;
405 	}
406 }
407 
scalar_context_float(const eval_scalar * s,eval_float * t)408 void scalar_context_float(const eval_scalar *s, eval_float *t)
409 {
410 	switch (s->type) {
411 	case SCALAR_INT:
412 		t->value = s->scalar.integer.value;
413 		break;
414 	case SCALAR_STR:  {
415 		char *x = binstr2cstr(s->scalar.str.value, s->scalar.str.len);
416 		t->value = strtod(x, (char**)NULL);
417 		free(x);
418 		break;
419 	}
420 	case SCALAR_FLOAT:
421 		*t = s->scalar.floatnum;
422 		break;
423 	default:
424 		break;
425 	}
426 }
427 
string_concat(eval_str * s,eval_str * a,eval_str * b)428 void string_concat(eval_str *s, eval_str *a, eval_str *b)
429 {
430 	s->value = ht_malloc(a->len+b->len ? a->len+b->len : 1);
431 	memcpy(s->value, a->value, a->len);
432 	memcpy(s->value + a->len, b->value, b->len);
433 	s->len = a->len+b->len;
434 
435 	free(a->value);
436 	a->len = 0;
437 	free(b->value);
438 	b->len = 0;
439 }
440 
scalar_clone(eval_scalar * result,const eval_scalar * s)441 void scalar_clone(eval_scalar *result, const eval_scalar *s)
442 {
443 	switch (s->type) {
444 	case SCALAR_INT: {
445 		*result = *s;
446 		break;
447 	}
448 	case SCALAR_STR:  {
449 		*result = *s;
450 		result->scalar.str.value = ht_malloc(result->scalar.str.len);
451 		memcpy(result->scalar.str.value, s->scalar.str.value, result->scalar.str.len);
452 		break;
453 	}
454 	case SCALAR_FLOAT: {
455 		*result = *s;
456 		break;
457 	}
458 	default:
459 		break;
460 	}
461 }
462 
scalar_concat(eval_scalar * s,const eval_scalar * a,const eval_scalar * b)463 void scalar_concat(eval_scalar *s, const eval_scalar *a, const eval_scalar *b)
464 {
465 	eval_str as, bs, rs;
466 	scalar_context_str(a, &as);
467 	scalar_context_str(b, &bs);
468 	string_concat(&rs, &as, &bs);
469 	s->type=SCALAR_STR;
470 	s->scalar.str=rs;
471 }
472 
scalar_destroy(eval_scalar * s)473 void scalar_destroy(eval_scalar *s)
474 {
475 	switch (s->type) {
476 		case SCALAR_STR:
477 			string_destroy(&s->scalar.str);
478 			break;
479 		default:
480 			break;
481 	}
482 }
483 
string_compare(const eval_str * a,const eval_str * b)484 int string_compare(const eval_str *a, const eval_str *b)
485 {
486 	if (a->len==b->len) {
487 		return memcmp(a->value, b->value, a->len);
488 	}
489 	return a->len-b->len;
490 }
491 
scalar_strop(eval_scalar * xr,const eval_scalar * xa,const eval_scalar * xb,int op)492 int scalar_strop(eval_scalar *xr, const eval_scalar *xa, const eval_scalar *xb, int op)
493 {
494 	eval_str as, bs;
495 	int r;
496 	int c;
497 	scalar_context_str(xa, &as);
498 	scalar_context_str(xb, &bs);
499 
500 	c = string_compare(&as, &bs);
501 
502 	switch (op) {
503 	case EVAL_STR_EQ: r=(c==0); break;
504 	case EVAL_STR_NE: r=(c!=0); break;
505 	case EVAL_STR_GT: r=(c>0); break;
506 	case EVAL_STR_GE: r=(c>=0); break;
507 	case EVAL_STR_LT: r=(c<0); break;
508 	case EVAL_STR_LE: r=(c>=0); break;
509 	default:
510 		return 0;
511 	}
512 	xr->type = SCALAR_INT;
513 	xr->scalar.integer.value = r;
514 	xr->scalar.integer.type = TYPE_UNKNOWN;
515 	return 1;
516 }
517 
scalar_float_op(eval_scalar * xr,const eval_scalar * xa,const eval_scalar * xb,int op)518 int scalar_float_op(eval_scalar *xr, const eval_scalar *xa, const eval_scalar *xb, int op)
519 {
520 	eval_float ai, bi;
521 	float a, b, r;
522 	scalar_context_float(xa, &ai);
523 	scalar_context_float(xb, &bi);
524 
525 	a = ai.value;
526 	b = bi.value;
527 	switch (op) {
528 		case '*': r = a*b; break;
529 		case '/': {
530 		    if (!b) {
531 			    set_eval_error("division by zero");
532 			    return 0;
533 		    }
534 		    r = a/b;
535 		    break;
536 		}
537 		case '+': r = a+b; break;
538 		case '-': r = a-b; break;
539 		case EVAL_POW: r = pow(a,b); break;
540 		default: {
541 			uint64 ri;
542 			switch (op) {
543 				case EVAL_EQ: ri = a==b; break;
544 				case EVAL_NE: ri = a!=b; break;
545 				case EVAL_GT: ri = a>b; break;
546 				case EVAL_GE: ri = a>=b; break;
547 				case EVAL_LT: ri = a<b; break;
548 				case EVAL_LE: ri = a<=b; break;
549 				case EVAL_LAND: ri = a && b; break;
550 				case EVAL_LXOR: ri = !a != !b; break;
551 				case EVAL_LOR: ri = a || b ; break;
552 				default:
553 					set_eval_error("invalid operator");
554 					return 0;
555 			}
556 			xr->type = SCALAR_INT;
557 			xr->scalar.integer.value = ri;
558 			xr->scalar.integer.type = TYPE_UNKNOWN;
559 			return 1;
560 		}
561 	}
562 	xr->type = SCALAR_FLOAT;
563 	xr->scalar.floatnum.value = r;
564 	return 1;
565 }
566 
scalar_int_op(eval_scalar * xr,const eval_scalar * xa,const eval_scalar * xb,int op)567 int scalar_int_op(eval_scalar *xr, const eval_scalar *xa, const eval_scalar *xb, int op)
568 {
569 	eval_int ai, bi;
570 	uint64 a, b, r;
571 	scalar_context_int(xa, &ai);
572 	scalar_context_int(xb, &bi);
573 
574 	a = ai.value;
575 	b = bi.value;
576 	switch (op) {
577 		case '*': r = a*b; break;
578 		case '/': {
579 		    if (!b) {
580 			    set_eval_error("division by zero");
581 			    return 0;
582 		    }
583 		    r = a/b;
584 		    break;
585 		}
586 		case '%': {
587 		    if (!b) {
588 			    set_eval_error("division by zero");
589 			    return 0;
590 		    }
591 		    r = a%b;
592 		    break;
593 		}
594 		case '+': r=a+b; break;
595 		case '-': r=a-b; break;
596 		case '&': r=a&b; break;
597 		case '|': r=a|b; break;
598 		case '^': r=a^b; break;
599 		// FIXME
600 		case EVAL_POW: r = ipow(a, b); break;
601 //		case EVAL_POW: r = to_qword((int)pow(QWORD_GET_INT(a),QWORD_GET_INT(b))); break;
602 		case EVAL_SHL: r = a << b; break;
603 		case EVAL_SHR: r = a >> b; break;
604 		case EVAL_EQ: r = a==b; break;
605 		case EVAL_NE: r = a!=b; break;
606 		case EVAL_GT: r = a>b; break;
607 		case EVAL_GE: r = a>=b; break;
608 		case EVAL_LT: r = a<b; break;
609 		case EVAL_LE: r = a<=b; break;
610 		case EVAL_LAND: r = a && b; break;
611 		case EVAL_LXOR: r = !a != !b; break;
612 		case EVAL_LOR: r = a || b; break;
613 		default:
614 			set_eval_error("invalid operator");
615 			return 0;
616 	}
617 	xr->type = SCALAR_INT;
618 	xr->scalar.integer.value = r;
619 	xr->scalar.integer.type = TYPE_UNKNOWN;
620 	return 1;
621 }
622 
scalar_op(eval_scalar * xr,eval_scalar * xa,eval_scalar * xb,int op)623 int scalar_op(eval_scalar *xr, eval_scalar *xa, eval_scalar *xb, int op)
624 {
625 	int r;
626 	if ((xa->type==SCALAR_FLOAT) || (xb->type==SCALAR_FLOAT)) {
627 		r=scalar_float_op(xr, xa, xb, op);
628 	} else {
629 		r=scalar_int_op(xr, xa, xb, op);
630 	}
631 	scalar_destroy(xa);
632 	scalar_destroy(xb);
633 	return r;
634 }
635 
scalar_negset(eval_scalar * xr,eval_scalar * xa)636 void scalar_negset(eval_scalar *xr, eval_scalar *xa)
637 {
638 	if (xa->type==SCALAR_FLOAT) {
639 		eval_float a;
640 		a=xa->scalar.floatnum;
641 
642 		xr->type=SCALAR_FLOAT;
643 		xr->scalar.floatnum.value=-a.value;
644 	} else {
645 		eval_int a;
646 		scalar_context_int(xa, &a);
647 
648 		xr->type=SCALAR_INT;
649 		xr->scalar.integer.value=-a.value;
650 		xr->scalar.integer.type=TYPE_UNKNOWN;
651 	}
652 	scalar_destroy(xa);
653 }
654 
scalar_notset(eval_scalar * xr,eval_scalar * xa)655 void scalar_notset(eval_scalar *xr, eval_scalar *xa)
656 {
657 	eval_int a;
658 	scalar_context_int(xa, &a);
659 
660 	xr->type=SCALAR_INT;
661 	xr->scalar.integer.value=~a.value;
662 	xr->scalar.integer.type=TYPE_UNKNOWN;
663 
664 	scalar_destroy(xa);
665 }
666 
scalar_lnotset(eval_scalar * xr,eval_scalar * xa)667 void scalar_lnotset(eval_scalar *xr, eval_scalar *xa)
668 {
669 	eval_int a;
670 	scalar_context_int(xa, &a);
671 
672 	xr->type = SCALAR_INT;
673 	xr->scalar.integer.value = !a.value;
674 	xr->scalar.integer.type = TYPE_UNKNOWN;
675 
676 	scalar_destroy(xa);
677 }
678 
scalar_miniif(eval_scalar * xr,eval_scalar * xa,eval_scalar * xb,eval_scalar * xc)679 void scalar_miniif(eval_scalar *xr, eval_scalar *xa, eval_scalar *xb, eval_scalar *xc)
680 {
681 	eval_int a;
682 	scalar_context_int(xa, &a);
683 	if (a.value != 0) {
684 		*xr = *xb;
685 	} else {
686 		*xr = *xc;
687 	}
688 	scalar_destroy(xa);
689 }
690 
691 /*
692  *	BUILTIN FUNCTIONS
693  */
694 
func_typeof(eval_scalar * r,eval_scalar * s)695 int func_typeof(eval_scalar *r, eval_scalar *s)
696 {
697 	switch (s->type) {
698 		case SCALAR_INT:
699 			scalar_create_str_c(r, "int");
700 			break;
701 		case SCALAR_STR:
702 			scalar_create_str_c(r, "string");
703 			break;
704 		case SCALAR_FLOAT:
705 			scalar_create_str_c(r, "float");
706 			break;
707 		default:
708 // FIXME: should never happen
709 			scalar_create_str_c(r, "unknown");
710 			break;
711 	}
712 	return 1;
713 }
714 
func_is_int(eval_scalar * r,eval_scalar * s)715 int func_is_int(eval_scalar *r, eval_scalar *s)
716 {
717 	if (s->type == SCALAR_INT) {
718 		scalar_create_int_c(r, 1);
719 	} else {
720 		scalar_create_int_c(r, 0);
721 	}
722 	return 1;
723 }
724 
func_is_string(eval_scalar * r,eval_scalar * s)725 int func_is_string(eval_scalar *r, eval_scalar *s)
726 {
727 	if (s->type == SCALAR_STR) {
728 		scalar_create_int_c(r, 1);
729 	} else {
730 		scalar_create_int_c(r, 0);
731 	}
732 	return 1;
733 }
734 
func_is_float(eval_scalar * r,eval_scalar * s)735 int func_is_float(eval_scalar *r, eval_scalar *s)
736 {
737 	if (s->type == SCALAR_FLOAT) {
738 		scalar_create_int_c(r, 1);
739 	} else {
740 		scalar_create_int_c(r, 0);
741 	}
742 	return 1;
743 }
744 
func_char(eval_scalar * r,eval_int * i)745 int func_char(eval_scalar *r, eval_int *i)
746 {
747 	eval_str s;
748 	char c = i->value;
749 	s.value = &c;
750 	s.len = 1;
751 	scalar_create_str(r, &s);
752 	return 1;
753 }
754 
func_byte(eval_scalar * r,eval_int * i)755 int func_byte(eval_scalar *r, eval_int *i)
756 {
757 	uint c = i->value;
758 	scalar_create_int_c(r, c & 0xff);
759 	return 1;
760 }
761 
func_word(eval_scalar * r,eval_int * i)762 int func_word(eval_scalar *r, eval_int *i)
763 {
764 	uint c = i->value;
765 	scalar_create_int_c(r, c & 0xffff);
766 	return 1;
767 }
768 
func_dword(eval_scalar * r,eval_int * i)769 int func_dword(eval_scalar *r, eval_int *i)
770 {
771 	uint c = i->value;
772 	scalar_create_int_q(r, c & 0xffffffff);
773 	return 1;
774 }
775 
func_sbyte(eval_scalar * r,eval_int * i)776 int func_sbyte(eval_scalar *r, eval_int *i)
777 {
778 	uint c = i->value;
779 	scalar_create_int_c(r, (signed char)c);
780 	return 1;
781 }
782 
func_short(eval_scalar * r,eval_int * i)783 int func_short(eval_scalar *r, eval_int *i)
784 {
785 	uint c = i->value;
786 	scalar_create_int_c(r, (short)c);
787 	return 1;
788 }
789 
func_long(eval_scalar * r,eval_int * i)790 int func_long(eval_scalar *r, eval_int *i)
791 {
792 	int c = i->value;
793 	scalar_create_int_c(r, c);
794 	return 1;
795 }
796 
func_float(eval_scalar * r,eval_float * p)797 int func_float(eval_scalar *r, eval_float *p)
798 {
799 	scalar_create_float(r, p);
800 	return 1;
801 }
802 
func_fmax(eval_scalar * r,eval_float * p1,eval_float * p2)803 int func_fmax(eval_scalar *r, eval_float *p1, eval_float *p2)
804 {
805 	r->type=SCALAR_FLOAT;
806 	r->scalar.floatnum.value=(p1->value>p2->value) ? p1->value : p2->value;
807 	return 1;
808 }
809 
func_fmin(eval_scalar * r,eval_float * p1,eval_float * p2)810 int func_fmin(eval_scalar *r, eval_float *p1, eval_float *p2)
811 {
812 	r->type=SCALAR_FLOAT;
813 	r->scalar.floatnum.value=(p1->value<p2->value) ? p1->value : p2->value;
814 	return 1;
815 }
816 
func_int(eval_scalar * r,eval_int * p)817 int func_int(eval_scalar *r, eval_int *p)
818 {
819 	scalar_create_int(r, p);
820 	return 1;
821 }
822 
func_ord(eval_scalar * r,eval_str * s)823 int func_ord(eval_scalar *r, eval_str *s)
824 {
825 	if (s->len>=1) {
826 		scalar_create_int_c(r, s->value[0]);
827 		return 1;
828 	}
829 	set_eval_error("string must at least contain one character");
830 	return 0;
831 }
832 
func_max(eval_scalar * r,eval_int * p1,eval_int * p2)833 int func_max(eval_scalar *r, eval_int *p1, eval_int *p2)
834 {
835 	scalar_create_int(r, (p1->value>p2->value) ? p1 : p2);
836 	return 1;
837 }
838 
func_min(eval_scalar * r,eval_int * p1,eval_int * p2)839 int func_min(eval_scalar *r, eval_int *p1, eval_int *p2)
840 {
841 	scalar_create_int(r, (p1->value<p2->value) ? p1 : p2);
842 	return 1;
843 }
844 
func_random(eval_scalar * r,eval_int * p1)845 int func_random(eval_scalar *r, eval_int *p1)
846 {
847 	uint64 d = rand();
848 	scalar_create_int_q(r, (p1->value != 0) ? (d % p1->value):0);
849 	return 1;
850 }
851 
func_rnd(eval_scalar * r)852 int func_rnd(eval_scalar *r)
853 {
854 	scalar_create_int_c(r, rand() % 2);
855 	return 1;
856 }
857 
func_round(eval_scalar * r,eval_float * p)858 int func_round(eval_scalar *r, eval_float *p)
859 {
860 	r->type=SCALAR_INT;
861 	r->scalar.integer.value=f2i(p->value+0.5);
862 	r->scalar.integer.type=TYPE_UNKNOWN;
863 	return 1;
864 }
865 
func_strchr(eval_scalar * r,eval_str * p1,eval_str * p2)866 int func_strchr(eval_scalar *r, eval_str *p1, eval_str *p2)
867 {
868 	if (p2->len) {
869 		if (p1->len) {
870 			char *pos = (char *)memchr(p1->value, *p2->value, p1->len);
871 			if (pos) {
872 				scalar_create_int_c(r, pos-p1->value);
873 			} else {
874 				scalar_create_int_c(r, -1);
875 			}
876 		} else {
877 			scalar_create_int_c(r, -1);
878 		}
879 		return 1;
880 	} else {
881 		return 0;
882 	}
883 }
884 
func_strcmp(eval_scalar * r,eval_str * p1,eval_str * p2)885 int func_strcmp(eval_scalar *r, eval_str *p1, eval_str *p2)
886 {
887 	int r2=memcmp(p1->value, p2->value, MIN(p1->len, p2->len));
888 	if (r2) {
889 		scalar_create_int_c(r, r2);
890 	} else {
891 		if (p1->len > p2->len) {
892 			scalar_create_int_c(r, 1);
893 		} else if (p1->len < p2->len) {
894 			scalar_create_int_c(r, -1);
895 		} else {
896 			scalar_create_int_c(r, 0);
897 		}
898 	}
899 	return 1;
900 }
901 
func_string(eval_scalar * r,eval_str * p)902 int func_string(eval_scalar *r, eval_str *p)
903 {
904 	scalar_create_str(r, p);
905 	return 1;
906 }
907 
func_strlen(eval_scalar * r,eval_str * p1)908 int func_strlen(eval_scalar *r, eval_str *p1)
909 {
910 	scalar_create_int_c(r, p1->len);
911 	return 1;
912 }
913 
func_strncmp(eval_scalar * r,eval_str * p1,eval_str * p2,eval_int * p3)914 int func_strncmp(eval_scalar *r, eval_str *p1, eval_str *p2, eval_int *p3)
915 {
916 	return 1;
917 }
918 
func_strrchr(eval_scalar * r,eval_str * p1,eval_str * p2)919 int func_strrchr(eval_scalar *r, eval_str *p1, eval_str *p2)
920 {
921 	return 1;
922 }
923 
func_strstr(eval_scalar * r,eval_str * p1,eval_str * p2)924 int func_strstr(eval_scalar *r, eval_str *p1, eval_str *p2)
925 {
926 
927 	return 1;
928 }
929 
func_substr(eval_scalar * r,eval_str * p1,eval_int * p2,eval_int * p3)930 int func_substr(eval_scalar *r, eval_str *p1, eval_int *p2, eval_int *p3)
931 {
932 	if (p2->value >= 0 && p3->value > 0) {
933 		if (p2->value < p1->len) {
934 			eval_str s;
935 			s.len = MIN(p3->value, p1->len - p2->value);
936 			s.value = &p1->value[p2->value];
937 			scalar_create_str(r, &s);
938 		} else {
939 			scalar_create_str_c(r, "");
940 		}
941 	} else {
942 		scalar_create_str_c(r, "");
943 	}
944 	return 1;
945 }
946 
func_trunc(eval_scalar * r,eval_float * p)947 int func_trunc(eval_scalar *r, eval_float *p)
948 {
949 	r->type=SCALAR_INT;
950 	r->scalar.integer.value=f2i(p->value);
951 	r->scalar.integer.type=TYPE_UNKNOWN;
952 	return 1;
953 }
954 
955 #define EVALFUNC_FMATH1(name) int func_##name(eval_scalar *r, eval_float *p)\
956 {\
957 	r->type=SCALAR_FLOAT;\
958 	r->scalar.floatnum.value=name(p->value);\
959 	return 1;\
960 }
961 
962 #define EVALFUNC_FMATH1i(name) int func_##name(eval_scalar *r, eval_float *p)\
963 {\
964 	r->type=SCALAR_INT;\
965 	r->scalar.integer.value=f2i(name(p->value));\
966 	r->scalar.integer.type=TYPE_UNKNOWN;\
967 	return 1;\
968 }
969 
970 #define EVALFUNC_FMATH2(name) int func_##name(eval_scalar *r, eval_float *p1, eval_float *p2)\
971 {\
972 	r->type=SCALAR_FLOAT;\
973 	r->scalar.floatnum.value=name(p1->value, p2->value);\
974 	return 1;\
975 }
976 
977 EVALFUNC_FMATH2(pow)
978 
EVALFUNC_FMATH1(sqrt)979 EVALFUNC_FMATH1(sqrt)
980 
981 EVALFUNC_FMATH1(exp)
982 EVALFUNC_FMATH1(log)
983 
984 EVALFUNC_FMATH1i(ceil)
985 EVALFUNC_FMATH1i(floor)
986 
987 EVALFUNC_FMATH1(sin)
988 EVALFUNC_FMATH1(cos)
989 EVALFUNC_FMATH1(tan)
990 
991 EVALFUNC_FMATH1(asin)
992 EVALFUNC_FMATH1(acos)
993 EVALFUNC_FMATH1(atan)
994 
995 EVALFUNC_FMATH1(sinh)
996 EVALFUNC_FMATH1(cosh)
997 EVALFUNC_FMATH1(tanh)
998 
999 #ifdef HAVE_ASINH
1000 EVALFUNC_FMATH1(asinh)
1001 #endif
1002 
1003 #ifdef HAVE_ACOSH
1004 EVALFUNC_FMATH1(acosh)
1005 #endif
1006 
1007 #ifdef HAVE_ATANH
1008 EVALFUNC_FMATH1(atanh)
1009 #endif
1010 
1011 void sprintf_puts(char **b, char *blimit, const char *buf)
1012 {
1013 	while (*b < blimit && *buf) {
1014 		**b = *(buf++);
1015 		(*b)++;
1016 	}
1017 }
1018 
sprintf_percent(char ** fmt,int * fmtl,char ** b,char * blimit,eval_scalar * s)1019 int sprintf_percent(char **fmt, int *fmtl, char **b, char *blimit, eval_scalar *s)
1020 {
1021 	char cfmt[32];
1022 	char buf[512];
1023 	int ci=1;
1024 	cfmt[0]='%';
1025 	while (*fmtl && ci < 32-1) {
1026 		cfmt[ci]=(*fmt)[0];
1027 		cfmt[ci+1]=0;
1028 		switch ((*fmt)[0]) {
1029 			case 'd':
1030 			case 'i':
1031 			case 'o':
1032 			case 'u':
1033 			case 'x':
1034 			case 'X':
1035 			case 'c': {
1036 				eval_int i;
1037 				scalar_context_int(s, &i);
1038 
1039 				ht_snprintf(buf, sizeof buf, cfmt, i.value);
1040 				sprintf_puts(b, blimit, buf);
1041 
1042 				return 1;
1043 			}
1044 			case 's': {
1045 				char *q=cfmt+1;
1046 				eval_str t;
1047 				scalar_context_str(s, &t);
1048 
1049 				while (*q!='s') {
1050 					if ((*q>='0') && (*q<='9')) {
1051 						unsigned int sl=strtol(q, NULL, 10);
1052 						if (sl>sizeof buf-1) sl=sizeof buf-1;
1053 						sprintf(q, "%ds", sl);
1054 						break;
1055 					} else {
1056 						switch (*q) {
1057 							case '+':
1058 							case '-':
1059 							case '#':
1060 							case ' ':
1061 								break;
1062 							default:
1063 							/* FIXME: invalid format */
1064 								break;
1065 						}
1066 					}
1067 					q++;
1068 				}
1069 
1070 				if ((unsigned int)t.len>sizeof buf-1) t.len=sizeof buf-1;
1071 				t.value[t.len]=0;
1072 
1073 				ht_snprintf(buf, sizeof buf, cfmt, t.value);
1074 
1075 				sprintf_puts(b, blimit, buf);
1076 
1077 				string_destroy(&t);
1078 				return 1;
1079 			}
1080 			case 'e':
1081 			case 'E':
1082 			case 'f':
1083 			case 'F':
1084 			case 'g':
1085 			case 'G': {
1086 				eval_float f;
1087 				scalar_context_float(s, &f);
1088 
1089 				ht_snprintf(buf, sizeof buf, cfmt, f.value);
1090 				sprintf_puts(b, blimit, buf);
1091 
1092 				return 1;
1093 			}
1094 			case '%':
1095 				sprintf_puts(b, blimit, "%");
1096 				return 1;
1097 		}
1098 		(*fmt)++;
1099 		(*fmtl)--;
1100 		ci++;
1101 	}
1102 	return 0;
1103 }
1104 
func_sprintf(eval_scalar * r,const eval_str * format,const eval_scalarlist * scalars)1105 int func_sprintf(eval_scalar *r, const eval_str *format, const eval_scalarlist *scalars)
1106 {
1107 	char buf[512];		/* FIXME: possible buffer overflow */
1108 	char *b=buf;
1109 	char *fmt;
1110 	int fmtl;
1111 	eval_scalar *s=scalars->scalars;
1112 
1113 	fmt=format->value;
1114 	fmtl=format->len;
1115 
1116 	while (fmtl) {
1117 		if (fmt[0]=='%') {
1118 			fmt++;
1119 			fmtl--;
1120 			if (!fmtl) break;
1121 			if (fmt[0]!='%') {
1122 				if (s-scalars->scalars >= scalars->count) {
1123 					DEBUG_DUMP("too few parameters");
1124 					return 0;
1125 				}
1126 				if (!sprintf_percent(&fmt, &fmtl, &b, buf+sizeof buf, s)) return 0;
1127 				s++;
1128 			} else {
1129 				*b++=fmt[0];
1130 				if (b-buf>=512) break;
1131 			}
1132 		} else {
1133 			*b++=fmt[0];
1134 			if (b-buf>=512) break;
1135 		}
1136 		fmt++;
1137 		fmtl--;
1138 	}
1139 	*b=0;
1140 	r->type=SCALAR_STR;
1141 	r->scalar.str.value=ht_strdup(buf);
1142 	r->scalar.str.len=strlen(r->scalar.str.value);
1143 	return 1;
1144 }
1145 
1146 /*
1147  *	FUNCTIONS
1148  */
1149 
func_eval(eval_scalar * r,eval_str * p)1150 int func_eval(eval_scalar *r, eval_str *p)
1151 {
1152 	char *q = ht_malloc(p->len+1);
1153 	int x;
1154 	memcpy(q, p->value, p->len);
1155 	q[p->len] = 0;
1156 	x = eval(r, q, g_eval_func_handler, g_eval_symbol_handler, eval_context);
1157 	free(q);
1158 /*	if (get_eval_error(NULL, NULL)) {
1159 		eval_error_pos+=lex_current_buffer_pos();
1160 	}*/
1161 	return x;
1162 }
1163 
func_error(eval_scalar * r,eval_str * s)1164 int func_error(eval_scalar *r, eval_str *s)
1165 {
1166 	char c[1024];
1167 	bin2str(c, s->value, MIN((unsigned int)s->len, sizeof c));
1168 	set_eval_error(c);
1169 	return 0;
1170 }
1171 
func_help_helper(eval_scalar * r,eval_str * s)1172 int func_help_helper(eval_scalar *r, eval_str *s)
1173 {
1174 	if (s->len > MAX_FUNCNAME_LEN) return 0;
1175 	char b[MAX_FUNCNAME_LEN+1];
1176 	bin2str(b, s->value, s->len);
1177 	set_helpmode(1, b);
1178 	eval_scalar str;
1179 	scalar_create_str_c(&str, "NaF()");
1180 	scalar_create_str_c(&helpstring, "");
1181 	func_eval(r, &str.scalar.str);
1182 	*r = helpstring;
1183 	scalar_destroy(&str);
1184 	set_helpmode(0, NULL);
1185 	return 1;
1186 }
1187 
func_whatis(eval_scalar * r,eval_str * s)1188 int func_whatis(eval_scalar *r, eval_str *s)
1189 {
1190 	int t = 0;
1191 	if (s->len != 0) t = func_help_helper(r, s);
1192 	if ((s->len == 0) || (r->scalar.str.len == 0)) {
1193 		char n[MAX_FUNCNAME_LEN+1];
1194 		bin2str(n, s->value, s->len);
1195 		set_eval_error("no such function \"%s\"", n);
1196 		return 0;
1197 	}
1198 	return t;
1199 }
1200 
func_help(eval_scalar * r)1201 int func_help(eval_scalar *r)
1202 {
1203 	eval_scalar str;
1204 	scalar_create_str_c(&str, "");
1205 	int t = func_help_helper(r, &str.scalar.str);
1206 	scalar_destroy(&str);
1207 	return t;
1208 }
1209 
1210 eval_func builtin_evalfuncs[]=	{
1211 /* eval */
1212 	{ "eval", (void*)&func_eval, {SCALAR_STR}, "evaluate string" },
1213 /* help */
1214 	{ "help", (void*)&func_help, {}, "get help on all functions"},
1215 	{ "whatis", (void*)&func_whatis, {SCALAR_STR}, "get help on specific function"},
1216 /* type juggling */
1217 	{ "int", (void*)&func_int, {SCALAR_INT}, "converts to integer" },
1218 	{ "string", (void*)&func_string, {SCALAR_STR}, "converts to string" },
1219 	{ "float", (void*)&func_float, {SCALAR_FLOAT}, "converts to float" },
1220 	{ "byte", (void*)&func_byte, {SCALAR_INT}, "converts to byte (1 bytes)" },
1221 	{ "word", (void*)&func_word, {SCALAR_INT}, "converts to uint16 (2 bytes unsigned)" },
1222 	{ "dword", (void*)&func_dword, {SCALAR_INT}, "converts to uint32 (4 bytes unsigned)" },
1223 	{ "sbyte", (void*)&func_sbyte, {SCALAR_INT}, "converts to signed byte (1 bytes signed)" },
1224 	{ "short", (void*)&func_short, {SCALAR_INT}, "converts to short (2 bytes signed)" },
1225 	{ "long", (void*)&func_long, {SCALAR_INT}, "converts to long (4 bytes signed)" },
1226 	{ "typeof", (void*)&func_typeof, {SCALAR_ANY}, "returns \"int\", \"string\" or \"float\"" },
1227 	{ "is_int", (void*)&func_is_int, {SCALAR_ANY}, "returns non-zero if param is an integer" },
1228 	{ "is_string", (void*)&func_is_string, {SCALAR_ANY}, "returns non-zero if param is a string" },
1229 	{ "is_float", (void*)&func_is_float, {SCALAR_ANY}, "returns non-zero if param is a float" },
1230 
1231 /* general */
1232 	{ "error", (void*)&func_error, {SCALAR_STR}, "abort with error" },
1233 /* string functions */
1234 	{ "char", (void*)&func_char, {SCALAR_INT}, "return the ascii character (1-char string) specified by p1" },
1235 	{ "ord", (void*)&func_ord, {SCALAR_STR}, "return the ordinal value of p1" },
1236 	{ "sprintf", (void*)&func_sprintf, {SCALAR_STR, SCALAR_VARARGS}, "returns formatted string" },
1237 	{ "strchr", (void*)&func_strchr, {SCALAR_STR, SCALAR_STR}, "returns position of first occurrence of character param2 in param1" },
1238 	{ "strcmp", (void*)&func_strcmp, {SCALAR_STR, SCALAR_STR}, "returns zero for equality, positive number for str1 > str2 and negative number for str1 < str2" },
1239 	{ "strlen", (void*)&func_strlen, {SCALAR_STR}, "returns length of string" },
1240 	{ "strncmp", (void*)&func_strncmp, {SCALAR_STR, SCALAR_STR, SCALAR_INT}, "like strcmp, but considers a maximum of param3 characters" },
1241 	{ "strstr", (void*)&func_strchr, {SCALAR_STR, SCALAR_STR}, "returns position of first occurrence of string param2 in param1" },
1242 	{ "substr", (void*)&func_substr, {SCALAR_STR, SCALAR_INT, SCALAR_INT}, "returns substring from param1, start param2, length param3" },
1243 /*	{ "stricmp", (void*)&func_stricmp, {SCALAR_STR, SCALAR_STR}, "like strcmp but case-insensitive" },
1244 	{ "strnicmp", (void*)&func_strnicmp, {SCALAR_STR, SCALAR_STR}, "" }, */
1245 /* math */
1246 	{ "pow", (void*)&func_pow, {SCALAR_FLOAT, SCALAR_FLOAT}, 0 },
1247 	{ "sqrt", (void*)&func_sqrt, {SCALAR_FLOAT}, 0 },
1248 
1249 	{ "fmin", (void*)&func_fmin, {SCALAR_FLOAT, SCALAR_FLOAT}, 0 },
1250 	{ "fmax", (void*)&func_fmax, {SCALAR_FLOAT, SCALAR_FLOAT}, 0 },
1251 	{ "min", (void*)&func_min, {SCALAR_INT, SCALAR_INT}, 0 },
1252 	{ "max", (void*)&func_max, {SCALAR_INT, SCALAR_INT}, 0 },
1253 
1254 	{ "random", (void*)&func_random, {SCALAR_INT}, "returns a random integer between 0 and param1-1" },
1255 	{ "rnd", (void*)&func_rnd, {}, "returns a random bit as integer (0 or 1)" },
1256 
1257 	{ "exp", (void*)&func_exp, {SCALAR_FLOAT}, 0 },
1258 	{ "log", (void*)&func_log, {SCALAR_FLOAT}, 0 },
1259 
1260 	{ "ceil", (void*)&func_ceil, {SCALAR_FLOAT}, 0 },
1261 	{ "floor", (void*)&func_floor, {SCALAR_FLOAT}, 0 },
1262 	{ "round", (void*)&func_round, {SCALAR_FLOAT}, 0 },
1263 	{ "trunc", (void*)&func_trunc, {SCALAR_FLOAT}, 0 },
1264 
1265 	{ "sin", (void*)&func_sin, {SCALAR_FLOAT}, 0 },
1266 	{ "cos", (void*)&func_cos, {SCALAR_FLOAT}, 0 },
1267 	{ "tan", (void*)&func_tan, {SCALAR_FLOAT}, 0 },
1268 
1269 	{ "asin", (void*)&func_asin, {SCALAR_FLOAT}, 0 },
1270 	{ "acos", (void*)&func_acos, {SCALAR_FLOAT}, 0 },
1271 	{ "atan", (void*)&func_atan, {SCALAR_FLOAT}, 0 },
1272 
1273 	{ "sinh", (void*)&func_sinh, {SCALAR_FLOAT}, 0 },
1274 	{ "cosh", (void*)&func_cosh, {SCALAR_FLOAT}, 0 },
1275 	{ "tanh", (void*)&func_tanh, {SCALAR_FLOAT}, 0 },
1276 
1277 #ifdef HAVE_ASINH
1278 	{ "asinh", (void*)&func_asinh, {SCALAR_FLOAT}, 0 },
1279 #endif
1280 
1281 #ifdef HAVE_ACOSH
1282 	{ "acosh", (void*)&func_acosh, {SCALAR_FLOAT}, 0 },
1283 #endif
1284 
1285 #ifdef HAVE_ATANH
1286 	{ "atanh", (void*)&func_atanh, {SCALAR_FLOAT}, 0 },
1287 #endif
1288 
1289 	{ NULL, NULL }
1290 };
1291 
match_evalfunc_proto(char * name,eval_scalarlist * params,eval_func * proto)1292 eval_protomatch match_evalfunc_proto(char *name, eval_scalarlist *params, eval_func *proto)
1293 {
1294 	int j;
1295 	int protoparams=0;
1296 
1297 	if (strcmp(name, proto->name)!=0) return PROTOMATCH_NAME_FAIL;
1298 
1299 	for (j=0; j<MAX_EVALFUNC_PARAMS; j++) {
1300 		if (proto->ptype[j]==SCALAR_NULL) break;
1301 		if (proto->ptype[j]==SCALAR_VARARGS) {
1302 			if (params->count > protoparams) protoparams=params->count;
1303 			break;
1304 		}
1305 		protoparams++;
1306 	}
1307 	return (protoparams==params->count) ? PROTOMATCH_OK : PROTOMATCH_PARAM_FAIL;
1308 }
1309 
exec_evalfunc(eval_scalar * r,eval_scalarlist * params,eval_func * proto)1310 int exec_evalfunc(eval_scalar *r, eval_scalarlist *params, eval_func *proto)
1311 {
1312 	int j;
1313 	int retv;
1314 	eval_scalar sc[MAX_EVALFUNC_PARAMS];
1315 	void *pptrs[MAX_EVALFUNC_PARAMS];
1316 	int protoparams=0;
1317 	eval_scalarlist *sclist=0;
1318 	const char *errmsg;
1319 	int errpos;
1320 
1321 	for (j=0; j<MAX_EVALFUNC_PARAMS; j++) {
1322 		sc[j].type=SCALAR_NULL;
1323 		pptrs[j]=NULL;
1324 	}
1325 
1326 	DEBUG_DUMP("%s:", proto->name);
1327 
1328 	for (j=0; j<MAX_EVALFUNC_PARAMS; j++) {
1329 		int term=0;
1330 		if (proto->ptype[j]==SCALAR_NULL) break;
1331 		switch (proto->ptype[j]) {
1332 			case SCALAR_INT:
1333 				protoparams++;
1334 				if (params->count<protoparams) return 0;
1335 				sc[j].type=SCALAR_INT;
1336 				scalar_context_int(&params->scalars[j], &sc[j].scalar.integer);
1337 				pptrs[j]=&sc[j].scalar.integer;
1338 
1339 				DEBUG_DUMP_SCALAR(&sc[j], "param %d: int=", j);
1340 				break;
1341 			case SCALAR_STR:
1342 				protoparams++;
1343 				if (params->count<protoparams) return 0;
1344 				sc[j].type=SCALAR_STR;
1345 				scalar_context_str(&params->scalars[j], &sc[j].scalar.str);
1346 				pptrs[j]=&sc[j].scalar.str;
1347 
1348 				DEBUG_DUMP_SCALAR(&sc[j], "param %d: str=", j);
1349 				break;
1350 			case SCALAR_FLOAT:
1351 				protoparams++;
1352 				if (params->count<protoparams) return 0;
1353 				sc[j].type=SCALAR_FLOAT;
1354 				scalar_context_float(&params->scalars[j], &sc[j].scalar.floatnum);
1355 				pptrs[j]=&sc[j].scalar.floatnum;
1356 
1357 				DEBUG_DUMP_SCALAR(&sc[j], "param %d: float=", j);
1358 				break;
1359 			case SCALAR_ANY: {
1360 				protoparams++;
1361 				if (params->count<protoparams) return 0;
1362 				scalar_clone(&sc[j], &params->scalars[j]);
1363 				pptrs[j] = &sc[j];
1364 
1365 				DEBUG_DUMP_SCALAR(&sc[j], "param %d: vararg=", j);
1366 				break;
1367 			}
1368 			case SCALAR_VARARGS: {
1369 				sclist = ht_malloc(sizeof (eval_scalarlist));
1370 				sclist->count=params->count-j;
1371 				if (sclist->count) {
1372 					sclist->scalars=(eval_scalar*)malloc(sizeof (eval_scalar) * sclist->count);
1373 					memcpy(sclist->scalars, &params->scalars[j], sizeof (eval_scalar) * sclist->count);
1374 				} else {
1375 					sclist->scalars=NULL;
1376 				}
1377 				pptrs[j]=sclist;
1378 				protoparams = params->count;
1379 				term=1;
1380 
1381 				DEBUG_DUMP_SCALARLIST(params, "param %d: varargs=", j);
1382 				break;
1383 			}
1384 			default:
1385 				set_eval_error("internal error (%s:%d)", __FILE__, __LINE__);
1386 				return 0;
1387 		}
1388 		if (term) break;
1389 	}
1390 	if (params->count == protoparams) {
1391 		DEBUG_DUMP_INDENT_IN;
1392 		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]);
1393 		DEBUG_DUMP_INDENT_OUT;
1394 	} else {
1395 		retv=0;
1396 	}
1397 	if (retv) {
1398 		DEBUG_DUMP_SCALAR(r, "returns ");
1399 	} else {
1400 		DEBUG_DUMP("fails...");
1401 	}
1402 
1403 	if (sclist) {
1404 		scalarlist_destroy_gentle(sclist);
1405 		free(sclist);
1406 	}
1407 
1408 	for (j=0; j<MAX_EVALFUNC_PARAMS; j++) {
1409 		if (sc[j].type!=SCALAR_NULL) {
1410 			scalar_destroy(&sc[j]);
1411 		}
1412 	}
1413 
1414 	if (!get_eval_error(NULL, NULL) && !retv) {
1415 		set_eval_error("?");
1416 	}
1417 
1418 	if (get_eval_error(&errmsg, &errpos)) {
1419 		char ee[MAX_ERRSTR_LEN+1];
1420 		ee[MAX_ERRSTR_LEN]=0;
1421 		ht_strlcpy(ee, proto->name, sizeof ee);
1422 		ht_strlcat(ee, "(): ", sizeof ee);
1423 		ht_strlcat(ee, errmsg, sizeof ee);
1424 		set_eval_error_ex(errpos, "%s", ee);
1425 	}
1426 	return retv;
1427 }
1428 
evalsymbol(eval_scalar * r,char * sname)1429 int evalsymbol(eval_scalar *r, char *sname)
1430 {
1431 	int s=0;
1432 	if (g_eval_symbol_handler) s = g_eval_symbol_handler(r, sname);
1433 	if (!get_eval_error(NULL, NULL) && !s) {
1434 		char sname_short[MAX_SYMBOLNAME_LEN+1];
1435 		ht_strlcpy(sname_short, sname, sizeof sname_short);
1436 		set_eval_error("unknown symbol: %s", sname_short);
1437 	}
1438 	return s;
1439 }
1440 
type2str(eval_scalartype t)1441 static const char *type2str(eval_scalartype t)
1442 {
1443 	switch (t) {
1444 	case SCALAR_INT:
1445 		return "INT";
1446 		break;
1447 	case SCALAR_STR:
1448 		return "STRING";
1449 		break;
1450 	case SCALAR_FLOAT:
1451 		return "FLOAT";
1452 		break;
1453 	case SCALAR_ANY:
1454 		return "ANY";
1455 		break;
1456 	case SCALAR_VARARGS:
1457 		return "...";
1458 		break;
1459 	default:
1460 		return 0;
1461 		break;
1462 	}
1463 }
1464 
proto_dump(char * buf,int bufsize,eval_func * proto,int full,const char * separator)1465 static void proto_dump(char *buf, int bufsize, eval_func *proto, int full, const char *separator)
1466 {
1467 // FIXME: buffer safety/possible buffer overflow
1468 	strcpy(buf, proto->name);
1469 	strcat(buf, "(");
1470 	for (int j=0; j<MAX_EVALFUNC_PARAMS; j++) {
1471 		if (proto->ptype[j]==SCALAR_NULL) break;
1472 		if (j) strcat(buf, ", ");
1473 		strcat(buf, type2str(proto->ptype[j]));
1474 		if (proto->ptype[j] == SCALAR_VARARGS) break;
1475 	}
1476 	strcat(buf, ")");
1477 	if (full && proto->desc) {
1478 		strcat(buf, separator);
1479 		strcat(buf, proto->desc);
1480 	}
1481 }
1482 
std_eval_func_handler(eval_scalar * result,char * fname,eval_scalarlist * params,eval_func * protos)1483 int std_eval_func_handler(eval_scalar *result, char *fname, eval_scalarlist *params, eval_func *protos)
1484 {
1485 	if (strlen(fname) > MAX_FUNCNAME_LEN) {
1486 		set_eval_error("invalid function, function name too long");
1487 		return 0;
1488 	}
1489 
1490 	if (helpmode) {
1491 		while (protos->name) {
1492 			char buf[256];
1493 			if ((!*helpname) || (*helpname && (strcmp(helpname, protos->name)==0))) {
1494 				if (protos->func) {
1495 					proto_dump(buf, sizeof buf, protos, 1, "\n");
1496 				} else {
1497 					strcpy(buf, protos->name);
1498 					strcat(buf, " : ");
1499 					strcat(buf, type2str(protos->ptype[0]));
1500 					strcat(buf, "\n");
1501 					strcat(buf, protos->desc);
1502 				}
1503 				strcat(buf, "\n\n");
1504 				eval_scalar s;
1505 				scalar_create_str_c(&s, buf);
1506 				eval_scalar r;
1507 				scalar_concat(&r, &helpstring, &s);
1508 				scalar_destroy(&helpstring);
1509 				scalar_destroy(&s);
1510 				helpstring = r;
1511 			}
1512 
1513 			protos++;
1514 		}
1515 	} else {
1516 		while (protos->name) {
1517 			if (protos->func)
1518 			switch (match_evalfunc_proto(fname, params, protos)) {
1519 				case PROTOMATCH_OK:
1520 					return exec_evalfunc(result, params, protos);
1521 				case PROTOMATCH_PARAM_FAIL: {
1522 					char b[256];
1523 					proto_dump(b, sizeof b, protos, 0, "");
1524 					set_eval_error("invalid params to function %s, declaration is: %s", protos->name, b);
1525 					return 0;
1526 				}
1527 				default: {}
1528 			}
1529 			protos++;
1530 		}
1531 	}
1532 	return 0;
1533 }
1534 
evalfunc(eval_scalar * r,char * fname,eval_scalarlist * params)1535 int evalfunc(eval_scalar *r, char *fname, eval_scalarlist *params)
1536 {
1537 	if (strlen(fname) > MAX_FUNCNAME_LEN) {
1538 		set_eval_error("invalid function, function name too long");
1539 		return 0;
1540 	}
1541 
1542 	int s;
1543 	if (g_eval_func_handler) {
1544 		s = g_eval_func_handler(r, fname, params);
1545 		if (get_eval_error(NULL, NULL)) return 0;
1546 		if (s) return s;
1547 	}
1548 
1549 	s = std_eval_func_handler(r, fname, params, builtin_evalfuncs);
1550 	if (get_eval_error(NULL, NULL)) return 0;
1551 	if (s) return s;
1552 
1553 	if (!helpmode) {
1554 		set_eval_error("unknown function %s", fname);
1555 		return 0;
1556 	} else return 1;
1557 }
1558 
eval_get_context()1559 void *eval_get_context()
1560 {
1561 	return eval_context;
1562 }
1563 
eval_set_context(void * context)1564 void eval_set_context(void *context)
1565 {
1566 	eval_context = context;
1567 }
1568 
eval_set_func_handler(eval_func_handler func_handler)1569 void eval_set_func_handler(eval_func_handler func_handler)
1570 {
1571 	g_eval_func_handler = func_handler;
1572 }
1573 
eval_set_symbol_handler(eval_symbol_handler symbol_handler)1574 void eval_set_symbol_handler(eval_symbol_handler symbol_handler)
1575 {
1576 	g_eval_symbol_handler = symbol_handler;
1577 }
1578 
1579