Update.
[glibc.git] / sunrpc / rpc_scan.c
blobdaecc32d436a669acb1ae695e2f1c41ebfe2adcb
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_FLOAT, "float"},
444 {TOK_DOUBLE, "double"},
445 {TOK_STRING, "string"},
446 {TOK_PROGRAM, "program"},
447 {TOK_VERSION, "version"},
448 {TOK_EOF, "??????"},
451 static void
452 findkind (const char **mark, token *tokp)
454 int len;
455 const token *s;
456 const char *str;
457 char *tmp;
459 str = *mark;
460 for (s = symbols; s->kind != TOK_EOF; s++)
462 len = strlen (s->str);
463 if (strncmp (str, s->str, len) == 0)
465 if (!isalnum (str[len]) && str[len] != '_')
467 tokp->kind = s->kind;
468 tokp->str = s->str;
469 *mark = str + len;
470 return;
474 tokp->kind = TOK_IDENT;
475 for (len = 0; isalnum (str[len]) || str[len] == '_'; len++);
476 tmp = alloc (len + 1);
477 strncpy (tmp, str, len);
478 tmp[len] = 0;
479 tokp->str = tmp;
480 *mark = str + len;
483 static int
484 cppline (const char *line)
486 return line == curline && *line == '#';
489 static int
490 directive (const char *line)
492 return line == curline && *line == '%';
495 static void
496 printdirective (const char *line)
498 f_print (fout, "%s", line + 1);
501 static void
502 docppline (const char *line, int *lineno, const char **fname)
504 char *file;
505 int num;
506 char *p;
508 line++;
509 while (isspace (*line))
511 line++;
513 num = atoi (line);
514 while (isdigit (*line))
516 line++;
518 while (isspace (*line))
520 line++;
522 if (*line != '"')
524 error (_("preprocessor error"));
526 line++;
527 p = file = alloc (strlen (line) + 1);
528 while (*line && *line != '"')
530 *p++ = *line++;
532 if (*line == 0)
534 error (_("preprocessor error"));
536 *p = 0;
537 if (*file == 0)
539 *fname = NULL;
541 else
543 *fname = file;
545 *lineno = num - 1;