8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / bc / bc.y
blob669aed4a57bc0f1493a9ecf02745309f82c4e4d4
1 %{
2 /*
3 * CDDL HEADER START
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.
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.
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]
21 * CDDL HEADER END
25 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
26 * Use is subject to license terms.
29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
30 /* All Rights Reserved */
33 #pragma ident "%Z%%M% %I% %E% SMI"
36 #include <stdio.h>
37 #include <stdarg.h>
38 #include <limits.h>
39 #include <libintl.h>
40 #include <locale.h>
41 #include <signal.h>
43 static void getout(int) __NORETURN;
44 static int *bundle(int, ...);
45 static void usage(void);
47 int cpeek(char, int, char, int, char);
48 void yyerror(char *);
51 %union {
52 int *iptr;
53 char *cptr;
54 int cc;
56 %start start;
57 %type <iptr> stat, def, slist, dlets, e
58 %type <iptr> slist, re, fprefix, cargs, eora, cons, constant, lora
59 %right '='
60 %left '+' '-'
61 %left '*' '/' '%'
62 %right '^'
63 %left UMINUS
65 %token <cptr> LETTER
66 %type <cptr> EQOP, CRS
67 %token <cc> DIGIT, SQRT, LENGTH, _IF, FFF, EQ
68 %token <cc> _WHILE _FOR NE LE GE INCR DECR
69 %token <cc> _RETURN _BREAK _DEFINE BASE OBASE SCALE
70 %token <cc> EQPL EQMI EQMUL EQDIV EQREM EQEXP
71 %token <cptr> _AUTO DOT
72 %token <cc> QSTR
75 #define STRING_SIZE (BC_STRING_MAX + 3) /* string plus quotes */
76 /* plus NULL */
78 FILE *in;
79 char cary[LINE_MAX+1];
80 char *cp = { cary };
81 char *cpend = &cary[LINE_MAX]; /* last address (not the null char) */
82 char string[STRING_SIZE];
83 char *str = { string };
84 int crs = '0';
85 int rcrs = '0'; /* reset crs */
86 int bindx = 0;
87 int lev = 0; /* current scope level */
88 int ln; /* line number of current file */
89 int *ttp;
90 char *ss; /* current input source */
91 int bstack[10] = { 0 };
92 char *numb[15] = {
93 " 0", " 1", " 2", " 3", " 4", " 5",
94 " 6", " 7", " 8", " 9", " 10", " 11",
95 " 12", " 13", " 14"
97 int *pre, *post;
98 int interact = 0; /* talking to a tty? */
101 start :
102 | start stat tail
104 output($2);
106 | start def dargs ')' '{' dlist slist '}'
108 ttp = bundle(6, pre, $7, post, "0", numb[lev], "Q");
109 conout(ttp, (char *)$2);
110 rcrs = crs;
111 output((int *)"");
112 lev = bindx = 0;
116 dlist : tail
117 | dlist _AUTO dlets tail
120 stat : e
121 = bundle(2, $1, "ps.");
123 = bundle(1, "");
124 | QSTR
125 = bundle(3, "[", $1, "]P");
126 | LETTER '=' e
127 = bundle(3, $3, "s", $1);
128 | LETTER '[' e ']' '=' e
129 = bundle(4, $6, $3, ":", geta($1));
130 | LETTER EQOP e
131 = bundle(6, "l", $1, $3, $2, "s", $1);
132 | LETTER '[' e ']' EQOP e
133 = bundle(8, $3, ";", geta($1), $6, $5, $3, ":", geta($1));
134 | _BREAK
135 = bundle(2, numb[lev-bstack[bindx-1]], "Q");
136 | _RETURN '(' e ')'
137 = bundle(4, $3, post, numb[lev], "Q");
138 | _RETURN '(' ')'
139 = bundle(4, "0", post, numb[lev], "Q");
140 | _RETURN
141 = bundle(4, "0", post, numb[lev], "Q");
142 | SCALE '=' e
143 = bundle(2, $3, "k");
144 | SCALE EQOP e
145 = bundle(4, "K", $3, $2, "k");
146 | BASE '=' e
147 = bundle(2, $3, "i");
148 | BASE EQOP e
149 = bundle(4, "I", $3, $2, "i");
150 | OBASE '=' e
151 = bundle(2, $3, "o");
152 | OBASE EQOP e
153 = bundle(4, "O", $3, $2, "o");
154 | '{' slist '}'
156 $$ = $2;
158 | FFF
159 = bundle(1, "fY");
160 | error
161 = bundle(1, "c");
162 | _IF CRS BLEV '(' re ')' stat
164 conout($7, $2);
165 bundle(3, $5, $2, " ");
167 | _WHILE CRS '(' re ')' stat BLEV
169 bundle(3, $6, $4, $2);
170 conout($$, $2);
171 bundle(3, $4, $2, " ");
173 | fprefix CRS re ';' e ')' stat BLEV
175 bundle(5, $7, $5, "s.", $3, $2);
176 conout($$, $2);
177 bundle(5, $1, "s.", $3, $2, " ");
179 | '~' LETTER '=' e
180 = bundle(3, $4, "S", $2);
183 EQOP : EQPL
185 $$ = "+";
187 | EQMI
189 $$ = "-";
191 | EQMUL
193 $$ = "*";
195 | EQDIV
197 $$ = "/";
199 | EQREM
201 $$ = "%%";
203 | EQEXP
205 $$ = "^";
209 fprefix : _FOR '(' e ';'
211 $$ = $3;
215 BLEV :
216 = --bindx;
219 slist : stat
220 | slist tail stat
221 = bundle(2, $1, $3);
224 tail : '\n'
226 ln++;
228 | ';'
231 re : e EQ e
233 $$ = bundle(3, $1, $3, "=");
235 | e '<' e
236 = bundle(3, $1, $3, ">");
237 | e '>' e
238 = bundle(3, $1, $3, "<");
239 | e NE e
240 = bundle(3, $1, $3, "!=");
241 | e GE e
242 = bundle(3, $1, $3, "!>");
243 | e LE e
244 = bundle(3, $1, $3, "!<");
246 = bundle(2, $1, " 0!=");
249 e : e '+' e
250 = bundle(3, $1, $3, "+");
251 | e '-' e
252 = bundle(3, $1, $3, "-");
253 | '-' e %prec UMINUS
254 = bundle(3, " 0", $2, "-");
255 | e '*' e
256 = bundle(3, $1, $3, "*");
257 | e '/' e
258 = bundle(3, $1, $3, "/");
259 | e '%' e
260 = bundle(3, $1, $3, "%%");
261 | e '^' e
262 = bundle(3, $1, $3, "^");
263 | LETTER '[' e ']'
264 = bundle(3, $3, ";", geta($1));
265 | LETTER INCR
266 = bundle(4, "l", $1, "d1+s", $1);
267 | INCR LETTER
268 = bundle(4, "l", $2, "1+ds", $2);
269 | DECR LETTER
270 = bundle(4, "l", $2, "1-ds", $2);
271 | LETTER DECR
272 = bundle(4, "l", $1, "d1-s", $1);
273 | LETTER '[' e ']' INCR
274 = bundle(7, $3, ";", geta($1), "d1+", $3, ":", geta($1));
275 | INCR LETTER '[' e ']'
276 = bundle(7, $4, ";", geta($2), "1+d", $4, ":", geta($2));
277 | LETTER '[' e ']' DECR
278 = bundle(7, $3, ";", geta($1), "d1-", $3, ":", geta($1));
279 | DECR LETTER '[' e ']'
280 = bundle(7, $4, ";", geta($2), "1-d", $4, ":", geta($2));
281 | SCALE INCR
282 = bundle(1, "Kd1+k");
283 | INCR SCALE
284 = bundle(1, "K1+dk");
285 | SCALE DECR
286 = bundle(1, "Kd1-k");
287 | DECR SCALE
288 = bundle(1, "K1-dk");
289 | BASE INCR
290 = bundle(1, "Id1+i");
291 | INCR BASE
292 = bundle(1, "I1+di");
293 | BASE DECR
294 = bundle(1, "Id1-i");
295 | DECR BASE
296 = bundle(1, "I1-di");
297 | OBASE INCR
298 = bundle(1, "Od1+o");
299 | INCR OBASE
300 = bundle(1, "O1+do");
301 | OBASE DECR
302 = bundle(1, "Od1-o");
303 | DECR OBASE
304 = bundle(1, "O1-do");
305 | LETTER '(' cargs ')'
306 = bundle(4, $3, "l", getf($1), "x");
307 | LETTER '(' ')'
308 = bundle(3, "l", getf($1), "x");
309 | cons
310 = bundle(2, " ", $1);
311 | DOT cons
312 = bundle(2, " .", $2);
313 | cons DOT cons
314 = bundle(4, " ", $1, ".", $3);
315 | cons DOT
316 = bundle(3, " ", $1, ".");
317 | DOT
319 $<cptr>$ = "l.";
321 | LETTER
322 = bundle(2, "l", $1);
323 | LETTER '=' e
324 = bundle(3, $3, "ds", $1);
325 | LETTER EQOP e %prec '='
326 = bundle(6, "l", $1, $3, $2, "ds", $1);
327 | LETTER '[' e ']' '=' e
328 = bundle(5, $6, "d", $3, ":", geta($1));
329 | LETTER '[' e ']' EQOP e
331 bundle(9, $3, ";", geta($1), $6, $5, "d", $3, ":",
332 geta($1));
334 | LENGTH '(' e ')'
335 = bundle(2, $3, "Z");
336 | SCALE '(' e ')'
337 = bundle(2, $3, "X"); /* must be before '(' e ')' */
338 | '(' e ')'
340 $$ = $2;
342 | '?'
343 = bundle(1, "?");
344 | SQRT '(' e ')'
345 = bundle(2, $3, "v");
346 | '~' LETTER
347 = bundle(2, "L", $2);
348 | SCALE '=' e
349 = bundle(2, $3, "dk");
350 | SCALE EQOP e %prec '='
351 = bundle(4, "K", $3, $2, "dk");
352 | BASE '=' e
353 = bundle(2, $3, "di");
354 | BASE EQOP e %prec '='
355 = bundle(4, "I", $3, $2, "di");
356 | OBASE '=' e
357 = bundle(2, $3, "do");
358 | OBASE EQOP e %prec '='
359 = bundle(4, "O", $3, $2, "do");
360 | SCALE
361 = bundle(1, "K");
362 | BASE
363 = bundle(1, "I");
364 | OBASE
365 = bundle(1, "O");
368 cargs : eora
369 | cargs ',' eora
370 = bundle(2, $1, $3);
372 eora : e
373 | LETTER '[' ']'
374 = bundle(2, "l", geta($1));
377 cons : constant
379 *cp++ = '\0';
382 constant: '_'
384 checkbuffer();
385 $<cptr>$ = cp;
386 *cp++ = '_';
388 | DIGIT
390 checkbuffer();
391 $<cptr>$ = cp;
392 *cp++ = $1;
394 | constant DIGIT
396 checkbuffer();
397 *cp++ = $2;
401 CRS :
403 checkbuffer();
404 $$ = cp;
405 *cp++ = crs++;
406 *cp++ = '\0';
407 if (crs == '[')
408 crs += 3;
409 if (crs == 'a')
410 crs = '{';
411 if (crs >= 0241) {
412 yyerror("program too big");
413 getout(1);
415 bstack[bindx++] = lev++;
419 def : _DEFINE LETTER '('
421 $$ = getf($2);
422 pre = (int *)"";
423 post = (int *)"";
424 lev = 1;
425 bstack[bindx = 0] = 0;
429 dargs : /* empty */
430 | lora
432 pp($1);
434 | dargs ',' lora
436 pp($3);
440 dlets : lora
441 = tp($1);
442 | dlets ',' lora
443 = tp($3);
446 lora : LETTER
448 $<cptr>$ = $1;
450 | LETTER '[' ']'
452 $$ = geta($1);
457 #define error 256
459 int peekc = -1;
460 int ifile; /* current index into sargv */
461 int sargc; /* size of sargv[] */
462 char **sargv; /* saved arg list without options */
464 char funtab[52] = {
465 01, 0, 02, 0, 03, 0, 04, 0, 05, 0, 06, 0, 07, 0,
466 010, 0, 011, 0, 012, 0, 013, 0, 014, 0, 015, 0, 016, 0, 017, 0,
467 020, 0, 021, 0, 022, 0, 023, 0, 024, 0, 025, 0, 026, 0, 027, 0,
468 030, 0, 031, 0, 032, 0
471 unsigned char atab[52] = {
472 0241, 0, 0242, 0, 0243, 0, 0244, 0, 0245, 0, 0246, 0, 0247, 0, 0250, 0,
473 0251, 0, 0252, 0, 0253, 0, 0254, 0, 0255, 0, 0256, 0, 0257, 0, 0260, 0,
474 0261, 0, 0262, 0, 0263, 0, 0264, 0, 0265, 0, 0266, 0, 0267, 0, 0270, 0,
475 0271, 0, 0272, 0
478 char *letr[26] = {
479 "a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
480 "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
481 "u", "v", "w", "x", "y", "z"
485 yylex(void)
487 int c, ch;
489 restart:
490 c = getch();
491 peekc = -1;
492 while (c == ' ' || c == '\t')
493 c = getch();
494 if (c == '\\') {
495 (void) getch();
496 goto restart;
498 if (c <= 'z' && c >= 'a') {
499 /* look ahead to look for reserved words */
500 peekc = getch();
501 if (peekc >= 'a' && peekc <= 'z') {
502 /* must be reserved word */
503 if (c == 'i' && peekc == 'f') {
504 c = _IF;
505 goto skip;
507 if (c == 'w' && peekc == 'h') {
508 c = _WHILE;
509 goto skip;
511 if (c == 'f' && peekc == 'o') {
512 c = _FOR;
513 goto skip;
515 if (c == 's' && peekc == 'q') {
516 c = SQRT;
517 goto skip;
519 if (c == 'r' && peekc == 'e') {
520 c = _RETURN;
521 goto skip;
523 if (c == 'b' && peekc == 'r') {
524 c = _BREAK;
525 goto skip;
527 if (c == 'd' && peekc == 'e') {
528 c = _DEFINE;
529 goto skip;
531 if (c == 's' && peekc == 'c') {
532 c = SCALE;
533 goto skip;
535 if (c == 'b' && peekc == 'a') {
536 c = BASE;
537 goto skip;
539 if (c == 'i' && peekc == 'b') {
540 c = BASE;
541 goto skip;
543 if (c == 'o' && peekc == 'b') {
544 c = OBASE;
545 goto skip;
547 if (c == 'd' && peekc == 'i') {
548 c = FFF;
549 goto skip;
551 if (c == 'a' && peekc == 'u') {
552 c = _AUTO;
553 goto skip;
555 if (c == 'l' && peekc == 'e') {
556 c = LENGTH;
557 goto skip;
559 if (c == 'q' && peekc == 'u') {
560 getout(0);
562 /* could not be found */
563 return (error);
565 skip: /* skip over rest of word */
566 peekc = -1;
567 while ((ch = getch()) >= 'a' && ch <= 'z')
569 peekc = ch;
570 return (c);
573 /* usual case; just one single letter */
575 yylval.cptr = letr[c-'a'];
576 return (LETTER);
579 if (c >= '0' && c <= '9' || c >= 'A' && c <= 'F') {
580 yylval.cc = c;
581 return (DIGIT);
584 switch (c) {
585 case '.':
586 return (DOT);
588 case '=':
589 switch ((peekc = getch())) {
590 case '=':
591 c = EQ;
592 goto gotit;
594 case '+':
595 c = EQPL;
596 goto gotit;
598 case '-':
599 c = EQMI;
600 goto gotit;
602 case '*':
603 c = EQMUL;
604 goto gotit;
606 case '/':
607 c = EQDIV;
608 goto gotit;
610 case '%':
611 c = EQREM;
612 goto gotit;
614 case '^':
615 c = EQEXP;
616 goto gotit;
618 default:
619 return ('=');
620 gotit:
621 peekc = -1;
622 return (c);
625 case '+':
626 return (cpeek('+', INCR, '=', EQPL, '+'));
628 case '-':
629 return (cpeek('-', DECR, '=', EQMI, '-'));
631 case '*':
632 return (cpeek('=', EQMUL, '\0', 0, '*'));
634 case '%':
635 return (cpeek('=', EQREM, '\0', 0, '%'));
637 case '^':
638 return (cpeek('=', EQEXP, '\0', 0, '^'));
640 case '<':
641 return (cpeek('=', LE, '\0', 0, '<'));
643 case '>':
644 return (cpeek('=', GE, '\0', 0, '>'));
646 case '!':
647 return (cpeek('=', NE, '\0', 0, '!'));
649 case '/':
650 if ((peekc = getch()) == '=') {
651 peekc = -1;
652 return (EQDIV);
654 if (peekc == '*') {
655 peekc = -1;
656 while ((getch() != '*') || ((peekc = getch()) != '/'))
658 peekc = -1;
659 goto restart;
661 else
662 return (c);
664 case '"':
665 yylval.cptr = str;
666 while ((c = getch()) != '"') {
667 *str++ = c;
668 if (str >= &string[STRING_SIZE-1]) {
669 yyerror("string space exceeded");
670 getout(1);
673 *str++ = '\0';
674 return (QSTR);
676 default:
677 return (c);
682 cpeek(char c1, int yes1, char c2, int yes2, char none)
684 int r;
686 peekc = getch();
687 if (peekc == c1)
688 r = yes1;
689 else if (peekc == c2)
690 r = yes2;
691 else
692 return (none);
693 peekc = -1;
694 return (r);
699 getch(void)
701 int ch;
702 char mbuf[LINE_MAX];
704 loop:
705 ch = (peekc < 0) ? getc(in) : peekc;
706 peekc = -1;
707 if (ch != EOF)
708 return (ch);
710 if (++ifile >= sargc) {
711 if (ifile >= sargc+1)
712 getout(0);
713 in = stdin;
714 ln = 0;
715 goto loop;
718 (void) fclose(in);
719 if ((in = fopen(sargv[ifile], "r")) != NULL) {
720 ln = 0;
721 ss = sargv[ifile];
722 goto loop;
724 (void) snprintf(mbuf, sizeof (mbuf), "can't open input file %s",
725 sargv[ifile]);
726 ln = -1;
727 ss = "command line";
728 yyerror(mbuf);
729 getout(1);
730 /*NOTREACHED*/
733 #define b_sp_max 5000
734 int b_space[b_sp_max];
735 int *b_sp_nxt = { b_space };
737 int bdebug = 0;
739 static int *
740 bundle(int i, ...)
742 va_list ap;
743 int *q;
745 va_start(ap, i);
746 q = b_sp_nxt;
747 if (bdebug)
748 printf("bundle %d elements at %o\n", i, q);
749 while (i-- > 0) {
750 if (b_sp_nxt >= & b_space[b_sp_max])
751 yyerror("bundling space exceeded");
752 *b_sp_nxt++ = va_arg(ap, int);
754 * b_sp_nxt++ = 0;
755 yyval.iptr = q;
756 va_end(ap);
757 return (q);
760 void
761 routput(int *p)
763 if (bdebug) printf("routput(%o)\n", p);
764 if (p >= &b_space[0] && p < &b_space[b_sp_max]) {
765 /* part of a bundle */
766 while (*p != 0)
767 routput((int *)*p++);
769 else
770 printf((char *)p); /* character string */
773 void
774 output(int *p)
776 routput(p);
777 b_sp_nxt = & b_space[0];
778 printf("\n");
779 (void) fflush(stdout);
780 cp = cary;
781 crs = rcrs;
784 void
785 conout(int *p, char *s)
787 printf("[");
788 routput(p);
789 printf("]s%s\n", s);
790 (void) fflush(stdout);
791 lev--;
794 void
795 yyerror(char *s)
797 if (ifile >= sargc)
798 ss = "teletype";
800 if (ss == 0 || *ss == 0)
801 (void) fprintf(stderr, gettext("%s on line %d\n"), s, ln+1);
802 else
803 (void) fprintf(stderr, gettext("%s on line %d, %s\n"),
804 s, ln+1, ss);
805 (void) fflush(stderr);
807 cp = cary;
808 crs = rcrs;
809 bindx = 0;
810 lev = 0;
811 b_sp_nxt = &b_space[0];
814 void
815 checkbuffer(void)
817 /* Do not exceed the last char in input line buffer */
818 if (cp >= cpend) {
819 yyerror("line too long\n");
820 getout(1);
824 void
825 pp(int *s)
827 /* puts the relevant stuff on pre and post for the letter s */
829 (void) bundle(3, "S", s, pre);
830 pre = yyval.iptr;
831 (void) bundle(4, post, "L", s, "s.");
832 post = yyval.iptr;
835 void
836 tp(int *s)
837 { /* same as pp, but for temps */
838 bundle(3, "0S", s, pre);
839 pre = yyval.iptr;
840 bundle(4, post, "L", s, "s.");
841 post = yyval.iptr;
844 void
845 yyinit(int argc, char **argv)
847 char mbuf[LINE_MAX];
849 (void) signal(SIGINT, SIG_IGN); /* ignore all interrupts */
851 sargv = argv;
852 sargc = argc;
853 if (sargc == 0)
854 in = stdin;
855 else if ((in = fopen(sargv[0], "r")) == NULL) {
856 (void) snprintf(mbuf, sizeof (mbuf), "can't open input file %s",
857 sargv[0]);
858 ln = -1;
859 ss = "command line";
860 yyerror(mbuf);
861 getout(1);
863 ifile = 0;
864 ln = 0;
865 ss = sargv[0];
868 static void
869 getout(int code)
871 printf("q");
872 (void) fflush(stdout);
873 exit(code);
876 int *
877 getf(char *p)
879 return ((int *) &funtab[2*(*p -0141)]);
882 int *
883 geta(char *p)
885 return ((int *) &atab[2*(*p - 0141)]);
889 main(int argc, char **argv)
891 int p[2];
892 int cflag = 0;
893 int lflag = 0;
894 int flag = 0;
895 char **av;
896 int filecounter = 0;
898 (void) setlocale(LC_ALL, "");
899 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
900 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
901 #endif
902 (void) textdomain(TEXT_DOMAIN);
904 while ((flag = getopt(argc, argv, "dcl")) != EOF) {
905 switch (flag) {
906 case 'd':
907 case 'c':
908 cflag++;
909 break;
911 case 'l':
912 lflag++;
913 break;
915 default:
916 fflush(stdout);
917 usage();
918 break;
922 argc -= optind;
923 av = &argv[optind];
926 * argc is the count of arguments, which should be filenames,
927 * remaining in argv. av is a pointer to the first of the
928 * remaining arguments.
931 for (filecounter = 0; filecounter < argc; filecounter++) {
932 if ((strlen(av[filecounter])) >= PATH_MAX) {
933 (void) fprintf(stderr,
934 gettext("File argument too long\n"));
935 exit(2);
939 if (lflag) {
941 * if the user wants to include the math library, prepend
942 * the math library filename to the argument list by
943 * overwriting the last option (there must be at least one
944 * supplied option if this is being done).
946 av = &argv[optind-1];
947 av[0] = "/usr/lib/lib.b";
948 argc++;
951 if (cflag) {
952 yyinit(argc, av);
953 yyparse();
954 exit(0);
957 pipe(p);
958 if (fork() == 0) {
959 (void) close(1);
960 dup(p[1]);
961 (void) close(p[0]);
962 (void) close(p[1]);
963 yyinit(argc, av);
964 yyparse();
965 exit(0);
967 (void) close(0);
968 dup(p[0]);
969 (void) close(p[0]);
970 (void) close(p[1]);
971 #ifdef XPG6
972 execl("/usr/xpg6/bin/dc", "dc", "-", 0);
973 #else
974 execl("/usr/bin/dc", "dc", "-", 0);
975 #endif
977 return (1);
980 static void
981 usage(void)
983 (void) fprintf(stderr, gettext(
984 "usage: bc [ -c ] [ -l ] [ file ... ]\n"));
985 exit(2);