Update.
[glibc.git] / sunrpc / rpc_scan.c
blob15c8e01178d7081fc617d15ed4d77db2f5f03092
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 <libintl.h>
45 #include "rpc_scan.h"
46 #include "rpc_parse.h"
47 #include "rpc_util.h"
48 #include "proto.h"
50 #define startcomment(where) (where[0] == '/' && where[1] == '*')
51 #define endcomment(where) (where[-1] == '*' && where[0] == '/')
53 static int pushed = 0; /* is a token pushed */
54 static token lasttok; /* last token, if pushed */
56 static void unget_token (token * tokp);
57 static void findstrconst (const char **str, const char **val);
58 static void findchrconst (const char **str, const char **val);
59 static void findconst (const char **str, const char **val);
60 static void findkind (const char **mark, token * tokp);
61 static int cppline (const char *line);
62 static int directive (const char *line);
63 static void printdirective (const char *line);
64 static void docppline (const char *line, int *lineno, const char **fname);
67 * scan expecting 1 given token
69 void
70 scan (tok_kind expect, token * tokp)
72 get_token (tokp);
73 if (tokp->kind != expect)
74 expected1 (expect);
78 * scan expecting any of the 2 given tokens
80 void
81 scan2 (tok_kind expect1, tok_kind expect2, token * tokp)
83 get_token (tokp);
84 if (tokp->kind != expect1 && tokp->kind != expect2)
86 expected2 (expect1, expect2);
91 * scan expecting any of the 3 given token
93 void
94 scan3 (tok_kind expect1, tok_kind expect2, tok_kind expect3, token * tokp)
96 get_token (tokp);
97 if (tokp->kind != expect1 && tokp->kind != expect2
98 && tokp->kind != expect3)
100 expected3 (expect1, expect2, expect3);
105 * scan expecting a constant, possibly symbolic
107 void
108 scan_num (token *tokp)
110 get_token (tokp);
111 switch (tokp->kind)
113 case TOK_IDENT:
114 break;
115 default:
116 error (_("constant or identifier expected"));
121 * Peek at the next token
123 void
124 peek (token *tokp)
126 get_token (tokp);
127 unget_token (tokp);
131 * Peek at the next token and scan it if it matches what you expect
134 peekscan (tok_kind expect, token *tokp)
136 peek (tokp);
137 if (tokp->kind == expect)
139 get_token (tokp);
140 return 1;
142 return 0;
146 * Get the next token, printing out any directive that are encountered.
148 void
149 get_token (token *tokp)
151 int commenting;
153 if (pushed)
155 pushed = 0;
156 *tokp = lasttok;
157 return;
159 commenting = 0;
160 for (;;)
162 if (*where == 0)
164 for (;;)
166 if (!fgets (curline, MAXLINESIZE, fin))
168 tokp->kind = TOK_EOF;
169 *curline = 0;
170 where = curline;
171 return;
173 linenum++;
174 if (commenting)
176 break;
178 else if (cppline (curline))
180 docppline (curline, &linenum,
181 &infilename);
183 else if (directive (curline))
185 printdirective (curline);
187 else
189 break;
192 where = curline;
194 else if (isspace (*where))
196 while (isspace (*where))
198 where++; /* eat */
201 else if (commenting)
203 for (where++; *where; where++)
205 if (endcomment (where))
207 where++;
208 commenting--;
209 break;
213 else if (startcomment (where))
215 where += 2;
216 commenting++;
218 else
220 break;
225 * 'where' is not whitespace, comment or directive Must be a token!
227 switch (*where)
229 case ':':
230 tokp->kind = TOK_COLON;
231 where++;
232 break;
233 case ';':
234 tokp->kind = TOK_SEMICOLON;
235 where++;
236 break;
237 case ',':
238 tokp->kind = TOK_COMMA;
239 where++;
240 break;
241 case '=':
242 tokp->kind = TOK_EQUAL;
243 where++;
244 break;
245 case '*':
246 tokp->kind = TOK_STAR;
247 where++;
248 break;
249 case '[':
250 tokp->kind = TOK_LBRACKET;
251 where++;
252 break;
253 case ']':
254 tokp->kind = TOK_RBRACKET;
255 where++;
256 break;
257 case '{':
258 tokp->kind = TOK_LBRACE;
259 where++;
260 break;
261 case '}':
262 tokp->kind = TOK_RBRACE;
263 where++;
264 break;
265 case '(':
266 tokp->kind = TOK_LPAREN;
267 where++;
268 break;
269 case ')':
270 tokp->kind = TOK_RPAREN;
271 where++;
272 break;
273 case '<':
274 tokp->kind = TOK_LANGLE;
275 where++;
276 break;
277 case '>':
278 tokp->kind = TOK_RANGLE;
279 where++;
280 break;
282 case '"':
283 tokp->kind = TOK_STRCONST;
284 findstrconst (&where, &tokp->str);
285 break;
286 case '\'':
287 tokp->kind = TOK_CHARCONST;
288 findchrconst (&where, &tokp->str);
289 break;
291 case '-':
292 case '0':
293 case '1':
294 case '2':
295 case '3':
296 case '4':
297 case '5':
298 case '6':
299 case '7':
300 case '8':
301 case '9':
302 tokp->kind = TOK_IDENT;
303 findconst (&where, &tokp->str);
304 break;
306 default:
307 if (!(isalpha (*where) || *where == '_'))
309 char buf[100];
310 char *p;
312 s_print (buf, _("illegal character in file: "));
313 p = buf + strlen (buf);
314 if (isprint (*where))
316 s_print (p, "%c", *where);
318 else
320 s_print (p, "%d", *where);
322 error (buf);
324 findkind (&where, tokp);
325 break;
329 static void
330 unget_token (token * tokp)
332 lasttok = *tokp;
333 pushed = 1;
336 static void
337 findstrconst (const char **str, const char **val)
339 const char *p;
340 char *tmp;
341 int size;
343 p = *str;
346 p++;
348 while (*p && *p != '"');
349 if (*p == 0)
351 error (_("unterminated string constant"));
353 p++;
354 size = p - *str;
355 tmp = alloc (size + 1);
356 strncpy (tmp, *str, size);
357 tmp[size] = 0;
358 *val = tmp;
359 *str = p;
362 static void
363 findchrconst (const char **str, const char **val)
365 const char *p;
366 char *tmp;
367 int size;
369 p = *str;
372 p++;
374 while (*p && *p != '\'');
375 if (*p == 0)
377 error (_("unterminated string constant"));
379 p++;
380 size = p - *str;
381 if (size != 3)
383 error (_("empty char string"));
385 tmp = alloc (size + 1);
386 strncpy (tmp, *str, size);
387 tmp[size] = 0;
388 *val = tmp;
389 *str = p;
392 static void
393 findconst (const char **str, const char **val)
395 const char *p;
396 char *tmp;
397 int size;
399 p = *str;
400 if (*p == '0' && *(p + 1) == 'x')
402 p++;
405 p++;
407 while (isxdigit (*p));
409 else
413 p++;
415 while (isdigit (*p));
417 size = p - *str;
418 tmp = alloc (size + 1);
419 strncpy (tmp, *str, size);
420 tmp[size] = 0;
421 *val = tmp;
422 *str = p;
425 static const token symbols[] =
427 {TOK_CONST, "const"},
428 {TOK_UNION, "union"},
429 {TOK_SWITCH, "switch"},
430 {TOK_CASE, "case"},
431 {TOK_DEFAULT, "default"},
432 {TOK_STRUCT, "struct"},
433 {TOK_TYPEDEF, "typedef"},
434 {TOK_ENUM, "enum"},
435 {TOK_OPAQUE, "opaque"},
436 {TOK_BOOL, "bool"},
437 {TOK_VOID, "void"},
438 {TOK_CHAR, "char"},
439 {TOK_INT, "int"},
440 {TOK_UNSIGNED, "unsigned"},
441 {TOK_SHORT, "short"},
442 {TOK_LONG, "long"},
443 {TOK_HYPER, "hyper"},
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 const 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;