]>
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 | */ | |
0d204b0a UD |
34 | |
35 | /* | |
e7fd8a39 UD |
36 | * rpc_scan.c, Scanner for the RPC protocol compiler |
37 | * Copyright (C) 1987, Sun Microsystems, Inc. | |
28f540f4 RM |
38 | */ |
39 | #include <stdio.h> | |
40 | #include <ctype.h> | |
0d204b0a | 41 | #include <string.h> |
4360eafd | 42 | #include <libintl.h> |
28f540f4 | 43 | #include "rpc_scan.h" |
0d204b0a | 44 | #include "rpc_parse.h" |
28f540f4 | 45 | #include "rpc_util.h" |
0d204b0a | 46 | #include "proto.h" |
28f540f4 RM |
47 | |
48 | #define startcomment(where) (where[0] == '/' && where[1] == '*') | |
49 | #define endcomment(where) (where[-1] == '*' && where[0] == '/') | |
50 | ||
e7fd8a39 UD |
51 | static int pushed = 0; /* is a token pushed */ |
52 | static token lasttok; /* last token, if pushed */ | |
28f540f4 | 53 | |
e7fd8a39 UD |
54 | static void unget_token (token * tokp); |
55 | static void findstrconst (const char **str, const char **val); | |
56 | static void findchrconst (const char **str, const char **val); | |
57 | static void findconst (const char **str, const char **val); | |
58 | static void findkind (const char **mark, token * tokp); | |
59 | static int cppline (const char *line); | |
60 | static int directive (const char *line); | |
61 | static void printdirective (const char *line); | |
62 | static void docppline (const char *line, int *lineno, const char **fname); | |
0d204b0a | 63 | |
28f540f4 | 64 | /* |
e7fd8a39 | 65 | * scan expecting 1 given token |
28f540f4 RM |
66 | */ |
67 | void | |
e7fd8a39 | 68 | scan (tok_kind expect, token * tokp) |
28f540f4 | 69 | { |
e7fd8a39 UD |
70 | get_token (tokp); |
71 | if (tokp->kind != expect) | |
880f421f | 72 | expected1 (expect); |
28f540f4 RM |
73 | } |
74 | ||
75 | /* | |
e7fd8a39 | 76 | * scan expecting any of the 2 given tokens |
28f540f4 RM |
77 | */ |
78 | void | |
e7fd8a39 | 79 | scan2 (tok_kind expect1, tok_kind expect2, token * tokp) |
28f540f4 | 80 | { |
e7fd8a39 UD |
81 | get_token (tokp); |
82 | if (tokp->kind != expect1 && tokp->kind != expect2) | |
83 | { | |
84 | expected2 (expect1, expect2); | |
85 | } | |
28f540f4 RM |
86 | } |
87 | ||
88 | /* | |
e7fd8a39 | 89 | * scan expecting any of the 3 given token |
28f540f4 RM |
90 | */ |
91 | void | |
e7fd8a39 | 92 | scan3 (tok_kind expect1, tok_kind expect2, tok_kind expect3, token * tokp) |
28f540f4 | 93 | { |
e7fd8a39 UD |
94 | get_token (tokp); |
95 | if (tokp->kind != expect1 && tokp->kind != expect2 | |
96 | && tokp->kind != expect3) | |
97 | { | |
98 | expected3 (expect1, expect2, expect3); | |
99 | } | |
28f540f4 RM |
100 | } |
101 | ||
28f540f4 | 102 | /* |
e7fd8a39 | 103 | * scan expecting a constant, possibly symbolic |
28f540f4 RM |
104 | */ |
105 | void | |
880f421f | 106 | scan_num (token *tokp) |
28f540f4 | 107 | { |
e7fd8a39 UD |
108 | get_token (tokp); |
109 | switch (tokp->kind) | |
110 | { | |
111 | case TOK_IDENT: | |
112 | break; | |
113 | default: | |
880f421f | 114 | error (_("constant or identifier expected")); |
e7fd8a39 | 115 | } |
28f540f4 RM |
116 | } |
117 | ||
28f540f4 | 118 | /* |
e7fd8a39 | 119 | * Peek at the next token |
28f540f4 RM |
120 | */ |
121 | void | |
880f421f | 122 | peek (token *tokp) |
28f540f4 | 123 | { |
e7fd8a39 UD |
124 | get_token (tokp); |
125 | unget_token (tokp); | |
28f540f4 RM |
126 | } |
127 | ||
28f540f4 | 128 | /* |
e7fd8a39 | 129 | * Peek at the next token and scan it if it matches what you expect |
28f540f4 RM |
130 | */ |
131 | int | |
880f421f | 132 | peekscan (tok_kind expect, token *tokp) |
28f540f4 | 133 | { |
e7fd8a39 UD |
134 | peek (tokp); |
135 | if (tokp->kind == expect) | |
136 | { | |
137 | get_token (tokp); | |
880f421f | 138 | return 1; |
e7fd8a39 | 139 | } |
880f421f | 140 | return 0; |
28f540f4 RM |
141 | } |
142 | ||
28f540f4 | 143 | /* |
e7fd8a39 | 144 | * Get the next token, printing out any directive that are encountered. |
28f540f4 RM |
145 | */ |
146 | void | |
880f421f | 147 | get_token (token *tokp) |
28f540f4 | 148 | { |
e7fd8a39 UD |
149 | int commenting; |
150 | ||
151 | if (pushed) | |
152 | { | |
153 | pushed = 0; | |
154 | *tokp = lasttok; | |
155 | return; | |
156 | } | |
157 | commenting = 0; | |
158 | for (;;) | |
159 | { | |
160 | if (*where == 0) | |
161 | { | |
162 | for (;;) | |
163 | { | |
164 | if (!fgets (curline, MAXLINESIZE, fin)) | |
165 | { | |
166 | tokp->kind = TOK_EOF; | |
167 | *curline = 0; | |
168 | where = curline; | |
169 | return; | |
170 | } | |
171 | linenum++; | |
172 | if (commenting) | |
173 | { | |
174 | break; | |
28f540f4 | 175 | } |
e7fd8a39 UD |
176 | else if (cppline (curline)) |
177 | { | |
178 | docppline (curline, &linenum, | |
179 | &infilename); | |
180 | } | |
181 | else if (directive (curline)) | |
182 | { | |
183 | printdirective (curline); | |
184 | } | |
185 | else | |
186 | { | |
187 | break; | |
188 | } | |
189 | } | |
190 | where = curline; | |
28f540f4 | 191 | } |
e7fd8a39 UD |
192 | else if (isspace (*where)) |
193 | { | |
194 | while (isspace (*where)) | |
195 | { | |
196 | where++; /* eat */ | |
197 | } | |
198 | } | |
199 | else if (commenting) | |
200 | { | |
201 | for (where++; *where; where++) | |
202 | { | |
203 | if (endcomment (where)) | |
204 | { | |
205 | where++; | |
206 | commenting--; | |
207 | break; | |
28f540f4 | 208 | } |
e7fd8a39 UD |
209 | } |
210 | } | |
211 | else if (startcomment (where)) | |
212 | { | |
213 | where += 2; | |
214 | commenting++; | |
215 | } | |
216 | else | |
217 | { | |
218 | break; | |
28f540f4 | 219 | } |
e7fd8a39 UD |
220 | } |
221 | ||
222 | /* | |
223 | * 'where' is not whitespace, comment or directive Must be a token! | |
224 | */ | |
225 | switch (*where) | |
226 | { | |
227 | case ':': | |
228 | tokp->kind = TOK_COLON; | |
229 | where++; | |
230 | break; | |
231 | case ';': | |
232 | tokp->kind = TOK_SEMICOLON; | |
233 | where++; | |
234 | break; | |
235 | case ',': | |
236 | tokp->kind = TOK_COMMA; | |
237 | where++; | |
238 | break; | |
239 | case '=': | |
240 | tokp->kind = TOK_EQUAL; | |
241 | where++; | |
242 | break; | |
243 | case '*': | |
244 | tokp->kind = TOK_STAR; | |
245 | where++; | |
246 | break; | |
247 | case '[': | |
248 | tokp->kind = TOK_LBRACKET; | |
249 | where++; | |
250 | break; | |
251 | case ']': | |
252 | tokp->kind = TOK_RBRACKET; | |
253 | where++; | |
254 | break; | |
255 | case '{': | |
256 | tokp->kind = TOK_LBRACE; | |
257 | where++; | |
258 | break; | |
259 | case '}': | |
260 | tokp->kind = TOK_RBRACE; | |
261 | where++; | |
262 | break; | |
263 | case '(': | |
264 | tokp->kind = TOK_LPAREN; | |
265 | where++; | |
266 | break; | |
267 | case ')': | |
268 | tokp->kind = TOK_RPAREN; | |
269 | where++; | |
270 | break; | |
271 | case '<': | |
272 | tokp->kind = TOK_LANGLE; | |
273 | where++; | |
274 | break; | |
275 | case '>': | |
276 | tokp->kind = TOK_RANGLE; | |
277 | where++; | |
278 | break; | |
279 | ||
280 | case '"': | |
281 | tokp->kind = TOK_STRCONST; | |
282 | findstrconst (&where, &tokp->str); | |
283 | break; | |
284 | case '\'': | |
285 | tokp->kind = TOK_CHARCONST; | |
286 | findchrconst (&where, &tokp->str); | |
287 | break; | |
288 | ||
289 | case '-': | |
290 | case '0': | |
291 | case '1': | |
292 | case '2': | |
293 | case '3': | |
294 | case '4': | |
295 | case '5': | |
296 | case '6': | |
297 | case '7': | |
298 | case '8': | |
299 | case '9': | |
300 | tokp->kind = TOK_IDENT; | |
301 | findconst (&where, &tokp->str); | |
302 | break; | |
303 | ||
304 | default: | |
305 | if (!(isalpha (*where) || *where == '_')) | |
306 | { | |
307 | char buf[100]; | |
308 | char *p; | |
309 | ||
310 | s_print (buf, _("illegal character in file: ")); | |
311 | p = buf + strlen (buf); | |
312 | if (isprint (*where)) | |
313 | { | |
314 | s_print (p, "%c", *where); | |
315 | } | |
316 | else | |
317 | { | |
318 | s_print (p, "%d", *where); | |
319 | } | |
320 | error (buf); | |
321 | } | |
322 | findkind (&where, tokp); | |
323 | break; | |
324 | } | |
28f540f4 RM |
325 | } |
326 | ||
0d204b0a | 327 | static void |
e7fd8a39 | 328 | unget_token (token * tokp) |
28f540f4 | 329 | { |
e7fd8a39 UD |
330 | lasttok = *tokp; |
331 | pushed = 1; | |
28f540f4 RM |
332 | } |
333 | ||
0d204b0a | 334 | static void |
e7fd8a39 | 335 | findstrconst (const char **str, const char **val) |
28f540f4 | 336 | { |
e7fd8a39 UD |
337 | const char *p; |
338 | char *tmp; | |
339 | int size; | |
340 | ||
341 | p = *str; | |
342 | do | |
343 | { | |
344 | p++; | |
345 | } | |
346 | while (*p && *p != '"'); | |
347 | if (*p == 0) | |
348 | { | |
349 | error (_("unterminated string constant")); | |
350 | } | |
351 | p++; | |
352 | size = p - *str; | |
353 | tmp = alloc (size + 1); | |
354 | strncpy (tmp, *str, size); | |
355 | tmp[size] = 0; | |
356 | *val = tmp; | |
357 | *str = p; | |
28f540f4 RM |
358 | } |
359 | ||
0d204b0a | 360 | static void |
e7fd8a39 | 361 | findchrconst (const char **str, const char **val) |
28f540f4 | 362 | { |
e7fd8a39 UD |
363 | const char *p; |
364 | char *tmp; | |
365 | int size; | |
366 | ||
367 | p = *str; | |
368 | do | |
369 | { | |
370 | p++; | |
371 | } | |
372 | while (*p && *p != '\''); | |
373 | if (*p == 0) | |
374 | { | |
375 | error (_("unterminated string constant")); | |
376 | } | |
377 | p++; | |
378 | size = p - *str; | |
379 | if (size != 3) | |
380 | { | |
381 | error (_("empty char string")); | |
382 | } | |
383 | tmp = alloc (size + 1); | |
384 | strncpy (tmp, *str, size); | |
385 | tmp[size] = 0; | |
386 | *val = tmp; | |
387 | *str = p; | |
0d204b0a UD |
388 | } |
389 | ||
390 | static void | |
e7fd8a39 | 391 | findconst (const char **str, const char **val) |
0d204b0a | 392 | { |
e7fd8a39 UD |
393 | const char *p; |
394 | char *tmp; | |
395 | int size; | |
396 | ||
397 | p = *str; | |
398 | if (*p == '0' && *(p + 1) == 'x') | |
399 | { | |
400 | p++; | |
401 | do | |
402 | { | |
403 | p++; | |
28f540f4 | 404 | } |
e7fd8a39 UD |
405 | while (isxdigit (*p)); |
406 | } | |
407 | else | |
408 | { | |
409 | do | |
410 | { | |
411 | p++; | |
412 | } | |
413 | while (isdigit (*p)); | |
414 | } | |
415 | size = p - *str; | |
416 | tmp = alloc (size + 1); | |
417 | strncpy (tmp, *str, size); | |
418 | tmp[size] = 0; | |
419 | *val = tmp; | |
420 | *str = p; | |
28f540f4 RM |
421 | } |
422 | ||
e7fd8a39 UD |
423 | static const token symbols[] = |
424 | { | |
425 | {TOK_CONST, "const"}, | |
426 | {TOK_UNION, "union"}, | |
427 | {TOK_SWITCH, "switch"}, | |
428 | {TOK_CASE, "case"}, | |
429 | {TOK_DEFAULT, "default"}, | |
430 | {TOK_STRUCT, "struct"}, | |
431 | {TOK_TYPEDEF, "typedef"}, | |
432 | {TOK_ENUM, "enum"}, | |
433 | {TOK_OPAQUE, "opaque"}, | |
434 | {TOK_BOOL, "bool"}, | |
435 | {TOK_VOID, "void"}, | |
436 | {TOK_CHAR, "char"}, | |
437 | {TOK_INT, "int"}, | |
438 | {TOK_UNSIGNED, "unsigned"}, | |
439 | {TOK_SHORT, "short"}, | |
440 | {TOK_LONG, "long"}, | |
ce64ae6b | 441 | {TOK_HYPER, "hyper"}, |
e7fd8a39 UD |
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 | { | |
0ecb606c | 538 | free (file); |
e7fd8a39 UD |
539 | *fname = NULL; |
540 | } | |
541 | else | |
542 | { | |
543 | *fname = file; | |
544 | } | |
545 | *lineno = num - 1; | |
28f540f4 | 546 | } |