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