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