]> git.ipfire.org Git - thirdparty/glibc.git/blame - sunrpc/rpc_scan.c
2.5-18.1
[thirdparty/glibc.git] / sunrpc / rpc_scan.c
CommitLineData
28f540f4
RM
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
0d204b0a
UD
7 * program developed by the user or with the express written consent of
8 * Sun Microsystems, Inc.
cbd3dceb 9 *
28f540f4
RM
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.
cbd3dceb 13 *
28f540f4
RM
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.
cbd3dceb 17 *
28f540f4
RM
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.
cbd3dceb 21 *
28f540f4
RM
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.
cbd3dceb 25 *
28f540f4
RM
26 * Sun Microsystems, Inc.
27 * 2550 Garcia Avenue
28 * Mountain View, California 94043
29 */
28f540f4
RM
30
31/*
0d204b0a
UD
32 * From: @(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI
33 */
0d204b0a
UD
34
35/*
e7fd8a39
UD
36 * rpc_scan.c, Scanner for the RPC protocol compiler
37 * Copyright (C) 1987, Sun Microsystems, Inc.
28f540f4
RM
38 */
39#include <stdio.h>
40#include <ctype.h>
0d204b0a 41#include <string.h>
4360eafd 42#include <libintl.h>
28f540f4 43#include "rpc_scan.h"
0d204b0a 44#include "rpc_parse.h"
28f540f4 45#include "rpc_util.h"
0d204b0a 46#include "proto.h"
28f540f4
RM
47
48#define startcomment(where) (where[0] == '/' && where[1] == '*')
49#define endcomment(where) (where[-1] == '*' && where[0] == '/')
50
e7fd8a39
UD
51static int pushed = 0; /* is a token pushed */
52static token lasttok; /* last token, if pushed */
28f540f4 53
e7fd8a39
UD
54static void unget_token (token * tokp);
55static void findstrconst (const char **str, const char **val);
56static void findchrconst (const char **str, const char **val);
57static void findconst (const char **str, const char **val);
58static void findkind (const char **mark, token * tokp);
59static int cppline (const char *line);
60static int directive (const char *line);
61static void printdirective (const char *line);
62static void docppline (const char *line, int *lineno, const char **fname);
0d204b0a 63
28f540f4 64/*
e7fd8a39 65 * scan expecting 1 given token
28f540f4
RM
66 */
67void
e7fd8a39 68scan (tok_kind expect, token * tokp)
28f540f4 69{
e7fd8a39
UD
70 get_token (tokp);
71 if (tokp->kind != expect)
880f421f 72 expected1 (expect);
28f540f4
RM
73}
74
75/*
e7fd8a39 76 * scan expecting any of the 2 given tokens
28f540f4
RM
77 */
78void
e7fd8a39 79scan2 (tok_kind expect1, tok_kind expect2, token * tokp)
28f540f4 80{
e7fd8a39
UD
81 get_token (tokp);
82 if (tokp->kind != expect1 && tokp->kind != expect2)
83 {
84 expected2 (expect1, expect2);
85 }
28f540f4
RM
86}
87
88/*
e7fd8a39 89 * scan expecting any of the 3 given token
28f540f4
RM
90 */
91void
e7fd8a39 92scan3 (tok_kind expect1, tok_kind expect2, tok_kind expect3, token * tokp)
28f540f4 93{
e7fd8a39
UD
94 get_token (tokp);
95 if (tokp->kind != expect1 && tokp->kind != expect2
96 && tokp->kind != expect3)
97 {
98 expected3 (expect1, expect2, expect3);
99 }
28f540f4
RM
100}
101
28f540f4 102/*
e7fd8a39 103 * scan expecting a constant, possibly symbolic
28f540f4
RM
104 */
105void
880f421f 106scan_num (token *tokp)
28f540f4 107{
e7fd8a39
UD
108 get_token (tokp);
109 switch (tokp->kind)
110 {
111 case TOK_IDENT:
112 break;
113 default:
880f421f 114 error (_("constant or identifier expected"));
e7fd8a39 115 }
28f540f4
RM
116}
117
28f540f4 118/*
e7fd8a39 119 * Peek at the next token
28f540f4
RM
120 */
121void
880f421f 122peek (token *tokp)
28f540f4 123{
e7fd8a39
UD
124 get_token (tokp);
125 unget_token (tokp);
28f540f4
RM
126}
127
28f540f4 128/*
e7fd8a39 129 * Peek at the next token and scan it if it matches what you expect
28f540f4
RM
130 */
131int
880f421f 132peekscan (tok_kind expect, token *tokp)
28f540f4 133{
e7fd8a39
UD
134 peek (tokp);
135 if (tokp->kind == expect)
136 {
137 get_token (tokp);
880f421f 138 return 1;
e7fd8a39 139 }
880f421f 140 return 0;
28f540f4
RM
141}
142
28f540f4 143/*
e7fd8a39 144 * Get the next token, printing out any directive that are encountered.
28f540f4
RM
145 */
146void
880f421f 147get_token (token *tokp)
28f540f4 148{
e7fd8a39
UD
149 int commenting;
150
151 if (pushed)
152 {
153 pushed = 0;
154 *tokp = lasttok;
155 return;
156 }
157 commenting = 0;
158 for (;;)
159 {
160 if (*where == 0)
161 {
162 for (;;)
163 {
164 if (!fgets (curline, MAXLINESIZE, fin))
165 {
166 tokp->kind = TOK_EOF;
167 *curline = 0;
168 where = curline;
169 return;
170 }
171 linenum++;
172 if (commenting)
173 {
174 break;
28f540f4 175 }
e7fd8a39
UD
176 else if (cppline (curline))
177 {
178 docppline (curline, &linenum,
179 &infilename);
180 }
181 else if (directive (curline))
182 {
183 printdirective (curline);
184 }
185 else
186 {
187 break;
188 }
189 }
190 where = curline;
28f540f4 191 }
e7fd8a39
UD
192 else if (isspace (*where))
193 {
194 while (isspace (*where))
195 {
196 where++; /* eat */
197 }
198 }
199 else if (commenting)
200 {
201 for (where++; *where; where++)
202 {
203 if (endcomment (where))
204 {
205 where++;
206 commenting--;
207 break;
28f540f4 208 }
e7fd8a39
UD
209 }
210 }
211 else if (startcomment (where))
212 {
213 where += 2;
214 commenting++;
215 }
216 else
217 {
218 break;
28f540f4 219 }
e7fd8a39
UD
220 }
221
222 /*
223 * 'where' is not whitespace, comment or directive Must be a token!
224 */
225 switch (*where)
226 {
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;
279
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;
288
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;
303
304 default:
305 if (!(isalpha (*where) || *where == '_'))
306 {
307 char buf[100];
308 char *p;
309
310 s_print (buf, _("illegal character in file: "));
311 p = buf + strlen (buf);
312 if (isprint (*where))
313 {
314 s_print (p, "%c", *where);
315 }
316 else
317 {
318 s_print (p, "%d", *where);
319 }
320 error (buf);
321 }
322 findkind (&where, tokp);
323 break;
324 }
28f540f4
RM
325}
326
0d204b0a 327static void
e7fd8a39 328unget_token (token * tokp)
28f540f4 329{
e7fd8a39
UD
330 lasttok = *tokp;
331 pushed = 1;
28f540f4
RM
332}
333
0d204b0a 334static void
e7fd8a39 335findstrconst (const char **str, const char **val)
28f540f4 336{
e7fd8a39
UD
337 const char *p;
338 char *tmp;
339 int size;
340
341 p = *str;
342 do
343 {
344 p++;
345 }
346 while (*p && *p != '"');
347 if (*p == 0)
348 {
349 error (_("unterminated string constant"));
350 }
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;
28f540f4
RM
358}
359
0d204b0a 360static void
e7fd8a39 361findchrconst (const char **str, const char **val)
28f540f4 362{
e7fd8a39
UD
363 const char *p;
364 char *tmp;
365 int size;
366
367 p = *str;
368 do
369 {
370 p++;
371 }
372 while (*p && *p != '\'');
373 if (*p == 0)
374 {
375 error (_("unterminated string constant"));
376 }
377 p++;
378 size = p - *str;
379 if (size != 3)
380 {
381 error (_("empty char string"));
382 }
383 tmp = alloc (size + 1);
384 strncpy (tmp, *str, size);
385 tmp[size] = 0;
386 *val = tmp;
387 *str = p;
0d204b0a
UD
388}
389
390static void
e7fd8a39 391findconst (const char **str, const char **val)
0d204b0a 392{
e7fd8a39
UD
393 const char *p;
394 char *tmp;
395 int size;
396
397 p = *str;
398 if (*p == '0' && *(p + 1) == 'x')
399 {
400 p++;
401 do
402 {
403 p++;
28f540f4 404 }
e7fd8a39
UD
405 while (isxdigit (*p));
406 }
407 else
408 {
409 do
410 {
411 p++;
412 }
413 while (isdigit (*p));
414 }
415 size = p - *str;
416 tmp = alloc (size + 1);
417 strncpy (tmp, *str, size);
418 tmp[size] = 0;
419 *val = tmp;
420 *str = p;
28f540f4
RM
421}
422
e7fd8a39
UD
423static const token symbols[] =
424{
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"},
ce64ae6b 441 {TOK_HYPER, "hyper"},
e7fd8a39
UD
442 {TOK_FLOAT, "float"},
443 {TOK_DOUBLE, "double"},
444 {TOK_STRING, "string"},
445 {TOK_PROGRAM, "program"},
446 {TOK_VERSION, "version"},
447 {TOK_EOF, "??????"},
28f540f4
RM
448};
449
0d204b0a 450static void
b13927da 451findkind (const char **mark, token *tokp)
28f540f4 452{
e7fd8a39 453 int len;
b13927da 454 const token *s;
e7fd8a39
UD
455 const char *str;
456 char *tmp;
457
458 str = *mark;
459 for (s = symbols; s->kind != TOK_EOF; s++)
460 {
461 len = strlen (s->str);
462 if (strncmp (str, s->str, len) == 0)
463 {
464 if (!isalnum (str[len]) && str[len] != '_')
465 {
466 tokp->kind = s->kind;
467 tokp->str = s->str;
468 *mark = str + len;
469 return;
470 }
28f540f4 471 }
e7fd8a39
UD
472 }
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;
28f540f4
RM
480}
481
0d204b0a 482static int
e7fd8a39 483cppline (const char *line)
28f540f4 484{
e7fd8a39 485 return line == curline && *line == '#';
28f540f4
RM
486}
487
0d204b0a 488static int
e7fd8a39 489directive (const char *line)
28f540f4 490{
e7fd8a39 491 return line == curline && *line == '%';
28f540f4
RM
492}
493
0d204b0a 494static void
e7fd8a39 495printdirective (const char *line)
28f540f4 496{
e7fd8a39 497 f_print (fout, "%s", line + 1);
28f540f4
RM
498}
499
0d204b0a 500static void
e7fd8a39 501docppline (const char *line, int *lineno, const char **fname)
28f540f4 502{
e7fd8a39
UD
503 char *file;
504 int num;
505 char *p;
506
507 line++;
508 while (isspace (*line))
509 {
510 line++;
511 }
512 num = atoi (line);
513 while (isdigit (*line))
514 {
515 line++;
516 }
517 while (isspace (*line))
518 {
519 line++;
520 }
521 if (*line != '"')
522 {
523 error (_("preprocessor error"));
524 }
525 line++;
526 p = file = alloc (strlen (line) + 1);
527 while (*line && *line != '"')
528 {
529 *p++ = *line++;
530 }
531 if (*line == 0)
532 {
533 error (_("preprocessor error"));
534 }
535 *p = 0;
536 if (*file == 0)
537 {
0ecb606c 538 free (file);
e7fd8a39
UD
539 *fname = NULL;
540 }
541 else
542 {
543 *fname = file;
544 }
545 *lineno = num - 1;
28f540f4 546}