1 /* expr.c */
2 /*****************************************************************************
3 					�ԣ�������У���������أԣ�
4 
5 							�μ���ɾ����
6 *****************************************************************************/
7 
8 #include "xtr.h"
9 
10 /***************************************************************************
11 
12 <fstring> : { <%-form> | <char> }*
13 
14 <%-form>     : '%' [<%-form2>]
15 
16 <%-form2>    : <env-var> '%'
17              | ['-'] <arg-#>
18              | ['-'] [<f-width>] {<func> | <func-call>}
19              | ':' <format> <expr-prim-f>
20              | <expr-prim-f>
21              | <\-sequence>
22              | '%'
23              | '<'
24              | '>'
25 
26 <format>     : {<f-flag>}* [<f-width>] ['.' <f-prec>] <f-type>
27 
28 <f-flag>     : ' ' | '+' | '-' | '#'
29 <f-width>    : <num>
30 <f-prec>     : <num>
31 <f-type>     : <null>
32              | 's' | 'd' | 'u' | 'o' | 'x' | 'X' | 'c' | 'O' | 'k'
33              | 'S' | 'C' | 'r' | 'R' | 'a' | 'A' | 'f' | 'e' | 'E'
34              | 'g' | 'G'
35 
36 <func-call>   : <func> { <func-args> | <expr-prim-f> }
37 
38 <func-args>   : '(' [ <expr-asgn> { ',' <expr-asgn> }* ] ')'
39 
40 <env-var>     : <name>
41 
42 <func>        : <name>
43 
44 <num>         : <digits>
45 
46 <name>    : {<alpha> | '_'} {<alpha> | '_' | <digit>}*
47 
48 <arg-#>   : <num>
49 
50 <expr>    : <expr-asgn> {',' <expr-asgn>}*
51 
52 <expr-asgn> : <var>
53               {'=' | '*=' | '/=' | '%=' | '+=' | '-='
54                    | '&=' | '^=' | '|=' | '<<=' | '>>=' | '**='}
55               <expr-asgn>
56             | <expr-cond>
57 
58 <expr-cond> : <expr-lor> ['?' <expr> ':' <expr-cond>}]
59 <expr-lor>  : <expr-land> {'||' <expr-land>}*
60 <expr-land> : <expr-or> {'&&' <expr-or>}*
61 <expr-or>   : <expr-xor> {'|' <expr-xor>}*
62 <expr-xor>  : <expr-and> {'^' <expr-and>}*
63 <expr-and>  : <expr-rel> {'&' <expr-rel>}*
64 <expr-rel>  : <expr-conc> {{'==' | '!=' | '<' | '<=' | '>' | '>='}<expr-conc>}*
65 <expr-conc> : <expr-sh> {<expr-sh>}*
66 <expr-sh>   : <expr-add> {{'<<' | '>>'} <expr-add>}*
67 <expr-add>  : <expr-mul> {{'+' | '-'} <expr-mul>}*
68 <expr-mul>  : <expr-pref> {{'*' | '/' | '%'} <expr-pref>}*
69 <expr-pref> : {'!' | '~' | '-' | '+'} <expr-pref> | <expr-pow>
70 <expr-pow>  : <expr-inc> {'**' <expr-inc>}*
71 <expr-inc>  : {'++' | '--'} <expr-prim> | <expr-prim> [ '++' | '--']
72 
73 <expr-prim>  : <expr-prim-f>
74              | <func-call>
75              | <var>
76              | <number>
77 
78 <expr-prim-f> : '(' <expr> ')'
79               | '[' <expr> ']'
80               | '{' <fstring> '}'
81               | '"' <qstring> '"'
82               | "'" <echar> "'"
83               | '`' <expr-prim>
84               | '@' <expr-prim>
85 
86 <number>  : <digits>
87           | '0x' <hexdigits>
88           | '0o' <octdigits>
89           | '0b' <bindigits>
90 
91 <var>     : <usr-var> | <sys-var>
92 
93 <usr-var> : <name>
94 <sys-var> : '.' <name>
95 
96 <qstring> : { <echar> }*
97 
98 <echar>   : { <char> | <\-sequence> }
99 
100 <\-sequence> : '\' <\-sequence2>
101 
102 <\-sequence2> : 'a'
103               | 'b'
104               | 'f'
105               | 'n'
106               | 'r'
107               | 't'
108               | 'v'
109               | 'e'
110               | 'c'
111               | 's'
112               | 'S'
113               | 'z'
114               | 'x' <hexdigits>
115               | 'o' <octdigits>
116               | ['d'] <digits>
117               | <char>
118 
119 ***************************************************************************/
120 
121 #define EXPR1_PREFS			"-!~+."
122 #define EXPR0_PREFS			"({\"'@`["
123 
124 /* ʸ���� p �� <expr> �Ǥ��뤫Ĵ�٤� */
125 #define IsExpr(p)		(*(p) && (IsKSym2Str(p) || \
126 							strchr(EXPR0_PREFS, *(p)) || \
127 							strchr(EXPR1_PREFS, *(p)) && *(p+1) != '='))
128 
129 /* ʸ���� p �� <expr-prim-f> �Ǥ��뤫Ĵ�٤� */
130 #define IsExprPrimF(p)	(*(p) && strchr(EXPR0_PREFS, *(p)))
131 
132 int
IsFuncArgStr(const uchar * p)133 IsFuncArgStr(const uchar *p)
134 {
135 	return IsExprPrimF(p);
136 }
137 
138 /******************************** EvalExpr ********************************/
139 
140 #if UNIX
141 #define ERROR_SE(fmt,s,e)												\
142 	do {																\
143 		uchar *_str, *_mbs;												\
144 		int _len;														\
145 		_len = (int)((e) - (s));										\
146 		_str = (uchar *)alloca(_len + 1);								\
147 		memcpy((char *)_str, (char *)(s), _len);						\
148 		_str[_len] = '\0';												\
149 		_mbs = (uchar *)alloca(_len * 2 + 1);							\
150 		sjis2mbstring((char *)_mbs, (char *)_str);						\
151 		Error((fmt), _mbs);												\
152 	} while (0)
153 #define ExprErr(s, e)		ERROR_SE("Invalid expression: %s", s, e)
154 #else
155 #define ExprErr(s, e)		Error(f_ExprErr, (int)((e)-(s)), (s))
156 static uchar f_ExprErr[] = "Invalid expression: %.*s";
157 #endif
158 
159 #if UNIX
160 #define DivZeroErr(s, e)	ERROR_SE("Can't divide by 0: %s", s, e)
161 #else
162 #define DivZeroErr(s, e)	Error(f_DivZeroErr, (int)((e)-(s)), (s))
163 static uchar f_DivZeroErr[] = "Can't divide by 0: %.*s";
164 #endif
165 
166 #if UNIX
167 #define AsgnErr(s, e)		ERROR_SE("Illegal assignment: %s", s, e)
168 #else
169 #define AsgnErr(s, e)		Error(f_AsgnErr, (int)((e)-(s)), (s))
170 static uchar f_AsgnErr[] = "Illegal assignment: %.*s";
171 #endif
172 
173 static int	unclosedflag;	/* ����ब�Ĥ��Ƥ��ʤ����Ȥ����ե饰 */
174 
175 static const uchar *srcp;
176 static const uchar *expr;
177 static uchar *valstr;
178 static int   vallen;
179 static exprval_t exprval;
180 
181 static int
ValNumStr(exprval_t val)182 ValNumStr(exprval_t val)
183 {
184 	if (nevflag) return 0;
185 
186 	return vallen = WtNumber(valstr, val);
187 }
188 
189 static int
ValNum(exprval_t val)190 ValNum(exprval_t val)
191 {
192 	if (nevflag) return 0;
193 
194 	if (val == 0) {
195 		return vallen = WtNum(valstr, 0);
196 	} else {
197 		*valstr = 0;
198 		return vallen = 0;
199 	}
200 }
201 
202 static int
ValStr(exprval_t val)203 ValStr(exprval_t val)
204 {
205 	if (nevflag) return 0;
206 
207 	if (val == 0 || vallen)
208 		return vallen;
209 	else
210 		return vallen = WtNumber(valstr, val);
211 }
212 
213 static exprval_t
ValVal(exprval_t val)214 ValVal(exprval_t val)
215 {
216 	if (nevflag) return 0;
217 
218 	if (val == 0)
219 		return RdNumber(valstr, (const uchar **)NULL);
220 	else
221 		return val;
222 }
223 
224 static exprval_t Expr ARGS((void));
225 static exprval_t Expr_asgn ARGS((void));
226 static exprval_t Expr_cond ARGS((void));
227 static exprval_t Expr_lor ARGS((void));
228 static exprval_t Expr_land ARGS((void));
229 static exprval_t Expr_or ARGS((void));
230 static exprval_t Expr_xor ARGS((void));
231 static exprval_t Expr_and ARGS((void));
232 static exprval_t Expr_rel ARGS((void));
233 static exprval_t Expr_conc ARGS((void));
234 static exprval_t Expr_sh ARGS((void));
235 static exprval_t Expr_add ARGS((void));
236 static exprval_t Expr_mul ARGS((void));
237 static exprval_t Expr_pref ARGS((void));
238 static exprval_t Expr_pow ARGS((void));
239 static exprval_t Expr_inc ARGS((void));
240 static exprval_t Expr_prim ARGS((void));
241 
242 
243 int
EvalExpr(uchar * dst,const uchar * src,const uchar ** endp,evlev_t evlevel)244 EvalExpr(uchar *dst, const uchar *src, const uchar **endp, evlev_t evlevel)
245 /* ����ɾ�����롣
246  * evlevel �Ǥɤ��ޤǼ����ɤफ�����
247  */
248 {
249 	int len;
250 	const uchar *srcp0 = srcp;
251 	const uchar *expr0 = expr;
252 	uchar *valstr0 = valstr;
253 	int   vallen0 = vallen;
254 	int   nevflag0 = nevflag;
255 
256 	assert(nevflag || dst != NULL);
257 	assert(src != NULL);
258 
259 	expr = srcp = SkipSpace(src);
260 	if (!nevflag)
261 		*dst = '\0';
262 
263 	valstr = dst;
264 	vallen = 0;
265 
266 	exprval = 0;
267 
268 	if (IsExpr(srcp)) {
269 		switch (evlevel) {
270 		case EXPR_MAX:
271 			exprval = Expr();
272 			break;
273 		case EXPR_SEMIMAX:
274 			exprval = Expr_asgn();
275 			break;
276 		case EXPR_MIN:
277 		case EXPR_PRIM:
278 			exprval = Expr_prim();
279 			break;
280 		default:
281 			assert(FALSE);
282 		}
283 	}
284 
285 	len = ValStr(exprval);
286 	if (endp)
287 		*endp = BackSkipSpace(src, srcp);
288 	else if (*CutSpace(srcp) != '\0' && *srcp != ';' && !noerrmode )
289 		ExprErr(src, SkipMoji(srcp));
290 
291 	srcp = srcp0;
292 	expr = expr0;
293 	valstr = valstr0;
294 	vallen = vallen0;
295 	nevflag = nevflag0;
296 	return len;
297 }
298 
299 /**************************************/
300 
301 static
Expr(void)302 exprval_t Expr(void)
303 /*
304  *  <expr>    : <expr-asgn> {',' <expr-asgn>}*
305  */
306 {
307 	exprval_t val = Expr_asgn();
308 
309 	while (*CutSpace(srcp) == ',') {
310 		srcp++;
311 		val = Expr_asgn();
312 	}
313 	return val;
314 }
315 
316 #if UNIX
317 #define UnkSysVarErr(s)													\
318 	do {																\
319 		uchar *_mbs = (uchar *)alloca(strlen((char *)(s)) * 2);			\
320 		sjis2mbstring((char *)_mbs, (char *)(s));						\
321 		Error("Unknown system variable: %s", _mbs);						\
322 	} while (0)
323 #else
324 #define UnkSysVarErr(s)		Error(f_UnkSysVar, s)
325 static uchar f_UnkSysVar[] = "Unknown system variable: %s";
326 #endif
327 
328 static void
PutVar1(const uchar * name,int nlen,const uchar * s,int len)329 PutVar1(const uchar *name, int nlen, const uchar *s, int len)
330 {
331 	uchar nbuf[128];
332 
333 	CopyStrN(nbuf, name, min(nlen, 127));
334 	if (*nbuf == '.') {
335 		exprval_t val = RdNumber(s, (const uchar **)NULL);
336 		void *varptr;
337 		unsigned vartyp = GetSysVar(&varptr, nbuf+1);
338 		if (vartyp == V_UNKNOWN) {
339 			if (!noerrmode)
340 				UnkSysVarErr(nbuf);
341 		} else if (vartyp & V_RONLY) {
342 			if (!noerrmode)
343 				AsgnErr(name, name+nlen);
344 		} else switch (vartyp) {
345 		case V_INT:
346 			*(int *)varptr = (int)val;
347 			break;
348 		case V_UINT:
349 			*(unsigned *)varptr = (unsigned)val;
350 			break;
351 		default:
352 			assert(FALSE);
353 		}
354 	} else {
355 		PutVar(nbuf, s, len);
356 	}
357 }
358 
359 static uchar *
GetVar1(const uchar * name,int nlen,int * lenp,exprval_t * valp)360 GetVar1(const uchar *name, int nlen, int *lenp, exprval_t *valp)
361 {
362 	uchar nbuf[128];
363 
364 	assert(name != NULL);
365 
366 	CopyStrN(nbuf, name, min(nlen, 127));
367 	if (*nbuf == '.') {
368 		void *varptr;
369 		unsigned vartyp = GetSysVar(&varptr, nbuf+1);
370 
371 		assert(valp != NULL);
372 
373 		if (vartyp == V_UNKNOWN) {
374 			if (!noerrmode)
375 				UnkSysVarErr(nbuf);
376 		} else switch (vartyp & ~V_RONLY) {
377 		case V_INT:
378 			*valp = (exprval_t)(*(int *)varptr);
379 			break;
380 		case V_UINT:
381 			*valp = (exprval_t)(*(unsigned *)varptr);
382 			break;
383 		default:
384 			assert(FALSE);
385 		}
386 		if (lenp) *lenp = 0;
387 		return NULL;
388 	} else {
389 		uchar *p = GetVar(nbuf, lenp);
390 		if (valp != NULL)
391 			*valp = RdNumber(p, (const uchar **)NULL);
392 		return p;
393 	}
394 }
395 
396 #ifdef FLOATEXPR
397  #define Add(a, b)		FAdd(a, b)
398  #define Sub(a, b)		FAdd(a, -(b))
399 
400 /* ��ư���������βø����ǡ���̤��ͤ�����������Ȥ� 0 �ˤʤ�褦�ˤ��� */
401 
402 static exprval_t
FAdd(exprval_t a,exprval_t b)403 FAdd(exprval_t a, exprval_t b)
404 {
405 	exprval_t c = a + b;
406 	if (Abs(c) > Abs(a) * _Paste2(10e-, DBL_DIG))
407 		return c;
408 	else {
409 		uchar buf[32];
410 		WtNumber(buf, a);
411 		a = RdNumber(buf, (const uchar **)NULL);
412 		WtNumber(buf, b);
413 		if (a + RdNumber(buf, (const uchar **)NULL) == 0)
414 			return 0;
415 		else
416 			return c;
417 	}
418 }
419 
420 #else
421  #define Add(a, b)		((a) + (b))
422  #define Sub(a, b)		((a) - (b))
423 #endif
424 
425 
426 static exprval_t Ex_sh ARGS((exprval_t a, exprval_t b, int rflag));
427 static exprval_t Ex_pow ARGS((exprval_t a, exprval_t b));
428 
429 #define IsAsgnOp(p)		(*((p)+1) != '=' ? \
430 							*(p) == '=' || \
431 							 *((p)+2) == '=' && \
432 							  (*(p) == '<' || *(p) == '>' || *(p) == '*') && \
433 							  *(p) == *((p)+1) : \
434 						    *(p) && strchr("*%/+-&^|", *(p)))
435 
436 #define SkipAsgnOp(p)	((p) + (*(p) == '=' ? 1 : *((p)+1) == '=' ? 2 : 3))
437 
438 #define IsVarStr(p)		(*(p) == '.' ? IsSym1_(*((p)+1)) : IsKSym1Str(p))
439 #define SkipVar(p)		(*(p) == '.' ? SkipSym2((p)+1) : SkipKSym2(p))
440 
441 static exprval_t
Expr_asgn(void)442 Expr_asgn(void)
443 /*
444  *  <expr-asgn> : <var>
445  *                {'=' | '*=' | '/=' | '%=' | '+=' | '-='
446  *                     | '&=' | '^=' | '|=' | '<<=' | '>>=' || '**='}
447  *                <expr-asgn>
448  *              | <expr-cond>
449  */
450 {
451 	const uchar *sp0 = CutSpace(srcp);
452 	const uchar *sp1;
453 	int  op;
454 	exprval_t  val;
455 	exprval_t  val2;
456 
457 	if (!IsVarStr(srcp)) {
458 		val = Expr_cond();
459 		CutSpace(srcp);
460 		if (IsAsgnOp(srcp) && (srcp = SkipAsgnOp(srcp), !noerrmode))
461 			AsgnErr(sp0, srcp);
462 		return val;
463 	}
464 	sp1 = SkipVar(srcp);
465 	srcp = SkipSpace(sp1);
466 	if (!IsAsgnOp(srcp)) {
467 		srcp = sp0;
468 		val = Expr_cond();
469 		CutSpace(srcp);
470 		if (IsAsgnOp(srcp) && (srcp = SkipAsgnOp(srcp), !noerrmode))
471 			AsgnErr(sp0, srcp);
472 		return val;
473 	}
474 	op = *srcp;
475 	if (op == '*' && *(srcp+1) == '*') op = 'P';
476 	srcp = SkipAsgnOp(srcp);
477 
478 	if (nevflag)
479 		return Expr_asgn();
480 
481 	if (op == '=') {
482 		val = Expr_asgn();
483 		ValStr(val);
484 		PutVar1(sp0, sp1-sp0, valstr, vallen);
485 	} else {
486 		GetVar1(sp0, sp1-sp0, (int *)NULL, &val);
487 		val2 = Expr_asgn();
488 		if (val2 == 0 && (op == '/' || op == '%')) {
489 			if (!noerrmode)
490 				DivZeroErr(sp0, srcp);
491 			else
492 				val2 = 1;
493 		}
494 		switch (op) {
495 		case '*':
496 			val *= val2;
497 			break;
498 		case '/':
499 			val /= val2;
500 			break;
501 		case '%':
502 #ifdef FLOATEXPR
503 			val = fmod(val, val2);
504 #else
505 			val %= val2;
506 #endif
507 			break;
508 		case '+':
509 			val = Add(val, val2);
510 			break;
511 		case '-':
512 			val = Sub(val, val2);
513 			break;
514 		case '&':
515 			val = (exprintval_t)val & (exprintval_t)val2;
516 			break;
517 		case '^':
518 			val = (exprintval_t)val ^ (exprintval_t)val2;
519 			break;
520 		case '|':
521 			val = (exprintval_t)val | (exprintval_t)val2;
522 			break;
523 		case '<':						/* <<= */
524 			val = Ex_sh(val, val2, 0);
525 			break;
526 		case '>':						/* >>= */
527 			val = Ex_sh(val, val2, 1);
528 			break;
529 		case 'P':						/* **= */
530 			val = Ex_pow(val, val2);
531 			break;
532 		default:
533 			assert(FALSE);				/* Never */
534 		}
535 		ValNumStr(val);
536 		PutVar1(sp0, sp1-sp0, valstr, vallen);
537 	}
538 	return val;
539 }
540 
541 static exprval_t
Expr_cond(void)542 Expr_cond(void)
543 /*
544  *  <expr-cond>  : <expr-lor> ['?' <expr> ':' <expr-cond>}]
545  */
546 {
547 	const uchar *sp0 = srcp;
548 	exprval_t val_c = Expr_lor();
549 	exprval_t val_th;
550 	exprval_t val_el;
551 	int nevflag0 = nevflag;
552 
553 	if (*CutSpace(srcp) != '?')
554 		return val_c;
555 
556 	srcp++;
557 	if (!val_c) nevflag = TRUE;
558 	val_th = Expr();
559 	if (*CutSpace(srcp) != ':') {
560 		if (!noerrmode)
561 			ExprErr(sp0, SkipMoji(srcp));
562 		else
563 			--srcp;
564 	}
565 	srcp++;
566 	nevflag = nevflag0;
567 	if (val_c) nevflag = TRUE;
568 	val_el = Expr_cond();
569 	nevflag = nevflag0;
570 	if (val_c)
571 		return val_th;
572 	else
573 		return val_el;
574 }
575 
576 static exprval_t
Expr_lor(void)577 Expr_lor(void)
578 /*
579  *  <expr-lor> : <expr-land> {'||' <expr-land>}*
580  */
581 {
582 	exprval_t val = Expr_land();
583 	int nevflag0 = nevflag;
584 
585 	while (*CutSpace(srcp) == '|' && *(srcp+1) == '|') {
586 		srcp += 2;
587 		if (val) {
588 			nevflag = TRUE;
589 			Expr_land();
590 		} else {
591 			val = Expr_land();
592 		}
593 	}
594 	nevflag = nevflag0;
595 	return val;
596 }
597 
598 static exprval_t
Expr_land(void)599 Expr_land(void)
600 /*
601  *  <expr-land> : <expr-or> {'&&' <expr-or>}*
602  */
603 {
604 	exprval_t val = Expr_or();
605 	int nevflag0 = nevflag;
606 
607 	while (*CutSpace(srcp) == '&' && *(srcp+1) == '&') {
608 		srcp += 2;
609 		if (val) {
610 			val = Expr_or();
611 		} else {
612 			nevflag = TRUE;
613 			Expr_or();
614 		}
615 	}
616 	nevflag = nevflag0;
617 	return val;
618 }
619 
620 static exprval_t
Expr_or(void)621 Expr_or(void)
622 /*
623  *  <expr-or>  : <expr-xor> {'|' <expr-xor>}*
624  */
625 {
626 	exprval_t val = Expr_xor();
627 	while (*CutSpace(srcp) == '|' && *(srcp+1) != '|' && *(srcp+1) != '=') {
628 		srcp++;
629 		if (!nevflag)
630 			val = (exprintval_t)val | (exprintval_t)Expr_xor();
631 		else
632 			(void)Expr_xor();
633 		ValNum(val);
634 	}
635 	return val;
636 }
637 
638 static exprval_t
Expr_xor(void)639 Expr_xor(void)
640 /*
641  *  <expr-xor> : <expr-and> {'^' <expr-and>}*
642  */
643 {
644 	exprval_t val = Expr_and();
645 	while (*CutSpace(srcp) == '^' && *(srcp+1) != '=') {
646 		srcp++;
647 		if (!nevflag)
648 			val = (exprintval_t)val ^ (exprintval_t)Expr_and();
649 		else
650 			(void)Expr_and();
651 		ValNum(val);
652 	}
653 	return val;
654 }
655 
656 static exprval_t
Expr_and(void)657 Expr_and(void)
658 /*
659  *  <expr-and>  : <expr-rel> {'&' <expr-rel>}*
660  */
661 {
662 	exprval_t val = Expr_rel();
663 	while (*CutSpace(srcp) == '&' && *(srcp+1) != '&' && *(srcp+1) != '=') {
664 		srcp++;
665 		if (!nevflag)
666 			val = (exprintval_t)val & (exprintval_t)Expr_rel();
667 		else
668 			(void)Expr_rel();
669 		ValNum(val);
670 	}
671 	return val;
672 }
673 
674 static exprval_t
Expr_rel(void)675 Expr_rel(void)
676 /*
677  *  <expr-rel>  : <expr-conc> {{'==' | '!=' | '<' | '<=' | '>' | '>='}
678  *                             <expr-conc>}*
679  */
680 {
681 	exprval_t val = Expr_conc();
682 	exprval_t val2;
683 	uchar *valstr0 = valstr;
684 	int  op;
685 	int  vallen0 = vallen;
686 
687 	while (1) {
688 		if ((op = *CutSpace(srcp)) == '=' ? *(srcp+1) == '=' :
689 		                  *srcp == '!' && *(srcp+1) == '=' ) {
690 			srcp += 2;
691 			ValStr(val);
692 			if (!nevflag)
693 				valstr += vallen + 1;
694 			vallen0 = vallen;
695 			val2 = Expr_conc();
696 			val = ((Sub(val, val2) == 0) && (vallen0 == ValStr(val2)) &&
697 						!memcmp(valstr0, valstr, vallen));
698 						/* ʸ����Ĺ����ޤ�ƴ����˰��פ�����Τ߿� */
699 			if (op == '!')
700 				val = !val;
701 			valstr = valstr0;
702 			ValNum(val);
703 		} else if (*srcp == '<' && *(srcp+1) == '=') {
704 			srcp += 2;
705 			val = Sub(val, Expr_conc()) <= 0;
706 			ValNum(val);
707 		} else if (*srcp == '<' && *(srcp+1) != '<') {
708 			srcp++;
709 			val = Sub(val, Expr_conc()) < 0;
710 			ValNum(val);
711 		} else if (*srcp == '>' && *(srcp+1) == '=') {
712 			srcp += 2;
713 			val = Sub(val, Expr_conc()) >= 0;
714 			ValNum(val);
715 		} else if (*srcp == '>' && *(srcp+1) != '>') {
716 			srcp++;
717 			val = Sub(val, Expr_conc()) > 0;
718 			ValNum(val);
719 		} else
720 			break;
721 	}
722 	return val;
723 }
724 
725 
726 static exprval_t
Expr_conc(void)727 Expr_conc(void)
728 /*
729  *  <expr-conc> : <expr-sh> {<expr-sh>}*
730  */
731 {
732 	uchar *valstr0 = valstr;
733 	exprval_t val = Expr_sh();
734 
735 	CutSpace(srcp);
736 	if (IsExpr(srcp)) {
737 		do {
738 			valstr += ValStr(val);
739 			val = Expr_sh();
740 			CutSpace(srcp);
741 		} while (IsExpr(srcp));
742 
743 		if (!nevflag) {
744 			ValStr(val);
745 			vallen += valstr - valstr0;
746 		}
747 		valstr = valstr0;
748 		val = ValVal(0);
749 	}
750 	return val;
751 }
752 
753 static exprval_t
Ex_sh(exprval_t a,exprval_t b,int rflag)754 Ex_sh(exprval_t a, exprval_t b, int rflag)
755 {
756 	if (b < 0) {
757 		rflag = !rflag;
758 		b = -b;
759 	}
760 	if (rflag)
761 		return (exprval_t)(exprintval_t)((unsigned long)a >> (exprintval_t)b);
762 	else
763 		return (exprval_t)(exprintval_t)((unsigned long)a << (exprintval_t)b);
764 }
765 
766 static exprval_t
Expr_sh(void)767 Expr_sh(void)
768 /*
769  *  <expr-sh>  : <expr-add> {{'<<' | '>>'} <expr-add>}*
770  */
771 {
772 	exprval_t val = Expr_add();
773 	while (*CutSpace(srcp) == '<' && *(srcp+1) == '<' && *(srcp+2) != '=' ||
774 		             *srcp == '>' && *(srcp+1) == '>' && *(srcp+2) != '=') {
775 		int rflag = *srcp == '>';
776 		srcp += 2;
777 		val = Ex_sh(val, Expr_add(), rflag);
778 		ValNum(val);
779 	}
780 	return val;
781 }
782 
783 static exprval_t
Expr_add(void)784 Expr_add(void)
785 /*
786  *  <expr-add>  : <expr-mul> {{'+' | '-'} <expr-mul>}*
787  */
788 {
789 	exprval_t val = Expr_mul();
790 	while (1)
791 		if (*CutSpace(srcp) == '+' && *(srcp+1) != '+' && *(srcp+1) != '=') {
792 			srcp++;
793 			val = Add(val, Expr_mul());
794 			ValNum(val);
795 		} else if (*srcp == '-' && *(srcp+1) != '-' && *(srcp+1) != '=') {
796 			srcp++;
797 			val = Sub(val, Expr_mul());
798 			ValNum(val);
799 		} else
800 			break;
801 	return val;
802 }
803 
804 static exprval_t
Expr_mul(void)805 Expr_mul(void)
806 /*
807  *  <expr-mul>  : <expr-pref> {{'*' | '/' | '%'} <expr-pref>}*
808  */
809 {
810 	const uchar *sp0 = CutSpace(srcp);
811 	exprval_t val = Expr_pref();
812 	exprval_t val2;
813 	int op;
814 
815 	while (((op = *(CutSpace(srcp))) == '*' || op == '/' || op == '%') &&
816 			*(srcp+1) != '*' && *(srcp+1) != '=') {
817 		srcp++;
818 		val2 = Expr_pref();
819 		if (!nevflag) {
820 			if (val2 == 0 && op != '*') {
821 				if (!noerrmode)
822 					DivZeroErr(sp0, srcp);
823 				else
824 					val2 = 1;
825 			}
826 			switch (op) {
827 			case '*':
828 				val *= val2;
829 				break;
830 			case '/':
831 				val /= val2;
832 				break;
833 			case '%':
834 #ifdef FLOATEXPR
835 				val = fmod(val, val2);
836 #else
837 				val %= val2;
838 #endif
839 				break;
840 			default:
841 				assert(FALSE);
842 			}
843 		}
844 		ValNum(val);
845 	}
846 	return val;
847 }
848 
849 
850 static exprval_t
Expr_pref(void)851 Expr_pref(void)
852 /*
853  *  <expr-pref>  : {'!' | '~' | '-' | '+'} <expr-pref>
854  *               | <expr-pow>
855  */
856 {
857 	exprval_t val;
858 
859 	if (*CutSpace(srcp) == '!' && *(srcp+1) != '=') {
860 		srcp++;
861 		val = !Expr_pref();
862 	} else if (*srcp == '~') {
863 		srcp++;
864 		val = ~(exprintval_t)Expr_pref();
865 	} else if (*srcp == '-' && *(srcp+1) != '-' && *(srcp+1) != '=') {
866 		srcp++;
867 		val = -Expr_pref();
868 	} else if (*srcp == '+' && *(srcp+1) != '+' && *(srcp+1) != '=') {
869 		srcp++;
870 		val = +Expr_pref();
871 	} else
872 		return Expr_pow();
873 
874 	ValNum(val);
875 	return val;
876 }
877 
878 static exprval_t
Ex_pow(exprval_t a,exprval_t b)879 Ex_pow(exprval_t a, exprval_t b)
880 {
881 	if (nevflag) return 0;
882 
883 	if (b == 0 || a == 1)
884 		return 1;
885 	else if (a == 0)
886 		return 0;
887 
888 #ifdef FLOATEXPR
889 	return pow(a, b);
890 
891 #else
892 	if (a == -1)
893 		return b & 1 ? -1 : 1;
894 	else if (b < 0)
895 		return 0;
896 	else if (b >= 64)	/* too big !! */
897 		return 0;
898 	else {
899 		exprval_t val = a;
900 		while (--b > 0)
901 			val *= a;
902 		return val;
903 	}
904 #endif
905 }
906 
907 static exprval_t
Expr_pow(void)908 Expr_pow(void)
909 /*
910  *  <expr-pow> : <expr-inc> {'**' <expr-inc>}*
911  */
912 {
913 	exprval_t val = Expr_inc();
914 	while (*CutSpace(srcp) == '*' && *(srcp+1) == '*' && *(srcp+2) != '=') {
915 		srcp += 2;
916 		val = Ex_pow(val, Expr_inc());
917 		ValNum(val);
918 	}
919 	return val;
920 }
921 
922 
923 #define IsIncDecOp(s)  ((*(s) == '+' || *(s) == '-') && *(s) == *((s)+1))
924 
925 static exprval_t
Expr_inc(void)926 Expr_inc(void)
927 /*
928  *  <expr-inc>  : {'++' | '--'} <expr-prim>
929  *              | <expr-prim> [ '++' | '--']
930  */
931 {
932 	const uchar *sp0 = CutSpace(srcp);
933 	const uchar *sp1;
934 	exprval_t val;
935 
936 	if (IsIncDecOp(srcp)) {
937 		srcp += 2;
938 		sp1 = CutSpace(srcp);
939 		val = Expr_prim();
940 		if (!IsVarStr(sp1)) {
941 			if (!noerrmode)
942 				AsgnErr(sp0, srcp);
943 		} else if (!nevflag) {
944 			if (*sp0 == '+')
945 				++val;
946 			else
947 				--val;
948 			ValNumStr(val);
949 			PutVar1(sp1, srcp-sp1, valstr, vallen);
950 		}
951 	} else {
952 		val = Expr_prim();
953 		sp1 = srcp;
954 		CutSpace(srcp);
955 		if (!IsIncDecOp(srcp))
956 			return val;
957 
958 		if (!IsVarStr(sp0)) {
959 			if (!noerrmode)
960 				AsgnErr(sp0, srcp+2);
961 		} else if (!nevflag) {
962 			ValNumStr(*srcp == '+' ? val + 1 : val - 1);
963 			PutVar1(sp0, sp1-sp0, valstr, vallen);
964 		}
965 		srcp += 2;
966 	}
967 	ValNum(val);
968 	return val;
969 }
970 
971 static int FuncCall ARGS((uchar *dst, const uchar *name, const uchar *src, const uchar **endp, exprval_t *fretvalp));
972 
973 static exprval_t
Expr_prim(void)974 Expr_prim(void)
975 /*
976  *  <expr-prim>  : '(' <expr> ')'
977  *               | '[' <expr> ']'
978  *               | '{' <fstring> '}'
979  *               | '"' <qstring> '"'
980  *               | "'" <echar> "'"
981  *               | '`' <expr-prim>
982  *               | '@' <expr-prim>
983  *               | <func-call>
984  *               | <sys-var>
985  *               | <usr-var>
986  *               | <number>
987  */
988 {
989 	uchar *dst = valstr;
990 	uchar *dstp = dst;
991 	const uchar *sp0;
992 	const uchar *p;
993 	exprval_t  val = 0;
994 
995 	assert(nevflag || dstp != NULL);
996 	assert(srcp != NULL);
997 
998 	unclosedflag = FALSE;			/* ����ब�Ĥ������Υ����å��� */
999 
1000 	while (*CutSpace(srcp) == '@')						/* '@' <expr-prim> */
1001 		srcp++;
1002 
1003 	sp0 = srcp;
1004 
1005 	if (!nevflag) {
1006 		*dstp = '\0';
1007 		vallen = 0;
1008 		val = 0;
1009 	}
1010 
1011 	if (*srcp == '(' || *srcp == '[') {					/* '(' <expr> ')' */
1012 														/* '[' <expr> ']' */
1013 		srcp = SkipSpace(srcp+1);
1014 		if (*srcp != ')' && *srcp != ']')
1015 			val = Expr();
1016 		if (*CutSpace(srcp) == (*sp0 == '(' ? ')' : ']')) {
1017 			srcp++;
1018 			unclosedflag = FALSE;
1019 		} else {
1020 			if (!noerrmode)
1021 #if UNIX
1022 			{
1023 				uchar *str, *mbs;
1024 				int len;
1025 
1026 				len = (int)(srcp - sp0);
1027 				str = (uchar *)alloca(len + 1);
1028 				memcpy((char *)str, (char *)sp0, len);
1029 				str[len] = '\0';
1030 				mbs = (uchar *)alloca(len * 2 + 1);
1031 				sjis2mbstring((char *)mbs, (char *)str);
1032 				Error("'%c' expected: %s", (*sp0 == '(' ? ')' : ']'), mbs);
1033 			}
1034 #else
1035 				Error("'%c' expected: %.*s",
1036 								(*sp0 == '(' ? ')' : ']'),
1037 								(int)(srcp-sp0), sp0);
1038 #endif
1039 			while (*srcp && *srcp != ')' && *srcp != ']') {
1040 				if (!IsExpr(srcp))
1041 					srcp = SkipMoji(srcp);
1042 				val = Expr();
1043 			}
1044 			if (*srcp) {
1045 				srcp++;
1046 				unclosedflag = FALSE;
1047 			} else {
1048 				unclosedflag = TRUE;
1049 			}
1050 		}
1051 	} else if (*srcp == '{') {							/* '{' <fstring> '}' */
1052 		dstp += EvalStringB(dstp, srcp+1, &srcp, 1);
1053 		valstr = dst;
1054 		if (!nevflag) {
1055 			vallen = dstp - dst;
1056 			val = ValVal(0);
1057 		}
1058 	} else if (*srcp == '"') {							/* '"' <qstring> '"' */
1059 		do {
1060 			dstp += ReadStringB(dstp, srcp+1, &srcp, '"');
1061 			if (*srcp == '"') {
1062 				srcp++;
1063 			} else {
1064 				unclosedflag = TRUE;
1065 				if (!noerrmode)
1066 #if UNIX
1067 				{
1068 					uchar *mbs = (uchar *)alloca(strlen((char *)sp0) * 2 + 1);
1069 					sjis2mbstring((char *)mbs, (char *)sp0);
1070 					Error("'\"' expected: %s", mbs);
1071 				}
1072 #else
1073 					Error("'\"' expected: %s", sp0);
1074 #endif
1075 				else
1076 					break;
1077 			}
1078 		} while (*srcp == '"');
1079 				/* ���֥륯�����Ȥ�Ϣ³���Ƥ����飱�Ĥ�ʸ����Ȥߤʤ� */
1080 
1081 		if (!nevflag) {
1082 			vallen = dstp - dst;
1083 			val = ValVal(0);
1084 		}
1085 
1086 	} else if (*srcp == '\'') {							/* "'" <echar> "'" */
1087 		dstp += ReadStringB(dstp, srcp+1, &srcp, '\'');
1088 		if (!nevflag) {
1089 			for (p = valstr; p < dstp; p++) {
1090 				val *= 0x100;
1091 				val += *p;
1092 			}
1093 		}
1094 		dstp = valstr;
1095 		if (*srcp == '\'') {
1096 			srcp++;
1097 		} else {
1098 			unclosedflag = TRUE;
1099 			if (!noerrmode)
1100 #if UNIX
1101 				{
1102 					uchar *mbs = (uchar *)alloca(strlen((char *)sp0) * 2 + 1);
1103 					sjis2mbstring((char *)mbs, (char *)sp0);
1104 					Error("\"'\" expected: %s", mbs);
1105 				}
1106 #else
1107 				Error("\"'\" expected: %s", sp0);
1108 #endif
1109 		}
1110 		ValNum(val);
1111 	} else if (*srcp == '`') {							/* '`' <expr-prim> */
1112 		srcp = SkipExpr(srcp+1, EXPR_PRIM, SKIP_ELSE0);
1113 		if (!nevflag) {
1114 			dstp += vallen = CopyStrDiff(dstp, SkipSpace(sp0+1), srcp);
1115 			val = ValVal(0);
1116 		}
1117 	} else if (IsKSym1Str(srcp)) {
1118 		srcp = SkipKSym2(srcp);
1119 		if (IsExprPrimF(srcp)) {						/* <func-call> */
1120 			dstp += FuncCall(dstp, sp0, srcp, &srcp, &val);
1121 			valstr = dst;
1122 			if (!nevflag) {
1123 				vallen = dstp - dst;
1124 				val = ValVal(val);
1125 			}
1126 		} else {										/* <usr-var> */
1127 			if (!nevflag) {
1128 				int len;
1129 				p = GetVar1(sp0, srcp-sp0, &len, (exprval_t *)NULL);
1130 				dstp += vallen = CopyStrN(dstp, p, len);
1131 				val = ValVal(0);
1132 			}
1133 		}
1134 	} else if (*srcp == '.' && !isdigit(*(srcp+1))) {	/* <sys-var> */
1135 		srcp++;
1136 		if (IsSym1_(*srcp)) {
1137 			srcp = SkipSym2(srcp);
1138 			if (!nevflag) {
1139 				CopyStrDiff(dstp, sp0+1, srcp);
1140 				GetVar1(sp0, srcp-sp0, (int *)NULL, &val);
1141 				ValNum(val);
1142 			}
1143 		}
1144 #if 0	/* %-form ���Ȥ���Ⱥ���Τ�Ȥˤʤ�Τǡ��ѻ� */
1145 	} else if (*srcp == '%') {
1146 		dstp += EvalPcForm(dstp, srcp+1, &srcp);
1147 		valstr = dst;
1148 		if (!nevflag) {
1149 			vallen = dstp - dst;
1150 			val = ValVal(0);
1151 		}
1152 #endif
1153 	} else {											/* <number> */
1154 		val = RdNumber(srcp, &p);
1155 		if (p == srcp && *p != '.' && !isdigit(*p)) {
1156 			/* ���ͤȤ����ɤ�ʤ���� */
1157 			if (!noerrmode)
1158 				ExprErr(expr, SkipMoji(p));
1159 			val = 0;
1160 		} else if (*(srcp = p) == '.' || isalnum(*srcp)) {
1161 			val = 0;
1162 			for (srcp++; isalnum(*srcp); srcp++);
1163 			if (!noerrmode)
1164 #if UNIX
1165 				ERROR_SE("Illegal number: %s", sp0, srcp);
1166 #else
1167 				Error("Illegal number: %.*s", (int)(srcp - sp0), sp0);
1168 #endif
1169 		} else {
1170 			ValNum(val);
1171 		}
1172 	}
1173 
1174 	assert(dst == valstr);
1175 	assert(!nevflag || dstp == valstr);
1176 
1177 	return val;
1178 }
1179 
1180 /*************************************************************************/
1181 
1182 int
RdNum(const uchar * src,const uchar ** endp)1183 RdNum(const uchar *src, const uchar **endp)
1184 {
1185 	return (int)strtol((const char *)src, (char**)endp, 10);
1186 }
1187 
1188 
1189 exprval_t
RdNumber(const uchar * src,const uchar ** endp)1190 RdNumber(const uchar *src, const uchar **endp)
1191 {
1192 	const uchar *srcp = SkipSpace(src);
1193 	int sn = *srcp == '+' ? 1 : *srcp == '-' ? -1 : 0;
1194 	const uchar *end;
1195 	exprval_t val;
1196 
1197 	if (!*src) {
1198 		if (endp)
1199 			*endp = src;
1200 		return 0;			/* �̥�ʸ������ͤ� 0 �Ȥ��� */
1201 	}
1202 
1203 	if (sn)
1204 		srcp++;
1205 
1206 	if (*srcp == '0' && isalpha(*(srcp + 1)) && isxdigit(*(srcp + 2))) {
1207 		int ch = TOLOWER(*(srcp + 1));
1208 		int radix = ch == 'b' ? 2 :
1209 					ch == 'o' ? 8 :
1210 					ch == 'd' ? 10 :
1211 					ch == 'x' ? 16 :
1212 					0;
1213 		if (radix) {
1214 			long ival = (long)strtoul((const char *)srcp + 2, (char**)&end, radix);
1215 			if (end != srcp + 2) {
1216 				if (endp)
1217 					*endp = end;
1218 				return sn < 0 ? -ival : ival;
1219 			}
1220 		}
1221 	}
1222 #ifdef FLOATEXPR
1223 	if ((*srcp == '.' && srcp++, isdigit(*srcp)))
1224 		val = strtod((const char *)src, (char **)&end);
1225 	else {
1226 		val = 0;
1227 		end = src;
1228 	}
1229 #else
1230 	val = strtol(src, (char**)&end, 10);
1231 #endif
1232 	if (end == src) {
1233 		/* ���Ȥ����ɤ�ʤ���� */
1234 
1235 		if (endp == NULL)
1236 			val = (exprval_t)((unsigned)(*src) * 0x100 + *(src+1));
1237 
1238 #if defined(FLOATEXPR) && defined(_MSC_VER)
1239 		/* MSC ��������ư�������黻(/FPa)���Ѥξ��Τ��� */
1240 		if (isdigit(*srcp)) {
1241 			/* MSC 6.0 ��������ư�������饤�֥���Ȥ��ȡ�strtod ��
1242 			  �����С��ե������Ȥ����Ȥ��Ƥ�ǧ���⤻���� 0 ���֤��Ƥ��ޤ�
1243 			  ���� */
1244 			val = sn < 0 ? EXPRVAL_MIN : EXPRVAL_MAX;
1245 			srcp = SkipDigit(srcp);
1246 			if (*srcp=='.')
1247 				srcp++;
1248 			end = srcp = SkipDigit(srcp);
1249 			if (*srcp=='e'||*srcp=='E') {
1250 				if (*++srcp == '-') {
1251 					val = 0;
1252 					srcp++;
1253 				} else if (*srcp=='+') {
1254 					srcp++;
1255 				}
1256 				if (isdigit(*srcp)) {
1257 					end = SkipDigit(srcp);
1258 				} else {
1259 					uchar *p = DupStrDiff(src, end);
1260 					val = strtod(p, NULL);
1261 					XFree((voidstar)p);
1262 				}
1263 			}
1264 		}
1265 #endif
1266 	}
1267 
1268 	if (endp)
1269 		*endp = end;
1270 
1271 	return val;
1272 }
1273 
1274 int
WtNum(uchar * dst,int num)1275 WtNum(uchar *dst, int num)
1276 {
1277 	sprintf((char *)dst, "%d", num);
1278 	return strlen((char *)dst);
1279 }
1280 
1281 int
WtNumber(uchar * dst,exprval_t num)1282 WtNumber(uchar *dst, exprval_t num)
1283 {
1284 	sprintf((char *)dst, EXPRVAL_PRINTF_FMT, num);
1285 	return strlen((char *)dst);
1286 }
1287 
1288 /******************************* EvalPcForm *******************************/
1289 
1290 static uchar *
SkipPFmt(const uchar * p)1291 SkipPFmt(const uchar *p)
1292 {
1293 	p += strspn((const char *)p, "-+ #");
1294 	p = SkipDigit(p);
1295 	if (*p == '.')
1296 		p = SkipDigit(p+1);
1297 	return (uchar *)p;
1298 }
1299 
1300 static int
CommaNum(uchar * dst,const uchar * src)1301 CommaNum(uchar *dst, const uchar *src)
1302 {
1303 	uchar *dstp = dst;
1304 	const uchar *srcp = src;
1305 	const uchar *srcp1;
1306 
1307 	while (*srcp && !isalnum(*srcp))
1308 		MoveMojiAdv(dstp, srcp);
1309 
1310 	srcp1 = srcp;
1311 	while (isalnum(*srcp))
1312 		srcp++;
1313 
1314 	dstp += StrCommaNum(dstp, srcp1, srcp - srcp1, ",", 1, 3);
1315 	dstp += CopyStr(dstp, srcp);
1316 
1317 	return dstp - dst;
1318 }
1319 
1320 static int
PFormatS(uchar * dst,const uchar * fmt,int f_type,const uchar * vals,int len)1321 PFormatS(uchar *dst, const uchar *fmt, int f_type, const uchar *vals, int len)
1322 {
1323 	if (!*(fmt+1)) {
1324 		/* �ե����ޥåȻ��꤬�ʤ���Ф��Τޤޥ��ԡ� */
1325 		return CopyStrN(dst, vals, len);
1326 	} else {
1327 		const uchar *p, *p2;
1328 		int leftflag = (strchr((const char *)fmt+1, '-') != NULL);
1329 		int fwidth = atoi((const char *)(p = fmt + 1 + strspn((const char *)fmt+1, "-+ #")));
1330 		int zeroflag = !leftflag && fwidth > 0 && *p == '0';
1331 		int fprec = (p2 = (uchar *)strchr((const char *)p, '.')) ? atoi((const char *)p2+1) :
1332 			((f_type == 'S' || !f_type && !fwidth) && *p) ? fwidth : len;
1333 			/* f_type=='S' ��fwidth���꤬����fprec����̵���ʤ�fprec=fwidth */
1334 			/* f_type==0 ��fwidth���� 0 ��fprec����̵���ʤ�fprec=0 */
1335 
1336 		int plen;
1337 		int flen;
1338 
1339 		assert(fwidth >= 0);
1340 		assert(fprec >= 0);
1341 
1342 		if (len <= fprec)
1343 			plen = len;
1344 		else
1345 			plen = NthIsKanji2(vals, fprec) ? fprec - 1 : fprec;
1346 
1347 		flen = fwidth < plen ? 0 : fwidth - plen;
1348 
1349 		if (leftflag) {
1350 			CopyStrN(dst, vals, plen);
1351 			memset(dst + plen, ' ', flen);
1352 			*(dst + plen + flen) = '\0';
1353 		} else {
1354 			memset(dst, zeroflag ? '0' : ' ', flen);
1355 			CopyStrN(dst + flen, vals, plen);
1356 		}
1357 		return plen + flen;
1358 	}
1359 }
1360 
1361 
1362 int
PFormat(uchar * dst,const uchar * f_fmt,const uchar * vals,int len)1363 PFormat(uchar *dst, const uchar *f_fmt, const uchar *vals, int len)
1364 {
1365 	uchar fmt[64];
1366 	uchar tmp[64];
1367 	exprval_t val = 0;
1368 	uchar *fmtp;
1369 	int f_type = 0;
1370 	int n;
1371 
1372 	fmt[0] = '%';
1373 	if (f_fmt)
1374 		strncpy((char *)fmt+1, (const char *)f_fmt, 50);
1375 	else
1376 		fmt[1] = '\0';
1377 
1378 	fmtp = StrLast(fmt+1);
1379 	if (isalpha(*fmtp)) {
1380 		f_type = *fmtp;
1381 		*fmtp = '\0';
1382 	}
1383 
1384 	if (f_type != 's' && f_type != 'S')
1385 		val = RdNumber(vals, (const uchar **)NULL);
1386 
1387 	fmtp = SkipPFmt(fmt+1);
1388 	if (*fmtp) {
1389 		if (!noerrmode)
1390 #if UNIX
1391 		{
1392 			uchar *mbs = (uchar *)alloca(strlen((char *)f_fmt) * 2 + 1);
1393 			sjis2mbstring((char *)mbs, (char *)f_fmt);
1394 			Error("Invalid Format: %s", mbs);
1395 		}
1396 #else
1397 			Error("Invalid Format: %s", f_fmt);
1398 #endif
1399 		else {
1400 			fmtp = fmt+1;
1401 			*fmtp = '\0';
1402 		}
1403 	}
1404 	switch (f_type) {
1405 	case 'S':
1406 	case 's':
1407 	case 0:
1408 	_case_s:
1409 		return PFormatS(dst, fmt, f_type, vals, len);
1410 	case 'd':
1411 		sprintf((char *)dst, strcat((char *)fmt, "ld"), (long)val);
1412 		return strlen((char *)dst);
1413 	case 'u':
1414 		sprintf((char *)dst, strcat((char *)fmt, "lu"), (unsigned long)val);
1415 		return strlen((char *)dst);
1416 	case 'o':
1417 		sprintf((char *)dst, strcat((char *)fmt, "lo"), (unsigned long)val);
1418 		return strlen((char *)dst);
1419 	case 'x':
1420 		sprintf((char *)dst, strcat((char *)fmt, "lx"), (unsigned long)val);
1421 		return strlen((char *)dst);
1422 	case 'X':
1423 		sprintf((char *)dst, strcat((char *)fmt, "lX"), (unsigned long)val);
1424 		return strlen((char *)dst);
1425 	case 'c':
1426 		tmp[n = SetMoji((unsigned)val, tmp)] = '\0';	/* ʸ������ʸ������Ѵ� */
1427 		return PFormat(dst, (uchar *)strcat((char *)fmt+1, "s"), tmp, n);
1428 
1429 	case 'O':				/* Ordinal */
1430 		n = MkNthNum(tmp, (long)val);
1431 		return PFormat(dst, (uchar *)strcat((char *)fmt+1, "s"), tmp, n);
1432 	case 'k':				/* kansuuji */
1433 		n = StrKanjiNum(tmp, vals, len);
1434 		return PFormat(dst, (uchar *)strcat((char *)fmt+1, "s"), tmp, n);
1435 	case 'C':				/* numer whith thousand sep */
1436 		n = CommaNum(tmp, vals);
1437 		return PFormat(dst, (uchar *)strcat((char *)fmt+1, "s"), tmp, n);
1438 	case 'r':
1439 	case 'R':
1440 		if (val < 1 || val > 3999)
1441 			goto _case_s;
1442 
1443 		n = MkRomNum(tmp, (int)val, isupper(f_type));
1444 		return PFormat(dst, (uchar *)strcat((char *)fmt+1, "s"), tmp, n);
1445 	case 'a':
1446 	case 'A':
1447 		if (val < 1 || val > 26)
1448 			goto _case_s;
1449 
1450 		sprintf((char *)dst, strcat((char *)fmt, "c"), (f_type - 1) + (int)val);
1451 
1452 		return strlen((char *)dst);
1453 
1454 #ifdef FLOATEXPR
1455 	case 'f':
1456 	case 'e':
1457 	case 'E':
1458 	case 'g':
1459 	case 'G':
1460 		*fmtp++ = f_type;
1461 		*fmtp = '\0';
1462 
1463 		sprintf((char *)dst, (char *)fmt, (double)val);
1464 
1465 		return strlen((char *)dst);
1466 #endif
1467 
1468 	default:
1469 		if (!noerrmode)
1470 			Error("Unknown format type: %c", f_type);
1471 		return 0;
1472 	}
1473 }
1474 
1475 
1476 /**************************************/
1477 
1478 static int
CopyEnvValN(uchar * dst,const uchar * name,int nlen)1479 CopyEnvValN(uchar *dst, const uchar *name, int nlen)
1480 {
1481 	uchar *val = NULL;
1482 	uchar var[128];
1483 	CopyStrN(var, name, min(nlen, 127));
1484 	StrUpper(var, var);
1485 	val = (uchar *)getenv((char *)var);
1486 
1487 	if (val) {
1488 		return CopyStr(dst, val);
1489 	} else {
1490 		*dst = 0;
1491 		return 0;
1492 	}
1493 }
1494 
1495 
1496 int
CopyEnvVal(uchar * dst,const uchar * name)1497 CopyEnvVal(uchar *dst, const uchar *name)
1498 {
1499 	return CopyEnvValN(dst, name, strlen((const char *)name));
1500 }
1501 
1502 int
EvalPcForm(uchar * dst,const uchar * src,const uchar ** endp)1503 EvalPcForm(uchar *dst, const uchar *src, const uchar **endp)
1504 /* src: <%-form2>   -- '%' �μ���ʸ����ؤ� */
1505 {
1506 	uchar *dstp = dst;
1507 	const uchar *srcp = src;
1508 	const uchar *sp0 = srcp;
1509 	const uchar *sp1;
1510 	int len;
1511 	int n;
1512 
1513 	uchar *fbuf = NULL;			/* �Ѵ������ѥХåե���malloc ���ΰ���ݡ� */
1514 	uchar *vbuf = NULL;			/* �ѿ���Ǽ�ѥХåե���malloc ���ΰ���ݡ� */
1515 
1516 	if (IsExprPrimF(srcp)) {
1517 		/*
1518 		 * '%' <expr-prim-f>
1519 		 */
1520 		dstp += EvalExpr(dstp, srcp, &srcp, EXPR_PRIM);
1521 
1522 	} else if (*srcp != '-' ? IsSym2_(*srcp) : IsSym2_(*(srcp+1))) {
1523 		/* '%' �θ夬�ѿ����ޤ��� '-'�դ��αѿ����ʤ� */
1524 		if (*srcp == '-')
1525 			srcp++;
1526 		sp1 = SkipDigit(srcp);
1527 		srcp = SkipSym2(srcp);
1528 
1529 		if (sp0 == sp1 && *srcp == '%') {
1530 			/*
1531 			 *  '%' <env-var> '%'
1532 			 */
1533 			if (!nevflag) {
1534 				dstp += CopyEnvValN(dstp, sp0, srcp - sp0);
1535 			}
1536 			srcp++;
1537 		} else if (sp1 == srcp) {
1538 			/*
1539 			 *	'%' ['-'] <arg-#>
1540 			 */
1541 			n = RdNum(sp0, &srcp);
1542 			if (!nevflag)
1543 				dstp += CopyArg(dstp, n);
1544 		} else {
1545 			/*
1546 			 *  '%' ['-'] [<f-width>] <func-call*>
1547 			 */
1548 			if (sp1 > sp0)
1549 				fbuf = DupStrDiff(sp0, sp1);
1550 			len = FuncCall(dstp, sp1, srcp, &srcp, (exprval_t *)NULL);
1551 			if (!nevflag) {
1552 				if (fbuf) {
1553 					vbuf = DupStrN(dstp, len);
1554 					dstp += PFormat(dstp, fbuf, vbuf, len);
1555 				} else {
1556 					dstp += len;
1557 				}
1558 			}
1559 		}
1560 	} else switch (*srcp) {
1561 
1562 #if 0	/* �Ȥ߹��ߴؿ� cmd(str), _(str) �����椺�ꡢ�ѻ� */
1563 	case '.':
1564 		/*
1565 		 * '%' '.' <expr-prim>
1566 		 */
1567 		vbuf = AEvalExpr(&len, srcp+1, &srcp, EXPR_PRIM);
1568 		if (!nevflag)
1569 			Command(vbuf);
1570 		break;
1571 #endif
1572 	case ':':
1573 		/*
1574 		 * '%' ':' <format> <expr-prim-f>
1575 		 */
1576 		srcp = SkipSym2(SkipPFmt(srcp+1));
1577 		fbuf = DupStrDiff(sp0+1, srcp);
1578 		if (IsExprPrimF(srcp)) {
1579 			vbuf = AEvalExpr(&len, srcp, &srcp, EXPR_PRIM);
1580 			if (!nevflag) {
1581 				dstp += PFormat(dstp, fbuf, vbuf, len);
1582 			}
1583 		}
1584 		break;
1585 
1586 #if 0	/* �Ȥ߹��ߴؿ� fn(path, fname) ��¸������Τǡ�����ϥܥ� */
1587 	case '/':
1588 		/*
1589 		 * '%' '/'
1590 		 */
1591 		srcp++;
1592 		if (!nevflag) {
1593 			if (*(dstp - 1) != DIRSLASH && *(dstp - 1) != ALTDIRSLASH)
1594 				*dstp++ = DIRSLASH;
1595 		}
1596 		break;
1597 #endif
1598 
1599 	case '\\':
1600 		/*
1601 		 * '%' <\-sequence>
1602 		 */
1603 		dstp += ReadEscSequence(dstp, srcp+1, &srcp);
1604 		break;
1605 	case '%':
1606 		/*
1607 		 * '%' '%'
1608 		 */
1609 		srcp++;
1610 		if (!nevflag)
1611 			*dstp++ = '%';
1612 		break;
1613 	case '<':
1614 		/*
1615 		 * '%' '<'
1616 		 */
1617 		srcp++;
1618 		if (!nevflag)
1619 			*dstp++ = '{';
1620 		break;
1621 	case '>':
1622 		/*
1623 		 * '%' '>'
1624 		 */
1625 		srcp++;
1626 		if (!nevflag)
1627 			*dstp++ = '}';
1628 		break;
1629 	default:
1630 		/*
1631 		 * '%'
1632 		 */
1633 		/* '%' �θ夬����¾��ʸ���ʤ顢���Τޤ� '%' ��ͭ���ˤ��� */
1634 		if (!nevflag)
1635 			*dstp++ = '%';
1636 	}
1637 	XFree((voidstar)fbuf);
1638 	XFree((voidstar)vbuf);
1639 
1640 	if (endp) *endp = srcp;
1641 	if (!nevflag)
1642 		*dstp = 0;
1643 	assert(!nevflag || dstp == dst);
1644 	return dstp - dst;
1645 }
1646 
1647 
1648 
1649 
1650 /******************************** FuncCall ********************************/
1651 
1652 #if UNIX
1653 #define ERROR_SS(fmt,n,s)												\
1654 	do {																\
1655 		uchar *_n, *_s;													\
1656 		_n = (uchar *)alloca(strlen((char *)(n)) * 2 + 1);				\
1657 		sjis2mbstring((char *)_n, (char *)(n));							\
1658 		_s = (uchar *)alloca(strlen((char *)(s)) * 2 + 1);				\
1659 		sjis2mbstring((char *)_s, (char *)(s));							\
1660 		Error((uchar *)(fmt), _n, _s);									\
1661 	} while (0)
1662 #define ArgErr()		ERROR_SS("Invalid argument: %s%s", name, src)
1663 #else
1664 #define ArgErr()		Error(f_ArgErr, name, src)
1665 static uchar f_ArgErr[] = "Invalid argument: %s%s";
1666 #endif
1667 
1668 #if UNIX
1669 #define ManyArgErr() \
1670 	ERROR_SS((IsExpr(srcp) ? "Too many arguments: %s%s" : "Invalid argument: %s%s"), name, src)
1671 #else
1672 #define ManyArgErr()	Error(IsExpr(srcp) ? f_ManyArgErr : f_ArgErr, \
1673 								name, src)
1674 static uchar f_ManyArgErr[] = "Too many arguments: %s%s";
1675 #endif
1676 
1677 static int
FuncCallSub(uchar * dst,const uchar * name,const uchar * src,const uchar ** endp,exprval_t * fretvalp)1678 FuncCallSub(uchar *dst, const uchar *name, const uchar *src, const uchar **endp, exprval_t *fretvalp)
1679 {
1680 	uchar *dstp = dst;
1681 	const uchar *srcp = src;
1682 	uchar *vbuf = NULL;
1683 	int   len = 0;
1684 	uchar *p;
1685 	sffnp_t 	funcp;
1686 	sftype_t	sftype;
1687 	int n1 = 0;
1688 	int n2 = 0;
1689 	exprval_t x1 = 0;
1690 	exprval_t x2 = 0;
1691 	uchar *vbuf2 = NULL;
1692 	int len2 = 0;
1693 	exprval_t val = 0;
1694 	int fargcnt = 0;
1695 
1696 	assert(!nevflag);
1697 	assert(src != NULL);
1698 
1699 	if ((sftype = GetSFunc(&funcp, name)) != SF_UNKNOWN) {
1700 		/*
1701 		 * <func> {<func-args> | <expr-prim-f>}
1702 		 */
1703 		if (*srcp != '(') {
1704 			/* ��������̤ǰϤޤ�Ƥ��ʤ���� */
1705 			/* ��İ����Τ߲�ǽ */
1706 			if (IsExprPrimF(srcp)) {
1707 				fargcnt++;
1708 				vbuf = AEvalExpr(&len, srcp, &srcp, EXPR_PRIM);
1709 				if (sftype < SF_S) {
1710 					x1 = exprval;
1711 					if (x1 > INT_MIN && x1 < INT_MAX)
1712 						n1 = (int)x1;
1713 				}
1714 			}
1715 		} else {
1716 			/*
1717 			 * <func-args> : '(' [ <expr-asgn> { ',' <expr-asgn> }* ] ')'
1718 			 */
1719 			/* ��̤ǰϤޤ�Ƥ����� */
1720 			srcp++;
1721 			CutSpace(srcp);
1722 			if (sftype >= SF_S && IsExpr(srcp)) {
1723 				/* ʸ��������ν��� */
1724 				fargcnt++;
1725 				vbuf = AEvalExpr(&len, srcp, &srcp, EXPR_SEMIMAX);
1726 				if (*CutSpace(srcp) == ',')
1727 					srcp++;
1728 
1729 				if (sftype >= SF_Sn_Sn && *CutSpace(srcp) != ')') {
1730 					/* ʸ����������ĤȤ�ؿ��ξ�� */
1731 					fargcnt++;
1732 					vbuf2 = AEvalExpr(&len2, srcp, &srcp, EXPR_SEMIMAX);
1733 					if (*CutSpace(srcp) == ',')
1734 						srcp++;
1735 				}
1736 			}
1737 			if (*CutSpace(srcp) != ')') {
1738 				/* ���Ͱ����ν��� */
1739 				if ((sftype == SF_0 || sftype == SF_S || sftype == SF_Sn
1740 									|| sftype == SF_Sn_Sn) && !noerrmode) {
1741 					ManyArgErr();
1742 				}
1743 				fargcnt++;
1744 				x1 = EvalExprVal(srcp, &srcp, EXPR_SEMIMAX);
1745 				if (x1 >= INT_MIN && x1 <= INT_MAX)
1746 					n1 = (int)x1;
1747 				if (*CutSpace(srcp) == ',')
1748 					srcp++;
1749 				if (*CutSpace(srcp) != ')') {
1750 					if ((sftype == SX_X || sftype == SF_X || sftype == SF_Sn_N
1751 										|| sftype == SF_Sn_Sn_N)&&!noerrmode) {
1752 						ManyArgErr();
1753 					}
1754 					fargcnt++;
1755 					x2 = EvalExprVal(srcp, &srcp, EXPR_SEMIMAX);
1756 					if (x2 >= INT_MIN && x2 <= INT_MAX)
1757 						n2 = (int)x2;
1758 					if (*CutSpace(srcp) == ',')
1759 						srcp++;
1760 				}
1761 			}
1762 			if (*CutSpace(srcp) == ')')
1763 				srcp++;
1764 			else {
1765 				if (!noerrmode)
1766 					ManyArgErr();
1767 				srcp = SkipExpr(src, EXPR_PRIM, SKIP_NOERR);
1768 			}
1769 		}
1770 		if (sftype >= SF_S && !vbuf)
1771 			vbuf = DupStr("");
1772 
1773 		fargc = fargcnt;
1774 
1775 		switch (sftype) {
1776 		case SF_0:
1777 			len = ((sf00fnp_t)funcp)(dstp);
1778 			break;
1779 		case SF_X:
1780 			len = ((sf01fnp_t)funcp)(dstp, x1);
1781 			break;
1782 		case SF_X_X:
1783 			len = ((sf02fnp_t)funcp)(dstp, x1, x2);
1784 			break;
1785 		case SF_S:
1786 			len = ((sfs0fnp_t)funcp)(dstp, vbuf);
1787 			break;
1788 		case SF_Sn:
1789 			len = ((sf10fnp_t)funcp)(dstp, vbuf, len);
1790 			break;
1791 		case SF_Sn_N:
1792 			len = ((sf11fnp_t)funcp)(dstp, vbuf, len, n1);
1793 			break;
1794 		case SF_Sn_N_N:
1795 			len = ((sf12fnp_t)funcp)(dstp, vbuf, len, n1, n2);
1796 			break;
1797 		case SF_Sn_Sn:
1798 			len = ((sf20fnp_t)funcp)(dstp, vbuf, len, vbuf2, len2);
1799 			break;
1800 		case SF_Sn_Sn_N:
1801 			len = ((sf21fnp_t)funcp)(dstp, vbuf, len, vbuf2, len2, n1);
1802 			break;
1803 		case SF_Sn_Sn_N_N:
1804 			len = ((sf22fnp_t)funcp)(dstp, vbuf, len, vbuf2, len2, n1, n2);
1805 			break;
1806 		case SX_X:
1807 			val = ((sfx1fnp_t)funcp)(x1);
1808 			len = (val == 0 || !fretvalp) ? WtNumber(dstp, val) : 0;
1809 			break;
1810 		case SX_X_X:
1811 			val = ((sfx2fnp_t)funcp)(x1, x2);
1812 			len = (val == 0 || !fretvalp) ? WtNumber(dstp, val) : 0;
1813 			break;
1814 		default:
1815 			assert(FALSE);
1816 		}
1817 		*(dstp += len) = '\0';
1818 
1819 	} else if ((p = GetSFVar(&len, name)) != NULL) {
1820 		/*
1821 		 * <func0arg>
1822 		 */
1823 		dstp += CopyStrN(dstp, p, len);
1824 		if (*srcp == '(' && (srcp++, *CutSpace(srcp) == ')')) {
1825 			srcp++;
1826 		} else {
1827 			srcp = src;
1828 			if (fretvalp || IsExprPrimF(srcp)) {
1829 				/* �ؿ��ƤӽФ������ξ�� */
1830 				if (!noerrmode)
1831 					ManyArgErr();
1832 				srcp = SkipExpr(srcp, EXPR_PRIM, SKIP_ELSE0);
1833 			}
1834 		}
1835 	} else if (!noerrmode) {
1836 #if UNIX
1837 		uchar *mbs = (uchar *)alloca(strlen((char *)name) * 2 + 1);
1838 		sjis2mbstring((char *)mbs, (char *)name);
1839 		Error("Unknown function: %s", mbs);
1840 #else
1841 		Error("Unknown function: %s", name);
1842 #endif
1843 	}
1844 	XFree((voidstar)vbuf2);
1845 	XFree((voidstar)vbuf);
1846 	if (endp) *endp = srcp;
1847 	if (fretvalp) *fretvalp = val;
1848 	return dstp - dst;
1849 }
1850 
1851 
1852 static int
FuncCall(uchar * dst,const uchar * name,const uchar * src,const uchar ** endp,exprval_t * fretvalp)1853 FuncCall(uchar *dst, const uchar *name, const uchar *src, const uchar **endp, exprval_t *fretvalp)
1854 {
1855 	const uchar *srcp = src;
1856 	macro_t		*macp;
1857 	int			len = 0;
1858 
1859 	assert(nevflag || dst != NULL);
1860 	assert(src != NULL);
1861 
1862 	name = DupStrDiff(name, src);
1863 
1864 	unclosedflag = FALSE;	/* �����ꥹ�Ȥγ�̤��Ĥ��Ƥ��뤫�Υ����å��� */
1865 
1866 	if (nevflag || (macp = GetMacro(name)) != NULL) {
1867 		if (IsExprPrimF(srcp)) {
1868 			srcp = SkipExpr(src, EXPR_PRIM, SKIP_NOERR);
1869 			if (unclosedflag && !nevflag && !noerrmode) {
1870 				srcp = SkipExpr(src, EXPR_PRIM, SKIP_NORMAL);
1871 				/* ����ǥ��顼�ˤʤäƤ����ˤϤ��ʤ��Ϥ� */
1872 				assert(FALSE);
1873 			}
1874 		}
1875 		if (!nevflag && !unclosedflag) {
1876 			uchar *vbuf;
1877 			vbuf = (*src == '(' && srcp != src)
1878 						  ? DupStrDiff(src+1, srcp-1)
1879 						  : DupStrDiff(src, srcp);
1880 			len = FuncMacroCall(dst, macp, vbuf);
1881 			unclosedflag = FALSE;
1882 			XFree((voidstar)vbuf);
1883 		}
1884 		if (fretvalp) *fretvalp = 0;
1885 		if (endp) *endp = srcp;
1886 	} else {
1887 		len = FuncCallSub(dst, name, src, endp, fretvalp);
1888 	}
1889 	XFree((voidstar)name);
1890 	return len;
1891 }
1892 
1893 
1894 /******************************* EvalString *******************************/
1895 
1896 int
EvalString(uchar * dst,const uchar * src)1897 EvalString(uchar *dst, const uchar *src)
1898 /* ʸ����ˡ�%-�Ѵ��Ӥ�ܤ�����ǤΥ��ԡ���Ԥ� */
1899 /* dst �˳�Ǽ����ʸ�����ʥ̥������ˤ��֤� */
1900 {
1901 	return EvalStringB(dst, src, (const uchar **)NULL, 0);
1902 }
1903 
1904 int
EvalStringB(uchar * dst,const uchar * src,const uchar ** endp,int bflag)1905 EvalStringB(uchar *dst, const uchar *src, const uchar **endp, int bflag)
1906 /* bflag �����ʤ顢'{' �μ���ʸ���ǸƤФ�ơ��б����� '}' �ޤ��ɤࡣ
1907  * ���ξ�硢�Ǹ�� '}'�ϥ��ԡ����ʤ����ɤ߼ΤƤ롣
1908  */
1909 {
1910 	uchar *dstp = dst;
1911 	const uchar *srcp = src;
1912 	int nestlevel = 1;
1913 	unsigned c;
1914 
1915 	assert(nevflag || dst != NULL);
1916 	assert(src != NULL);
1917 
1918 	unclosedflag = FALSE;
1919 
1920 	while (*srcp) {
1921 		c = RdMoji(srcp);
1922 		if (c == '%')
1923 			dstp += EvalPcForm(dstp, srcp, &srcp);
1924 		else {
1925 			if (bflag) {
1926 				if (c == '{')
1927 					nestlevel++;
1928 				else if (c == '}') {
1929 					if (--nestlevel == 0)
1930 						break;					/* �����ޤ� */
1931 				}
1932 			}
1933 			if (!nevflag)
1934 				dstp += SetMoji(c, dstp);
1935 		}
1936 	}
1937 	if (bflag && nestlevel != 0) {
1938 		unclosedflag = TRUE;
1939 		if (!noerrmode)
1940 #if UNIX
1941 		{
1942 			uchar *mbs = (uchar *)alloca(strlen((char *)src) * 2 + 1);
1943 			sjis2mbstring((char *)mbs, (char *)src);
1944 			Error("'}' expected: {%s", mbs);
1945 		}
1946 #else
1947 			Error("'}' expected: {%s", src);
1948 #endif
1949 	} else {
1950 		unclosedflag = FALSE;
1951 	}
1952 	if (endp) *endp = srcp;
1953 	if (!nevflag) *dstp = 0;
1954 	assert(!nevflag || dstp == dst);
1955 	return dstp - dst;
1956 }
1957 
1958 
1959 int
EvalStringN(uchar * dst,const uchar * src,int n)1960 EvalStringN(uchar *dst, const uchar *src, int n)
1961 {
1962 	uchar *dstp = dst;
1963 	uchar *dp1 = dst;
1964 	const uchar *srcp = src;
1965 	const uchar *src_e = src + n;
1966 
1967 	assert(dst != NULL);
1968 	assert(src != NULL);
1969 	assert(n >= 0);
1970 
1971 	while (srcp < src_e) {
1972 		dp1 = dstp;
1973 		if (*srcp == '%')
1974 			dstp += EvalPcForm(dstp, srcp+1, &srcp);
1975 		else
1976 			MoveMojiAdv(dstp, srcp);
1977 	}
1978 	if (srcp > src_e)
1979 		dstp = dp1;
1980 	*dstp = 0;
1981 	return dstp - dst;
1982 }
1983 
1984 
1985 /**************************************************************************/
1986 
1987 
1988 
1989 int
EvalExprStr(uchar * dst,const uchar * src)1990 EvalExprStr(uchar *dst, const uchar *src)
1991 {
1992 	return EvalExpr(dst, src, (const uchar **)NULL, EXPR_MAX);
1993 }
1994 
1995 
1996 exprval_t
EvalExprVal(const uchar * src,const uchar ** endp,evlev_t evlevel)1997 EvalExprVal(const uchar *src, const uchar **endp, evlev_t evlevel)
1998 /* ����ɾ�����ƿ��Ȥ��Ƥ��ͤ��֤� */
1999 {
2000 	uchar *vbuf = AEvalExpr((int *)NULL, src, endp, evlevel);
2001 	XFree((voidstar)vbuf);
2002 	return exprval;
2003 }
2004 
2005 uchar *
SkipExpr(const uchar * src,evlev_t evlevel,skipmode_t skipmode)2006 SkipExpr(const uchar *src, evlev_t evlevel, skipmode_t skipmode)
2007 /* �����ɤ����Ф� */
2008 {
2009 	int 	nevflag0 = nevflag;
2010 	int 	noerrmode0 = noerrmode;
2011 	uchar 	*vbuf;
2012 	const uchar	*srcp;
2013 	const uchar	*sp0 = SkipSpace(src);
2014 
2015 	nevflag = TRUE;
2016 	noerrmode = (skipmode != SKIP_NORMAL);
2017 	vbuf = AEvalExpr((int *)NULL, sp0, &srcp, evlevel);
2018 	XFree((voidstar)vbuf);
2019 
2020 	if (unclosedflag || srcp == sp0) {
2021 		switch (skipmode) {
2022 		case SKIP_ELSE0:
2023 			srcp = src;
2024 			break;
2025 		case SKIP_ELSE1:
2026 			srcp = SkipMoji(sp0);
2027 			break;
2028 		default:
2029 			;
2030 		}
2031 	}
2032 	noerrmode = noerrmode0;
2033 	nevflag = nevflag0;
2034 	return (uchar*)srcp;
2035 }
2036 
2037 /**************************************/
2038 
2039 /* AEval... �ΰ�γ����դ� */
2040 
2041 #define AllocEvalBuf()	(nevflag ? (uchar *)NULL : (uchar *)XMalloc(evalbufsize))
2042 
2043 static void
CheckEvalBufLen(int len)2044 CheckEvalBufLen(int len)
2045 {
2046 	assert(!nevflag || len == 0);
2047 	if (len >= (int)evalbufsize)
2048 		FError("Eval buffer over");
2049 }
2050 
2051 uchar *
AEvalExpr(int * lenp,const uchar * src,const uchar ** endp,evlev_t evlevel)2052 AEvalExpr(int *lenp, const uchar *src, const uchar **endp,
2053 													evlev_t evlevel)
2054 {
2055 	int len;
2056 	uchar *dst = AllocEvalBuf();
2057 	len = EvalExpr(dst, src, endp, evlevel);
2058 	CheckEvalBufLen(len);
2059 	if (lenp) *lenp = len;
2060 	return (uchar *)XRealloc((voidstar)dst, len+1);
2061 }
2062 
2063 uchar *
AEvalPcForm(int * lenp,const uchar * src,const uchar ** endp)2064 AEvalPcForm(int *lenp, const uchar *src, const uchar **endp)
2065 {
2066 	int len;
2067 	uchar *dst = AllocEvalBuf();
2068 	len = EvalPcForm(dst, src, endp);
2069 	CheckEvalBufLen(len);
2070 	if (lenp) *lenp = len;
2071 	return (uchar *)XRealloc((voidstar)dst, len+1);
2072 }
2073 
2074 uchar *
AEvalString(int * lenp,const uchar * src)2075 AEvalString(int *lenp, const uchar *src)
2076 {
2077 	return AEvalStringB(lenp, src, (const uchar **)NULL, 0);
2078 }
2079 
2080 uchar *
AEvalStringB(int * lenp,const uchar * src,const uchar ** endp,int bflag)2081 AEvalStringB(int *lenp, const uchar *src, const uchar **endp, int bflag)
2082 {
2083 	int len;
2084 	uchar *dst = AllocEvalBuf();
2085 	len = EvalStringB(dst, src, endp, bflag);
2086 	CheckEvalBufLen(len);
2087 	if (lenp) *lenp = len;
2088 	return (uchar *)XRealloc((voidstar)dst, len+1);
2089 }
2090 
2091 uchar *
AEvalStringN(int * lenp,const uchar * src,int n)2092 AEvalStringN(int *lenp, const uchar *src, int n)
2093 {
2094 	int len;
2095 	uchar *dst = AllocEvalBuf();
2096 	len = EvalStringN(dst, src, n);
2097 	CheckEvalBufLen(len);
2098 	if (lenp) *lenp = len;
2099 	return (uchar *)XRealloc((voidstar)dst, len+1);
2100 }
2101 
2102 uchar *
AEvalExprStr(int * lenp,const uchar * src)2103 AEvalExprStr(int *lenp, const uchar *src)
2104 {
2105 	int len;
2106 	uchar *dst = AllocEvalBuf();
2107 	len = EvalExprStr(dst, src);
2108 	CheckEvalBufLen(len);
2109 	if (lenp) *lenp = len;
2110 	return (uchar *)XRealloc((voidstar)dst, len+1);
2111 }
2112 
2113 uchar *
AReadString(int * lenp,const uchar * src)2114 AReadString(int *lenp, const uchar *src)
2115 {
2116 	return AReadStringB(lenp, src, (const uchar **)NULL, EOF);
2117 }
2118 
2119 uchar *
AReadStringB(int * lenp,const uchar * src,const uchar ** endp,int brkchr)2120 AReadStringB(int *lenp, const uchar *src,const uchar **endp,int brkchr)
2121 {
2122 	int len;
2123 	uchar *dst = AllocEvalBuf();
2124 	len = ReadStringB(dst, src, endp, brkchr);
2125 	CheckEvalBufLen(len);
2126 	if (lenp) *lenp = len;
2127 	return (uchar *)XRealloc((voidstar)dst, len+1);
2128 }
2129 
2130 /*
2131  * Local variables:
2132  * mode: c
2133  * c-indent-level: 4
2134  * c-continued-statement-offset: 4
2135  * c-brace-offset: -4
2136  * c-argdecl-indent: 4
2137  * c-label-offset: -4
2138  * tab-width: 4
2139  * tab-stop-list: (4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64 68 72 76 80)
2140  * End:
2141  */
2142