Update.
[glibc.git] / sunrpc / rpc_scan.c
blobacffab2a89b01df6ec55361b9dafdf688179011e
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)
74 expected1 (expect);
79 * scan expecting any of the 2 given tokens
81 void
82 scan2 (tok_kind expect1, tok_kind expect2, token * tokp)
84 get_token (tokp);
85 if (tokp->kind != expect1 && tokp->kind != expect2)
87 expected2 (expect1, expect2);
92 * scan expecting any of the 3 given token
94 void
95 scan3 (tok_kind expect1, tok_kind expect2, tok_kind expect3, token * tokp)
97 get_token (tokp);
98 if (tokp->kind != expect1 && tokp->kind != expect2
99 && tokp->kind != expect3)
101 expected3 (expect1, expect2, expect3);
106 * scan expecting a constant, possibly symbolic
108 void
109 scan_num (token * tokp)
111 get_token (tokp);
112 switch (tokp->kind)
114 case TOK_IDENT:
115 break;
116 default:
117 error ("constant or identifier expected");
122 * Peek at the next token
124 void
125 peek (token * tokp)
127 get_token (tokp);
128 unget_token (tokp);
132 * Peek at the next token and scan it if it matches what you expect
135 peekscan (tok_kind expect, token * tokp)
137 peek (tokp);
138 if (tokp->kind == expect)
140 get_token (tokp);
141 return (1);
143 return (0);
147 * Get the next token, printing out any directive that are encountered.
149 void
150 get_token (token * tokp)
152 int commenting;
154 if (pushed)
156 pushed = 0;
157 *tokp = lasttok;
158 return;
160 commenting = 0;
161 for (;;)
163 if (*where == 0)
165 for (;;)
167 if (!fgets (curline, MAXLINESIZE, fin))
169 tokp->kind = TOK_EOF;
170 *curline = 0;
171 where = curline;
172 return;
174 linenum++;
175 if (commenting)
177 break;
179 else if (cppline (curline))
181 docppline (curline, &linenum,
182 &infilename);
184 else if (directive (curline))
186 printdirective (curline);
188 else
190 break;
193 where = curline;
195 else if (isspace (*where))
197 while (isspace (*where))
199 where++; /* eat */
202 else if (commenting)
204 for (where++; *where; where++)
206 if (endcomment (where))
208 where++;
209 commenting--;
210 break;
214 else if (startcomment (where))
216 where += 2;
217 commenting++;
219 else
221 break;
226 * 'where' is not whitespace, comment or directive Must be a token!
228 switch (*where)
230 case ':':
231 tokp->kind = TOK_COLON;
232 where++;
233 break;
234 case ';':
235 tokp->kind = TOK_SEMICOLON;
236 where++;
237 break;
238 case ',':
239 tokp->kind = TOK_COMMA;
240 where++;
241 break;
242 case '=':
243 tokp->kind = TOK_EQUAL;
244 where++;
245 break;
246 case '*':
247 tokp->kind = TOK_STAR;
248 where++;
249 break;
250 case '[':
251 tokp->kind = TOK_LBRACKET;
252 where++;
253 break;
254 case ']':
255 tokp->kind = TOK_RBRACKET;
256 where++;
257 break;
258 case '{':
259 tokp->kind = TOK_LBRACE;
260 where++;
261 break;
262 case '}':
263 tokp->kind = TOK_RBRACE;
264 where++;
265 break;
266 case '(':
267 tokp->kind = TOK_LPAREN;
268 where++;
269 break;
270 case ')':
271 tokp->kind = TOK_RPAREN;
272 where++;
273 break;
274 case '<':
275 tokp->kind = TOK_LANGLE;
276 where++;
277 break;
278 case '>':
279 tokp->kind = TOK_RANGLE;
280 where++;
281 break;
283 case '"':
284 tokp->kind = TOK_STRCONST;
285 findstrconst (&where, &tokp->str);
286 break;
287 case '\'':
288 tokp->kind = TOK_CHARCONST;
289 findchrconst (&where, &tokp->str);
290 break;
292 case '-':
293 case '0':
294 case '1':
295 case '2':
296 case '3':
297 case '4':
298 case '5':
299 case '6':
300 case '7':
301 case '8':
302 case '9':
303 tokp->kind = TOK_IDENT;
304 findconst (&where, &tokp->str);
305 break;
307 default:
308 if (!(isalpha (*where) || *where == '_'))
310 char buf[100];
311 char *p;
313 s_print (buf, _("illegal character in file: "));
314 p = buf + strlen (buf);
315 if (isprint (*where))
317 s_print (p, "%c", *where);
319 else
321 s_print (p, "%d", *where);
323 error (buf);
325 findkind (&where, tokp);
326 break;
330 static void
331 unget_token (token * tokp)
333 lasttok = *tokp;
334 pushed = 1;
337 static void
338 findstrconst (const char **str, const char **val)
340 const char *p;
341 char *tmp;
342 int size;
344 p = *str;
347 p++;
349 while (*p && *p != '"');
350 if (*p == 0)
352 error (_("unterminated string constant"));
354 p++;
355 size = p - *str;
356 tmp = alloc (size + 1);
357 strncpy (tmp, *str, size);
358 tmp[size] = 0;
359 *val = tmp;
360 *str = p;
363 static void
364 findchrconst (const char **str, const char **val)
366 const char *p;
367 char *tmp;
368 int size;
370 p = *str;
373 p++;
375 while (*p && *p != '\'');
376 if (*p == 0)
378 error (_("unterminated string constant"));
380 p++;
381 size = p - *str;
382 if (size != 3)
384 error (_("empty char string"));
386 tmp = alloc (size + 1);
387 strncpy (tmp, *str, size);
388 tmp[size] = 0;
389 *val = tmp;
390 *str = p;
393 static void
394 findconst (const char **str, const char **val)
396 const char *p;
397 char *tmp;
398 int size;
400 p = *str;
401 if (*p == '0' && *(p + 1) == 'x')
403 p++;
406 p++;
408 while (isxdigit (*p));
410 else
414 p++;
416 while (isdigit (*p));
418 size = p - *str;
419 tmp = alloc (size + 1);
420 strncpy (tmp, *str, size);
421 tmp[size] = 0;
422 *val = tmp;
423 *str = p;
426 static const token symbols[] =
428 {TOK_CONST, "const"},
429 {TOK_UNION, "union"},
430 {TOK_SWITCH, "switch"},
431 {TOK_CASE, "case"},
432 {TOK_DEFAULT, "default"},
433 {TOK_STRUCT, "struct"},
434 {TOK_TYPEDEF, "typedef"},
435 {TOK_ENUM, "enum"},
436 {TOK_OPAQUE, "opaque"},
437 {TOK_BOOL, "bool"},
438 {TOK_VOID, "void"},
439 {TOK_CHAR, "char"},
440 {TOK_INT, "int"},
441 {TOK_UNSIGNED, "unsigned"},
442 {TOK_SHORT, "short"},
443 {TOK_LONG, "long"},
444 {TOK_FLOAT, "float"},
445 {TOK_DOUBLE, "double"},
446 {TOK_STRING, "string"},
447 {TOK_PROGRAM, "program"},
448 {TOK_VERSION, "version"},
449 {TOK_EOF, "??????"},
452 static void
453 findkind (const char **mark, token * tokp)
455 int len;
456 token *s;
457 const char *str;
458 char *tmp;
460 str = *mark;
461 for (s = symbols; s->kind != TOK_EOF; s++)
463 len = strlen (s->str);
464 if (strncmp (str, s->str, len) == 0)
466 if (!isalnum (str[len]) && str[len] != '_')
468 tokp->kind = s->kind;
469 tokp->str = s->str;
470 *mark = str + len;
471 return;
475 tokp->kind = TOK_IDENT;
476 for (len = 0; isalnum (str[len]) || str[len] == '_'; len++);
477 tmp = alloc (len + 1);
478 strncpy (tmp, str, len);
479 tmp[len] = 0;
480 tokp->str = tmp;
481 *mark = str + len;
484 static int
485 cppline (const char *line)
487 return line == curline && *line == '#';
490 static int
491 directive (const char *line)
493 return line == curline && *line == '%';
496 static void
497 printdirective (const char *line)
499 f_print (fout, "%s", line + 1);
502 static void
503 docppline (const char *line, int *lineno, const char **fname)
505 char *file;
506 int num;
507 char *p;
509 line++;
510 while (isspace (*line))
512 line++;
514 num = atoi (line);
515 while (isdigit (*line))
517 line++;
519 while (isspace (*line))
521 line++;
523 if (*line != '"')
525 error (_("preprocessor error"));
527 line++;
528 p = file = alloc (strlen (line) + 1);
529 while (*line && *line != '"')
531 *p++ = *line++;
533 if (*line == 0)
535 error (_("preprocessor error"));
537 *p = 0;
538 if (*file == 0)
540 *fname = NULL;
542 else
544 *fname = file;
546 *lineno = num - 1;