2007-09-13 H.J. Lu <hongjiu.lu@intel.com>
[glibc.git] / sunrpc / rpc_scan.c
blobaf90ef6973ff23e6e64e4fe08fc6b7ac842e6b5c
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
36 * rpc_scan.c, Scanner for the RPC protocol compiler
37 * Copyright (C) 1987, Sun Microsystems, Inc.
39 #include <stdio.h>
40 #include <ctype.h>
41 #include <string.h>
42 #include <libintl.h>
43 #include "rpc_scan.h"
44 #include "rpc_parse.h"
45 #include "rpc_util.h"
46 #include "proto.h"
48 #define startcomment(where) (where[0] == '/' && where[1] == '*')
49 #define endcomment(where) (where[-1] == '*' && where[0] == '/')
51 static int pushed = 0; /* is a token pushed */
52 static token lasttok; /* last token, if pushed */
54 static void unget_token (token * tokp);
55 static void findstrconst (const char **str, const char **val);
56 static void findchrconst (const char **str, const char **val);
57 static void findconst (const char **str, const char **val);
58 static void findkind (const char **mark, token * tokp);
59 static int cppline (const char *line);
60 static int directive (const char *line);
61 static void printdirective (const char *line);
62 static void docppline (const char *line, int *lineno, const char **fname);
65 * scan expecting 1 given token
67 void
68 scan (tok_kind expect, token * tokp)
70 get_token (tokp);
71 if (tokp->kind != expect)
72 expected1 (expect);
76 * scan expecting any of the 2 given tokens
78 void
79 scan2 (tok_kind expect1, tok_kind expect2, token * tokp)
81 get_token (tokp);
82 if (tokp->kind != expect1 && tokp->kind != expect2)
84 expected2 (expect1, expect2);
89 * scan expecting any of the 3 given token
91 void
92 scan3 (tok_kind expect1, tok_kind expect2, tok_kind expect3, token * tokp)
94 get_token (tokp);
95 if (tokp->kind != expect1 && tokp->kind != expect2
96 && tokp->kind != expect3)
98 expected3 (expect1, expect2, expect3);
103 * scan expecting a constant, possibly symbolic
105 void
106 scan_num (token *tokp)
108 get_token (tokp);
109 switch (tokp->kind)
111 case TOK_IDENT:
112 break;
113 default:
114 error (_("constant or identifier expected"));
119 * Peek at the next token
121 void
122 peek (token *tokp)
124 get_token (tokp);
125 unget_token (tokp);
129 * Peek at the next token and scan it if it matches what you expect
132 peekscan (tok_kind expect, token *tokp)
134 peek (tokp);
135 if (tokp->kind == expect)
137 get_token (tokp);
138 return 1;
140 return 0;
144 * Get the next token, printing out any directive that are encountered.
146 void
147 get_token (token *tokp)
149 int commenting;
151 if (pushed)
153 pushed = 0;
154 *tokp = lasttok;
155 return;
157 commenting = 0;
158 for (;;)
160 if (*where == 0)
162 for (;;)
164 if (!fgets (curline, MAXLINESIZE, fin))
166 tokp->kind = TOK_EOF;
167 *curline = 0;
168 where = curline;
169 return;
171 linenum++;
172 if (commenting)
174 break;
176 else if (cppline (curline))
178 docppline (curline, &linenum,
179 &infilename);
181 else if (directive (curline))
183 printdirective (curline);
185 else
187 break;
190 where = curline;
192 else if (isspace (*where))
194 while (isspace (*where))
196 where++; /* eat */
199 else if (commenting)
201 for (where++; *where; where++)
203 if (endcomment (where))
205 where++;
206 commenting--;
207 break;
211 else if (startcomment (where))
213 where += 2;
214 commenting++;
216 else
218 break;
223 * 'where' is not whitespace, comment or directive Must be a token!
225 switch (*where)
227 case ':':
228 tokp->kind = TOK_COLON;
229 where++;
230 break;
231 case ';':
232 tokp->kind = TOK_SEMICOLON;
233 where++;
234 break;
235 case ',':
236 tokp->kind = TOK_COMMA;
237 where++;
238 break;
239 case '=':
240 tokp->kind = TOK_EQUAL;
241 where++;
242 break;
243 case '*':
244 tokp->kind = TOK_STAR;
245 where++;
246 break;
247 case '[':
248 tokp->kind = TOK_LBRACKET;
249 where++;
250 break;
251 case ']':
252 tokp->kind = TOK_RBRACKET;
253 where++;
254 break;
255 case '{':
256 tokp->kind = TOK_LBRACE;
257 where++;
258 break;
259 case '}':
260 tokp->kind = TOK_RBRACE;
261 where++;
262 break;
263 case '(':
264 tokp->kind = TOK_LPAREN;
265 where++;
266 break;
267 case ')':
268 tokp->kind = TOK_RPAREN;
269 where++;
270 break;
271 case '<':
272 tokp->kind = TOK_LANGLE;
273 where++;
274 break;
275 case '>':
276 tokp->kind = TOK_RANGLE;
277 where++;
278 break;
280 case '"':
281 tokp->kind = TOK_STRCONST;
282 findstrconst (&where, &tokp->str);
283 break;
284 case '\'':
285 tokp->kind = TOK_CHARCONST;
286 findchrconst (&where, &tokp->str);
287 break;
289 case '-':
290 case '0':
291 case '1':
292 case '2':
293 case '3':
294 case '4':
295 case '5':
296 case '6':
297 case '7':
298 case '8':
299 case '9':
300 tokp->kind = TOK_IDENT;
301 findconst (&where, &tokp->str);
302 break;
304 default:
305 if (!(isalpha (*where) || *where == '_'))
307 char buf[100];
308 char *p;
310 s_print (buf, _("illegal character in file: "));
311 p = buf + strlen (buf);
312 if (isprint (*where))
314 s_print (p, "%c", *where);
316 else
318 s_print (p, "%d", *where);
320 error (buf);
322 findkind (&where, tokp);
323 break;
327 static void
328 unget_token (token * tokp)
330 lasttok = *tokp;
331 pushed = 1;
334 static void
335 findstrconst (const char **str, const char **val)
337 const char *p;
338 char *tmp;
339 int size;
341 p = *str;
344 p++;
346 while (*p && *p != '"');
347 if (*p == 0)
349 error (_("unterminated string constant"));
351 p++;
352 size = p - *str;
353 tmp = alloc (size + 1);
354 strncpy (tmp, *str, size);
355 tmp[size] = 0;
356 *val = tmp;
357 *str = p;
360 static void
361 findchrconst (const char **str, const char **val)
363 const char *p;
364 char *tmp;
365 int size;
367 p = *str;
370 p++;
372 while (*p && *p != '\'');
373 if (*p == 0)
375 error (_("unterminated string constant"));
377 p++;
378 size = p - *str;
379 if (size != 3)
381 error (_("empty char string"));
383 tmp = alloc (size + 1);
384 strncpy (tmp, *str, size);
385 tmp[size] = 0;
386 *val = tmp;
387 *str = p;
390 static void
391 findconst (const char **str, const char **val)
393 const char *p;
394 char *tmp;
395 int size;
397 p = *str;
398 if (*p == '0' && *(p + 1) == 'x')
400 p++;
403 p++;
405 while (isxdigit (*p));
407 else
411 p++;
413 while (isdigit (*p));
415 size = p - *str;
416 tmp = alloc (size + 1);
417 strncpy (tmp, *str, size);
418 tmp[size] = 0;
419 *val = tmp;
420 *str = p;
423 static const token symbols[] =
425 {TOK_CONST, "const"},
426 {TOK_UNION, "union"},
427 {TOK_SWITCH, "switch"},
428 {TOK_CASE, "case"},
429 {TOK_DEFAULT, "default"},
430 {TOK_STRUCT, "struct"},
431 {TOK_TYPEDEF, "typedef"},
432 {TOK_ENUM, "enum"},
433 {TOK_OPAQUE, "opaque"},
434 {TOK_BOOL, "bool"},
435 {TOK_VOID, "void"},
436 {TOK_CHAR, "char"},
437 {TOK_INT, "int"},
438 {TOK_UNSIGNED, "unsigned"},
439 {TOK_SHORT, "short"},
440 {TOK_LONG, "long"},
441 {TOK_HYPER, "hyper"},
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 free (file);
539 *fname = NULL;
541 else
543 *fname = file;
545 *lineno = num - 1;