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