]> git.ipfire.org Git - thirdparty/glibc.git/blame - sunrpc/rpc_scan.c
Update.
[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 */
e7fd8a39 34char scan_rcsid[] =
0d204b0a
UD
35 "$Id$";
36
37/*
e7fd8a39
UD
38 * rpc_scan.c, Scanner for the RPC protocol compiler
39 * Copyright (C) 1987, Sun Microsystems, Inc.
28f540f4
RM
40 */
41#include <stdio.h>
42#include <ctype.h>
0d204b0a 43#include <string.h>
28f540f4 44#include "rpc_scan.h"
0d204b0a 45#include "rpc_parse.h"
28f540f4 46#include "rpc_util.h"
0d204b0a 47#include "proto.h"
28f540f4
RM
48
49#define startcomment(where) (where[0] == '/' && where[1] == '*')
50#define endcomment(where) (where[-1] == '*' && where[0] == '/')
51
e7fd8a39
UD
52static int pushed = 0; /* is a token pushed */
53static token lasttok; /* last token, if pushed */
28f540f4 54
e7fd8a39
UD
55static void unget_token (token * tokp);
56static void findstrconst (const char **str, const char **val);
57static void findchrconst (const char **str, const char **val);
58static void findconst (const char **str, const char **val);
59static void findkind (const char **mark, token * tokp);
60static int cppline (const char *line);
61static int directive (const char *line);
62static void printdirective (const char *line);
63static void docppline (const char *line, int *lineno, const char **fname);
0d204b0a 64
28f540f4 65/*
e7fd8a39 66 * scan expecting 1 given token
28f540f4
RM
67 */
68void
e7fd8a39 69scan (tok_kind expect, token * tokp)
28f540f4 70{
e7fd8a39
UD
71 get_token (tokp);
72 if (tokp->kind != expect)
880f421f 73 expected1 (expect);
28f540f4
RM
74}
75
76/*
e7fd8a39 77 * scan expecting any of the 2 given tokens
28f540f4
RM
78 */
79void
e7fd8a39 80scan2 (tok_kind expect1, tok_kind expect2, token * tokp)
28f540f4 81{
e7fd8a39
UD
82 get_token (tokp);
83 if (tokp->kind != expect1 && tokp->kind != expect2)
84 {
85 expected2 (expect1, expect2);
86 }
28f540f4
RM
87}
88
89/*
e7fd8a39 90 * scan expecting any of the 3 given token
28f540f4
RM
91 */
92void
e7fd8a39 93scan3 (tok_kind expect1, tok_kind expect2, tok_kind expect3, token * tokp)
28f540f4 94{
e7fd8a39
UD
95 get_token (tokp);
96 if (tokp->kind != expect1 && tokp->kind != expect2
97 && tokp->kind != expect3)
98 {
99 expected3 (expect1, expect2, expect3);
100 }
28f540f4
RM
101}
102
28f540f4 103/*
e7fd8a39 104 * scan expecting a constant, possibly symbolic
28f540f4
RM
105 */
106void
880f421f 107scan_num (token *tokp)
28f540f4 108{
e7fd8a39
UD
109 get_token (tokp);
110 switch (tokp->kind)
111 {
112 case TOK_IDENT:
113 break;
114 default:
880f421f 115 error (_("constant or identifier expected"));
e7fd8a39 116 }
28f540f4
RM
117}
118
28f540f4 119/*
e7fd8a39 120 * Peek at the next token
28f540f4
RM
121 */
122void
880f421f 123peek (token *tokp)
28f540f4 124{
e7fd8a39
UD
125 get_token (tokp);
126 unget_token (tokp);
28f540f4
RM
127}
128
28f540f4 129/*
e7fd8a39 130 * Peek at the next token and scan it if it matches what you expect
28f540f4
RM
131 */
132int
880f421f 133peekscan (tok_kind expect, token *tokp)
28f540f4 134{
e7fd8a39
UD
135 peek (tokp);
136 if (tokp->kind == expect)
137 {
138 get_token (tokp);
880f421f 139 return 1;
e7fd8a39 140 }
880f421f 141 return 0;
28f540f4
RM
142}
143
28f540f4 144/*
e7fd8a39 145 * Get the next token, printing out any directive that are encountered.
28f540f4
RM
146 */
147void
880f421f 148get_token (token *tokp)
28f540f4 149{
e7fd8a39
UD
150 int commenting;
151
152 if (pushed)
153 {
154 pushed = 0;
155 *tokp = lasttok;
156 return;
157 }
158 commenting = 0;
159 for (;;)
160 {
161 if (*where == 0)
162 {
163 for (;;)
164 {
165 if (!fgets (curline, MAXLINESIZE, fin))
166 {
167 tokp->kind = TOK_EOF;
168 *curline = 0;
169 where = curline;
170 return;
171 }
172 linenum++;
173 if (commenting)
174 {
175 break;
28f540f4 176 }
e7fd8a39
UD
177 else if (cppline (curline))
178 {
179 docppline (curline, &linenum,
180 &infilename);
181 }
182 else if (directive (curline))
183 {
184 printdirective (curline);
185 }
186 else
187 {
188 break;
189 }
190 }
191 where = curline;
28f540f4 192 }
e7fd8a39
UD
193 else if (isspace (*where))
194 {
195 while (isspace (*where))
196 {
197 where++; /* eat */
198 }
199 }
200 else if (commenting)
201 {
202 for (where++; *where; where++)
203 {
204 if (endcomment (where))
205 {
206 where++;
207 commenting--;
208 break;
28f540f4 209 }
e7fd8a39
UD
210 }
211 }
212 else if (startcomment (where))
213 {
214 where += 2;
215 commenting++;
216 }
217 else
218 {
219 break;
28f540f4 220 }
e7fd8a39
UD
221 }
222
223 /*
224 * 'where' is not whitespace, comment or directive Must be a token!
225 */
226 switch (*where)
227 {
228 case ':':
229 tokp->kind = TOK_COLON;
230 where++;
231 break;
232 case ';':
233 tokp->kind = TOK_SEMICOLON;
234 where++;
235 break;
236 case ',':
237 tokp->kind = TOK_COMMA;
238 where++;
239 break;
240 case '=':
241 tokp->kind = TOK_EQUAL;
242 where++;
243 break;
244 case '*':
245 tokp->kind = TOK_STAR;
246 where++;
247 break;
248 case '[':
249 tokp->kind = TOK_LBRACKET;
250 where++;
251 break;
252 case ']':
253 tokp->kind = TOK_RBRACKET;
254 where++;
255 break;
256 case '{':
257 tokp->kind = TOK_LBRACE;
258 where++;
259 break;
260 case '}':
261 tokp->kind = TOK_RBRACE;
262 where++;
263 break;
264 case '(':
265 tokp->kind = TOK_LPAREN;
266 where++;
267 break;
268 case ')':
269 tokp->kind = TOK_RPAREN;
270 where++;
271 break;
272 case '<':
273 tokp->kind = TOK_LANGLE;
274 where++;
275 break;
276 case '>':
277 tokp->kind = TOK_RANGLE;
278 where++;
279 break;
280
281 case '"':
282 tokp->kind = TOK_STRCONST;
283 findstrconst (&where, &tokp->str);
284 break;
285 case '\'':
286 tokp->kind = TOK_CHARCONST;
287 findchrconst (&where, &tokp->str);
288 break;
289
290 case '-':
291 case '0':
292 case '1':
293 case '2':
294 case '3':
295 case '4':
296 case '5':
297 case '6':
298 case '7':
299 case '8':
300 case '9':
301 tokp->kind = TOK_IDENT;
302 findconst (&where, &tokp->str);
303 break;
304
305 default:
306 if (!(isalpha (*where) || *where == '_'))
307 {
308 char buf[100];
309 char *p;
310
311 s_print (buf, _("illegal character in file: "));
312 p = buf + strlen (buf);
313 if (isprint (*where))
314 {
315 s_print (p, "%c", *where);
316 }
317 else
318 {
319 s_print (p, "%d", *where);
320 }
321 error (buf);
322 }
323 findkind (&where, tokp);
324 break;
325 }
28f540f4
RM
326}
327
0d204b0a 328static void
e7fd8a39 329unget_token (token * tokp)
28f540f4 330{
e7fd8a39
UD
331 lasttok = *tokp;
332 pushed = 1;
28f540f4
RM
333}
334
0d204b0a 335static void
e7fd8a39 336findstrconst (const char **str, const char **val)
28f540f4 337{
e7fd8a39
UD
338 const char *p;
339 char *tmp;
340 int size;
341
342 p = *str;
343 do
344 {
345 p++;
346 }
347 while (*p && *p != '"');
348 if (*p == 0)
349 {
350 error (_("unterminated string constant"));
351 }
352 p++;
353 size = p - *str;
354 tmp = alloc (size + 1);
355 strncpy (tmp, *str, size);
356 tmp[size] = 0;
357 *val = tmp;
358 *str = p;
28f540f4
RM
359}
360
0d204b0a 361static void
e7fd8a39 362findchrconst (const char **str, const char **val)
28f540f4 363{
e7fd8a39
UD
364 const char *p;
365 char *tmp;
366 int size;
367
368 p = *str;
369 do
370 {
371 p++;
372 }
373 while (*p && *p != '\'');
374 if (*p == 0)
375 {
376 error (_("unterminated string constant"));
377 }
378 p++;
379 size = p - *str;
380 if (size != 3)
381 {
382 error (_("empty char string"));
383 }
384 tmp = alloc (size + 1);
385 strncpy (tmp, *str, size);
386 tmp[size] = 0;
387 *val = tmp;
388 *str = p;
0d204b0a
UD
389}
390
391static void
e7fd8a39 392findconst (const char **str, const char **val)
0d204b0a 393{
e7fd8a39
UD
394 const char *p;
395 char *tmp;
396 int size;
397
398 p = *str;
399 if (*p == '0' && *(p + 1) == 'x')
400 {
401 p++;
402 do
403 {
404 p++;
28f540f4 405 }
e7fd8a39
UD
406 while (isxdigit (*p));
407 }
408 else
409 {
410 do
411 {
412 p++;
413 }
414 while (isdigit (*p));
415 }
416 size = p - *str;
417 tmp = alloc (size + 1);
418 strncpy (tmp, *str, size);
419 tmp[size] = 0;
420 *val = tmp;
421 *str = p;
28f540f4
RM
422}
423
e7fd8a39
UD
424static const token symbols[] =
425{
426 {TOK_CONST, "const"},
427 {TOK_UNION, "union"},
428 {TOK_SWITCH, "switch"},
429 {TOK_CASE, "case"},
430 {TOK_DEFAULT, "default"},
431 {TOK_STRUCT, "struct"},
432 {TOK_TYPEDEF, "typedef"},
433 {TOK_ENUM, "enum"},
434 {TOK_OPAQUE, "opaque"},
435 {TOK_BOOL, "bool"},
436 {TOK_VOID, "void"},
437 {TOK_CHAR, "char"},
438 {TOK_INT, "int"},
439 {TOK_UNSIGNED, "unsigned"},
440 {TOK_SHORT, "short"},
441 {TOK_LONG, "long"},
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 {
538 *fname = NULL;
539 }
540 else
541 {
542 *fname = file;
543 }
544 *lineno = num - 1;
28f540f4 545}