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