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