rpc_util.c revision 299509
154359Sroberto/* 254359Sroberto * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 354359Sroberto * unrestricted use provided that this legend is included on all tape 454359Sroberto * media and as a part of the software program in whole or part. Users 554359Sroberto * may copy or modify Sun RPC without charge, but are not authorized 654359Sroberto * to license or distribute it to anyone else except as part of a product or 754359Sroberto * program developed by the user. 854359Sroberto * 954359Sroberto * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1054359Sroberto * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1154359Sroberto * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1254359Sroberto * 1354359Sroberto * Sun RPC is provided with no support and without any obligation on the 1454359Sroberto * part of Sun Microsystems, Inc. to assist in its use, correction, 1554359Sroberto * modification or enhancement. 1654359Sroberto * 1754359Sroberto * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 1854359Sroberto * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 1954359Sroberto * OR ANY PART THEREOF. 2054359Sroberto * 2154359Sroberto * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2254359Sroberto * or profits or other special, indirect and consequential damages, even if 23182007Sroberto * Sun has been advised of the possibility of such damages. 24182007Sroberto * 25182007Sroberto * Sun Microsystems, Inc. 26290001Sglebius * 2550 Garcia Avenue 27290001Sglebius * Mountain View, California 94043 28290001Sglebius */ 29290001Sglebius 30290001Sglebius#if 0 31182007Sroberto#ifndef lint 32182007Sroberto#ident "@(#)rpc_util.c 1.14 93/07/05 SMI" 33290001Sglebiusstatic char sccsid[] = "@(#)rpc_util.c 1.11 89/02/22 (C) 1987 SMI"; 34290001Sglebius#endif 35290001Sglebius#endif 36290001Sglebius 37182007Sroberto#include <sys/cdefs.h> 38182007Sroberto__FBSDID("$FreeBSD: head/usr.bin/rpcgen/rpc_util.c 299509 2016-05-12 03:49:05Z cem $"); 39290001Sglebius 40182007Sroberto/* 41182007Sroberto * rpc_util.c, Utility routines for the RPC protocol compiler 42182007Sroberto * Copyright (C) 1989, Sun Microsystems, Inc. 43290001Sglebius */ 44290001Sglebius#include <err.h> 45290001Sglebius#include <ctype.h> 4654359Sroberto#include <stdio.h> 4754359Sroberto#include <string.h> 4854359Sroberto#include <unistd.h> 4954359Sroberto#include "rpc_parse.h" 5054359Sroberto#include "rpc_scan.h" 5154359Sroberto#include "rpc_util.h" 5254359Sroberto 5354359Sroberto#define ARGEXT "argument" 5454359Sroberto 5554359Srobertochar curline[MAXLINESIZE]; /* current read line */ 5654359Srobertochar *where = curline; /* current point in line */ 5754359Srobertoint linenum = 0; /* current line number */ 5854359Sroberto 5954359Srobertoconst char *infilename; /* input filename */ 6082498Sroberto 6182498Sroberto#define NFILES 7 6282498Srobertostatic const char *outfiles[NFILES]; /* output file names */ 6382498Srobertostatic int nfiles; 6454359Sroberto 6554359SrobertoFILE *fout; /* file pointer of current output */ 6654359SrobertoFILE *fin; /* file pointer of current input */ 6754359Sroberto 6854359Srobertolist *defined; /* list of defined things */ 6954359Sroberto 7054359Srobertostatic void printwhere( void ); 7154359Sroberto 7254359Sroberto/* 7354359Sroberto * Reinitialize the world 7454359Sroberto */ 7554359Srobertovoid 7654359Srobertoreinitialize(void) 7754359Sroberto{ 7854359Sroberto memset(curline, 0, MAXLINESIZE); 7954359Sroberto where = curline; 8054359Sroberto linenum = 0; 8154359Sroberto defined = NULL; 8254359Sroberto} 8354359Sroberto 84182007Sroberto/* 85182007Sroberto * string equality 86182007Sroberto */ 87182007Srobertoint 88182007Srobertostreq(const char *a, const char *b) 89182007Sroberto{ 90290001Sglebius return (strcmp(a, b) == 0); 91290001Sglebius} 92290001Sglebius 93290001Sglebius/* 94290001Sglebius * find a value in a list 95290001Sglebius */ 96290001Sglebiusdefinition * 97290001Sglebiusfindval(list *lst, const char *val, int (*cmp)(definition *, const char *)) 98290001Sglebius{ 99290001Sglebius for (; lst != NULL; lst = lst->next) { 100290001Sglebius if ((*cmp) (lst->val, val)) { 101290001Sglebius return (lst->val); 10254359Sroberto } 103290001Sglebius } 104290001Sglebius return (NULL); 105290001Sglebius} 106290001Sglebius 107290001Sglebius/* 108290001Sglebius * store a value in a list 109290001Sglebius */ 110290001Sglebiusvoid 111290001Sglebiusstoreval(list **lstp, definition *val) 112290001Sglebius{ 113290001Sglebius list **l; 114290001Sglebius list *lst; 115290001Sglebius 116290001Sglebius for (l = lstp; *l != NULL; l = (list **) & (*l)->next); 117290001Sglebius lst = XALLOC(list); 118290001Sglebius lst->val = val; 119290001Sglebius lst->next = NULL; 120290001Sglebius *l = lst; 12154359Sroberto} 12254359Sroberto 12354359Srobertostatic int 12454359Srobertofindit(definition *def, const char *type) 12554359Sroberto{ 126182007Sroberto return (streq(def->def_name, type)); 12754359Sroberto} 12854359Sroberto 12954359Srobertostatic const char * 130182007Srobertofixit(const char *type, const char *orig) 13154359Sroberto{ 13254359Sroberto definition *def; 13354359Sroberto 13454359Sroberto def = (definition *) FINDVAL(defined, type, findit); 13554359Sroberto if (def == NULL || def->def_kind != DEF_TYPEDEF) { 13654359Sroberto return (orig); 13754359Sroberto } 13854359Sroberto switch (def->def.ty.rel) { 13954359Sroberto case REL_VECTOR: 14054359Sroberto if (streq(def->def.ty.old_type, "opaque")) 14154359Sroberto return ("char"); 14254359Sroberto else 14354359Sroberto return (def->def.ty.old_type); 14454359Sroberto 14554359Sroberto case REL_ALIAS: 14654359Sroberto return (fixit(def->def.ty.old_type, orig)); 14754359Sroberto default: 14854359Sroberto return (orig); 14954359Sroberto } 15054359Sroberto} 15154359Sroberto 15254359Srobertoconst char * 15354359Srobertofixtype(const char *type) 15454359Sroberto{ 15554359Sroberto return (fixit(type, type)); 15654359Sroberto} 15754359Sroberto 15854359Srobertoconst char * 15954359Srobertostringfix(const char *type) 16054359Sroberto{ 16154359Sroberto if (streq(type, "string")) { 16254359Sroberto return ("wrapstring"); 16354359Sroberto } else { 16454359Sroberto return (type); 165182007Sroberto } 166290001Sglebius} 167290001Sglebius 168290001Sglebiusvoid 169290001Sglebiusptype(const char *prefix, const char *type, int follow) 170290001Sglebius{ 171182007Sroberto if (prefix != NULL) { 172182007Sroberto if (streq(prefix, "enum")) { 173182007Sroberto f_print(fout, "enum "); 174182007Sroberto } else { 175182007Sroberto f_print(fout, "struct "); 176182007Sroberto } 177182007Sroberto } 178182007Sroberto if (streq(type, "bool")) { 17954359Sroberto f_print(fout, "bool_t "); 18054359Sroberto } else if (streq(type, "string")) { 18154359Sroberto f_print(fout, "char *"); 18254359Sroberto } else { 18354359Sroberto f_print(fout, "%s ", follow ? fixtype(type) : type); 18482498Sroberto } 18582498Sroberto} 18682498Sroberto 18782498Srobertostatic int 18882498Srobertotypedefed(definition *def, const char *type) 18982498Sroberto{ 19082498Sroberto if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) { 19154359Sroberto return (0); 19254359Sroberto } else { 19354359Sroberto return (streq(def->def_name, type)); 19454359Sroberto } 195182007Sroberto} 196182007Sroberto 19754359Srobertoint 198290001Sglebiusisvectordef(const char *type, relation rel) 199290001Sglebius{ 200290001Sglebius definition *def; 201290001Sglebius 202290001Sglebius for (;;) { 203290001Sglebius switch (rel) { 204290001Sglebius case REL_VECTOR: 205290001Sglebius return (!streq(type, "string")); 206290001Sglebius case REL_ARRAY: 20754359Sroberto return (0); 20854359Sroberto case REL_POINTER: 20954359Sroberto return (0); 21054359Sroberto case REL_ALIAS: 21154359Sroberto def = (definition *) FINDVAL(defined, type, typedefed); 21254359Sroberto if (def == NULL) { 21354359Sroberto return (0); 21454359Sroberto } 21554359Sroberto type = def->def.ty.old_type; 21654359Sroberto rel = def->def.ty.rel; 21754359Sroberto } 21854359Sroberto } 21954359Sroberto 22054359Sroberto return (0); 221182007Sroberto} 222182007Sroberto 223182007Srobertochar * 224182007Srobertolocase(const char *str) 225290001Sglebius{ 226182007Sroberto char c; 227182007Sroberto static char buf[100]; 228182007Sroberto char *p = buf; 229182007Sroberto 230182007Sroberto while ( (c = *str++) ) { 231182007Sroberto *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; 232182007Sroberto } 23354359Sroberto *p = 0; 23454359Sroberto return (buf); 23554359Sroberto} 23654359Sroberto 23754359Srobertovoid 238290001Sglebiuspvname_svc(const char *pname, const char *vnum) 23954359Sroberto{ 240290001Sglebius f_print(fout, "%s_%s_svc", locase(pname), vnum); 24154359Sroberto} 24254359Sroberto 24354359Srobertovoid 244182007Srobertopvname(const char *pname, const char *vnum) 245182007Sroberto{ 246182007Sroberto f_print(fout, "%s_%s", locase(pname), vnum); 247182007Sroberto} 248290001Sglebius 249182007Sroberto/* 250182007Sroberto * print a useful (?) error message, and then die 251182007Sroberto */ 252182007Srobertovoid 25354359Srobertoerror(const char *msg) 254182007Sroberto{ 255182007Sroberto printwhere(); 256182007Sroberto warnx("%s, line %d: %s", infilename, linenum, msg); 257182007Sroberto crash(); 258182007Sroberto} 25954359Sroberto 26054359Sroberto/* 26154359Sroberto * Something went wrong, unlink any files that we may have created and then 26254359Sroberto * die. 26354359Sroberto */ 264290001Sglebiusvoid __dead2 26554359Srobertocrash(void) 26654359Sroberto{ 26754359Sroberto int i; 26854359Sroberto 26954359Sroberto for (i = 0; i < nfiles; i++) { 27054359Sroberto (void) unlink(outfiles[i]); 271290001Sglebius } 27254359Sroberto exit(1); 27354359Sroberto} 27454359Sroberto 275290001Sglebiusvoid 27654359Srobertorecord_open(const char *file) 27754359Sroberto{ 278290001Sglebius if (nfiles < NFILES) { 27954359Sroberto outfiles[nfiles++] = file; 28054359Sroberto } else { 28154359Sroberto warnx("too many files"); 28254359Sroberto crash(); 28354359Sroberto } 28454359Sroberto} 28554359Sroberto 28682498Srobertostatic char expectbuf[100]; 28754359Srobertostatic const char *toktostr(tok_kind kind); 28854359Sroberto 28954359Sroberto/* 29054359Sroberto * error, token encountered was not the expected one 29154359Sroberto */ 29254359Srobertovoid 29354359Srobertoexpected1(tok_kind exp1) 29454359Sroberto{ 29554359Sroberto s_print(expectbuf, "expected '%s'", 29654359Sroberto toktostr(exp1)); 29754359Sroberto error(expectbuf); 29854359Sroberto} 29954359Sroberto 30054359Sroberto/* 30154359Sroberto * error, token encountered was not one of two expected ones 30254359Sroberto */ 30354359Srobertovoid 30454359Srobertoexpected2(tok_kind exp1, tok_kind exp2) 30554359Sroberto{ 30682498Sroberto s_print(expectbuf, "expected '%s' or '%s'", 307290001Sglebius toktostr(exp1), 30854359Sroberto toktostr(exp2)); 30954359Sroberto error(expectbuf); 310290001Sglebius} 311290001Sglebius 312290001Sglebius/* 313290001Sglebius * error, token encountered was not one of 3 expected ones 31454359Sroberto */ 31554359Srobertovoid 31654359Srobertoexpected3(tok_kind exp1, tok_kind exp2, tok_kind exp3) 31754359Sroberto{ 31854359Sroberto s_print(expectbuf, "expected '%s', '%s' or '%s'", 31954359Sroberto toktostr(exp1), 32054359Sroberto toktostr(exp2), 32154359Sroberto toktostr(exp3)); 32254359Sroberto error(expectbuf); 32354359Sroberto} 32454359Sroberto 32554359Srobertovoid 32654359Srobertotabify(FILE *f, int tab) 32754359Sroberto{ 32854359Sroberto while (tab--) { 32954359Sroberto (void) fputc('\t', f); 33054359Sroberto } 33154359Sroberto} 33254359Sroberto 33354359Sroberto 33454359Srobertostatic token tokstrings[] = { 33554359Sroberto {TOK_IDENT, "identifier"}, 33654359Sroberto {TOK_CONST, "const"}, 33754359Sroberto {TOK_RPAREN, ")"}, 33854359Sroberto {TOK_LPAREN, "("}, 33954359Sroberto {TOK_RBRACE, "}"}, 34054359Sroberto {TOK_LBRACE, "{"}, 34154359Sroberto {TOK_LBRACKET, "["}, 34254359Sroberto {TOK_RBRACKET, "]"}, 34354359Sroberto {TOK_STAR, "*"}, 34454359Sroberto {TOK_COMMA, ","}, 34554359Sroberto {TOK_EQUAL, "="}, 34654359Sroberto {TOK_COLON, ":"}, 347290001Sglebius {TOK_SEMICOLON, ";"}, 34854359Sroberto {TOK_UNION, "union"}, 34954359Sroberto {TOK_STRUCT, "struct"}, 35054359Sroberto {TOK_SWITCH, "switch"}, 35154359Sroberto {TOK_CASE, "case"}, 35254359Sroberto {TOK_DEFAULT, "default"}, 35354359Sroberto {TOK_ENUM, "enum"}, 35454359Sroberto {TOK_TYPEDEF, "typedef"}, 35554359Sroberto {TOK_INT, "int"}, 35654359Sroberto {TOK_SHORT, "short"}, 35754359Sroberto {TOK_LONG, "long"}, 35854359Sroberto {TOK_UNSIGNED, "unsigned"}, 35954359Sroberto {TOK_DOUBLE, "double"}, 36054359Sroberto {TOK_FLOAT, "float"}, 36154359Sroberto {TOK_CHAR, "char"}, 36254359Sroberto {TOK_STRING, "string"}, 36354359Sroberto {TOK_OPAQUE, "opaque"}, 36454359Sroberto {TOK_BOOL, "bool"}, 36554359Sroberto {TOK_VOID, "void"}, 36654359Sroberto {TOK_PROGRAM, "program"}, 36754359Sroberto {TOK_VERSION, "version"}, 368290001Sglebius {TOK_EOF, "??????"} 369290001Sglebius}; 370290001Sglebius 371290001Sglebiusstatic const char * 372290001Sglebiustoktostr(tok_kind kind) 373290001Sglebius{ 374290001Sglebius token *sp; 375290001Sglebius 376290001Sglebius for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++); 37754359Sroberto return (sp->str); 37854359Sroberto} 37954359Sroberto 38054359Srobertostatic void 38154359Srobertoprintbuf(void) 38254359Sroberto{ 38354359Sroberto char c; 384182007Sroberto int i; 38554359Sroberto int cnt; 38654359Sroberto 38754359Sroberto# define TABSIZE 4 38854359Sroberto 38954359Sroberto for (i = 0; (c = curline[i]); i++) { 390182007Sroberto if (c == '\t') { 39154359Sroberto cnt = 8 - (i % TABSIZE); 39254359Sroberto c = ' '; 39354359Sroberto } else { 39454359Sroberto cnt = 1; 39554359Sroberto } 39654359Sroberto while (cnt--) { 39754359Sroberto (void) fputc(c, stderr); 39854359Sroberto } 39954359Sroberto } 40054359Sroberto} 40154359Sroberto 40254359Srobertostatic void 40354359Srobertoprintwhere(void) 40454359Sroberto{ 40554359Sroberto int i; 40654359Sroberto char c; 40754359Sroberto int cnt; 40854359Sroberto 409132451Sroberto printbuf(); 410132451Sroberto for (i = 0; i < where - curline; i++) { 41154359Sroberto c = curline[i]; 41254359Sroberto if (c == '\t') { 41354359Sroberto cnt = 8 - (i % TABSIZE); 41454359Sroberto } else { 41554359Sroberto cnt = 1; 41654359Sroberto } 41754359Sroberto while (cnt--) { 41854359Sroberto (void) fputc('^', stderr); 419182007Sroberto } 420182007Sroberto } 421290001Sglebius (void) fputc('\n', stderr); 42254359Sroberto} 423290001Sglebius 424290001Sglebiuschar * 42554359Srobertomake_argname(const char *pname, const char *vname) 426182007Sroberto{ 427182007Sroberto char *name; 428182007Sroberto 429182007Sroberto name = xmalloc(strlen(pname) + strlen(vname) + strlen(ARGEXT) + 3); 430182007Sroberto sprintf(name, "%s_%s_%s", locase(pname), vname, ARGEXT); 431182007Sroberto return (name); 432182007Sroberto} 433182007Sroberto 43454359Srobertobas_type *typ_list_h; 435182007Srobertobas_type *typ_list_t; 436182007Sroberto 437182007Srobertovoid 438182007Srobertoadd_type(int len, const char *type) 439182007Sroberto{ 440182007Sroberto bas_type *ptr; 441182007Sroberto 442290001Sglebius ptr = XALLOC(bas_type); 443290001Sglebius 444290001Sglebius ptr->name = type; 445290001Sglebius ptr->length = len; 446290001Sglebius ptr->next = NULL; 447290001Sglebius if (typ_list_t == NULL) 448290001Sglebius { 449290001Sglebius 450290001Sglebius typ_list_t = ptr; 451290001Sglebius typ_list_h = ptr; 452290001Sglebius } 453290001Sglebius else 454290001Sglebius { 455290001Sglebius typ_list_t->next = ptr; 456290001Sglebius typ_list_t = ptr; 457290001Sglebius } 458290001Sglebius} 459290001Sglebius 460290001Sglebius 461290001Sglebiusbas_type * 46254359Srobertofind_type(const char *type) 463182007Sroberto{ 46454359Sroberto bas_type * ptr; 465182007Sroberto 466290001Sglebius ptr = typ_list_h; 467290001Sglebius while (ptr != NULL) 468182007Sroberto { 469182007Sroberto if (strcmp(ptr->name, type) == 0) 470182007Sroberto return (ptr); 471290001Sglebius else 472290001Sglebius ptr = ptr->next; 473290001Sglebius } 474182007Sroberto return (NULL); 47554359Sroberto} 476182007Sroberto 477290001Sglebiusvoid * 478290001Sglebiusxmalloc(size_t size) 479182007Sroberto{ 48054359Sroberto void *p; 481182007Sroberto 482290001Sglebius if ((p = malloc(size)) == NULL) { 483290001Sglebius warnx("malloc failed"); 484182007Sroberto crash(); 48554359Sroberto } 486182007Sroberto return (p); 487290001Sglebius} 488290001Sglebius 489182007Srobertovoid * 49054359Srobertoxrealloc(void *ptr, size_t size) 491182007Sroberto{ 492182007Sroberto void *p; 49354359Sroberto 494290001Sglebius if ((p = realloc(ptr, size)) == NULL) { 495290001Sglebius warnx("realloc failed"); 496290001Sglebius crash(); 497182007Sroberto } 49854359Sroberto return (p); 499182007Sroberto} 500290001Sglebius 50154359Srobertochar * 502182007Srobertoxstrdup(const char *str) 503182007Sroberto{ 50454359Sroberto char *p; 505182007Sroberto 50654359Sroberto if ((p = strdup(str)) == NULL) { 50754359Sroberto warnx("strdup failed"); 50854359Sroberto crash(); 50954359Sroberto } 510182007Sroberto return (p); 511182007Sroberto} 512182007Sroberto