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_util.c 1.14 93/07/05 SMI" 3312798Swpaulstatic char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI"; 341897Swollman#endif 3527935Scharnier#endif 361897Swollman 37100441Scharnier#include <sys/cdefs.h> 38100441Scharnier__FBSDID("$FreeBSD$"); 39100441Scharnier 401897Swollman/* 418874Srgrimes * rpc_util.c, Utility routines for the RPC protocol compiler 4212798Swpaul * Copyright (C) 1989, Sun Microsystems, Inc. 431897Swollman */ 4427935Scharnier#include <err.h> 45200462Sdelphij#include <ctype.h> 461897Swollman#include <stdio.h> 4717142Sjkh#include <string.h> 4817142Sjkh#include <unistd.h> 49152398Sdwmalone#include "rpc_parse.h" 501897Swollman#include "rpc_scan.h" 511897Swollman#include "rpc_util.h" 521897Swollman 5312798Swpaul#define ARGEXT "argument" 5412798Swpaul 551897Swollmanchar curline[MAXLINESIZE]; /* current read line */ 5612798Swpaulchar *where = curline; /* current point in line */ 5712798Swpaulint linenum = 0; /* current line number */ 581897Swollman 59152398Sdwmaloneconst char *infilename; /* input filename */ 601897Swollman 6112798Swpaul#define NFILES 7 62241737Sedstatic const char *outfiles[NFILES]; /* output file names */ 63241737Sedstatic int nfiles; 641897Swollman 6512798SwpaulFILE *fout; /* file pointer of current output */ 6612798SwpaulFILE *fin; /* file pointer of current input */ 671897Swollman 6812798Swpaullist *defined; /* list of defined things */ 691897Swollman 7092921Simpstatic void printwhere( void ); 711897Swollman 721897Swollman/* 738874Srgrimes * Reinitialize the world 741897Swollman */ 7517142Sjkhvoid 76152398Sdwmalonereinitialize(void) 771897Swollman{ 7812798Swpaul memset(curline, 0, MAXLINESIZE); 791897Swollman where = curline; 801897Swollman linenum = 0; 811897Swollman defined = NULL; 821897Swollman} 831897Swollman 841897Swollman/* 858874Srgrimes * string equality 861897Swollman */ 8717142Sjkhint 88152398Sdwmalonestreq(const char *a, const char *b) 891897Swollman{ 901897Swollman return (strcmp(a, b) == 0); 911897Swollman} 921897Swollman 931897Swollman/* 948874Srgrimes * find a value in a list 951897Swollman */ 9612798Swpauldefinition * 97152398Sdwmalonefindval(list *lst, const char *val, int (*cmp)(definition *, const char *)) 981897Swollman{ 991897Swollman for (; lst != NULL; lst = lst->next) { 1001897Swollman if ((*cmp) (lst->val, val)) { 1011897Swollman return (lst->val); 1021897Swollman } 1031897Swollman } 1041897Swollman return (NULL); 1051897Swollman} 1061897Swollman 1071897Swollman/* 1088874Srgrimes * store a value in a list 1091897Swollman */ 1101897Swollmanvoid 111152398Sdwmalonestoreval(list **lstp, definition *val) 1121897Swollman{ 1131897Swollman list **l; 1141897Swollman list *lst; 1151897Swollman 1161897Swollman for (l = lstp; *l != NULL; l = (list **) & (*l)->next); 117100441Scharnier lst = XALLOC(list); 1181897Swollman lst->val = val; 1191897Swollman lst->next = NULL; 1201897Swollman *l = lst; 1211897Swollman} 1221897Swollman 12317142Sjkhstatic int 124152398Sdwmalonefindit(definition *def, const char *type) 1251897Swollman{ 1261897Swollman return (streq(def->def_name, type)); 1271897Swollman} 1281897Swollman 129152398Sdwmalonestatic const char * 130152398Sdwmalonefixit(const char *type, const char *orig) 1311897Swollman{ 1321897Swollman definition *def; 1331897Swollman 1341897Swollman def = (definition *) FINDVAL(defined, type, findit); 1351897Swollman if (def == NULL || def->def_kind != DEF_TYPEDEF) { 1361897Swollman return (orig); 1371897Swollman } 1381897Swollman switch (def->def.ty.rel) { 1391897Swollman case REL_VECTOR: 14012798Swpaul if (streq(def->def.ty.old_type, "opaque")) 14112798Swpaul return ("char"); 14212798Swpaul else 14312798Swpaul return (def->def.ty.old_type); 14412798Swpaul 1451897Swollman case REL_ALIAS: 1461897Swollman return (fixit(def->def.ty.old_type, orig)); 1471897Swollman default: 1481897Swollman return (orig); 1491897Swollman } 1501897Swollman} 1511897Swollman 152152398Sdwmaloneconst char * 153152398Sdwmalonefixtype(const char *type) 1541897Swollman{ 1551897Swollman return (fixit(type, type)); 1561897Swollman} 1571897Swollman 158152398Sdwmaloneconst char * 159152398Sdwmalonestringfix(const char *type) 1601897Swollman{ 1611897Swollman if (streq(type, "string")) { 1621897Swollman return ("wrapstring"); 1631897Swollman } else { 1641897Swollman return (type); 1651897Swollman } 1661897Swollman} 1671897Swollman 1681897Swollmanvoid 169152398Sdwmaloneptype(const char *prefix, const char *type, int follow) 1701897Swollman{ 1711897Swollman if (prefix != NULL) { 1721897Swollman if (streq(prefix, "enum")) { 1731897Swollman f_print(fout, "enum "); 1741897Swollman } else { 1751897Swollman f_print(fout, "struct "); 1761897Swollman } 1771897Swollman } 1781897Swollman if (streq(type, "bool")) { 1791897Swollman f_print(fout, "bool_t "); 1801897Swollman } else if (streq(type, "string")) { 1811897Swollman f_print(fout, "char *"); 1821897Swollman } else { 1831897Swollman f_print(fout, "%s ", follow ? fixtype(type) : type); 1841897Swollman } 1851897Swollman} 1861897Swollman 18717142Sjkhstatic int 188152398Sdwmalonetypedefed(definition *def, const char *type) 1891897Swollman{ 1901897Swollman if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) { 1911897Swollman return (0); 1921897Swollman } else { 1931897Swollman return (streq(def->def_name, type)); 1941897Swollman } 1951897Swollman} 1961897Swollman 19717142Sjkhint 198152398Sdwmaloneisvectordef(const char *type, relation rel) 1991897Swollman{ 2001897Swollman definition *def; 2011897Swollman 2021897Swollman for (;;) { 2031897Swollman switch (rel) { 2041897Swollman case REL_VECTOR: 2051897Swollman return (!streq(type, "string")); 2061897Swollman case REL_ARRAY: 2071897Swollman return (0); 2081897Swollman case REL_POINTER: 2091897Swollman return (0); 2101897Swollman case REL_ALIAS: 2111897Swollman def = (definition *) FINDVAL(defined, type, typedefed); 2121897Swollman if (def == NULL) { 2131897Swollman return (0); 2141897Swollman } 2151897Swollman type = def->def.ty.old_type; 2161897Swollman rel = def->def.ty.rel; 2171897Swollman } 2181897Swollman } 21917142Sjkh 22017142Sjkh return (0); 2211897Swollman} 2221897Swollman 22312798Swpaulchar * 224152398Sdwmalonelocase(const char *str) 2251897Swollman{ 2261897Swollman char c; 2271897Swollman static char buf[100]; 2281897Swollman char *p = buf; 2291897Swollman 23017142Sjkh while ( (c = *str++) ) { 2311897Swollman *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; 2321897Swollman } 2331897Swollman *p = 0; 2341897Swollman return (buf); 2351897Swollman} 2361897Swollman 23712798Swpaulvoid 238152398Sdwmalonepvname_svc(const char *pname, const char *vnum) 23912798Swpaul{ 24012798Swpaul f_print(fout, "%s_%s_svc", locase(pname), vnum); 24112798Swpaul} 2421897Swollman 2431897Swollmanvoid 244152398Sdwmalonepvname(const char *pname, const char *vnum) 2451897Swollman{ 2461897Swollman f_print(fout, "%s_%s", locase(pname), vnum); 2471897Swollman} 2481897Swollman 2491897Swollman/* 2508874Srgrimes * print a useful (?) error message, and then die 2511897Swollman */ 2521897Swollmanvoid 253152398Sdwmaloneerror(const char *msg) 2541897Swollman{ 2551897Swollman printwhere(); 25627935Scharnier warnx("%s, line %d: %s", infilename, linenum, msg); 2571897Swollman crash(); 2581897Swollman} 2591897Swollman 2601897Swollman/* 2611897Swollman * Something went wrong, unlink any files that we may have created and then 2628874Srgrimes * die. 2631897Swollman */ 26417142Sjkhvoid 265152398Sdwmalonecrash(void) 2661897Swollman{ 2671897Swollman int i; 2681897Swollman 2691897Swollman for (i = 0; i < nfiles; i++) { 2701897Swollman (void) unlink(outfiles[i]); 2711897Swollman } 2721897Swollman exit(1); 2731897Swollman} 2741897Swollman 2751897Swollmanvoid 276152398Sdwmalonerecord_open(const char *file) 2771897Swollman{ 2781897Swollman if (nfiles < NFILES) { 2791897Swollman outfiles[nfiles++] = file; 2801897Swollman } else { 28127935Scharnier warnx("too many files"); 2821897Swollman crash(); 2831897Swollman } 2841897Swollman} 2851897Swollman 2861897Swollmanstatic char expectbuf[100]; 287152398Sdwmalonestatic const char *toktostr(tok_kind kind); 2881897Swollman 2891897Swollman/* 2908874Srgrimes * error, token encountered was not the expected one 2911897Swollman */ 2921897Swollmanvoid 293152398Sdwmaloneexpected1(tok_kind exp1) 2941897Swollman{ 2951897Swollman s_print(expectbuf, "expected '%s'", 2961897Swollman toktostr(exp1)); 2971897Swollman error(expectbuf); 2981897Swollman} 2991897Swollman 3001897Swollman/* 3018874Srgrimes * error, token encountered was not one of two expected ones 3021897Swollman */ 3031897Swollmanvoid 304152398Sdwmaloneexpected2(tok_kind exp1, tok_kind exp2) 3051897Swollman{ 3061897Swollman s_print(expectbuf, "expected '%s' or '%s'", 3071897Swollman toktostr(exp1), 3081897Swollman toktostr(exp2)); 3091897Swollman error(expectbuf); 3101897Swollman} 3111897Swollman 3121897Swollman/* 3138874Srgrimes * error, token encountered was not one of 3 expected ones 3141897Swollman */ 3151897Swollmanvoid 316152398Sdwmaloneexpected3(tok_kind exp1, tok_kind exp2, tok_kind exp3) 3171897Swollman{ 3181897Swollman s_print(expectbuf, "expected '%s', '%s' or '%s'", 3191897Swollman toktostr(exp1), 3201897Swollman toktostr(exp2), 3211897Swollman toktostr(exp3)); 3221897Swollman error(expectbuf); 3231897Swollman} 3241897Swollman 3251897Swollmanvoid 326152398Sdwmalonetabify(FILE *f, int tab) 3271897Swollman{ 3281897Swollman while (tab--) { 3291897Swollman (void) fputc('\t', f); 3301897Swollman } 3311897Swollman} 3321897Swollman 3331897Swollman 3341897Swollmanstatic token tokstrings[] = { 33512798Swpaul {TOK_IDENT, "identifier"}, 33612798Swpaul {TOK_CONST, "const"}, 33712798Swpaul {TOK_RPAREN, ")"}, 33812798Swpaul {TOK_LPAREN, "("}, 33912798Swpaul {TOK_RBRACE, "}"}, 34012798Swpaul {TOK_LBRACE, "{"}, 34112798Swpaul {TOK_LBRACKET, "["}, 34212798Swpaul {TOK_RBRACKET, "]"}, 34312798Swpaul {TOK_STAR, "*"}, 34412798Swpaul {TOK_COMMA, ","}, 34512798Swpaul {TOK_EQUAL, "="}, 34612798Swpaul {TOK_COLON, ":"}, 34712798Swpaul {TOK_SEMICOLON, ";"}, 34812798Swpaul {TOK_UNION, "union"}, 34912798Swpaul {TOK_STRUCT, "struct"}, 35012798Swpaul {TOK_SWITCH, "switch"}, 35112798Swpaul {TOK_CASE, "case"}, 35212798Swpaul {TOK_DEFAULT, "default"}, 35312798Swpaul {TOK_ENUM, "enum"}, 35412798Swpaul {TOK_TYPEDEF, "typedef"}, 35512798Swpaul {TOK_INT, "int"}, 35612798Swpaul {TOK_SHORT, "short"}, 35712798Swpaul {TOK_LONG, "long"}, 35812798Swpaul {TOK_UNSIGNED, "unsigned"}, 35912798Swpaul {TOK_DOUBLE, "double"}, 36012798Swpaul {TOK_FLOAT, "float"}, 36112798Swpaul {TOK_CHAR, "char"}, 36212798Swpaul {TOK_STRING, "string"}, 36312798Swpaul {TOK_OPAQUE, "opaque"}, 36412798Swpaul {TOK_BOOL, "bool"}, 36512798Swpaul {TOK_VOID, "void"}, 36612798Swpaul {TOK_PROGRAM, "program"}, 36712798Swpaul {TOK_VERSION, "version"}, 36812798Swpaul {TOK_EOF, "??????"} 3691897Swollman}; 3701897Swollman 371152398Sdwmalonestatic const char * 372152398Sdwmalonetoktostr(tok_kind kind) 3731897Swollman{ 3741897Swollman token *sp; 3751897Swollman 3761897Swollman for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++); 3771897Swollman return (sp->str); 3781897Swollman} 3791897Swollman 38017142Sjkhstatic void 381152398Sdwmaloneprintbuf(void) 3821897Swollman{ 3831897Swollman char c; 3841897Swollman int i; 3851897Swollman int cnt; 3861897Swollman 3871897Swollman# define TABSIZE 4 3881897Swollman 38917142Sjkh for (i = 0; (c = curline[i]); i++) { 3901897Swollman if (c == '\t') { 3911897Swollman cnt = 8 - (i % TABSIZE); 3921897Swollman c = ' '; 3931897Swollman } else { 3941897Swollman cnt = 1; 3951897Swollman } 3961897Swollman while (cnt--) { 3971897Swollman (void) fputc(c, stderr); 3981897Swollman } 3991897Swollman } 4001897Swollman} 4011897Swollman 40217142Sjkhstatic void 403152398Sdwmaloneprintwhere(void) 4041897Swollman{ 4051897Swollman int i; 4061897Swollman char c; 4071897Swollman int cnt; 4081897Swollman 4091897Swollman printbuf(); 4101897Swollman for (i = 0; i < where - curline; i++) { 4111897Swollman c = curline[i]; 4121897Swollman if (c == '\t') { 4131897Swollman cnt = 8 - (i % TABSIZE); 4141897Swollman } else { 4151897Swollman cnt = 1; 4161897Swollman } 4171897Swollman while (cnt--) { 4181897Swollman (void) fputc('^', stderr); 4191897Swollman } 4201897Swollman } 4211897Swollman (void) fputc('\n', stderr); 4221897Swollman} 42312798Swpaul 42412798Swpaulchar * 425152398Sdwmalonemake_argname(const char *pname, const char *vname) 42612798Swpaul{ 42712798Swpaul char *name; 42812798Swpaul 429100441Scharnier name = xmalloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3); 43012798Swpaul sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT); 43112798Swpaul return (name); 43212798Swpaul} 43312798Swpaul 43412798Swpaulbas_type *typ_list_h; 43512798Swpaulbas_type *typ_list_t; 43612798Swpaul 43717142Sjkhvoid 438152398Sdwmaloneadd_type(int len, const char *type) 43912798Swpaul{ 44012798Swpaul bas_type *ptr; 44112798Swpaul 442100441Scharnier ptr = XALLOC(bas_type); 44312798Swpaul 44412798Swpaul ptr->name = type; 44512798Swpaul ptr->length = len; 44612798Swpaul ptr->next = NULL; 44712798Swpaul if (typ_list_t == NULL) 44812798Swpaul { 44912798Swpaul 45012798Swpaul typ_list_t = ptr; 45112798Swpaul typ_list_h = ptr; 45212798Swpaul } 45312798Swpaul else 45412798Swpaul { 45512798Swpaul typ_list_t->next = ptr; 45612798Swpaul typ_list_t = ptr; 45712798Swpaul }; 45812798Swpaul} 45912798Swpaul 46012798Swpaul 461152398Sdwmalonebas_type * 462152398Sdwmalonefind_type(const char *type) 46312798Swpaul{ 46412798Swpaul bas_type * ptr; 46512798Swpaul 46612798Swpaul ptr = typ_list_h; 46712798Swpaul while (ptr != NULL) 46812798Swpaul { 46912798Swpaul if (strcmp(ptr->name, type) == 0) 47012798Swpaul return (ptr); 47112798Swpaul else 47212798Swpaul ptr = ptr->next; 47312798Swpaul }; 47412798Swpaul return (NULL); 47512798Swpaul} 476100441Scharnier 477100441Scharniervoid * 478100441Scharnierxmalloc(size_t size) 479100441Scharnier{ 480100441Scharnier void *p; 481100441Scharnier 482100441Scharnier if ((p = malloc(size)) == NULL) { 483100441Scharnier warnx("malloc failed"); 484100441Scharnier crash(); 485100441Scharnier } 486100441Scharnier return (p); 487100441Scharnier} 488100441Scharnier 489100441Scharniervoid * 490100441Scharnierxrealloc(void *ptr, size_t size) 491100441Scharnier{ 492100441Scharnier void *p; 493100441Scharnier 494100441Scharnier if ((p = realloc(ptr, size)) == NULL) { 495100441Scharnier warnx("realloc failed"); 496100441Scharnier crash(); 497100441Scharnier } 498100441Scharnier return (p); 499100441Scharnier} 500100441Scharnier 501100441Scharnierchar * 502100441Scharnierxstrdup(const char *str) 503100441Scharnier{ 504100441Scharnier char *p; 505100441Scharnier 506100441Scharnier if ((p = strdup(str)) == NULL) { 507100441Scharnier warnx("strdup failed"); 508100441Scharnier crash(); 509100441Scharnier } 510100441Scharnier return (p); 511100441Scharnier} 512