1/* expr.c */ 2/***************************************************************************** 3 �s�������@�o�����������������@�w�s�q 4 5 �m���̕]���n 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 132int 133IsFuncArgStr(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)) 156static 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)) 163static 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)) 170static uchar f_AsgnErr[] = "Illegal assignment: %.*s"; 171#endif 172 173static int unclosedflag; /* ���ʗނ����Ă��Ȃ����Ƃ������t���O */ 174 175static const uchar *srcp; 176static const uchar *expr; 177static uchar *valstr; 178static int vallen; 179static exprval_t exprval; 180 181static int 182ValNumStr(exprval_t val) 183{ 184 if (nevflag) return 0; 185 186 return vallen = WtNumber(valstr, val); 187} 188 189static int 190ValNum(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 202static int 203ValStr(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 213static exprval_t 214ValVal(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 224static exprval_t Expr ARGS((void)); 225static exprval_t Expr_asgn ARGS((void)); 226static exprval_t Expr_cond ARGS((void)); 227static exprval_t Expr_lor ARGS((void)); 228static exprval_t Expr_land ARGS((void)); 229static exprval_t Expr_or ARGS((void)); 230static exprval_t Expr_xor ARGS((void)); 231static exprval_t Expr_and ARGS((void)); 232static exprval_t Expr_rel ARGS((void)); 233static exprval_t Expr_conc ARGS((void)); 234static exprval_t Expr_sh ARGS((void)); 235static exprval_t Expr_add ARGS((void)); 236static exprval_t Expr_mul ARGS((void)); 237static exprval_t Expr_pref ARGS((void)); 238static exprval_t Expr_pow ARGS((void)); 239static exprval_t Expr_inc ARGS((void)); 240static exprval_t Expr_prim ARGS((void)); 241 242 243int 244EvalExpr(uchar *dst, const uchar *src, const uchar **endp, evlev_t evlevel) 245/* ����]������B 246 * evlevel �łǂ��܂Ŏ���ǂނ����w�� 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 301static 302exprval_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) 325static uchar f_UnkSysVar[] = "Unknown system variable: %s"; 326#endif 327 328static void 329PutVar1(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 359static uchar * 360GetVar1(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/* ���������_���̉����Z�ŁA���ʂ̒l������������Ƃ� 0 �ɂȂ�悤�ɂ��� */ 401 402static exprval_t 403FAdd(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 426static exprval_t Ex_sh ARGS((exprval_t a, exprval_t b, int rflag)); 427static 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 441static exprval_t 442Expr_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 541static exprval_t 542Expr_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 576static exprval_t 577Expr_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 598static exprval_t 599Expr_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 620static exprval_t 621Expr_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 638static exprval_t 639Expr_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 656static exprval_t 657Expr_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 674static exprval_t 675Expr_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 /* �����������܂߂Ċ��S�Ɉ�v����ꍇ�̂ݐ^ */ 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 726static exprval_t 727Expr_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 753static exprval_t 754Ex_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 766static exprval_t 767Expr_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 783static exprval_t 784Expr_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 804static exprval_t 805Expr_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 850static exprval_t 851Expr_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 878static exprval_t 879Ex_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 907static exprval_t 908Expr_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 925static exprval_t 926Expr_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 971static int FuncCall ARGS((uchar *dst, const uchar *name, const uchar *src, const uchar **endp, exprval_t *fretvalp)); 972 973static exprval_t 974Expr_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; /* ���ʗނ��������̃`�F�b�N�p */ 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 /* �_�u���N�H�[�g���A�����Ă�����P�̕�����Ƃ݂Ȃ� */ 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 �����Ƃ���ƍ����̂��ƂɂȂ�̂ŁA�p�~ */ 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 /* ���l�Ƃ��ēǂ߂Ȃ���� */ 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 1182int 1183RdNum(const uchar *src, const uchar **endp) 1184{ 1185 return (int)strtol((const char *)src, (char**)endp, 10); 1186} 1187 1188 1189exprval_t 1190RdNumber(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; /* �k��������̒l�� 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 �̑�֕��������_���Z(/FPa)�g�p�̏ꍇ�̂��� */ 1240 if (isdigit(*srcp)) { 1241 /* MSC 6.0 �̑�֕��������_���C�u�������g���ƁAstrtod �� 1242 �I�[�o�[�t���[�����Ƃ����Ƃ��Ă̔F���������� 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 1274int 1275WtNum(uchar *dst, int num) 1276{ 1277 sprintf((char *)dst, "%d", num); 1278 return strlen((char *)dst); 1279} 1280 1281int 1282WtNumber(uchar *dst, exprval_t num) 1283{ 1284 sprintf((char *)dst, EXPRVAL_PRINTF_FMT, num); 1285 return strlen((char *)dst); 1286} 1287 1288/******************************* EvalPcForm *******************************/ 1289 1290static uchar * 1291SkipPFmt(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 1300static int 1301CommaNum(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 1320static int 1321PFormatS(uchar *dst, const uchar *fmt, int f_type, const uchar *vals, int len) 1322{ 1323 if (!*(fmt+1)) { 1324 /* �t�H�[�}�b�g�w�肪�Ȃ�����̂܂܃R�s�[ */ 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�w�肪����fprec�w�薳���Ȃ�fprec=fwidth */ 1334 /* f_type==0 ��fwidth�w�� 0 ��fprec�w�薳���Ȃ�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 1362int 1363PFormat(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 1478static int 1479CopyEnvValN(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 1496int 1497CopyEnvVal(uchar *dst, const uchar *name) 1498{ 1499 return CopyEnvValN(dst, name, strlen((const char *)name)); 1500} 1501 1502int 1503EvalPcForm(uchar *dst, const uchar *src, const uchar **endp) 1504/* src: <%-form2> -- '%' �̎��̕������w�� */ 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; /* �ϊ������p�o�b�t�@�imalloc �ŗ̈�m�ہj */ 1514 uchar *vbuf = NULL; /* �ϐ��i�[�p�o�b�t�@�imalloc �ŗ̈�m�ہj */ 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 /* '%' �̌オ�p�����܂��� '-'�t���̉p�����Ȃ� */ 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 /* �g�ݍ��݊� cmd(str), _(str) �ɖ����䂸��A�p�~ */ 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 /* �g�ݍ��݊� fn(path, fname) �����������̂ŁA����̓{�c */ 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 /* '%' �̌オ���̑��̕����Ȃ�A���̂܂� '%' ��L���ɂ��� */ 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) 1665static 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) 1674static uchar f_ManyArgErr[] = "Too many arguments: %s%s"; 1675#endif 1676 1677static int 1678FuncCallSub(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 /* ������������Q�Ƃ���̏ꍇ */ 1731 fargcnt++; 1732 vbuf2 = AEvalExpr(&len2, srcp, &srcp, EXPR_SEMIMAX); 1733 if (*CutSpace(srcp) == ',') 1734 srcp++; 1735 } 1736 } 1737 if (*CutSpace(srcp) != ')') { 1738 /* ���l�����̏��� */ 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 /* ���Ăяo���`���̏ꍇ */ 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 1852static int 1853FuncCall(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; /* �������X�g�̊��ʂ����Ă��邩�̃`�F�b�N�p */ 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 /* ����ŃG���[�ɂȂ��Ă����ɂ͂��Ȃ��͂� */ 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 1896int 1897EvalString(uchar *dst, const uchar *src) 1898/* ������Ɂq%-�ϊ��r���{������ł̃R�s�[���s�� */ 1899/* dst �Ɋi�[�����������i�k���������j��Ԃ� */ 1900{ 1901 return EvalStringB(dst, src, (const uchar **)NULL, 0); 1902} 1903 1904int 1905EvalStringB(uchar *dst, const uchar *src, const uchar **endp, int bflag) 1906/* bflag ���^�Ȃ�A'{' �̎��̕����ŌĂ�āA�Ή����� '}' �܂œǂށB 1907 * ���̏ꍇ�A�Ō�� '}'�̓R�s�[���Ȃ��œǂݎ̂Ă�B 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 1959int 1960EvalStringN(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 1989int 1990EvalExprStr(uchar *dst, const uchar *src) 1991{ 1992 return EvalExpr(dst, src, (const uchar **)NULL, EXPR_MAX); 1993} 1994 1995 1996exprval_t 1997EvalExprVal(const uchar *src, const uchar **endp, evlev_t evlevel) 1998/* ����]�����Đ��Ƃ��Ă̒l��Ԃ� */ 1999{ 2000 uchar *vbuf = AEvalExpr((int *)NULL, src, endp, evlevel); 2001 XFree((voidstar)vbuf); 2002 return exprval; 2003} 2004 2005uchar * 2006SkipExpr(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... �̈�̊m�ەt�� */ 2040 2041#define AllocEvalBuf() (nevflag ? (uchar *)NULL : (uchar *)XMalloc(evalbufsize)) 2042 2043static void 2044CheckEvalBufLen(int len) 2045{ 2046 assert(!nevflag || len == 0); 2047 if (len >= (int)evalbufsize) 2048 FError("Eval buffer over"); 2049} 2050 2051uchar * 2052AEvalExpr(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 2063uchar * 2064AEvalPcForm(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 2074uchar * 2075AEvalString(int *lenp, const uchar *src) 2076{ 2077 return AEvalStringB(lenp, src, (const uchar **)NULL, 0); 2078} 2079 2080uchar * 2081AEvalStringB(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 2091uchar * 2092AEvalStringN(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 2102uchar * 2103AEvalExprStr(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 2113uchar * 2114AReadString(int *lenp, const uchar *src) 2115{ 2116 return AReadStringB(lenp, src, (const uchar **)NULL, EOF); 2117} 2118 2119uchar * 2120AReadStringB(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