1 %{ 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License, Version 1.0 only 7 * (the "License"). You may not use this file except in compliance 8 * with the License. 9 * 10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11 * or http://www.opensolaris.org/os/licensing. 12 * See the License for the specific language governing permissions 13 * and limitations under the License. 14 * 15 * When distributing Covered Code, include this CDDL HEADER in each 16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17 * If applicable, add the following below this CDDL HEADER, with the 18 * fields enclosed by brackets "[]" replaced with your own identifying 19 * information: Portions Copyright [yyyy] [name of copyright owner] 20 * 21 * CDDL HEADER END 22 */ 23 %} 24 /* 25 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 30 /* All Rights Reserved */ 31 32 %{ 33 #include <stdio.h> 34 #include <stdarg.h> 35 #include <limits.h> 36 #include <libintl.h> 37 #include <locale.h> 38 #include <signal.h> 39 40 static void getout(int) __NORETURN; 41 static int *bundle(int, ...); 42 static void usage(void); 43 44 int cpeek(char, int, char, int, char); 45 int yyerror(const char *); 46 47 #define STRING_SIZE (BC_STRING_MAX + 3) /* string plus quotes */ 48 /* plus NULL */ 49 50 FILE *in; 51 char cary[LINE_MAX+1]; 52 char *cp = { cary }; 53 char *cpend = &cary[LINE_MAX]; /* last address (not the null char) */ 54 char string[STRING_SIZE]; 55 char *str = { string }; 56 int crs = '0'; 57 int rcrs = '0'; /* reset crs */ 58 int bindx = 0; 59 int lev = 0; /* current scope level */ 60 int ln; /* line number of current file */ 61 int *ttp; 62 char *ss; /* current input source */ 63 int bstack[10] = { 0 }; 64 char *numb[15] = { 65 " 0", " 1", " 2", " 3", " 4", " 5", 66 " 6", " 7", " 8", " 9", " 10", " 11", 67 " 12", " 13", " 14" 68 }; 69 int *pre, *post; 70 int interact = 0; /* talking to a tty? */ 71 %} 72 73 %union { 74 int *iptr; 75 char *cptr; 76 int cc; 77 } 78 %start start; 79 %type <iptr> stat def slist dlets e 80 %type <iptr> re fprefix cargs eora cons constant lora 81 %right '=' 82 %left '+' '-' 83 %left '*' '/' '%' 84 %right '^' 85 %left UMINUS 86 87 %token <cptr> LETTER 88 %type <cptr> EQOP CRS 89 %token <cc> DIGIT SQRT LENGTH _IF FFF EQ 90 %token <cc> _WHILE _FOR NE LE GE INCR DECR 91 %token <cc> _RETURN _BREAK _DEFINE BASE OBASE SCALE 92 %token <cc> EQPL EQMI EQMUL EQDIV EQREM EQEXP 93 %token <cptr> _AUTO DOT 94 %token <cc> QSTR 95 96 %% 97 start : 98 | start stat tail 99 { 100 output($2); 101 } 102 | start def dargs ')' '{' dlist slist '}' 103 { 104 ttp = bundle(6, pre, $7, post, "0", numb[lev], "Q"); 105 conout(ttp, (char *)$2); 106 rcrs = crs; 107 output((int *)""); 108 lev = bindx = 0; 109 } 110 ; 111 112 dlist : tail 113 | dlist _AUTO dlets tail 114 ; 115 116 stat : e 117 { 118 bundle(2, $1, "ps."); 119 } 120 | 121 { 122 bundle(1, ""); 123 } 124 | QSTR 125 { 126 bundle(3, "[", $1, "]P"); 127 } 128 | LETTER '=' e 129 { 130 bundle(3, $3, "s", $1); 131 } 132 | LETTER '[' e ']' '=' e 133 { 134 bundle(4, $6, $3, ":", geta($1)); 135 } 136 | LETTER EQOP e 137 { 138 bundle(6, "l", $1, $3, $2, "s", $1); 139 } 140 | LETTER '[' e ']' EQOP e 141 { 142 bundle(8, $3, ";", geta($1), $6, $5, $3, ":", geta($1)); 143 } 144 | _BREAK 145 { 146 bundle(2, numb[lev-bstack[bindx-1]], "Q"); 147 } 148 | _RETURN '(' e ')' 149 { 150 bundle(4, $3, post, numb[lev], "Q"); 151 } 152 | _RETURN '(' ')' 153 { 154 bundle(4, "0", post, numb[lev], "Q"); 155 } 156 | _RETURN 157 { 158 bundle(4, "0", post, numb[lev], "Q"); 159 } 160 | SCALE '=' e 161 { 162 bundle(2, $3, "k"); 163 } 164 | SCALE EQOP e 165 { 166 bundle(4, "K", $3, $2, "k"); 167 } 168 | BASE '=' e 169 { 170 bundle(2, $3, "i"); 171 } 172 | BASE EQOP e 173 { 174 bundle(4, "I", $3, $2, "i"); 175 } 176 | OBASE '=' e 177 { 178 bundle(2, $3, "o"); 179 } 180 | OBASE EQOP e 181 { 182 bundle(4, "O", $3, $2, "o"); 183 } 184 | '{' slist '}' 185 { 186 $$ = $2; 187 } 188 | FFF 189 { 190 bundle(1, "fY"); 191 } 192 | error 193 { 194 bundle(1, "c"); 195 } 196 | _IF CRS BLEV '(' re ')' stat 197 { 198 conout($7, $2); 199 bundle(3, $5, $2, " "); 200 } 201 | _WHILE CRS '(' re ')' stat BLEV 202 { 203 bundle(3, $6, $4, $2); 204 conout($$, $2); 205 bundle(3, $4, $2, " "); 206 } 207 | fprefix CRS re ';' e ')' stat BLEV 208 { 209 bundle(5, $7, $5, "s.", $3, $2); 210 conout($$, $2); 211 bundle(5, $1, "s.", $3, $2, " "); 212 } 213 | '~' LETTER '=' e 214 { 215 bundle(3, $4, "S", $2); 216 } 217 ; 218 219 EQOP : EQPL 220 { 221 $$ = "+"; 222 } 223 | EQMI 224 { 225 $$ = "-"; 226 } 227 | EQMUL 228 { 229 $$ = "*"; 230 } 231 | EQDIV 232 { 233 $$ = "/"; 234 } 235 | EQREM 236 { 237 $$ = "%%"; 238 } 239 | EQEXP 240 { 241 $$ = "^"; 242 } 243 ; 244 245 fprefix : _FOR '(' e ';' 246 { 247 $$ = $3; 248 } 249 ; 250 251 BLEV : 252 { 253 --bindx; 254 } 255 ; 256 257 slist : stat 258 | slist tail stat 259 { 260 bundle(2, $1, $3); 261 } 262 ; 263 264 tail : '\n' 265 { 266 ln++; 267 } 268 | ';' 269 ; 270 271 re : e EQ e 272 { 273 $$ = bundle(3, $1, $3, "="); 274 } 275 | e '<' e 276 { 277 bundle(3, $1, $3, ">"); 278 } 279 | e '>' e 280 { 281 bundle(3, $1, $3, "<"); 282 } 283 | e NE e 284 { 285 bundle(3, $1, $3, "!="); 286 } 287 | e GE e 288 { 289 bundle(3, $1, $3, "!>"); 290 } 291 | e LE e 292 { 293 bundle(3, $1, $3, "!<"); 294 } 295 | e 296 { 297 bundle(2, $1, " 0!="); 298 } 299 ; 300 301 e : e '+' e 302 { 303 bundle(3, $1, $3, "+"); 304 } 305 | e '-' e 306 { 307 bundle(3, $1, $3, "-"); 308 } 309 | '-' e %prec UMINUS 310 { 311 bundle(3, " 0", $2, "-"); 312 } 313 | e '*' e 314 { 315 bundle(3, $1, $3, "*"); 316 } 317 | e '/' e 318 { 319 bundle(3, $1, $3, "/"); 320 } 321 | e '%' e 322 { 323 bundle(3, $1, $3, "%%"); 324 } 325 | e '^' e 326 { 327 bundle(3, $1, $3, "^"); 328 } 329 | LETTER '[' e ']' 330 { 331 bundle(3, $3, ";", geta($1)); 332 } 333 | LETTER INCR 334 { 335 bundle(4, "l", $1, "d1+s", $1); 336 } 337 | INCR LETTER 338 { 339 bundle(4, "l", $2, "1+ds", $2); 340 } 341 | DECR LETTER 342 { 343 bundle(4, "l", $2, "1-ds", $2); 344 } 345 | LETTER DECR 346 { 347 bundle(4, "l", $1, "d1-s", $1); 348 } 349 | LETTER '[' e ']' INCR 350 { 351 bundle(7, $3, ";", geta($1), "d1+", $3, ":", geta($1)); 352 } 353 | INCR LETTER '[' e ']' 354 { 355 bundle(7, $4, ";", geta($2), "1+d", $4, ":", geta($2)); 356 } 357 | LETTER '[' e ']' DECR 358 { 359 bundle(7, $3, ";", geta($1), "d1-", $3, ":", geta($1)); 360 } 361 | DECR LETTER '[' e ']' 362 { 363 bundle(7, $4, ";", geta($2), "1-d", $4, ":", geta($2)); 364 } 365 | SCALE INCR 366 { 367 bundle(1, "Kd1+k"); 368 } 369 | INCR SCALE 370 { 371 bundle(1, "K1+dk"); 372 } 373 | SCALE DECR 374 { 375 bundle(1, "Kd1-k"); 376 } 377 | DECR SCALE 378 { 379 bundle(1, "K1-dk"); 380 } 381 | BASE INCR 382 { 383 bundle(1, "Id1+i"); 384 } 385 | INCR BASE 386 { 387 bundle(1, "I1+di"); 388 } 389 | BASE DECR 390 { 391 bundle(1, "Id1-i"); 392 } 393 | DECR BASE 394 { 395 bundle(1, "I1-di"); 396 } 397 | OBASE INCR 398 { 399 bundle(1, "Od1+o"); 400 } 401 | INCR OBASE 402 { 403 bundle(1, "O1+do"); 404 } 405 | OBASE DECR 406 { 407 bundle(1, "Od1-o"); 408 } 409 | DECR OBASE 410 { 411 bundle(1, "O1-do"); 412 } 413 | LETTER '(' cargs ')' 414 { 415 bundle(4, $3, "l", getf($1), "x"); 416 } 417 | LETTER '(' ')' 418 { 419 bundle(3, "l", getf($1), "x"); 420 } 421 | cons 422 { 423 bundle(2, " ", $1); 424 } 425 | DOT cons 426 { 427 bundle(2, " .", $2); 428 } 429 | cons DOT cons 430 { 431 bundle(4, " ", $1, ".", $3); 432 } 433 | cons DOT 434 { 435 bundle(3, " ", $1, "."); 436 } 437 | DOT 438 { 439 $<cptr>$ = "l."; 440 } 441 | LETTER 442 { 443 bundle(2, "l", $1); 444 } 445 | LETTER '=' e 446 { 447 bundle(3, $3, "ds", $1); 448 } 449 | LETTER EQOP e %prec '=' 450 { 451 bundle(6, "l", $1, $3, $2, "ds", $1); 452 } 453 | LETTER '[' e ']' '=' e 454 { 455 bundle(5, $6, "d", $3, ":", geta($1)); 456 } 457 | LETTER '[' e ']' EQOP e 458 { 459 bundle(9, $3, ";", geta($1), $6, $5, "d", $3, ":", 460 geta($1)); 461 } 462 | LENGTH '(' e ')' 463 { 464 bundle(2, $3, "Z"); 465 } 466 | SCALE '(' e ')' 467 { 468 bundle(2, $3, "X"); /* must be before '(' e ')' */ 469 } 470 | '(' e ')' 471 { 472 $$ = $2; 473 } 474 | '?' 475 { 476 bundle(1, "?"); 477 } 478 | SQRT '(' e ')' 479 { 480 bundle(2, $3, "v"); 481 } 482 | '~' LETTER 483 { 484 bundle(2, "L", $2); 485 } 486 | SCALE '=' e 487 { 488 bundle(2, $3, "dk"); 489 } 490 | SCALE EQOP e %prec '=' 491 { 492 bundle(4, "K", $3, $2, "dk"); 493 } 494 | BASE '=' e 495 { 496 bundle(2, $3, "di"); 497 } 498 | BASE EQOP e %prec '=' 499 { 500 bundle(4, "I", $3, $2, "di"); 501 } 502 | OBASE '=' e 503 { 504 bundle(2, $3, "do"); 505 } 506 | OBASE EQOP e %prec '=' 507 { 508 bundle(4, "O", $3, $2, "do"); 509 } 510 | SCALE 511 { 512 bundle(1, "K"); 513 } 514 | BASE 515 { 516 bundle(1, "I"); 517 } 518 | OBASE 519 { 520 bundle(1, "O"); 521 } 522 ; 523 524 cargs : eora 525 | cargs ',' eora 526 { 527 bundle(2, $1, $3); 528 } 529 ; 530 eora : e 531 | LETTER '[' ']' 532 { 533 bundle(2, "l", geta($1)); 534 } 535 ; 536 537 cons : constant 538 { 539 *cp++ = '\0'; 540 } 541 542 constant: '_' 543 { 544 checkbuffer(); 545 $<cptr>$ = cp; 546 *cp++ = '_'; 547 } 548 | DIGIT 549 { 550 checkbuffer(); 551 $<cptr>$ = cp; 552 *cp++ = $1; 553 } 554 | constant DIGIT 555 { 556 checkbuffer(); 557 *cp++ = $2; 558 } 559 ; 560 561 CRS : 562 { 563 checkbuffer(); 564 $$ = cp; 565 *cp++ = crs++; 566 *cp++ = '\0'; 567 if (crs == '[') 568 crs += 3; 569 if (crs == 'a') 570 crs = '{'; 571 if (crs >= 0241) { 572 (void) yyerror("program too big"); 573 getout(1); 574 } 575 bstack[bindx++] = lev++; 576 } 577 ; 578 579 def : _DEFINE LETTER '(' 580 { 581 $$ = getf($2); 582 pre = (int *)""; 583 post = (int *)""; 584 lev = 1; 585 bstack[bindx = 0] = 0; 586 } 587 ; 588 589 dargs : /* empty */ 590 | lora 591 { 592 pp($1); 593 } 594 | dargs ',' lora 595 { 596 pp($3); 597 } 598 ; 599 600 dlets : lora 601 { 602 tp($1); 603 } 604 | dlets ',' lora 605 { 606 tp($3); 607 } 608 ; 609 610 lora : LETTER 611 { 612 $<cptr>$ = $1; 613 } 614 | LETTER '[' ']' 615 { 616 $$ = geta($1); 617 } 618 ; 619 620 %% 621 #define error 256 622 623 int peekc = -1; 624 int ifile; /* current index into sargv */ 625 int sargc; /* size of sargv[] */ 626 char **sargv; /* saved arg list without options */ 627 628 char funtab[52] = { 629 01, 0, 02, 0, 03, 0, 04, 0, 05, 0, 06, 0, 07, 0, 630 010, 0, 011, 0, 012, 0, 013, 0, 014, 0, 015, 0, 016, 0, 017, 0, 631 020, 0, 021, 0, 022, 0, 023, 0, 024, 0, 025, 0, 026, 0, 027, 0, 632 030, 0, 031, 0, 032, 0 633 }; 634 635 unsigned char atab[52] = { 636 0241, 0, 0242, 0, 0243, 0, 0244, 0, 0245, 0, 0246, 0, 0247, 0, 0250, 0, 637 0251, 0, 0252, 0, 0253, 0, 0254, 0, 0255, 0, 0256, 0, 0257, 0, 0260, 0, 638 0261, 0, 0262, 0, 0263, 0, 0264, 0, 0265, 0, 0266, 0, 0267, 0, 0270, 0, 639 0271, 0, 0272, 0 640 }; 641 642 char *letr[26] = { 643 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", 644 "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", 645 "u", "v", "w", "x", "y", "z" 646 }; 647 648 int 649 yylex(void) 650 { 651 int c, ch; 652 653 restart: 654 c = getch(); 655 peekc = -1; 656 while (c == ' ' || c == '\t') 657 c = getch(); 658 if (c == '\\') { 659 (void) getch(); 660 goto restart; 661 } 662 if (c <= 'z' && c >= 'a') { 663 /* look ahead to look for reserved words */ 664 peekc = getch(); 665 if (peekc >= 'a' && peekc <= 'z') { 666 /* must be reserved word */ 667 if (c == 'i' && peekc == 'f') { 668 c = _IF; 669 goto skip; 670 } 671 if (c == 'w' && peekc == 'h') { 672 c = _WHILE; 673 goto skip; 674 } 675 if (c == 'f' && peekc == 'o') { 676 c = _FOR; 677 goto skip; 678 } 679 if (c == 's' && peekc == 'q') { 680 c = SQRT; 681 goto skip; 682 } 683 if (c == 'r' && peekc == 'e') { 684 c = _RETURN; 685 goto skip; 686 } 687 if (c == 'b' && peekc == 'r') { 688 c = _BREAK; 689 goto skip; 690 } 691 if (c == 'd' && peekc == 'e') { 692 c = _DEFINE; 693 goto skip; 694 } 695 if (c == 's' && peekc == 'c') { 696 c = SCALE; 697 goto skip; 698 } 699 if (c == 'b' && peekc == 'a') { 700 c = BASE; 701 goto skip; 702 } 703 if (c == 'i' && peekc == 'b') { 704 c = BASE; 705 goto skip; 706 } 707 if (c == 'o' && peekc == 'b') { 708 c = OBASE; 709 goto skip; 710 } 711 if (c == 'd' && peekc == 'i') { 712 c = FFF; 713 goto skip; 714 } 715 if (c == 'a' && peekc == 'u') { 716 c = _AUTO; 717 goto skip; 718 } 719 if (c == 'l' && peekc == 'e') { 720 c = LENGTH; 721 goto skip; 722 } 723 if (c == 'q' && peekc == 'u') { 724 getout(0); 725 } 726 /* could not be found */ 727 return (error); 728 729 skip: /* skip over rest of word */ 730 peekc = -1; 731 while ((ch = getch()) >= 'a' && ch <= 'z') 732 ; 733 peekc = ch; 734 return (c); 735 } 736 737 /* usual case; just one single letter */ 738 739 yylval.cptr = letr[c-'a']; 740 return (LETTER); 741 } 742 743 if (c >= '0' && c <= '9' || c >= 'A' && c <= 'F') { 744 yylval.cc = c; 745 return (DIGIT); 746 } 747 748 switch (c) { 749 case '.': 750 return (DOT); 751 752 case '=': 753 switch ((peekc = getch())) { 754 case '=': 755 c = EQ; 756 goto gotit; 757 758 case '+': 759 c = EQPL; 760 goto gotit; 761 762 case '-': 763 c = EQMI; 764 goto gotit; 765 766 case '*': 767 c = EQMUL; 768 goto gotit; 769 770 case '/': 771 c = EQDIV; 772 goto gotit; 773 774 case '%': 775 c = EQREM; 776 goto gotit; 777 778 case '^': 779 c = EQEXP; 780 goto gotit; 781 782 default: 783 return ('='); 784 gotit: 785 peekc = -1; 786 return (c); 787 } 788 789 case '+': 790 return (cpeek('+', INCR, '=', EQPL, '+')); 791 792 case '-': 793 return (cpeek('-', DECR, '=', EQMI, '-')); 794 795 case '*': 796 return (cpeek('=', EQMUL, '\0', 0, '*')); 797 798 case '%': 799 return (cpeek('=', EQREM, '\0', 0, '%')); 800 801 case '^': 802 return (cpeek('=', EQEXP, '\0', 0, '^')); 803 804 case '<': 805 return (cpeek('=', LE, '\0', 0, '<')); 806 807 case '>': 808 return (cpeek('=', GE, '\0', 0, '>')); 809 810 case '!': 811 return (cpeek('=', NE, '\0', 0, '!')); 812 813 case '/': 814 if ((peekc = getch()) == '=') { 815 peekc = -1; 816 return (EQDIV); 817 } 818 if (peekc == '*') { 819 peekc = -1; 820 while ((getch() != '*') || ((peekc = getch()) != '/')) 821 ; 822 peekc = -1; 823 goto restart; 824 } 825 else 826 return (c); 827 828 case '"': 829 yylval.cptr = str; 830 while ((c = getch()) != '"') { 831 *str++ = c; 832 if (str >= &string[STRING_SIZE-1]) { 833 (void) yyerror("string space exceeded"); 834 getout(1); 835 } 836 } 837 *str++ = '\0'; 838 return (QSTR); 839 840 default: 841 return (c); 842 } 843 } 844 845 int 846 cpeek(char c1, int yes1, char c2, int yes2, char none) 847 { 848 int r; 849 850 peekc = getch(); 851 if (peekc == c1) 852 r = yes1; 853 else if (peekc == c2) 854 r = yes2; 855 else 856 return (none); 857 peekc = -1; 858 return (r); 859 } 860 861 862 int 863 getch(void) 864 { 865 int ch; 866 char mbuf[LINE_MAX]; 867 868 loop: 869 ch = (peekc < 0) ? getc(in) : peekc; 870 peekc = -1; 871 if (ch != EOF) 872 return (ch); 873 874 if (++ifile >= sargc) { 875 if (ifile >= sargc+1) 876 getout(0); 877 in = stdin; 878 ln = 0; 879 goto loop; 880 } 881 882 (void) fclose(in); 883 if ((in = fopen(sargv[ifile], "r")) != NULL) { 884 ln = 0; 885 ss = sargv[ifile]; 886 goto loop; 887 } 888 (void) snprintf(mbuf, sizeof (mbuf), "can't open input file %s", 889 sargv[ifile]); 890 ln = -1; 891 ss = "command line"; 892 (void) yyerror(mbuf); 893 getout(1); 894 /*NOTREACHED*/ 895 } 896 897 #define b_sp_max 5000 898 int b_space[b_sp_max]; 899 int *b_sp_nxt = { b_space }; 900 901 int bdebug = 0; 902 903 static int * 904 bundle(int i, ...) 905 { 906 va_list ap; 907 int *q; 908 909 va_start(ap, i); 910 q = b_sp_nxt; 911 if (bdebug) 912 printf("bundle %d elements at %o\n", i, q); 913 while (i-- > 0) { 914 if (b_sp_nxt >= & b_space[b_sp_max]) 915 (void) yyerror("bundling space exceeded"); 916 *b_sp_nxt++ = va_arg(ap, int); 917 } 918 * b_sp_nxt++ = 0; 919 yyval.iptr = q; 920 va_end(ap); 921 return (q); 922 } 923 924 void 925 routput(int *p) 926 { 927 if (bdebug) printf("routput(%o)\n", p); 928 if (p >= &b_space[0] && p < &b_space[b_sp_max]) { 929 /* part of a bundle */ 930 while (*p != 0) 931 routput((int *)*p++); 932 } 933 else 934 printf((char *)p); /* character string */ 935 } 936 937 void 938 output(int *p) 939 { 940 routput(p); 941 b_sp_nxt = & b_space[0]; 942 printf("\n"); 943 (void) fflush(stdout); 944 cp = cary; 945 crs = rcrs; 946 } 947 948 void 949 conout(int *p, char *s) 950 { 951 printf("["); 952 routput(p); 953 printf("]s%s\n", s); 954 (void) fflush(stdout); 955 lev--; 956 } 957 958 int 959 yyerror(const char *s) 960 { 961 if (ifile >= sargc) 962 ss = "teletype"; 963 964 if (ss == 0 || *ss == 0) 965 (void) fprintf(stderr, gettext("%s on line %d\n"), s, ln+1); 966 else 967 (void) fprintf(stderr, gettext("%s on line %d, %s\n"), 968 s, ln+1, ss); 969 (void) fflush(stderr); 970 971 cp = cary; 972 crs = rcrs; 973 bindx = 0; 974 lev = 0; 975 b_sp_nxt = &b_space[0]; 976 return (0); 977 } 978 979 void 980 checkbuffer(void) 981 { 982 /* Do not exceed the last char in input line buffer */ 983 if (cp >= cpend) { 984 (void) yyerror("line too long\n"); 985 getout(1); 986 } 987 } 988 989 void 990 pp(int *s) 991 { 992 /* puts the relevant stuff on pre and post for the letter s */ 993 994 (void) bundle(3, "S", s, pre); 995 pre = yyval.iptr; 996 (void) bundle(4, post, "L", s, "s."); 997 post = yyval.iptr; 998 } 999 1000 void 1001 tp(int *s) 1002 { /* same as pp, but for temps */ 1003 bundle(3, "0S", s, pre); 1004 pre = yyval.iptr; 1005 bundle(4, post, "L", s, "s."); 1006 post = yyval.iptr; 1007 } 1008 1009 void 1010 yyinit(int argc, char **argv) 1011 { 1012 char mbuf[LINE_MAX]; 1013 1014 (void) signal(SIGINT, SIG_IGN); /* ignore all interrupts */ 1015 1016 sargv = argv; 1017 sargc = argc; 1018 if (sargc == 0) 1019 in = stdin; 1020 else if ((in = fopen(sargv[0], "r")) == NULL) { 1021 (void) snprintf(mbuf, sizeof (mbuf), "can't open input file %s", 1022 sargv[0]); 1023 ln = -1; 1024 ss = "command line"; 1025 (void) yyerror(mbuf); 1026 getout(1); 1027 } 1028 ifile = 0; 1029 ln = 0; 1030 ss = sargv[0]; 1031 } 1032 1033 static void 1034 getout(int code) 1035 { 1036 printf("q"); 1037 (void) fflush(stdout); 1038 exit(code); 1039 } 1040 1041 int * 1042 getf(char *p) 1043 { 1044 return ((int *) &funtab[2*(*p -0141)]); 1045 } 1046 1047 int * 1048 geta(char *p) 1049 { 1050 return ((int *) &atab[2*(*p - 0141)]); 1051 } 1052 1053 int 1054 main(int argc, char **argv) 1055 { 1056 int p[2]; 1057 int cflag = 0; 1058 int lflag = 0; 1059 int flag = 0; 1060 char **av; 1061 int filecounter = 0; 1062 1063 (void) setlocale(LC_ALL, ""); 1064 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 1065 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */ 1066 #endif 1067 (void) textdomain(TEXT_DOMAIN); 1068 1069 while ((flag = getopt(argc, argv, "dcl")) != EOF) { 1070 switch (flag) { 1071 case 'd': 1072 case 'c': 1073 cflag++; 1074 break; 1075 1076 case 'l': 1077 lflag++; 1078 break; 1079 1080 default: 1081 fflush(stdout); 1082 usage(); 1083 break; 1084 } 1085 } 1086 1087 argc -= optind; 1088 av = &argv[optind]; 1089 1090 /* 1091 * argc is the count of arguments, which should be filenames, 1092 * remaining in argv. av is a pointer to the first of the 1093 * remaining arguments. 1094 */ 1095 1096 for (filecounter = 0; filecounter < argc; filecounter++) { 1097 if ((strlen(av[filecounter])) >= PATH_MAX) { 1098 (void) fprintf(stderr, 1099 gettext("File argument too long\n")); 1100 exit(2); 1101 } 1102 } 1103 1104 if (lflag) { 1105 /* 1106 * if the user wants to include the math library, prepend 1107 * the math library filename to the argument list by 1108 * overwriting the last option (there must be at least one 1109 * supplied option if this is being done). 1110 */ 1111 av = &argv[optind-1]; 1112 av[0] = "/usr/lib/lib.b"; 1113 argc++; 1114 } 1115 1116 if (cflag) { 1117 yyinit(argc, av); 1118 yyparse(); 1119 exit(0); 1120 } 1121 1122 pipe(p); 1123 if (fork() == 0) { 1124 (void) close(1); 1125 dup(p[1]); 1126 (void) close(p[0]); 1127 (void) close(p[1]); 1128 yyinit(argc, av); 1129 yyparse(); 1130 exit(0); 1131 } 1132 (void) close(0); 1133 dup(p[0]); 1134 (void) close(p[0]); 1135 (void) close(p[1]); 1136 #ifdef XPG6 1137 execl("/usr/xpg6/bin/dc", "dc", "-", 0); 1138 #else 1139 execl("/usr/bin/dc", "dc", "-", 0); 1140 #endif 1141 1142 return (1); 1143 } 1144 1145 static void 1146 usage(void) 1147 { 1148 (void) fprintf(stderr, gettext( 1149 "usage: bc [ -c ] [ -l ] [ file ... ]\n")); 1150 exit(2); 1151 } 1152