Update.
[glibc.git] / sunrpc / rpc_scan.c
blobaa988052b16e16062a9ec0e6ed04f0b661f29b12
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 char scan_rcsid[] =
35 "$Id$";
38 * rpc_scan.c, Scanner for the RPC protocol compiler
39 * Copyright (C) 1987, Sun Microsystems, Inc.
41 #include <stdio.h>
42 #include <ctype.h>
43 #include <string.h>
44 #include "rpc_scan.h"
45 #include "rpc_parse.h"
46 #include "rpc_util.h"
47 #include "proto.h"
49 #define startcomment(where) (where[0] == '/' && where[1] == '*')
50 #define endcomment(where) (where[-1] == '*' && where[0] == '/')
52 static int pushed = 0; /* is a token pushed */
53 static token lasttok; /* last token, if pushed */
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);
66 * scan expecting 1 given token
68 void
69 scan (tok_kind expect, token * tokp)
71 get_token (tokp);
72 if (tokp->kind != expect)
73 expected1 (expect);
77 * scan expecting any of the 2 given tokens
79 void
80 scan2 (tok_kind expect1, tok_kind expect2, token * tokp)
82 get_token (tokp);
83 if (tokp->kind != expect1 && tokp->kind != expect2)
85 expected2 (expect1, expect2);
90 * scan expecting any of the 3 given token
92 void
93 scan3 (tok_kind expect1, tok_kind expect2, tok_kind expect3, token * tokp)
95 get_token (tokp);
96 if (tokp->kind != expect1 && tokp->kind != expect2
97 && tokp->kind != expect3)
99 expected3 (expect1, expect2, expect3);
104 * scan expecting a constant, possibly symbolic
106 void
107 scan_num (token *tokp)
109 get_token (tokp);
110 switch (tokp->kind)
112 case TOK_IDENT:
113 break;
114 default:
115 error (_("constant or identifier expected"));
120 * Peek at the next token
122 void
123 peek (token *tokp)
125 get_token (tokp);
126 unget_token (tokp);
130 * Peek at the next token and scan it if it matches what you expect
133 peekscan (tok_kind expect, token *tokp)
135 peek (tokp);
136 if (tokp->kind == expect)
138 get_token (tokp);
139 return 1;
141 return 0;
145 * Get the next token, printing out any directive that are encountered.
147 void
148 get_token (token *tokp)
150 int commenting;
152 if (pushed)
154 pushed = 0;
155 *tokp = lasttok;
156 return;
158 commenting = 0;
159 for (;;)
161 if (*where == 0)
163 for (;;)
165 if (!fgets (curline, MAXLINESIZE, fin))
167 tokp->kind = TOK_EOF;
168 *curline = 0;
169 where = curline;
170 return;
172 linenum++;
173 if (commenting)
175 break;
177 else if (cppline (curline))
179 docppline (curline, &linenum,
180 &infilename);
182 else if (directive (curline))
184 printdirective (curline);
186 else
188 break;
191 where = curline;
193 else if (isspace (*where))
195 while (isspace (*where))
197 where++; /* eat */
200 else if (commenting)
202 for (where++; *where; where++)
204 if (endcomment (where))
206 where++;
207 commenting--;
208 break;
212 else if (startcomment (where))
214 where += 2;
215 commenting++;
217 else
219 break;
224 * 'where' is not whitespace, comment or directive Must be a token!
226 switch (*where)
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;
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;
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;
305 default:
306 if (!(isalpha (*where) || *where == '_'))
308 char buf[100];
309 char *p;
311 s_print (buf, _("illegal character in file: "));
312 p = buf + strlen (buf);
313 if (isprint (*where))
315 s_print (p, "%c", *where);
317 else
319 s_print (p, "%d", *where);
321 error (buf);
323 findkind (&where, tokp);
324 break;
328 static void
329 unget_token (token * tokp)
331 lasttok = *tokp;
332 pushed = 1;
335 static void
336 findstrconst (const char **str, const char **val)
338 const char *p;
339 char *tmp;
340 int size;
342 p = *str;
345 p++;
347 while (*p && *p != '"');
348 if (*p == 0)
350 error (_("unterminated string constant"));
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;
361 static void
362 findchrconst (const char **str, const char **val)
364 const char *p;
365 char *tmp;
366 int size;
368 p = *str;
371 p++;
373 while (*p && *p != '\'');
374 if (*p == 0)
376 error (_("unterminated string constant"));
378 p++;
379 size = p - *str;
380 if (size != 3)
382 error (_("empty char string"));
384 tmp = alloc (size + 1);
385 strncpy (tmp, *str, size);
386 tmp[size] = 0;
387 *val = tmp;
388 *str = p;
391 static void
392 findconst (const char **str, const char **val)
394 const char *p;
395 char *tmp;
396 int size;
398 p = *str;
399 if (*p == '0' && *(p + 1) == 'x')
401 p++;
404 p++;
406 while (isxdigit (*p));
408 else
412 p++;
414 while (isdigit (*p));
416 size = p - *str;
417 tmp = alloc (size + 1);
418 strncpy (tmp, *str, size);
419 tmp[size] = 0;
420 *val = tmp;
421 *str = p;
424 static const token symbols[] =
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, "??????"},
450 static void
451 findkind (const char **mark, token *tokp)
453 int len;
454 const token *s;
455 const char *str;
456 char *tmp;
458 str = *mark;
459 for (s = symbols; s->kind != TOK_EOF; s++)
461 len = strlen (s->str);
462 if (strncmp (str, s->str, len) == 0)
464 if (!isalnum (str[len]) && str[len] != '_')
466 tokp->kind = s->kind;
467 tokp->str = s->str;
468 *mark = str + len;
469 return;
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;
482 static int
483 cppline (const char *line)
485 return line == curline && *line == '#';
488 static int
489 directive (const char *line)
491 return line == curline && *line == '%';
494 static void
495 printdirective (const char *line)
497 f_print (fout, "%s", line + 1);
500 static void
501 docppline (const char *line, int *lineno, const char **fname)
503 char *file;
504 int num;
505 char *p;
507 line++;
508 while (isspace (*line))
510 line++;
512 num = atoi (line);
513 while (isdigit (*line))
515 line++;
517 while (isspace (*line))
519 line++;
521 if (*line != '"')
523 error (_("preprocessor error"));
525 line++;
526 p = file = alloc (strlen (line) + 1);
527 while (*line && *line != '"')
529 *p++ = *line++;
531 if (*line == 0)
533 error (_("preprocessor error"));
535 *p = 0;
536 if (*file == 0)
538 *fname = NULL;
540 else
542 *fname = file;
544 *lineno = num - 1;