11897Swollman/* 21897Swollman * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 31897Swollman * unrestricted use provided that this legend is included on all tape 41897Swollman * media and as a part of the software program in whole or part. Users 51897Swollman * may copy or modify Sun RPC without charge, but are not authorized 61897Swollman * to license or distribute it to anyone else except as part of a product or 71897Swollman * program developed by the user. 8100441Scharnier * 91897Swollman * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 101897Swollman * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 111897Swollman * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 12100441Scharnier * 131897Swollman * Sun RPC is provided with no support and without any obligation on the 141897Swollman * part of Sun Microsystems, Inc. to assist in its use, correction, 151897Swollman * modification or enhancement. 16100441Scharnier * 171897Swollman * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 181897Swollman * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 191897Swollman * OR ANY PART THEREOF. 20100441Scharnier * 211897Swollman * In no event will Sun Microsystems, Inc. be liable for any lost revenue 221897Swollman * or profits or other special, indirect and consequential damages, even if 231897Swollman * Sun has been advised of the possibility of such damages. 24100441Scharnier * 251897Swollman * Sun Microsystems, Inc. 261897Swollman * 2550 Garcia Avenue 271897Swollman * Mountain View, California 94043 281897Swollman */ 2912798Swpaul 30100441Scharnier#if 0 311897Swollman#ifndef lint 32146833Sstefanf#ident "@(#)rpc_scan.c 1.13 93/07/05 SMI" 3312798Swpaulstatic char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI"; 341897Swollman#endif 3599979Salfred#endif 361897Swollman 37100441Scharnier#include <sys/cdefs.h> 38100441Scharnier__FBSDID("$FreeBSD$"); 39100441Scharnier 401897Swollman/* 41100441Scharnier * rpc_scan.c, Scanner for the RPC protocol compiler 42100441Scharnier * Copyright (C) 1987, Sun Microsystems, Inc. 431897Swollman */ 4412798Swpaul 4567191Sbrian#include <sys/types.h> 4667191Sbrian 4712798Swpaul#include <sys/wait.h> 481897Swollman#include <stdio.h> 491897Swollman#include <ctype.h> 5012798Swpaul#include <string.h> 51152398Sdwmalone#include "rpc_parse.h" 521897Swollman#include "rpc_scan.h" 531897Swollman#include "rpc_util.h" 541897Swollman 551897Swollman#define startcomment(where) (where[0] == '/' && where[1] == '*') 561897Swollman#define endcomment(where) (where[-1] == '*' && where[0] == '/') 571897Swollman 581897Swollmanstatic int pushed = 0; /* is a token pushed */ 591897Swollmanstatic token lasttok; /* last token, if pushed */ 601897Swollman 6192921Simpstatic void unget_token( token * ); 62152398Sdwmalonestatic void findstrconst(char **, const char **); 63152398Sdwmalonestatic void findchrconst(char **, const char **); 64152398Sdwmalonestatic void findconst(char **, const char **); 6592921Simpstatic void findkind( char **, token * ); 6692921Simpstatic int cppline( char * ); 6792921Simpstatic int directive( char * ); 6892921Simpstatic void printdirective( char * ); 69152398Sdwmalonestatic void docppline(char *, int *, const char **); 7012798Swpaul 711897Swollman/* 72100441Scharnier * scan expecting 1 given token 731897Swollman */ 741897Swollmanvoid 75152398Sdwmalonescan(tok_kind expect, token *tokp) 761897Swollman{ 771897Swollman get_token(tokp); 781897Swollman if (tokp->kind != expect) { 791897Swollman expected1(expect); 801897Swollman } 811897Swollman} 821897Swollman 831897Swollman/* 84100441Scharnier * scan expecting any of the 2 given tokens 851897Swollman */ 861897Swollmanvoid 87152398Sdwmalonescan2(tok_kind expect1, tok_kind expect2, token *tokp) 881897Swollman{ 891897Swollman get_token(tokp); 901897Swollman if (tokp->kind != expect1 && tokp->kind != expect2) { 911897Swollman expected2(expect1, expect2); 921897Swollman } 931897Swollman} 941897Swollman 951897Swollman/* 96100441Scharnier * scan expecting any of the 3 given token 971897Swollman */ 981897Swollmanvoid 99152398Sdwmalonescan3(tok_kind expect1, tok_kind expect2, tok_kind expect3, token *tokp) 1001897Swollman{ 1011897Swollman get_token(tokp); 1021897Swollman if (tokp->kind != expect1 && tokp->kind != expect2 1031897Swollman && tokp->kind != expect3) { 1041897Swollman expected3(expect1, expect2, expect3); 1051897Swollman } 1061897Swollman} 1071897Swollman 1081897Swollman/* 109100441Scharnier * scan expecting a constant, possibly symbolic 1101897Swollman */ 1111897Swollmanvoid 112152398Sdwmalonescan_num(token *tokp) 1131897Swollman{ 1141897Swollman get_token(tokp); 1151897Swollman switch (tokp->kind) { 1161897Swollman case TOK_IDENT: 1171897Swollman break; 1181897Swollman default: 1191897Swollman error("constant or identifier expected"); 1201897Swollman } 1211897Swollman} 1221897Swollman 1231897Swollman/* 124100441Scharnier * Peek at the next token 1251897Swollman */ 1261897Swollmanvoid 127152398Sdwmalonepeek(token *tokp) 1281897Swollman{ 1291897Swollman get_token(tokp); 1301897Swollman unget_token(tokp); 1311897Swollman} 1321897Swollman 1331897Swollman/* 134100441Scharnier * Peek at the next token and scan it if it matches what you expect 1351897Swollman */ 1361897Swollmanint 137152398Sdwmalonepeekscan(tok_kind expect, token *tokp) 1381897Swollman{ 1391897Swollman peek(tokp); 1401897Swollman if (tokp->kind == expect) { 1411897Swollman get_token(tokp); 1421897Swollman return (1); 1431897Swollman } 1441897Swollman return (0); 1451897Swollman} 1461897Swollman 1471897Swollman/* 148100441Scharnier * Get the next token, printing out any directive that are encountered. 1491897Swollman */ 1501897Swollmanvoid 151152398Sdwmaloneget_token(token *tokp) 1521897Swollman{ 1531897Swollman int commenting; 15412798Swpaul int stat = 0; 15512798Swpaul 15612798Swpaul 1571897Swollman if (pushed) { 1581897Swollman pushed = 0; 1591897Swollman *tokp = lasttok; 1601897Swollman return; 1611897Swollman } 1621897Swollman commenting = 0; 1631897Swollman for (;;) { 1641897Swollman if (*where == 0) { 1651897Swollman for (;;) { 1661897Swollman if (!fgets(curline, MAXLINESIZE, fin)) { 1671897Swollman tokp->kind = TOK_EOF; 16812798Swpaul /* now check if cpp returned non NULL value */ 16912798Swpaul waitpid(childpid, &stat, WUNTRACED); 17012798Swpaul if (stat > 0) { 17112798Swpaul /* Set return value from rpcgen */ 17212798Swpaul nonfatalerrors = stat >> 8; 17312798Swpaul } 1741897Swollman *where = 0; 1751897Swollman return; 1761897Swollman } 1771897Swollman linenum++; 1781897Swollman if (commenting) { 1791897Swollman break; 1801897Swollman } else if (cppline(curline)) { 181100441Scharnier docppline(curline, &linenum, 1821897Swollman &infilename); 1831897Swollman } else if (directive(curline)) { 1841897Swollman printdirective(curline); 1851897Swollman } else { 1861897Swollman break; 1871897Swollman } 1881897Swollman } 1891897Swollman where = curline; 1901897Swollman } else if (isspace(*where)) { 1911897Swollman while (isspace(*where)) { 1921897Swollman where++; /* eat */ 1931897Swollman } 1941897Swollman } else if (commenting) { 19512798Swpaul for (where++; *where; where++) { 19612798Swpaul if (endcomment(where)) { 19712798Swpaul where++; 19812798Swpaul commenting--; 19912798Swpaul break; 20012798Swpaul } 2011897Swollman } 2021897Swollman } else if (startcomment(where)) { 2031897Swollman where += 2; 2041897Swollman commenting++; 2051897Swollman } else { 2061897Swollman break; 2071897Swollman } 2081897Swollman } 2091897Swollman 2101897Swollman /* 211100441Scharnier * 'where' is not whitespace, comment or directive Must be a token! 2121897Swollman */ 2131897Swollman switch (*where) { 2141897Swollman case ':': 2151897Swollman tokp->kind = TOK_COLON; 2161897Swollman where++; 2171897Swollman break; 2181897Swollman case ';': 2191897Swollman tokp->kind = TOK_SEMICOLON; 2201897Swollman where++; 2211897Swollman break; 2221897Swollman case ',': 2231897Swollman tokp->kind = TOK_COMMA; 2241897Swollman where++; 2251897Swollman break; 2261897Swollman case '=': 2271897Swollman tokp->kind = TOK_EQUAL; 2281897Swollman where++; 2291897Swollman break; 2301897Swollman case '*': 2311897Swollman tokp->kind = TOK_STAR; 2321897Swollman where++; 2331897Swollman break; 2341897Swollman case '[': 2351897Swollman tokp->kind = TOK_LBRACKET; 2361897Swollman where++; 2371897Swollman break; 2381897Swollman case ']': 2391897Swollman tokp->kind = TOK_RBRACKET; 2401897Swollman where++; 2411897Swollman break; 2421897Swollman case '{': 2431897Swollman tokp->kind = TOK_LBRACE; 2441897Swollman where++; 2451897Swollman break; 2461897Swollman case '}': 2471897Swollman tokp->kind = TOK_RBRACE; 2481897Swollman where++; 2491897Swollman break; 2501897Swollman case '(': 2511897Swollman tokp->kind = TOK_LPAREN; 2521897Swollman where++; 2531897Swollman break; 2541897Swollman case ')': 2551897Swollman tokp->kind = TOK_RPAREN; 2561897Swollman where++; 2571897Swollman break; 2581897Swollman case '<': 2591897Swollman tokp->kind = TOK_LANGLE; 2601897Swollman where++; 2611897Swollman break; 2621897Swollman case '>': 2631897Swollman tokp->kind = TOK_RANGLE; 2641897Swollman where++; 2651897Swollman break; 2661897Swollman 2671897Swollman case '"': 2681897Swollman tokp->kind = TOK_STRCONST; 2691897Swollman findstrconst(&where, &tokp->str); 2701897Swollman break; 27112798Swpaul case '\'': 27212798Swpaul tokp->kind = TOK_CHARCONST; 27312798Swpaul findchrconst(&where, &tokp->str); 27412798Swpaul break; 2751897Swollman 2761897Swollman case '-': 2771897Swollman case '0': 2781897Swollman case '1': 2791897Swollman case '2': 2801897Swollman case '3': 2811897Swollman case '4': 2821897Swollman case '5': 2831897Swollman case '6': 2841897Swollman case '7': 2851897Swollman case '8': 2861897Swollman case '9': 2871897Swollman tokp->kind = TOK_IDENT; 2881897Swollman findconst(&where, &tokp->str); 2891897Swollman break; 2901897Swollman 2911897Swollman default: 2921897Swollman if (!(isalpha(*where) || *where == '_')) { 2931897Swollman char buf[100]; 2941897Swollman char *p; 2951897Swollman 2961897Swollman s_print(buf, "illegal character in file: "); 2971897Swollman p = buf + strlen(buf); 2981897Swollman if (isprint(*where)) { 2991897Swollman s_print(p, "%c", *where); 3001897Swollman } else { 3011897Swollman s_print(p, "%d", *where); 3021897Swollman } 3031897Swollman error(buf); 3041897Swollman } 3051897Swollman findkind(&where, tokp); 3061897Swollman break; 3071897Swollman } 3081897Swollman} 3091897Swollman 31017142Sjkhstatic void 311152398Sdwmaloneunget_token(token *tokp) 3121897Swollman{ 3131897Swollman lasttok = *tokp; 3141897Swollman pushed = 1; 3151897Swollman} 3161897Swollman 31717142Sjkhstatic void 318152398Sdwmalonefindstrconst(char **str, const char **val) 3191897Swollman{ 3201897Swollman char *p; 321152398Sdwmalone char *tmp; 3221897Swollman int size; 3231897Swollman 3241897Swollman p = *str; 3251897Swollman do { 32617142Sjkh p++; 3271897Swollman } while (*p && *p != '"'); 3281897Swollman if (*p == 0) { 3291897Swollman error("unterminated string constant"); 3301897Swollman } 3311897Swollman p++; 332223922Sdelphij size = p - *str + 1; 333223922Sdelphij tmp = xmalloc(size); 334223922Sdelphij (void) strlcpy(tmp, *str, size); 335152398Sdwmalone *val = tmp; 3361897Swollman *str = p; 3371897Swollman} 3381897Swollman 33917142Sjkhstatic void 340152398Sdwmalonefindchrconst(char **str, const char **val) 34112798Swpaul{ 34212798Swpaul char *p; 343152398Sdwmalone char *tmp; 34412798Swpaul int size; 34512798Swpaul 34612798Swpaul p = *str; 34712798Swpaul do { 34817142Sjkh p++; 34912798Swpaul } while (*p && *p != '\''); 35012798Swpaul if (*p == 0) { 35112798Swpaul error("unterminated string constant"); 35212798Swpaul } 35312798Swpaul p++; 354223922Sdelphij size = p - *str + 1; 355223922Sdelphij if (size != 4) { 35612798Swpaul error("empty char string"); 35712798Swpaul } 358223922Sdelphij tmp = xmalloc(size); 359223922Sdelphij (void) strlcpy(tmp, *str, size); 360152398Sdwmalone *val = tmp; 36112798Swpaul *str = p; 36212798Swpaul} 36312798Swpaul 36417142Sjkhstatic void 365152398Sdwmalonefindconst(char **str, const char **val) 3661897Swollman{ 3671897Swollman char *p; 368152398Sdwmalone char *tmp; 3691897Swollman int size; 3701897Swollman 3711897Swollman p = *str; 3721897Swollman if (*p == '0' && *(p + 1) == 'x') { 3731897Swollman p++; 3741897Swollman do { 3751897Swollman p++; 3761897Swollman } while (isxdigit(*p)); 3771897Swollman } else { 3781897Swollman do { 3791897Swollman p++; 3801897Swollman } while (isdigit(*p)); 3811897Swollman } 382223922Sdelphij size = p - *str + 1; 383223922Sdelphij tmp = xmalloc(size); 384223922Sdelphij (void) strlcpy(tmp, *str, size); 385152398Sdwmalone *val = tmp; 3861897Swollman *str = p; 3871897Swollman} 3881897Swollman 3891897Swollmanstatic token symbols[] = { 3901897Swollman {TOK_CONST, "const"}, 3911897Swollman {TOK_UNION, "union"}, 3921897Swollman {TOK_SWITCH, "switch"}, 3931897Swollman {TOK_CASE, "case"}, 3941897Swollman {TOK_DEFAULT, "default"}, 3951897Swollman {TOK_STRUCT, "struct"}, 3961897Swollman {TOK_TYPEDEF, "typedef"}, 3971897Swollman {TOK_ENUM, "enum"}, 3981897Swollman {TOK_OPAQUE, "opaque"}, 3991897Swollman {TOK_BOOL, "bool"}, 4001897Swollman {TOK_VOID, "void"}, 4011897Swollman {TOK_CHAR, "char"}, 4021897Swollman {TOK_INT, "int"}, 4031897Swollman {TOK_UNSIGNED, "unsigned"}, 4041897Swollman {TOK_SHORT, "short"}, 4051897Swollman {TOK_LONG, "long"}, 40612798Swpaul {TOK_HYPER, "hyper"}, 4071897Swollman {TOK_FLOAT, "float"}, 4081897Swollman {TOK_DOUBLE, "double"}, 40912798Swpaul {TOK_QUAD, "quadruple"}, 4101897Swollman {TOK_STRING, "string"}, 4111897Swollman {TOK_PROGRAM, "program"}, 4121897Swollman {TOK_VERSION, "version"}, 4131897Swollman {TOK_EOF, "??????"}, 4141897Swollman}; 4151897Swollman 41617142Sjkhstatic void 417152398Sdwmalonefindkind(char **mark, token *tokp) 4181897Swollman{ 4191897Swollman int len; 4201897Swollman token *s; 421152398Sdwmalone char *str, *tmp; 4221897Swollman 4231897Swollman str = *mark; 4241897Swollman for (s = symbols; s->kind != TOK_EOF; s++) { 4251897Swollman len = strlen(s->str); 4261897Swollman if (strncmp(str, s->str, len) == 0) { 4271897Swollman if (!isalnum(str[len]) && str[len] != '_') { 4281897Swollman tokp->kind = s->kind; 4291897Swollman tokp->str = s->str; 4301897Swollman *mark = str + len; 4311897Swollman return; 4321897Swollman } 4331897Swollman } 4341897Swollman } 4351897Swollman tokp->kind = TOK_IDENT; 4361897Swollman for (len = 0; isalnum(str[len]) || str[len] == '_'; len++); 437152398Sdwmalone tmp = xmalloc(len + 1); 438223922Sdelphij (void) strlcpy(tmp, str, len + 1); 439152398Sdwmalone tokp->str = tmp; 4401897Swollman *mark = str + len; 4411897Swollman} 4421897Swollman 44317142Sjkhstatic int 444152398Sdwmalonecppline(char *line) 4451897Swollman{ 4461897Swollman return (line == curline && *line == '#'); 4471897Swollman} 4481897Swollman 44917142Sjkhstatic int 450152398Sdwmalonedirective(char *line) 4511897Swollman{ 4521897Swollman return (line == curline && *line == '%'); 4531897Swollman} 4541897Swollman 45517142Sjkhstatic void 456152398Sdwmaloneprintdirective(char *line) 4571897Swollman{ 4581897Swollman f_print(fout, "%s", line + 1); 4591897Swollman} 4601897Swollman 46117142Sjkhstatic void 462152398Sdwmalonedocppline(char *line, int *lineno, const char **fname) 4631897Swollman{ 4641897Swollman char *file; 4651897Swollman int num; 4661897Swollman char *p; 4671897Swollman 4681897Swollman line++; 4691897Swollman while (isspace(*line)) { 4701897Swollman line++; 4711897Swollman } 4721897Swollman num = atoi(line); 4731897Swollman while (isdigit(*line)) { 4741897Swollman line++; 4751897Swollman } 4761897Swollman while (isspace(*line)) { 4771897Swollman line++; 4781897Swollman } 4791897Swollman if (*line != '"') { 4801897Swollman error("preprocessor error"); 4811897Swollman } 4821897Swollman line++; 483100441Scharnier p = file = xmalloc(strlen(line) + 1); 4841897Swollman while (*line && *line != '"') { 4851897Swollman *p++ = *line++; 4861897Swollman } 4871897Swollman if (*line == 0) { 4881897Swollman error("preprocessor error"); 4891897Swollman } 4901897Swollman *p = 0; 4911897Swollman if (*file == 0) { 4921897Swollman *fname = NULL; 4931897Swollman } else { 4941897Swollman *fname = file; 4951897Swollman } 4961897Swollman *lineno = num - 1; 4971897Swollman} 498