8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / sgs / lex / common / sub1.c
blob69eb0b545c1e0ba738d7b25843e4ed0a23a63282
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 /* Copyright (c) 1988 AT&T */
27 /* All Rights Reserved */
29 #pragma ident "%Z%%M% %I% %E% SMI"
31 #include "ldefs.h"
32 #include <limits.h>
35 * return next line of input, throw away trailing '\n'
36 * and also throw away trailing blanks (spaces and tabs)
37 * returns 0 if eof is had immediately
40 CHR *
41 getl(CHR *p)
43 int c;
44 CHR *s, *t, *u;
45 int blank = 0;
47 t = s = p;
48 while (((c = gch()) != 0) && c != '\n') {
49 if (t >= &p[BUF_SIZ])
50 error("definitions too long");
51 if (c == ' ' || c == '\t') {
52 if (!blank) {
53 blank = 1;
54 u = t;
56 } else
57 blank = 0;
59 *t++ = c;
61 if (blank)
62 *u = 0;
63 else
64 *t = 0;
66 if (c == 0 && s == t)
67 return ((CHR *) 0);
68 prev = '\n';
69 pres = '\n';
70 return (s);
73 int
74 space(int ch)
76 switch (ch) {
77 case ' ':
78 case '\t':
79 case '\n':
80 return (1);
82 return (0);
85 int
86 digit(int c)
88 return (c >= '0' && c <= '9');
91 /* VARARGS1 */
92 void
93 error(s, p, d)
94 char *s;
95 int p, d;
97 /* if(!eof) */
98 if (!yyline)
99 (void) fprintf(errorf, "Command line: ");
100 else {
101 (void) fprintf(errorf,
102 !no_input ? "" : "\"%s\":", sargv[optind]);
103 (void) fprintf(errorf, "line %d: ", yyline);
105 (void) fprintf(errorf, "Error: ");
106 /*LINTED: E_SEC_PRINTF_VAR_FMT*/
107 (void) fprintf(errorf, s, p, d);
108 (void) putc('\n', errorf);
109 if (fatal)
110 error_tail();
113 void
114 error_tail(void)
116 #ifdef DEBUG
117 if (debug && sect != ENDSECTION) {
118 sect1dump();
119 sect2dump();
121 #endif
123 if (report == 1)
124 statistics();
125 exit(1);
126 /* NOTREACHED */
129 /* VARARGS1 */
130 void
131 warning(s, p, d)
132 char *s;
133 int p, d;
135 if (!eof)
136 if (!yyline)
137 (void) fprintf(errorf, "Command line: ");
138 else {
139 (void) fprintf(errorf,
140 !no_input?"":"\"%s\":", sargv[optind]);
141 (void) fprintf(errorf,
142 "line %d: ", yyline);
144 (void) fprintf(errorf, "Warning: ");
145 /*LINTED: E_SEC_PRINTF_VAR_FMT*/
146 (void) fprintf(errorf, s, p, d);
147 (void) putc('\n', errorf);
148 (void) fflush(errorf);
149 if (fout)
150 (void) fflush(fout);
151 (void) fflush(stdout);
155 * This function is apparently unused, but lint flags the fact
156 * that it does not have the same signature as the libc function
157 * of the same name. So, take it out of view for lint.
159 #if !defined(__lint)
161 index(int a, CHR *s)
163 int k;
164 for (k = 0; s[k]; k++)
165 if (s[k] == a)
166 return (k);
167 return (-1);
169 #endif
172 alpha(int c)
174 return ('a' <= c && c <= 'z' ||
175 'A' <= c && c <= 'Z');
179 printable(int c)
181 return (c > 040 && c < 0177);
184 void
185 lgate(void)
187 char fname[20];
189 if (lgatflg)
190 return;
191 lgatflg = 1;
192 if (fout == NULL) {
193 (void) sprintf(fname, "lex.yy.%c", ratfor ? 'r' : 'c');
194 fout = fopen(fname, "w");
196 if (fout == NULL)
197 error("Can't open %s", fname);
198 if (ratfor)
199 (void) fprintf(fout, "#\n");
200 phead1();
204 * scopy(ptr to str, ptr to str) - copy first arg str to second
205 * returns ptr to second arg
207 void
208 scopy(CHR *s, CHR *t)
210 CHR *i;
211 i = t;
212 while (*i++ = *s++)
217 * convert string t, return integer value
220 siconv(CHR *t)
222 int i, sw;
223 CHR *s;
224 s = t;
225 while (space(*s))
226 s++;
227 if (!digit(*s) && *s != '-')
228 error("missing translation value");
229 sw = 0;
230 if (*s == '-') {
231 sw = 1;
232 s++;
234 if (!digit(*s))
235 error("incomplete translation format");
236 i = 0;
237 while ('0' <= *s && *s <= '9')
238 i = i * 10 + (*(s++)-'0');
239 return (sw ? -i : i);
243 * slength(ptr to str) - return integer length of string arg
244 * excludes '\0' terminator
247 slength(CHR *s)
249 int n;
250 CHR *t;
251 t = s;
252 for (n = 0; *t++; n++)
254 return (n);
258 * scomp(x,y) - return -1 if x < y,
259 * 0 if x == y,
260 * return 1 if x > y, all lexicographically
263 scomp(CHR *x, CHR *y)
265 CHR *a, *d;
266 a = (CHR *) x;
267 d = (CHR *) y;
268 while (*a || *d) {
269 if (*a > *d)
270 return (1);
271 if (*a < *d)
272 return (-1);
273 a++;
274 d++;
276 return (0);
280 ctrans(CHR **ss)
282 int c, k;
283 if ((c = **ss) != '\\')
284 return (c);
285 switch (c = *++*ss) {
286 case 'a':
287 c = '\a';
288 warning("\\a is ANSI C \"alert\" character");
289 break;
290 case 'v': c = '\v'; break;
291 case 'n': c = '\n'; break;
292 case 't': c = '\t'; break;
293 case 'r': c = '\r'; break;
294 case 'b': c = '\b'; break;
295 case 'f': c = 014; break; /* form feed for ascii */
296 case '\\': c = '\\'; break;
297 case 'x': {
298 int dd;
299 warning("\\x is ANSI C hex escape");
300 if (digit((dd = *++*ss)) ||
301 ('a' <= dd && dd <= 'f') ||
302 ('A' <= dd && dd <= 'F')) {
303 c = 0;
304 while (digit(dd) ||
305 ('A' <= dd && dd <= 'F') ||
306 ('a' <= dd && dd <= 'f')) {
307 if (digit(dd))
308 c = c*16 + dd - '0';
309 else if (dd >= 'a')
310 c = c*16 + 10 + dd - 'a';
311 else
312 c = c*16 + 10 + dd - 'A';
313 dd = *++*ss;
315 } else
316 c = 'x';
317 break;
319 case '0': case '1': case '2': case '3':
320 case '4': case '5': case '6': case '7':
321 c -= '0';
322 while ((k = *(*ss+1)) >= '0' && k <= '7') {
323 c = c*8 + k - '0';
324 (*ss)++;
326 break;
328 return (c);
331 void
332 cclinter(int sw)
334 /* sw = 1 ==> ccl */
335 int i, j, k;
336 int m;
337 if (!sw) { /* is NCCL */
338 for (i = 1; i < ncg; i++)
339 symbol[i] ^= 1; /* reverse value */
341 for (i = 1; i < ncg; i++)
342 if (symbol[i])
343 break;
344 if (i >= ncg)
345 return;
346 i = cindex[i];
347 /* see if ccl is already in our table */
348 j = 0;
349 if (i) {
350 for (j = 1; j < ncg; j++) {
351 if ((symbol[j] && cindex[j] != i) ||
352 (!symbol[j] && cindex[j] == i))
353 break;
356 if (j >= ncg)
357 return; /* already in */
358 m = 0;
359 k = 0;
360 for (i = 1; i < ncg; i++) {
361 if (symbol[i]) {
362 if (!cindex[i]) {
363 cindex[i] = ccount;
364 symbol[i] = 0;
365 m = 1;
366 } else
367 k = 1;
370 /* m == 1 implies last value of ccount has been used */
371 if (m)
372 ccount++;
373 if (k == 0)
374 return; /* is now in as ccount wholly */
375 /* intersection must be computed */
376 for (i = 1; i < ncg; i++) {
377 if (symbol[i]) {
378 m = 0;
379 j = cindex[i]; /* will be non-zero */
380 for (k = 1; k < ncg; k++) {
381 if (cindex[k] == j) {
382 if (symbol[k])
383 symbol[k] = 0;
384 else {
385 cindex[k] = ccount;
386 m = 1;
390 if (m)
391 ccount++;
397 usescape(int c)
399 char d;
400 switch (c) {
401 case 'a':
402 c = '\a';
403 warning("\\a is ANSI C \"alert\" character"); break;
404 case 'v': c = '\v'; break;
405 case 'n': c = '\n'; break;
406 case 'r': c = '\r'; break;
407 case 't': c = '\t'; break;
408 case 'b': c = '\b'; break;
409 case 'f': c = 014; break; /* form feed for ascii */
410 case 'x': {
411 int dd;
412 if (digit((dd = gch())) ||
413 ('A' <= dd && dd <= 'F') ||
414 ('a' <= dd && dd <= 'f')) {
415 c = 0;
416 while (digit(dd) ||
417 ('A' <= dd && dd <= 'F') ||
418 ('a' <= dd && dd <= 'f')) {
419 if (digit(dd))
420 c = c*16 + dd - '0';
421 else if (dd >= 'a')
422 c = c*16 + 10 + dd - 'a';
423 else
424 c = c*16 + 10 + dd - 'A';
425 if (!digit(peek) &&
426 !('A' <= peek && peek <= 'F') &&
427 !('a' <= peek && peek <= 'f'))
428 break;
429 dd = gch();
432 } else
433 c = 'x';
434 break;
436 case '0': case '1': case '2': case '3':
437 case '4': case '5': case '6': case '7':
438 c -= '0';
439 while ('0' <= (d = gch()) && d <= '7') {
440 c = c * 8 + (d-'0');
441 if (!('0' <= peek && peek <= '7')) break;
444 break;
447 if (handleeuc && !isascii(c)) {
448 char tmpchar = c & 0x00ff;
449 (void) mbtowc((wchar_t *)&c, &tmpchar, sizeof (tmpchar));
451 return (c);
455 lookup(CHR *s, CHR **t)
457 int i;
458 i = 0;
459 while (*t) {
460 if (scomp(s, *t) == 0)
461 return (i);
462 i++;
463 t++;
465 return (-1);
468 void
469 cpycom(CHR *p)
471 static CHR *t;
472 static int c;
473 t = p;
475 if (sargv[optind] == NULL)
476 (void) fprintf(fout, "\n# line %d\n", yyline);
477 else
478 (void) fprintf(fout,
479 "\n# line %d \"%s\"\n", yyline, sargv[optind]);
481 (void) putc(*t++, fout);
482 (void) putc(*t++, fout);
483 while (*t) {
484 while (*t == '*') {
485 (void) putc(*t++, fout);
486 if (*t == '/')
487 goto backcall;
490 * FIX BUG #1058428, not parsing comments correctly
491 * that span more than one line
493 if (*t != NULL)
494 (void) putc(*t++, fout);
496 (void) putc('\n', fout);
497 while (c = gch()) {
498 while (c == '*') {
499 (void) putc((char)c, fout);
500 if ((c = gch()) == '/') {
501 while ((c = gch()) == ' ' || c == '\t')
503 if (!space(c))
504 error("unacceptable statement");
505 prev = '\n';
506 goto backcall;
509 (void) putc((char)c, fout);
511 error("unexpected EOF inside comment");
512 backcall:
513 (void) putc('/', fout);
514 (void) putc('\n', fout);
518 * copy C action to the next ; or closing
521 cpyact(void)
523 int brac, c, mth;
524 static int sw, savline;
526 brac = 0;
527 sw = TRUE;
528 savline = yyline;
530 if (sargv[optind] == NULL)
531 (void) fprintf(fout, "\n# line %d\n", yyline);
532 else
533 (void) fprintf(fout,
534 "\n# line %d \"%s\"\n", yyline, sargv[optind]);
536 while (!eof) {
537 c = gch();
538 swt:
539 switch (c) {
540 case '|':
541 if (brac == 0 && sw == TRUE) {
542 if (peek == '|')
543 (void) gch(); /* eat up an extra '|' */
544 return (0);
546 break;
547 case ';':
548 if (brac == 0) {
549 (void) putwc(c, fout);
550 (void) putc('\n', fout);
551 return (1);
553 break;
554 case '{':
555 brac++;
556 savline = yyline;
557 break;
558 case '}':
559 brac--;
560 if (brac == 0) {
561 (void) putwc(c, fout);
562 (void) putc('\n', fout);
563 return (1);
565 break;
566 case '/':
567 (void) putwc(c, fout);
568 c = gch();
569 if (c != '*')
570 goto swt;
571 (void) putwc(c, fout);
572 savline = yyline;
573 while (c = gch()) {
574 while (c == '*') {
575 (void) putwc(c, fout);
576 if ((c = gch()) == '/') {
577 (void) putc('/', fout);
578 while ((c = gch()) == ' ' ||
579 c == '\t' || c == '\n')
580 (void) putwc(c, fout);
581 goto swt;
584 (void) putc((char)c, fout);
586 yyline = savline;
587 error("EOF inside comment");
588 /* NOTREACHED */
589 break;
590 case '\'': /* character constant */
591 case '"': /* character string */
592 mth = c;
593 (void) putwc(c, fout);
594 while (c = gch()) {
595 if (c == '\\') {
596 (void) putwc(c, fout);
597 c = gch();
599 else
600 if (c == mth)
601 goto loop;
602 (void) putwc(c, fout);
603 if (c == '\n') {
604 yyline--;
605 error(
606 "Non-terminated string or character constant");
609 error("EOF in string or character constant");
610 /* NOTREACHED */
611 break;
612 case '\0':
613 yyline = savline;
614 error("Action does not terminate");
615 /* NOTREACHED */
616 break;
617 default:
618 break; /* usual character */
620 loop:
621 if (c != ' ' && c != '\t' && c != '\n')
622 sw = FALSE;
623 (void) putwc(c, fout);
624 if (peek == '\n' && !brac && copy_line) {
625 (void) putc('\n', fout);
626 return (1);
629 error("Premature EOF");
630 return (0);
634 gch(void)
636 int c;
637 prev = pres;
638 c = pres = peek;
639 peek = pushptr > pushc ? *--pushptr : getwc(fin);
640 while (peek == EOF) {
641 if (no_input) {
642 if (!yyline)
643 error("Cannot read from -- %s",
644 sargv[optind]);
645 if (optind < sargc-1) {
646 yyline = 0;
647 if (fin != stdin)
648 (void) fclose(fin);
649 fin = fopen(sargv[++optind], "r");
650 if (fin == NULL)
651 error("Cannot open file -- %s",
652 sargv[optind]);
653 peek = getwc(fin);
654 } else
655 break;
656 } else {
657 if (fin != stdin)
658 (void) fclose(fin);
659 if (!yyline)
660 error("Cannot read from -- standard input");
661 else
662 break;
665 if (c == EOF) {
666 eof = TRUE;
667 return (0);
669 if (c == '\n')
670 yyline++;
671 return (c);
675 mn2(int a, int d, int c)
677 if (tptr >= treesize) {
678 tptr++;
679 error("Parse tree too big %s",
680 (treesize == TREESIZE ? "\nTry using %e num" : ""));
682 if (d >= treesize) {
683 error("Parse error");
685 name[tptr] = a;
686 left[tptr] = d;
687 right[tptr] = c;
688 parent[tptr] = 0;
689 nullstr[tptr] = 0;
690 switch (a) {
691 case RSTR:
692 parent[d] = tptr;
693 break;
694 case BAR:
695 case RNEWE:
696 if (nullstr[d] || nullstr[c])
697 nullstr[tptr] = TRUE;
698 parent[d] = parent[c] = tptr;
699 break;
700 case RCAT:
701 case DIV:
702 if (nullstr[d] && nullstr[c])
703 nullstr[tptr] = TRUE;
704 parent[d] = parent[c] = tptr;
705 break;
706 /* XCU4: add RXSCON */
707 case RXSCON:
708 case RSCON:
709 parent[d] = tptr;
710 nullstr[tptr] = nullstr[d];
711 break;
712 #ifdef DEBUG
713 default:
714 warning("bad switch mn2 %d %d", a, d);
715 break;
716 #endif
718 return (tptr++);
722 mn1(int a, int d)
724 if (tptr >= treesize) {
725 tptr++;
726 error("Parse tree too big %s",
727 (treesize == TREESIZE ? "\nTry using %e num" : ""));
729 name[tptr] = a;
730 left[tptr] = d;
731 parent[tptr] = 0;
732 nullstr[tptr] = 0;
733 switch (a) {
734 case RCCL:
735 case RNCCL:
736 if (slength((CHR *)d) == 0)
737 nullstr[tptr] = TRUE;
738 break;
739 case STAR:
740 case QUEST:
741 nullstr[tptr] = TRUE;
742 parent[d] = tptr;
743 break;
744 case PLUS:
745 case CARAT:
746 nullstr[tptr] = nullstr[d];
747 parent[d] = tptr;
748 break;
749 case S2FINAL:
750 nullstr[tptr] = TRUE;
751 break;
752 #ifdef DEBUG
753 case FINAL:
754 case S1FINAL:
755 break;
756 default:
757 warning("bad switch mn1 %d %d", a, d);
758 break;
759 #endif
761 return (tptr++);
765 mn0(int a)
767 if (tptr >= treesize) {
768 tptr++;
769 error("Parse tree too big %s",
770 (treesize == TREESIZE ? "\nTry using %e num" : ""));
773 name[tptr] = a;
774 parent[tptr] = 0;
775 nullstr[tptr] = 0;
776 if (ISOPERATOR(a)) {
777 switch (a) {
778 case DOT: break;
779 case RNULLS: nullstr[tptr] = TRUE; break;
780 #ifdef DEBUG
781 default:
782 warning("bad switch mn0 %d", a);
783 break;
784 #endif
787 return (tptr++);
790 void
791 munput(int t, CHR *p)
793 int i, j;
794 if (t == 'c') {
795 *pushptr++ = peek;
796 peek = *p;
797 } else if (t == 's') {
798 *pushptr++ = peek;
799 peek = p[0];
800 i = slength(p);
801 for (j = i - 1; j >= 1; j--)
802 *pushptr++ = p[j];
804 if (pushptr >= pushc + TOKENSIZE)
805 error("Too many characters pushed");
809 dupl(int n)
811 /* duplicate the subtree whose root is n, return ptr to it */
812 int i;
813 i = name[n];
814 if (!ISOPERATOR(i))
815 return (mn0(i));
816 switch (i) {
817 case DOT:
818 case RNULLS:
819 return (mn0(i));
820 case RCCL: case RNCCL: case FINAL: case S1FINAL: case S2FINAL:
821 return (mn1(i, left[n]));
822 case STAR: case QUEST: case PLUS: case CARAT:
823 return (mn1(i, dupl(left[n])));
825 /* XCU4: add RXSCON */
826 case RSTR: case RSCON: case RXSCON:
827 return (mn2(i, dupl(left[n]), right[n]));
828 case BAR: case RNEWE: case RCAT: case DIV:
829 return (mn2(i, dupl(left[n]), dupl(right[n])));
831 return (0);
834 #ifdef DEBUG
835 void
836 allprint(CHR c)
838 switch (c) {
839 case 014:
840 (void) printf("\\f");
841 charc++;
842 break;
843 case '\n':
844 (void) printf("\\n");
845 charc++;
846 break;
847 case '\t':
848 (void) printf("\\t");
849 charc++;
850 break;
851 case '\b':
852 (void) printf("\\b");
853 charc++;
854 break;
855 case ' ':
856 (void) printf("\\_");
857 break;
858 default:
859 if (!iswprint(c)) {
860 printf("\\x%-2x", c); /* up to fashion. */
861 charc += 3;
862 } else
863 (void) putwc(c, stdout);
864 break;
866 charc++;
869 void
870 strpt(CHR *s)
872 charc = 0;
873 while (*s) {
874 allprint(*s++);
875 if (charc > LINESIZE) {
876 charc = 0;
877 (void) printf("\n\t");
882 void
883 sect1dump(void)
885 int i;
886 (void) printf("Sect 1:\n");
887 if (def[0]) {
888 (void) printf("str trans\n");
889 i = -1;
890 while (def[++i])
891 (void) printf("%ws\t%ws\n", def[i], subs[i]);
893 if (sname[0]) {
894 (void) printf("start names\n");
895 i = -1;
896 while (sname[++i])
897 (void) printf("%ws\n", sname[i]);
899 if (chset == TRUE) {
900 (void) printf("char set changed\n");
901 for (i = 1; i < NCH; i++) {
902 if (i != ctable[i]) {
903 allprint(i);
904 (void) putchar(' ');
905 iswprint(ctable[i]) ?
906 (void) putwc(ctable[i], stdout) :
907 (void) printf("%d", ctable[i]);
908 (void) putchar('\n');
914 void
915 sect2dump(void)
917 (void) printf("Sect 2:\n");
918 treedump();
921 void
922 treedump(void)
924 int t;
925 CHR *p;
926 (void) printf("treedump %d nodes:\n", tptr);
927 for (t = 0; t < tptr; t++) {
928 (void) printf("%4d ", t);
929 parent[t] ? (void) printf("p=%4d", parent[t]) :
930 (void) printf(" ");
931 (void) printf(" ");
932 if (!ISOPERATOR(name[t])) {
933 allprint(name[t]);
934 } else
935 switch (name[t]) {
936 case RSTR:
937 (void) printf("%d ", left[t]);
938 allprint(right[t]);
939 break;
940 case RCCL:
941 (void) printf("ccl ");
942 strpt(left[t]);
943 break;
944 case RNCCL:
945 (void) printf("nccl ");
946 strpt(left[t]);
947 break;
948 case DIV:
949 (void) printf("/ %d %d", left[t], right[t]);
950 break;
951 case BAR:
952 (void) printf("| %d %d", left[t], right[t]);
953 break;
954 case RCAT:
955 (void) printf("cat %d %d", left[t], right[t]);
956 break;
957 case PLUS:
958 (void) printf("+ %d", left[t]);
959 break;
960 case STAR:
961 (void) printf("* %d", left[t]);
962 break;
963 case CARAT:
964 (void) printf("^ %d", left[t]);
965 break;
966 case QUEST:
967 (void) printf("? %d", left[t]);
968 break;
969 case RNULLS:
970 (void) printf("nullstring");
971 break;
972 case FINAL:
973 (void) printf("final %d", left[t]);
974 break;
975 case S1FINAL:
976 (void) printf("s1final %d", left[t]);
977 break;
978 case S2FINAL:
979 (void) printf("s2final %d", left[t]);
980 break;
981 case RNEWE:
982 (void) printf("new %d %d", left[t], right[t]);
983 break;
985 /* XCU4: add RXSCON */
986 case RXSCON:
987 p = (CHR *)right[t];
988 (void) printf("exstart %s", sname[*p++-1]);
989 while (*p)
990 (void) printf(", %ws", sname[*p++-1]);
991 (void) printf(" %d", left[t]);
992 break;
993 case RSCON:
994 p = (CHR *)right[t];
995 (void) printf("start %s", sname[*p++-1]);
996 while (*p)
997 (void) printf(", %ws", sname[*p++-1]);
998 (void) printf(" %d", left[t]);
999 break;
1000 case DOT:
1001 printf("dot");
1002 break;
1003 default:
1004 (void) printf(
1005 "unknown %d %d %d", name[t], left[t], right[t]);
1006 break;
1008 if (nullstr[t])
1009 (void) printf("\t(null poss.)");
1010 (void) putchar('\n');
1013 #endif