Annotation of src/usr.bin/rpcgen/rpc_scan.c, Revision 1.1.1.1
1.1 deraadt 1: /* $NetBSD: rpc_scan.c,v 1.4 1995/06/11 21:50:02 pk Exp $ */
2: /*
3: * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
4: * unrestricted use provided that this legend is included on all tape
5: * media and as a part of the software program in whole or part. Users
6: * may copy or modify Sun RPC without charge, but are not authorized
7: * to license or distribute it to anyone else except as part of a product or
8: * program developed by the user or with the express written consent of
9: * Sun Microsystems, Inc.
10: *
11: * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12: * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13: * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14: *
15: * Sun RPC is provided with no support and without any obligation on the
16: * part of Sun Microsystems, Inc. to assist in its use, correction,
17: * modification or enhancement.
18: *
19: * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20: * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21: * OR ANY PART THEREOF.
22: *
23: * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24: * or profits or other special, indirect and consequential damages, even if
25: * Sun has been advised of the possibility of such damages.
26: *
27: * Sun Microsystems, Inc.
28: * 2550 Garcia Avenue
29: * Mountain View, California 94043
30: */
31:
32: #ifndef lint
33: static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
34: #endif
35:
36: /*
37: * rpc_scan.c, Scanner for the RPC protocol compiler
38: * Copyright (C) 1987, Sun Microsystems, Inc.
39: */
40: #include <sys/cdefs.h>
41: #include <stdlib.h>
42: #include <stdio.h>
43: #include <ctype.h>
44: #include <string.h>
45: #include "rpc_scan.h"
46: #include "rpc_parse.h"
47: #include "rpc_util.h"
48:
49: static unget_token __P((token *tokp));
50: static findstrconst __P((char **, char **));
51: static findchrconst __P((char **, char **));
52: static findconst __P((char **, char **));
53: static findkind __P((char **, token *));
54: static cppline __P((char *));
55: static directive __P((char *));
56: static printdirective __P((char *));
57: static docppline __P((char *, int *, char **));
58:
59: #define startcomment(where) (where[0] == '/' && where[1] == '*')
60: #define endcomment(where) (where[-1] == '*' && where[0] == '/')
61:
62: static int pushed = 0; /* is a token pushed */
63: static token lasttok; /* last token, if pushed */
64:
65: /*
66: * scan expecting 1 given token
67: */
68: void
69: scan(expect, tokp)
70: tok_kind expect;
71: token *tokp;
72: {
73: get_token(tokp);
74: if (tokp->kind != expect) {
75: expected1(expect);
76: }
77: }
78:
79: /*
80: * scan expecting any of the 2 given tokens
81: */
82: void
83: scan2(expect1, expect2, tokp)
84: tok_kind expect1;
85: tok_kind expect2;
86: token *tokp;
87: {
88: get_token(tokp);
89: if (tokp->kind != expect1 && tokp->kind != expect2) {
90: expected2(expect1, expect2);
91: }
92: }
93:
94: /*
95: * scan expecting any of the 3 given token
96: */
97: void
98: scan3(expect1, expect2, expect3, tokp)
99: tok_kind expect1;
100: tok_kind expect2;
101: tok_kind expect3;
102: token *tokp;
103: {
104: get_token(tokp);
105: if (tokp->kind != expect1 && tokp->kind != expect2
106: && tokp->kind != expect3) {
107: expected3(expect1, expect2, expect3);
108: }
109: }
110:
111: /*
112: * scan expecting a constant, possibly symbolic
113: */
114: void
115: scan_num(tokp)
116: token *tokp;
117: {
118: get_token(tokp);
119: switch (tokp->kind) {
120: case TOK_IDENT:
121: break;
122: default:
123: error("constant or identifier expected");
124: }
125: }
126:
127: /*
128: * Peek at the next token
129: */
130: void
131: peek(tokp)
132: token *tokp;
133: {
134: get_token(tokp);
135: unget_token(tokp);
136: }
137:
138: /*
139: * Peek at the next token and scan it if it matches what you expect
140: */
141: int
142: peekscan(expect, tokp)
143: tok_kind expect;
144: token *tokp;
145: {
146: peek(tokp);
147: if (tokp->kind == expect) {
148: get_token(tokp);
149: return (1);
150: }
151: return (0);
152: }
153:
154: /*
155: * Get the next token, printing out any directive that are encountered.
156: */
157: void
158: get_token(tokp)
159: token *tokp;
160: {
161: int commenting;
162:
163: if (pushed) {
164: pushed = 0;
165: *tokp = lasttok;
166: return;
167: }
168: commenting = 0;
169: for (;;) {
170: if (*where == 0) {
171: for (;;) {
172: if (!fgets(curline, MAXLINESIZE, fin)) {
173: tokp->kind = TOK_EOF;
174: *where = 0;
175: return;
176: }
177: linenum++;
178: if (commenting) {
179: break;
180: } else if (cppline(curline)) {
181: docppline(curline, &linenum,
182: &infilename);
183: } else if (directive(curline)) {
184: printdirective(curline);
185: } else {
186: break;
187: }
188: }
189: where = curline;
190: } else if (isspace(*where)) {
191: while (isspace(*where)) {
192: where++; /* eat */
193: }
194: } else if (commenting) {
195: for (where++; *where; where++) {
196: if (endcomment(where)) {
197: where++;
198: commenting--;
199: break;
200: }
201: }
202: } else if (startcomment(where)) {
203: where += 2;
204: commenting++;
205: } else {
206: break;
207: }
208: }
209:
210: /*
211: * 'where' is not whitespace, comment or directive Must be a token!
212: */
213: switch (*where) {
214: case ':':
215: tokp->kind = TOK_COLON;
216: where++;
217: break;
218: case ';':
219: tokp->kind = TOK_SEMICOLON;
220: where++;
221: break;
222: case ',':
223: tokp->kind = TOK_COMMA;
224: where++;
225: break;
226: case '=':
227: tokp->kind = TOK_EQUAL;
228: where++;
229: break;
230: case '*':
231: tokp->kind = TOK_STAR;
232: where++;
233: break;
234: case '[':
235: tokp->kind = TOK_LBRACKET;
236: where++;
237: break;
238: case ']':
239: tokp->kind = TOK_RBRACKET;
240: where++;
241: break;
242: case '{':
243: tokp->kind = TOK_LBRACE;
244: where++;
245: break;
246: case '}':
247: tokp->kind = TOK_RBRACE;
248: where++;
249: break;
250: case '(':
251: tokp->kind = TOK_LPAREN;
252: where++;
253: break;
254: case ')':
255: tokp->kind = TOK_RPAREN;
256: where++;
257: break;
258: case '<':
259: tokp->kind = TOK_LANGLE;
260: where++;
261: break;
262: case '>':
263: tokp->kind = TOK_RANGLE;
264: where++;
265: break;
266:
267: case '"':
268: tokp->kind = TOK_STRCONST;
269: findstrconst(&where, &tokp->str);
270: break;
271: case '\'':
272: tokp->kind = TOK_CHARCONST;
273: findchrconst(&where, &tokp->str);
274: break;
275:
276: case '-':
277: case '0':
278: case '1':
279: case '2':
280: case '3':
281: case '4':
282: case '5':
283: case '6':
284: case '7':
285: case '8':
286: case '9':
287: tokp->kind = TOK_IDENT;
288: findconst(&where, &tokp->str);
289: break;
290:
291: default:
292: if (!(isalpha(*where) || *where == '_')) {
293: char buf[100];
294: char *p;
295:
296: s_print(buf, "illegal character in file: ");
297: p = buf + strlen(buf);
298: if (isprint(*where)) {
299: s_print(p, "%c", *where);
300: } else {
301: s_print(p, "%d", *where);
302: }
303: error(buf);
304: }
305: findkind(&where, tokp);
306: break;
307: }
308: }
309:
310: static
311: unget_token(tokp)
312: token *tokp;
313: {
314: lasttok = *tokp;
315: pushed = 1;
316: }
317:
318: static
319: findstrconst(str, val)
320: char **str;
321: char **val;
322: {
323: char *p;
324: int size;
325:
326: p = *str;
327: do {
328: *p++;
329: } while (*p && *p != '"');
330: if (*p == 0) {
331: error("unterminated string constant");
332: }
333: p++;
334: size = p - *str;
335: *val = alloc(size + 1);
336: (void) strncpy(*val, *str, size);
337: (*val)[size] = 0;
338: *str = p;
339: }
340:
341: static
342: findchrconst(str, val)
343: char **str;
344: char **val;
345: {
346: char *p;
347: int size;
348:
349: p = *str;
350: do {
351: *p++;
352: } while (*p && *p != '\'');
353: if (*p == 0) {
354: error("unterminated string constant");
355: }
356: p++;
357: size = p - *str;
358: if (size != 3) {
359: error("empty char string");
360: }
361: *val = alloc(size + 1);
362: (void) strncpy(*val, *str, size);
363: (*val)[size] = 0;
364: *str = p;
365: }
366:
367: static
368: findconst(str, val)
369: char **str;
370: char **val;
371: {
372: char *p;
373: int size;
374:
375: p = *str;
376: if (*p == '0' && *(p + 1) == 'x') {
377: p++;
378: do {
379: p++;
380: } while (isxdigit(*p));
381: } else {
382: do {
383: p++;
384: } while (isdigit(*p));
385: }
386: size = p - *str;
387: *val = alloc(size + 1);
388: (void) strncpy(*val, *str, size);
389: (*val)[size] = 0;
390: *str = p;
391: }
392:
393: static token symbols[] = {
394: {TOK_CONST, "const"},
395: {TOK_UNION, "union"},
396: {TOK_SWITCH, "switch"},
397: {TOK_CASE, "case"},
398: {TOK_DEFAULT, "default"},
399: {TOK_STRUCT, "struct"},
400: {TOK_TYPEDEF, "typedef"},
401: {TOK_ENUM, "enum"},
402: {TOK_OPAQUE, "opaque"},
403: {TOK_BOOL, "bool"},
404: {TOK_VOID, "void"},
405: {TOK_CHAR, "char"},
406: {TOK_INT, "int"},
407: {TOK_UNSIGNED, "unsigned"},
408: {TOK_SHORT, "short"},
409: {TOK_LONG, "long"},
410: {TOK_FLOAT, "float"},
411: {TOK_DOUBLE, "double"},
412: {TOK_STRING, "string"},
413: {TOK_PROGRAM, "program"},
414: {TOK_VERSION, "version"},
415: {TOK_EOF, "??????"},
416: };
417:
418: static
419: findkind(mark, tokp)
420: char **mark;
421: token *tokp;
422: {
423: int len;
424: token *s;
425: char *str;
426:
427: str = *mark;
428: for (s = symbols; s->kind != TOK_EOF; s++) {
429: len = strlen(s->str);
430: if (strncmp(str, s->str, len) == 0) {
431: if (!isalnum(str[len]) && str[len] != '_') {
432: tokp->kind = s->kind;
433: tokp->str = s->str;
434: *mark = str + len;
435: return;
436: }
437: }
438: }
439: tokp->kind = TOK_IDENT;
440: for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
441: tokp->str = alloc(len + 1);
442: (void) strncpy(tokp->str, str, len);
443: tokp->str[len] = 0;
444: *mark = str + len;
445: }
446:
447: static
448: cppline(line)
449: char *line;
450: {
451: return (line == curline && *line == '#');
452: }
453:
454: static
455: directive(line)
456: char *line;
457: {
458: return (line == curline && *line == '%');
459: }
460:
461: static
462: printdirective(line)
463: char *line;
464: {
465: f_print(fout, "%s", line + 1);
466: }
467:
468: static
469: docppline(line, lineno, fname)
470: char *line;
471: int *lineno;
472: char **fname;
473: {
474: char *file;
475: int num;
476: char *p;
477:
478: line++;
479: while (isspace(*line)) {
480: line++;
481: }
482: num = atoi(line);
483: while (isdigit(*line)) {
484: line++;
485: }
486: while (isspace(*line)) {
487: line++;
488: }
489: if (*line != '"') {
490: error("preprocessor error");
491: }
492: line++;
493: p = file = alloc(strlen(line) + 1);
494: while (*line && *line != '"') {
495: *p++ = *line++;
496: }
497: if (*line == 0) {
498: error("preprocessor error");
499: }
500: *p = 0;
501: if (*file == 0) {
502: *fname = NULL;
503: } else {
504: *fname = file;
505: }
506: *lineno = num - 1;
507: }