]> git.cameronkatri.com Git - apple_cmds.git/blob - developer_cmds/rpcgen/rpc_scan.c
Update README.md
[apple_cmds.git] / developer_cmds / rpcgen / rpc_scan.c
1 /* $NetBSD: rpc_scan.c,v 1.6 1997/10/18 10:54:05 lukem 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 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI";
36 #else
37 __RCSID("$NetBSD: rpc_scan.c,v 1.6 1997/10/18 10:54:05 lukem Exp $");
38 #endif
39 #endif
40
41 /*
42 * rpc_scan.c, Scanner for the RPC protocol compiler
43 * Copyright (C) 1987, Sun Microsystems, Inc.
44 */
45 #include <stdlib.h>
46 #include <stdio.h>
47 #include <ctype.h>
48 #include <string.h>
49 #include "rpc_scan.h"
50 #include "rpc_parse.h"
51 #include "rpc_util.h"
52
53 #define startcomment(where) (where[0] == '/' && where[1] == '*')
54 #define endcomment(where) (where[-1] == '*' && where[0] == '/')
55
56 static void unget_token __P((token *));
57 static void findstrconst __P((char **, char **));
58 static void findchrconst __P((char **, char **));
59 static void findconst __P((char **, char **));
60 static void findkind __P((char **, token *));
61 static int cppline __P((char *));
62 static int directive __P((char *));
63 static void printdirective __P((char *));
64 static void docppline __P((char *, int *, char **));
65
66 static int pushed = 0; /* is a token pushed */
67 static token lasttok; /* last token, if pushed */
68
69 /*
70 * scan expecting 1 given token
71 */
72 void
73 scan(expect, tokp)
74 tok_kind expect;
75 token *tokp;
76 {
77 get_token(tokp);
78 if (tokp->kind != expect) {
79 expected1(expect);
80 }
81 }
82 /*
83 * scan expecting any of the 2 given tokens
84 */
85 void
86 scan2(expect1, expect2, tokp)
87 tok_kind expect1;
88 tok_kind expect2;
89 token *tokp;
90 {
91 get_token(tokp);
92 if (tokp->kind != expect1 && tokp->kind != expect2) {
93 expected2(expect1, expect2);
94 }
95 }
96 /*
97 * scan expecting any of the 3 given token
98 */
99 void
100 scan3(expect1, expect2, expect3, tokp)
101 tok_kind expect1;
102 tok_kind expect2;
103 tok_kind expect3;
104 token *tokp;
105 {
106 get_token(tokp);
107 if (tokp->kind != expect1 && tokp->kind != expect2
108 && tokp->kind != expect3) {
109 expected3(expect1, expect2, expect3);
110 }
111 }
112 /*
113 * scan expecting a constant, possibly symbolic
114 */
115 void
116 scan_num(tokp)
117 token *tokp;
118 {
119 get_token(tokp);
120 switch (tokp->kind) {
121 case TOK_IDENT:
122 break;
123 default:
124 error("constant or identifier expected");
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 * Peek at the next token and scan it if it matches what you expect
139 */
140 int
141 peekscan(expect, tokp)
142 tok_kind expect;
143 token *tokp;
144 {
145 peek(tokp);
146 if (tokp->kind == expect) {
147 get_token(tokp);
148 return (1);
149 }
150 return (0);
151 }
152 /*
153 * Get the next token, printing out any directive that are encountered.
154 */
155 void
156 get_token(tokp)
157 token *tokp;
158 {
159 int commenting;
160 int stat = 0;
161
162 if (pushed) {
163 pushed = 0;
164 *tokp = lasttok;
165 return;
166 }
167 commenting = 0;
168 for (;;) {
169 if (*where == 0) {
170 for (;;) {
171 if (!fgets(curline, MAXLINESIZE, fin)) {
172 tokp->kind = TOK_EOF;
173 /* now check if cpp returned non NULL value */
174 waitpid(childpid, &stat, WUNTRACED);
175 if (stat > 0) {
176 /* Set return value from rpcgen */
177 nonfatalerrors = stat >> 8;
178 }
179 *where = 0;
180 return;
181 }
182 linenum++;
183 if (commenting) {
184 break;
185 } else
186 /* skip lines beginning with #pragma */
187 if (!strncmp(curline, "#pragma", 7)) *curline = 0;
188 else if (cppline(curline)) {
189 docppline(curline, &linenum,
190 &infilename);
191 } else
192 if (directive(curline)) {
193 printdirective(curline);
194 } else {
195 break;
196 }
197 }
198 where = curline;
199 } else
200 if (isspace(*where)) {
201 while (isspace(*where)) {
202 where++; /* eat */
203 }
204 } else
205 if (commenting) {
206 for (where++; *where; where++) {
207 if (endcomment(where)) {
208 where++;
209 commenting--;
210 break;
211 }
212 }
213 } else
214 if (startcomment(where)) {
215 where += 2;
216 commenting++;
217 } else {
218 break;
219 }
220 }
221
222 /*
223 * 'where' is not whitespace, comment or directive Must be a token!
224 */
225 switch (*where) {
226 case ':':
227 tokp->kind = TOK_COLON;
228 where++;
229 break;
230 case ';':
231 tokp->kind = TOK_SEMICOLON;
232 where++;
233 break;
234 case ',':
235 tokp->kind = TOK_COMMA;
236 where++;
237 break;
238 case '=':
239 tokp->kind = TOK_EQUAL;
240 where++;
241 break;
242 case '*':
243 tokp->kind = TOK_STAR;
244 where++;
245 break;
246 case '[':
247 tokp->kind = TOK_LBRACKET;
248 where++;
249 break;
250 case ']':
251 tokp->kind = TOK_RBRACKET;
252 where++;
253 break;
254 case '{':
255 tokp->kind = TOK_LBRACE;
256 where++;
257 break;
258 case '}':
259 tokp->kind = TOK_RBRACE;
260 where++;
261 break;
262 case '(':
263 tokp->kind = TOK_LPAREN;
264 where++;
265 break;
266 case ')':
267 tokp->kind = TOK_RPAREN;
268 where++;
269 break;
270 case '<':
271 tokp->kind = TOK_LANGLE;
272 where++;
273 break;
274 case '>':
275 tokp->kind = TOK_RANGLE;
276 where++;
277 break;
278
279 case '"':
280 tokp->kind = TOK_STRCONST;
281 findstrconst(&where, &tokp->str);
282 break;
283 case '\'':
284 tokp->kind = TOK_CHARCONST;
285 findchrconst(&where, &tokp->str);
286 break;
287
288 case '-':
289 case '0':
290 case '1':
291 case '2':
292 case '3':
293 case '4':
294 case '5':
295 case '6':
296 case '7':
297 case '8':
298 case '9':
299 tokp->kind = TOK_IDENT;
300 findconst(&where, &tokp->str);
301 break;
302
303 default:
304 if (!(isalpha(*where) || *where == '_')) {
305 char buf[100];
306 char *p;
307
308 s_print(buf, "illegal character in file: ");
309 p = buf + strlen(buf);
310 if (isprint(*where)) {
311 s_print(p, "%c", *where);
312 } else {
313 s_print(p, "%d", *where);
314 }
315 error(buf);
316 }
317 findkind(&where, tokp);
318 break;
319 }
320 }
321
322 static void
323 unget_token(tokp)
324 token *tokp;
325 {
326 lasttok = *tokp;
327 pushed = 1;
328 }
329
330 static void
331 findstrconst(str, val)
332 char **str;
333 char **val;
334 {
335 char *p;
336 int size;
337
338 p = *str;
339 do {
340 p++;
341 } while (*p && *p != '"');
342 if (*p == 0) {
343 error("unterminated string constant");
344 }
345 p++;
346 size = p - *str;
347 *val = alloc(size + 1);
348 (void) strncpy(*val, *str, size);
349 (*val)[size] = 0;
350 *str = p;
351 }
352
353 static void
354 findchrconst(str, val)
355 char **str;
356 char **val;
357 {
358 char *p;
359 int size;
360
361 p = *str;
362 do {
363 p++;
364 } while (*p && *p != '\'');
365 if (*p == 0) {
366 error("unterminated string constant");
367 }
368 p++;
369 size = p - *str;
370 if (size != 3) {
371 error("empty char string");
372 }
373 *val = alloc(size + 1);
374 (void) strncpy(*val, *str, size);
375 (*val)[size] = 0;
376 *str = p;
377 }
378
379 static void
380 findconst(str, val)
381 char **str;
382 char **val;
383 {
384 char *p;
385 int size;
386
387 p = *str;
388 if (*p == '0' && *(p + 1) == 'x') {
389 p++;
390 do {
391 p++;
392 } while (isxdigit(*p));
393 } else {
394 do {
395 p++;
396 } while (isdigit(*p));
397 }
398 size = p - *str;
399 *val = alloc(size + 1);
400 (void) strncpy(*val, *str, size);
401 (*val)[size] = 0;
402 *str = p;
403 }
404
405 static token symbols[] = {
406 {TOK_CONST, "const"},
407 {TOK_UNION, "union"},
408 {TOK_SWITCH, "switch"},
409 {TOK_CASE, "case"},
410 {TOK_DEFAULT, "default"},
411 {TOK_STRUCT, "struct"},
412 {TOK_TYPEDEF, "typedef"},
413 {TOK_ENUM, "enum"},
414 {TOK_OPAQUE, "opaque"},
415 {TOK_BOOL, "bool"},
416 {TOK_VOID, "void"},
417 {TOK_CHAR, "char"},
418 {TOK_INT, "int"},
419 {TOK_UNSIGNED, "unsigned"},
420 {TOK_SHORT, "short"},
421 {TOK_LONG, "long"},
422 {TOK_HYPER, "hyper"},
423 {TOK_FLOAT, "float"},
424 {TOK_DOUBLE, "double"},
425 {TOK_QUAD, "quadruple"},
426 {TOK_STRING, "string"},
427 {TOK_PROGRAM, "program"},
428 {TOK_VERSION, "version"},
429 {TOK_EOF, "??????"},
430 };
431
432 static void
433 findkind(mark, tokp)
434 char **mark;
435 token *tokp;
436 {
437 int len;
438 token *s;
439 char *str;
440
441 str = *mark;
442 for (s = symbols; s->kind != TOK_EOF; s++) {
443 len = strlen(s->str);
444 if (strncmp(str, s->str, len) == 0) {
445 if (!isalnum(str[len]) && str[len] != '_') {
446 tokp->kind = s->kind;
447 tokp->str = s->str;
448 *mark = str + len;
449 return;
450 }
451 }
452 }
453 tokp->kind = TOK_IDENT;
454 for (len = 0; isalnum(str[len]) || str[len] == '_'; len++);
455 tokp->str = alloc(len + 1);
456 (void) strncpy(tokp->str, str, len);
457 tokp->str[len] = 0;
458 *mark = str + len;
459 }
460
461 static int
462 cppline(line)
463 char *line;
464 {
465 return (line == curline && *line == '#');
466 }
467
468 static int
469 directive(line)
470 char *line;
471 {
472 return (line == curline && *line == '%');
473 }
474
475 static void
476 printdirective(line)
477 char *line;
478 {
479 f_print(fout, "%s", line + 1);
480 }
481
482 static void
483 docppline(line, lineno, fname)
484 char *line;
485 int *lineno;
486 char **fname;
487 {
488 char *file;
489 int num;
490 char *p;
491
492 line++;
493 while (isspace(*line)) {
494 line++;
495 }
496 num = atoi(line);
497 while (isdigit(*line)) {
498 line++;
499 }
500 while (isspace(*line)) {
501 line++;
502 }
503 if (*line != '"') {
504 error("preprocessor error");
505 }
506 line++;
507 p = file = alloc(strlen(line) + 1);
508 while (*line && *line != '"') {
509 *p++ = *line++;
510 }
511 if (*line == 0) {
512 error("preprocessor error");
513 }
514 *p = 0;
515 if (*file == 0) {
516 *fname = NULL;
517 } else {
518 *fname = file;
519 }
520 *lineno = num - 1;
521 }