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