2 * Copyright (c) 2009, Sun Microsystems, Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 * - Redistributions in binary form must reproduce the above copyright notice,
10 * this list of conditions and the following disclaimer in the documentation
11 * and/or other materials provided with the distribution.
12 * - Neither the name of Sun Microsystems, Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
30 static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
34 * rpc_scan.c, Scanner for the RPC protocol compiler
35 * Copyright (C) 1987, Sun Microsystems, Inc.
41 #include "rpc_parse.h"
44 static void unget_token(token *tokp);
45 static void findstrconst(char **str, char **val);
46 static void findchrconst(char **str, char **val);
47 static void findconst(char **str, char **val);
48 static void findkind(char **mark, token *tokp);
49 static int cppline(char *line);
50 static int directive(char *line);
51 static void printdirective(char *line);
52 static void docppline(char *line, int *lineno, char **fname);
54 #define startcomment(where) (where[0] == '/' && where[1] == '*')
55 #define endcomment(where) (where[-1] == '*' && where[0] == '/')
57 static int pushed = 0; /* is a token pushed */
58 static token lasttok; /* last token, if pushed */
61 * scan expecting 1 given token
64 scan(tok_kind expect, token *tokp)
67 if (tokp->kind != expect) {
73 * scan expecting any of the 2 given tokens
76 scan2(tok_kind expect1, tok_kind expect2, token *tokp)
79 if (tokp->kind != expect1 && tokp->kind != expect2) {
80 expected2(expect1, expect2);
85 * scan expecting any of the 3 given token
88 scan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp)
91 if (tokp->kind != expect1 && tokp->kind != expect2
92 && tokp->kind != expect3) {
93 expected3(expect1, expect2, expect3);
98 * scan expecting a constant, possibly symbolic
101 scan_num(token *tokp)
104 switch (tokp->kind) {
108 error("constant or identifier expected");
113 * Peek at the next token
123 * Peek at the next token and scan it if it matches what you expect
126 peekscan(tok_kind expect, token *tokp)
129 if (tokp->kind == expect) {
137 * Get the next token, printing out any directive that are encountered.
140 get_token(token *tokp)
153 if (!fgets(curline, MAXLINESIZE, fin)) {
154 tokp->kind = TOK_EOF;
161 } else if (cppline(curline)) {
162 docppline(curline, &linenum,
164 } else if (directive(curline)) {
165 printdirective(curline);
171 } else if (isspace(*where)) {
172 while (isspace(*where)) {
175 } else if (commenting) {
176 for (where++; *where; where++) {
177 if (endcomment(where)) {
183 } else if (startcomment(where)) {
192 * 'where' is not whitespace, comment or directive Must be a token!
196 tokp->kind = TOK_COLON;
200 tokp->kind = TOK_SEMICOLON;
204 tokp->kind = TOK_COMMA;
208 tokp->kind = TOK_EQUAL;
212 tokp->kind = TOK_STAR;
216 tokp->kind = TOK_LBRACKET;
220 tokp->kind = TOK_RBRACKET;
224 tokp->kind = TOK_LBRACE;
228 tokp->kind = TOK_RBRACE;
232 tokp->kind = TOK_LPAREN;
236 tokp->kind = TOK_RPAREN;
240 tokp->kind = TOK_LANGLE;
244 tokp->kind = TOK_RANGLE;
249 tokp->kind = TOK_STRCONST;
250 findstrconst(&where, &tokp->str);
253 tokp->kind = TOK_CHARCONST;
254 findchrconst(&where, &tokp->str);
268 tokp->kind = TOK_IDENT;
269 findconst(&where, &tokp->str);
273 if (!(isalpha(*where) || *where == '_')) {
277 s_print(buf, "illegal character in file: ");
278 p = buf + strlen(buf);
279 if (isprint(*where)) {
280 s_print(p, "%c", *where);
282 s_print(p, "%d", *where);
286 findkind(&where, tokp);
292 unget_token(token *tokp)
299 findstrconst(char **str, char **val)
307 } while (*p && *p != '"');
309 error("unterminated string constant");
313 *val = alloc(size + 1);
314 (void) strncpy(*val, *str, size);
320 findchrconst(char **str, char **val)
328 } while (*p && *p != '\'');
330 error("unterminated string constant");
335 error("empty char string");
337 *val = alloc(size + 1);
338 (void) strncpy(*val, *str, size);
344 findconst(char **str, char **val)
350 if (*p == '0' && *(p + 1) == 'x') {
354 } while (isxdigit(*p));
358 } while (isdigit(*p));
361 *val = alloc(size + 1);
362 (void) strncpy(*val, *str, size);
367 static token symbols[] = {
368 {TOK_CONST, "const"},
369 {TOK_UNION, "union"},
370 {TOK_SWITCH, "switch"},
372 {TOK_DEFAULT, "default"},
373 {TOK_STRUCT, "struct"},
374 {TOK_TYPEDEF, "typedef"},
376 {TOK_OPAQUE, "opaque"},
381 {TOK_UNSIGNED, "unsigned"},
382 {TOK_SHORT, "short"},
383 {TOK_INT32, "int32"},
384 {TOK_FLOAT, "float"},
385 {TOK_DOUBLE, "double"},
386 {TOK_STRING, "string"},
387 {TOK_PROGRAM, "program"},
388 {TOK_VERSION, "version"},
393 findkind(char **mark, token *tokp)
400 for (s = symbols; s->kind != TOK_EOF; s++) {
401 len = strlen(s->str);
402 if (strncmp(str, s->str, len) == 0) {
403 if (!isalnum(str[len]) && str[len] != '_') {
404 tokp->kind = s->kind;
411 tokp->kind = TOK_IDENT;
412 for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
413 tokp->str = alloc(len + 1);
414 (void) strncpy(tokp->str, str, len);
422 return (line == curline && *line == '#');
426 directive(char *line)
428 return (line == curline && *line == '%');
432 printdirective(char *line)
434 f_print(fout, "%s", line + 1);
438 docppline(char *line, int *lineno, char **fname)
445 while (isspace(*line)) {
449 while (isdigit(*line)) {
452 while (isspace(*line)) {
456 error("preprocessor error");
459 p = file = alloc(strlen(line) + 1);
460 while (*line && *line != '"') {
464 error("preprocessor error");