rpc_scan.c revision 92921
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. 812798Swpaul * 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. 1212798Swpaul * 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. 1612798Swpaul * 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. 2012798Swpaul * 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. 2412798Swpaul * 251897Swollman * Sun Microsystems, Inc. 261897Swollman * 2550 Garcia Avenue 271897Swollman * Mountain View, California 94043 2867191Sbrian * 2967191Sbrian * $FreeBSD: head/usr.bin/rpcgen/rpc_scan.c 92921 2002-03-22 01:33:25Z imp $ 301897Swollman */ 3112798Swpaul 3212798Swpaul#ident "@(#)rpc_scan.c 1.13 93/07/05 SMI" 3312798Swpaul 341897Swollman#ifndef lint 3512798Swpaulstatic char sccsid[] = "@(#)rpc_scan.c 1.11 89/02/22 (C) 1987 SMI"; 361897Swollman#endif 371897Swollman 381897Swollman/* 3912798Swpaul * rpc_scan.c, Scanner for the RPC protocol compiler 4012798Swpaul * Copyright (C) 1987, Sun Microsystems, Inc. 411897Swollman */ 4212798Swpaul 4367191Sbrian#include <sys/types.h> 4467191Sbrian 4512798Swpaul#include <sys/wait.h> 461897Swollman#include <stdio.h> 471897Swollman#include <ctype.h> 4812798Swpaul#include <string.h> 491897Swollman#include "rpc_scan.h" 5012798Swpaul#include "rpc_parse.h" 511897Swollman#include "rpc_util.h" 521897Swollman 531897Swollman#define startcomment(where) (where[0] == '/' && where[1] == '*') 541897Swollman#define endcomment(where) (where[-1] == '*' && where[0] == '/') 551897Swollman 561897Swollmanstatic int pushed = 0; /* is a token pushed */ 571897Swollmanstatic token lasttok; /* last token, if pushed */ 581897Swollman 5992921Simpstatic void unget_token( token * ); 6092921Simpstatic void findstrconst( char **, char **); 6192921Simpstatic void findchrconst( char **, char **); 6292921Simpstatic void findconst( char **, char **); 6392921Simpstatic void findkind( char **, token * ); 6492921Simpstatic int cppline( char * ); 6592921Simpstatic int directive( char * ); 6692921Simpstatic void printdirective( char * ); 6792921Simpstatic void docppline( char *, int *, char ** ); 6812798Swpaul 691897Swollman/* 7012798Swpaul * scan expecting 1 given token 711897Swollman */ 721897Swollmanvoid 731897Swollmanscan(expect, tokp) 741897Swollman tok_kind expect; 751897Swollman token *tokp; 761897Swollman{ 771897Swollman get_token(tokp); 781897Swollman if (tokp->kind != expect) { 791897Swollman expected1(expect); 801897Swollman } 811897Swollman} 821897Swollman 831897Swollman/* 8412798Swpaul * scan expecting any of the 2 given tokens 851897Swollman */ 861897Swollmanvoid 871897Swollmanscan2(expect1, expect2, tokp) 881897Swollman tok_kind expect1; 891897Swollman tok_kind expect2; 901897Swollman token *tokp; 911897Swollman{ 921897Swollman get_token(tokp); 931897Swollman if (tokp->kind != expect1 && tokp->kind != expect2) { 941897Swollman expected2(expect1, expect2); 951897Swollman } 961897Swollman} 971897Swollman 981897Swollman/* 9912798Swpaul * scan expecting any of the 3 given token 1001897Swollman */ 1011897Swollmanvoid 1021897Swollmanscan3(expect1, expect2, expect3, tokp) 1031897Swollman tok_kind expect1; 1041897Swollman tok_kind expect2; 1051897Swollman tok_kind expect3; 1061897Swollman token *tokp; 1071897Swollman{ 1081897Swollman get_token(tokp); 1091897Swollman if (tokp->kind != expect1 && tokp->kind != expect2 1101897Swollman && tokp->kind != expect3) { 1111897Swollman expected3(expect1, expect2, expect3); 1121897Swollman } 1131897Swollman} 1141897Swollman 1151897Swollman/* 11612798Swpaul * scan expecting a constant, possibly symbolic 1171897Swollman */ 1181897Swollmanvoid 1191897Swollmanscan_num(tokp) 1201897Swollman token *tokp; 1211897Swollman{ 1221897Swollman get_token(tokp); 1231897Swollman switch (tokp->kind) { 1241897Swollman case TOK_IDENT: 1251897Swollman break; 1261897Swollman default: 1271897Swollman error("constant or identifier expected"); 1281897Swollman } 1291897Swollman} 1301897Swollman 1311897Swollman/* 13212798Swpaul * Peek at the next token 1331897Swollman */ 1341897Swollmanvoid 1351897Swollmanpeek(tokp) 1361897Swollman token *tokp; 1371897Swollman{ 1381897Swollman get_token(tokp); 1391897Swollman unget_token(tokp); 1401897Swollman} 1411897Swollman 1421897Swollman/* 14312798Swpaul * Peek at the next token and scan it if it matches what you expect 1441897Swollman */ 1451897Swollmanint 1461897Swollmanpeekscan(expect, tokp) 1471897Swollman tok_kind expect; 1481897Swollman token *tokp; 1491897Swollman{ 1501897Swollman peek(tokp); 1511897Swollman if (tokp->kind == expect) { 1521897Swollman get_token(tokp); 1531897Swollman return (1); 1541897Swollman } 1551897Swollman return (0); 1561897Swollman} 1571897Swollman 1581897Swollman/* 15912798Swpaul * Get the next token, printing out any directive that are encountered. 1601897Swollman */ 1611897Swollmanvoid 1621897Swollmanget_token(tokp) 1631897Swollman token *tokp; 1641897Swollman{ 1651897Swollman int commenting; 16612798Swpaul int stat = 0; 16712798Swpaul 16812798Swpaul 1691897Swollman if (pushed) { 1701897Swollman pushed = 0; 1711897Swollman *tokp = lasttok; 1721897Swollman return; 1731897Swollman } 1741897Swollman commenting = 0; 1751897Swollman for (;;) { 1761897Swollman if (*where == 0) { 1771897Swollman for (;;) { 1781897Swollman if (!fgets(curline, MAXLINESIZE, fin)) { 1791897Swollman tokp->kind = TOK_EOF; 18012798Swpaul /* now check if cpp returned non NULL value */ 18112798Swpaul waitpid(childpid, &stat, WUNTRACED); 18212798Swpaul if (stat > 0) { 18312798Swpaul /* Set return value from rpcgen */ 18412798Swpaul nonfatalerrors = stat >> 8; 18512798Swpaul } 1861897Swollman *where = 0; 1871897Swollman return; 1881897Swollman } 1891897Swollman linenum++; 1901897Swollman if (commenting) { 1911897Swollman break; 1921897Swollman } else if (cppline(curline)) { 19312798Swpaul docppline(curline, &linenum, 1941897Swollman &infilename); 1951897Swollman } else if (directive(curline)) { 1961897Swollman printdirective(curline); 1971897Swollman } else { 1981897Swollman break; 1991897Swollman } 2001897Swollman } 2011897Swollman where = curline; 2021897Swollman } else if (isspace(*where)) { 2031897Swollman while (isspace(*where)) { 2041897Swollman where++; /* eat */ 2051897Swollman } 2061897Swollman } else if (commenting) { 20712798Swpaul for (where++; *where; where++) { 20812798Swpaul if (endcomment(where)) { 20912798Swpaul where++; 21012798Swpaul commenting--; 21112798Swpaul break; 21212798Swpaul } 2131897Swollman } 2141897Swollman } else if (startcomment(where)) { 2151897Swollman where += 2; 2161897Swollman commenting++; 2171897Swollman } else { 2181897Swollman break; 2191897Swollman } 2201897Swollman } 2211897Swollman 2221897Swollman /* 22312798Swpaul * 'where' is not whitespace, comment or directive Must be a token! 2241897Swollman */ 2251897Swollman switch (*where) { 2261897Swollman case ':': 2271897Swollman tokp->kind = TOK_COLON; 2281897Swollman where++; 2291897Swollman break; 2301897Swollman case ';': 2311897Swollman tokp->kind = TOK_SEMICOLON; 2321897Swollman where++; 2331897Swollman break; 2341897Swollman case ',': 2351897Swollman tokp->kind = TOK_COMMA; 2361897Swollman where++; 2371897Swollman break; 2381897Swollman case '=': 2391897Swollman tokp->kind = TOK_EQUAL; 2401897Swollman where++; 2411897Swollman break; 2421897Swollman case '*': 2431897Swollman tokp->kind = TOK_STAR; 2441897Swollman where++; 2451897Swollman break; 2461897Swollman case '[': 2471897Swollman tokp->kind = TOK_LBRACKET; 2481897Swollman where++; 2491897Swollman break; 2501897Swollman case ']': 2511897Swollman tokp->kind = TOK_RBRACKET; 2521897Swollman where++; 2531897Swollman break; 2541897Swollman case '{': 2551897Swollman tokp->kind = TOK_LBRACE; 2561897Swollman where++; 2571897Swollman break; 2581897Swollman case '}': 2591897Swollman tokp->kind = TOK_RBRACE; 2601897Swollman where++; 2611897Swollman break; 2621897Swollman case '(': 2631897Swollman tokp->kind = TOK_LPAREN; 2641897Swollman where++; 2651897Swollman break; 2661897Swollman case ')': 2671897Swollman tokp->kind = TOK_RPAREN; 2681897Swollman where++; 2691897Swollman break; 2701897Swollman case '<': 2711897Swollman tokp->kind = TOK_LANGLE; 2721897Swollman where++; 2731897Swollman break; 2741897Swollman case '>': 2751897Swollman tokp->kind = TOK_RANGLE; 2761897Swollman where++; 2771897Swollman break; 2781897Swollman 2791897Swollman case '"': 2801897Swollman tokp->kind = TOK_STRCONST; 2811897Swollman findstrconst(&where, &tokp->str); 2821897Swollman break; 28312798Swpaul case '\'': 28412798Swpaul tokp->kind = TOK_CHARCONST; 28512798Swpaul findchrconst(&where, &tokp->str); 28612798Swpaul break; 2871897Swollman 2881897Swollman case '-': 2891897Swollman case '0': 2901897Swollman case '1': 2911897Swollman case '2': 2921897Swollman case '3': 2931897Swollman case '4': 2941897Swollman case '5': 2951897Swollman case '6': 2961897Swollman case '7': 2971897Swollman case '8': 2981897Swollman case '9': 2991897Swollman tokp->kind = TOK_IDENT; 3001897Swollman findconst(&where, &tokp->str); 3011897Swollman break; 3021897Swollman 3031897Swollman default: 3041897Swollman if (!(isalpha(*where) || *where == '_')) { 3051897Swollman char buf[100]; 3061897Swollman char *p; 3071897Swollman 3081897Swollman s_print(buf, "illegal character in file: "); 3091897Swollman p = buf + strlen(buf); 3101897Swollman if (isprint(*where)) { 3111897Swollman s_print(p, "%c", *where); 3121897Swollman } else { 3131897Swollman s_print(p, "%d", *where); 3141897Swollman } 3151897Swollman error(buf); 3161897Swollman } 3171897Swollman findkind(&where, tokp); 3181897Swollman break; 3191897Swollman } 3201897Swollman} 3211897Swollman 32217142Sjkhstatic void 3231897Swollmanunget_token(tokp) 3241897Swollman token *tokp; 3251897Swollman{ 3261897Swollman lasttok = *tokp; 3271897Swollman pushed = 1; 3281897Swollman} 3291897Swollman 33017142Sjkhstatic void 3311897Swollmanfindstrconst(str, val) 3321897Swollman char **str; 3331897Swollman char **val; 3341897Swollman{ 3351897Swollman char *p; 3361897Swollman int size; 3371897Swollman 3381897Swollman p = *str; 3391897Swollman do { 34017142Sjkh p++; 3411897Swollman } while (*p && *p != '"'); 3421897Swollman if (*p == 0) { 3431897Swollman error("unterminated string constant"); 3441897Swollman } 3451897Swollman p++; 3461897Swollman size = p - *str; 3471897Swollman *val = alloc(size + 1); 3481897Swollman (void) strncpy(*val, *str, size); 3491897Swollman (*val)[size] = 0; 3501897Swollman *str = p; 3511897Swollman} 3521897Swollman 35317142Sjkhstatic void 35412798Swpaulfindchrconst(str, val) 35512798Swpaul char **str; 35612798Swpaul char **val; 35712798Swpaul{ 35812798Swpaul char *p; 35912798Swpaul int size; 36012798Swpaul 36112798Swpaul p = *str; 36212798Swpaul do { 36317142Sjkh p++; 36412798Swpaul } while (*p && *p != '\''); 36512798Swpaul if (*p == 0) { 36612798Swpaul error("unterminated string constant"); 36712798Swpaul } 36812798Swpaul p++; 36912798Swpaul size = p - *str; 37012798Swpaul if (size != 3) { 37112798Swpaul error("empty char string"); 37212798Swpaul } 37312798Swpaul *val = alloc(size + 1); 37412798Swpaul (void) strncpy(*val, *str, size); 37512798Swpaul (*val)[size] = 0; 37612798Swpaul *str = p; 37712798Swpaul} 37812798Swpaul 37917142Sjkhstatic void 3801897Swollmanfindconst(str, val) 3811897Swollman char **str; 3821897Swollman char **val; 3831897Swollman{ 3841897Swollman char *p; 3851897Swollman int size; 3861897Swollman 3871897Swollman p = *str; 3881897Swollman if (*p == '0' && *(p + 1) == 'x') { 3891897Swollman p++; 3901897Swollman do { 3911897Swollman p++; 3921897Swollman } while (isxdigit(*p)); 3931897Swollman } else { 3941897Swollman do { 3951897Swollman p++; 3961897Swollman } while (isdigit(*p)); 3971897Swollman } 3981897Swollman size = p - *str; 3991897Swollman *val = alloc(size + 1); 4001897Swollman (void) strncpy(*val, *str, size); 4011897Swollman (*val)[size] = 0; 4021897Swollman *str = p; 4031897Swollman} 4041897Swollman 4051897Swollmanstatic token symbols[] = { 4061897Swollman {TOK_CONST, "const"}, 4071897Swollman {TOK_UNION, "union"}, 4081897Swollman {TOK_SWITCH, "switch"}, 4091897Swollman {TOK_CASE, "case"}, 4101897Swollman {TOK_DEFAULT, "default"}, 4111897Swollman {TOK_STRUCT, "struct"}, 4121897Swollman {TOK_TYPEDEF, "typedef"}, 4131897Swollman {TOK_ENUM, "enum"}, 4141897Swollman {TOK_OPAQUE, "opaque"}, 4151897Swollman {TOK_BOOL, "bool"}, 4161897Swollman {TOK_VOID, "void"}, 4171897Swollman {TOK_CHAR, "char"}, 4181897Swollman {TOK_INT, "int"}, 4191897Swollman {TOK_UNSIGNED, "unsigned"}, 4201897Swollman {TOK_SHORT, "short"}, 4211897Swollman {TOK_LONG, "long"}, 42212798Swpaul {TOK_HYPER, "hyper"}, 4231897Swollman {TOK_FLOAT, "float"}, 4241897Swollman {TOK_DOUBLE, "double"}, 42512798Swpaul {TOK_QUAD, "quadruple"}, 4261897Swollman {TOK_STRING, "string"}, 4271897Swollman {TOK_PROGRAM, "program"}, 4281897Swollman {TOK_VERSION, "version"}, 4291897Swollman {TOK_EOF, "??????"}, 4301897Swollman}; 4311897Swollman 43217142Sjkhstatic void 4331897Swollmanfindkind(mark, tokp) 4341897Swollman char **mark; 4351897Swollman token *tokp; 4361897Swollman{ 4371897Swollman int len; 4381897Swollman token *s; 4391897Swollman char *str; 4401897Swollman 4411897Swollman str = *mark; 4421897Swollman for (s = symbols; s->kind != TOK_EOF; s++) { 4431897Swollman len = strlen(s->str); 4441897Swollman if (strncmp(str, s->str, len) == 0) { 4451897Swollman if (!isalnum(str[len]) && str[len] != '_') { 4461897Swollman tokp->kind = s->kind; 4471897Swollman tokp->str = s->str; 4481897Swollman *mark = str + len; 4491897Swollman return; 4501897Swollman } 4511897Swollman } 4521897Swollman } 4531897Swollman tokp->kind = TOK_IDENT; 4541897Swollman for (len = 0; isalnum(str[len]) || str[len] == '_'; len++); 4551897Swollman tokp->str = alloc(len + 1); 4561897Swollman (void) strncpy(tokp->str, str, len); 4571897Swollman tokp->str[len] = 0; 4581897Swollman *mark = str + len; 4591897Swollman} 4601897Swollman 46117142Sjkhstatic int 4621897Swollmancppline(line) 4631897Swollman char *line; 4641897Swollman{ 4651897Swollman return (line == curline && *line == '#'); 4661897Swollman} 4671897Swollman 46817142Sjkhstatic int 4691897Swollmandirective(line) 4701897Swollman char *line; 4711897Swollman{ 4721897Swollman return (line == curline && *line == '%'); 4731897Swollman} 4741897Swollman 47517142Sjkhstatic void 4761897Swollmanprintdirective(line) 4771897Swollman char *line; 4781897Swollman{ 4791897Swollman f_print(fout, "%s", line + 1); 4801897Swollman} 4811897Swollman 48217142Sjkhstatic void 4831897Swollmandocppline(line, lineno, fname) 4841897Swollman char *line; 4851897Swollman int *lineno; 4861897Swollman char **fname; 4871897Swollman{ 4881897Swollman char *file; 4891897Swollman int num; 4901897Swollman char *p; 4911897Swollman 4921897Swollman line++; 4931897Swollman while (isspace(*line)) { 4941897Swollman line++; 4951897Swollman } 4961897Swollman num = atoi(line); 4971897Swollman while (isdigit(*line)) { 4981897Swollman line++; 4991897Swollman } 5001897Swollman while (isspace(*line)) { 5011897Swollman line++; 5021897Swollman } 5031897Swollman if (*line != '"') { 5041897Swollman error("preprocessor error"); 5051897Swollman } 5061897Swollman line++; 5071897Swollman p = file = alloc(strlen(line) + 1); 5081897Swollman while (*line && *line != '"') { 5091897Swollman *p++ = *line++; 5101897Swollman } 5111897Swollman if (*line == 0) { 5121897Swollman error("preprocessor error"); 5131897Swollman } 5141897Swollman *p = 0; 5151897Swollman if (*file == 0) { 5161897Swollman *fname = NULL; 5171897Swollman } else { 5181897Swollman *fname = file; 5191897Swollman } 5201897Swollman *lineno = num - 1; 5211897Swollman} 522