[BZ #610]
[glibc.git] / sunrpc / rpc_scan.c
blobd6211e91053725dc5d745c3ebd08835fcbd9ea8d
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
7 * program developed by the user or with the express written consent of
8 * Sun Microsystems, Inc.
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.
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.
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.
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.
26 * Sun Microsystems, Inc.
27 * 2550 Garcia Avenue
28 * Mountain View, California 94043
32 * From: @(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI
34 #if defined(LIBC_SCCS) && !defined(lint)
35 static const char scan_rcsid[] =
36 "$Id$";
37 #endif
40 * rpc_scan.c, Scanner for the RPC protocol compiler
41 * Copyright (C) 1987, Sun Microsystems, Inc.
43 #include <stdio.h>
44 #include <ctype.h>
45 #include <string.h>
46 #include <libintl.h>
47 #include "rpc_scan.h"
48 #include "rpc_parse.h"
49 #include "rpc_util.h"
50 #include "proto.h"
52 #define startcomment(where) (where[0] == '/' && where[1] == '*')
53 #define endcomment(where) (where[-1] == '*' && where[0] == '/')
55 static int pushed = 0; /* is a token pushed */
56 static token lasttok; /* last token, if pushed */
58 static void unget_token (token * tokp);
59 static void findstrconst (const char **str, const char **val);
60 static void findchrconst (const char **str, const char **val);
61 static void findconst (const char **str, const char **val);
62 static void findkind (const char **mark, token * tokp);
63 static int cppline (const char *line);
64 static int directive (const char *line);
65 static void printdirective (const char *line);
66 static void docppline (const char *line, int *lineno, const char **fname);
69 * scan expecting 1 given token
71 void
72 scan (tok_kind expect, token * tokp)
74 get_token (tokp);
75 if (tokp->kind != expect)
76 expected1 (expect);
80 * scan expecting any of the 2 given tokens
82 void
83 scan2 (tok_kind expect1, tok_kind expect2, token * tokp)
85 get_token (tokp);
86 if (tokp->kind != expect1 && tokp->kind != expect2)
88 expected2 (expect1, expect2);
93 * scan expecting any of the 3 given token
95 void
96 scan3 (tok_kind expect1, tok_kind expect2, tok_kind expect3, token * tokp)
98 get_token (tokp);
99 if (tokp->kind != expect1 && tokp->kind != expect2
100 && tokp->kind != expect3)
102 expected3 (expect1, expect2, expect3);
107 * scan expecting a constant, possibly symbolic
109 void
110 scan_num (token *tokp)
112 get_token (tokp);
113 switch (tokp->kind)
115 case TOK_IDENT:
116 break;
117 default:
118 error (_("constant or identifier expected"));
123 * Peek at the next token
125 void
126 peek (token *tokp)
128 get_token (tokp);
129 unget_token (tokp);
133 * Peek at the next token and scan it if it matches what you expect
136 peekscan (tok_kind expect, token *tokp)
138 peek (tokp);
139 if (tokp->kind == expect)
141 get_token (tokp);
142 return 1;
144 return 0;
148 * Get the next token, printing out any directive that are encountered.
150 void
151 get_token (token *tokp)
153 int commenting;
155 if (pushed)
157 pushed = 0;
158 *tokp = lasttok;
159 return;
161 commenting = 0;
162 for (;;)
164 if (*where == 0)
166 for (;;)
168 if (!fgets (curline, MAXLINESIZE, fin))
170 tokp->kind = TOK_EOF;
171 *curline = 0;
172 where = curline;
173 return;
175 linenum++;
176 if (commenting)
178 break;
180 else if (cppline (curline))
182 docppline (curline, &linenum,
183 &infilename);
185 else if (directive (curline))
187 printdirective (curline);
189 else
191 break;
194 where = curline;
196 else if (isspace (*where))
198 while (isspace (*where))
200 where++; /* eat */
203 else if (commenting)
205 for (where++; *where; where++)
207 if (endcomment (where))
209 where++;
210 commenting--;
211 break;
215 else if (startcomment (where))
217 where += 2;
218 commenting++;
220 else
222 break;
227 * 'where' is not whitespace, comment or directive Must be a token!
229 switch (*where)
231 case ':':
232 tokp->kind = TOK_COLON;
233 where++;
234 break;
235 case ';':
236 tokp->kind = TOK_SEMICOLON;
237 where++;
238 break;
239 case ',':
240 tokp->kind = TOK_COMMA;
241 where++;
242 break;
243 case '=':
244 tokp->kind = TOK_EQUAL;
245 where++;
246 break;
247 case '*':
248 tokp->kind = TOK_STAR;
249 where++;
250 break;
251 case '[':
252 tokp->kind = TOK_LBRACKET;
253 where++;
254 break;
255 case ']':
256 tokp->kind = TOK_RBRACKET;
257 where++;
258 break;
259 case '{':
260 tokp->kind = TOK_LBRACE;
261 where++;
262 break;
263 case '}':
264 tokp->kind = TOK_RBRACE;
265 where++;
266 break;
267 case '(':
268 tokp->kind = TOK_LPAREN;
269 where++;
270 break;
271 case ')':
272 tokp->kind = TOK_RPAREN;
273 where++;
274 break;
275 case '<':
276 tokp->kind = TOK_LANGLE;
277 where++;
278 break;
279 case '>':
280 tokp->kind = TOK_RANGLE;
281 where++;
282 break;
284 case '"':
285 tokp->kind = TOK_STRCONST;
286 findstrconst (&where, &tokp->str);
287 break;
288 case '\'':
289 tokp->kind = TOK_CHARCONST;
290 findchrconst (&where, &tokp->str);
291 break;
293 case '-':
294 case '0':
295 case '1':
296 case '2':
297 case '3':
298 case '4':
299 case '5':
300 case '6':
301 case '7':
302 case '8':
303 case '9':
304 tokp->kind = TOK_IDENT;
305 findconst (&where, &tokp->str);
306 break;
308 default:
309 if (!(isalpha (*where) || *where == '_'))
311 char buf[100];
312 char *p;
314 s_print (buf, _("illegal character in file: "));
315 p = buf + strlen (buf);
316 if (isprint (*where))
318 s_print (p, "%c", *where);
320 else
322 s_print (p, "%d", *where);
324 error (buf);
326 findkind (&where, tokp);
327 break;
331 static void
332 unget_token (token * tokp)
334 lasttok = *tokp;
335 pushed = 1;
338 static void
339 findstrconst (const char **str, const char **val)
341 const char *p;
342 char *tmp;
343 int size;
345 p = *str;
348 p++;
350 while (*p && *p != '"');
351 if (*p == 0)
353 error (_("unterminated string constant"));
355 p++;
356 size = p - *str;
357 tmp = alloc (size + 1);
358 strncpy (tmp, *str, size);
359 tmp[size] = 0;
360 *val = tmp;
361 *str = p;
364 static void
365 findchrconst (const char **str, const char **val)
367 const char *p;
368 char *tmp;
369 int size;
371 p = *str;
374 p++;
376 while (*p && *p != '\'');
377 if (*p == 0)
379 error (_("unterminated string constant"));
381 p++;
382 size = p - *str;
383 if (size != 3)
385 error (_("empty char string"));
387 tmp = alloc (size + 1);
388 strncpy (tmp, *str, size);
389 tmp[size] = 0;
390 *val = tmp;
391 *str = p;
394 static void
395 findconst (const char **str, const char **val)
397 const char *p;
398 char *tmp;
399 int size;
401 p = *str;
402 if (*p == '0' && *(p + 1) == 'x')
404 p++;
407 p++;
409 while (isxdigit (*p));
411 else
415 p++;
417 while (isdigit (*p));
419 size = p - *str;
420 tmp = alloc (size + 1);
421 strncpy (tmp, *str, size);
422 tmp[size] = 0;
423 *val = tmp;
424 *str = p;
427 static const token symbols[] =
429 {TOK_CONST, "const"},
430 {TOK_UNION, "union"},
431 {TOK_SWITCH, "switch"},
432 {TOK_CASE, "case"},
433 {TOK_DEFAULT, "default"},
434 {TOK_STRUCT, "struct"},
435 {TOK_TYPEDEF, "typedef"},
436 {TOK_ENUM, "enum"},
437 {TOK_OPAQUE, "opaque"},
438 {TOK_BOOL, "bool"},
439 {TOK_VOID, "void"},
440 {TOK_CHAR, "char"},
441 {TOK_INT, "int"},
442 {TOK_UNSIGNED, "unsigned"},
443 {TOK_SHORT, "short"},
444 {TOK_LONG, "long"},
445 {TOK_HYPER, "hyper"},
446 {TOK_FLOAT, "float"},
447 {TOK_DOUBLE, "double"},
448 {TOK_STRING, "string"},
449 {TOK_PROGRAM, "program"},
450 {TOK_VERSION, "version"},
451 {TOK_EOF, "??????"},
454 static void
455 findkind (const char **mark, token *tokp)
457 int len;
458 const token *s;
459 const char *str;
460 char *tmp;
462 str = *mark;
463 for (s = symbols; s->kind != TOK_EOF; s++)
465 len = strlen (s->str);
466 if (strncmp (str, s->str, len) == 0)
468 if (!isalnum (str[len]) && str[len] != '_')
470 tokp->kind = s->kind;
471 tokp->str = s->str;
472 *mark = str + len;
473 return;
477 tokp->kind = TOK_IDENT;
478 for (len = 0; isalnum (str[len]) || str[len] == '_'; len++);
479 tmp = alloc (len + 1);
480 strncpy (tmp, str, len);
481 tmp[len] = 0;
482 tokp->str = tmp;
483 *mark = str + len;
486 static int
487 cppline (const char *line)
489 return line == curline && *line == '#';
492 static int
493 directive (const char *line)
495 return line == curline && *line == '%';
498 static void
499 printdirective (const char *line)
501 f_print (fout, "%s", line + 1);
504 static void
505 docppline (const char *line, int *lineno, const char **fname)
507 char *file;
508 int num;
509 char *p;
511 line++;
512 while (isspace (*line))
514 line++;
516 num = atoi (line);
517 while (isdigit (*line))
519 line++;
521 while (isspace (*line))
523 line++;
525 if (*line != '"')
527 error (_("preprocessor error"));
529 line++;
530 p = file = alloc (strlen (line) + 1);
531 while (*line && *line != '"')
533 *p++ = *line++;
535 if (*line == 0)
537 error (_("preprocessor error"));
539 *p = 0;
540 if (*file == 0)
542 *fname = NULL;
544 else
546 *fname = file;
548 *lineno = num - 1;