1 /* @(#)rpc_util.c 2.1 88/08/01 4.0 RPCSRC */ 2 /* 3 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 4 * unrestricted use provided that this legend is included on all tape 5 * media and as a part of the software program in whole or part. Users 6 * may copy or modify Sun RPC without charge, but are not authorized 7 * to license or distribute it to anyone else except as part of a product or 8 * program developed by the user. 9 * 10 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 11 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 12 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 13 * 14 * Sun RPC is provided with no support and without any obligation on the 15 * part of Sun Microsystems, Inc. to assist in its use, correction, 16 * modification or enhancement. 17 * 18 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 19 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 20 * OR ANY PART THEREOF. 21 * 22 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 23 * or profits or other special, indirect and consequential damages, even if 24 * Sun has been advised of the possibility of such damages. 25 * 26 * Sun Microsystems, Inc. 27 * 2550 Garcia Avenue 28 * Mountain View, California 94043 29 */ 30 #ifndef lint 31 static char sccsid[] = "@(#)rpc_util.c 1.5 87/06/24 (C) 1987 SMI"; 32 #endif 33 34 /* 35 * rpc_util.c, Utility routines for the RPC protocol compiler 36 * Copyright (C) 1987, Sun Microsystems, Inc. 37 */ 38 #include <stdio.h> 39 #include "rpc_scan.h" 40 #include "rpc_parse.h" 41 #include "rpc_util.h" 42 43 char curline[MAXLINESIZE]; /* current read line */ 44 char *where = curline; /* current point in line */ 45 int linenum = 0; /* current line number */ 46 47 char *infilename; /* input filename */ 48 49 #define NFILES 4 50 char *outfiles[NFILES]; /* output file names */ 51 int nfiles; 52 53 FILE *fout; /* file pointer of current output */ 54 FILE *fin; /* file pointer of current input */ 55 56 list *defined; /* list of defined things */ 57 58 static int printwhere(); 59 60 /* 61 * Reinitialize the world 62 */ 63 reinitialize() 64 { 65 bzero(curline, MAXLINESIZE); 66 where = curline; 67 linenum = 0; 68 defined = NULL; 69 } 70 71 /* 72 * string equality 73 */ 74 streq(a, b) 75 char *a; 76 char *b; 77 { 78 return (strcmp(a, b) == 0); 79 } 80 81 /* 82 * find a value in a list 83 */ 84 char * 85 findval(lst, val, cmp) 86 list *lst; 87 char *val; 88 int (*cmp) (); 89 90 { 91 for (; lst != NULL; lst = lst->next) { 92 if ((*cmp) (lst->val, val)) { 93 return (lst->val); 94 } 95 } 96 return (NULL); 97 } 98 99 /* 100 * store a value in a list 101 */ 102 void 103 storeval(lstp, val) 104 list **lstp; 105 char *val; 106 { 107 list **l; 108 list *lst; 109 110 for (l = lstp; *l != NULL; l = (list **) & (*l)->next); 111 lst = ALLOC(list); 112 lst->val = val; 113 lst->next = NULL; 114 *l = lst; 115 } 116 117 118 static 119 findit(def, type) 120 definition *def; 121 char *type; 122 { 123 return (streq(def->def_name, type)); 124 } 125 126 127 static char * 128 fixit(type, orig) 129 char *type; 130 char *orig; 131 { 132 definition *def; 133 134 def = (definition *) FINDVAL(defined, type, findit); 135 if (def == NULL || def->def_kind != DEF_TYPEDEF) { 136 return (orig); 137 } 138 switch (def->def.ty.rel) { 139 case REL_VECTOR: 140 return (def->def.ty.old_type); 141 case REL_ALIAS: 142 return (fixit(def->def.ty.old_type, orig)); 143 default: 144 return (orig); 145 } 146 } 147 148 char * 149 fixtype(type) 150 char *type; 151 { 152 return (fixit(type, type)); 153 } 154 155 char * 156 stringfix(type) 157 char *type; 158 { 159 if (streq(type, "string")) { 160 return ("wrapstring"); 161 } else { 162 return (type); 163 } 164 } 165 166 void 167 ptype(prefix, type, follow) 168 char *prefix; 169 char *type; 170 int follow; 171 { 172 if (prefix != NULL) { 173 if (streq(prefix, "enum")) { 174 f_print(fout, "enum "); 175 } else { 176 f_print(fout, "struct "); 177 } 178 } 179 if (streq(type, "bool")) { 180 f_print(fout, "bool_t "); 181 } else if (streq(type, "string")) { 182 f_print(fout, "char *"); 183 } else { 184 f_print(fout, "%s ", follow ? fixtype(type) : type); 185 } 186 } 187 188 189 static 190 typedefed(def, type) 191 definition *def; 192 char *type; 193 { 194 if (def->def_kind != DEF_TYPEDEF || def->def.ty.old_prefix != NULL) { 195 return (0); 196 } else { 197 return (streq(def->def_name, type)); 198 } 199 } 200 201 isvectordef(type, rel) 202 char *type; 203 relation rel; 204 { 205 definition *def; 206 207 for (;;) { 208 switch (rel) { 209 case REL_VECTOR: 210 return (!streq(type, "string")); 211 case REL_ARRAY: 212 return (0); 213 case REL_POINTER: 214 return (0); 215 case REL_ALIAS: 216 def = (definition *) FINDVAL(defined, type, typedefed); 217 if (def == NULL) { 218 return (0); 219 } 220 type = def->def.ty.old_type; 221 rel = def->def.ty.rel; 222 } 223 } 224 } 225 226 227 static char * 228 locase(str) 229 char *str; 230 { 231 char c; 232 static char buf[100]; 233 char *p = buf; 234 235 while (c = *str++) { 236 *p++ = (c >= 'A' && c <= 'Z') ? (c - 'A' + 'a') : c; 237 } 238 *p = 0; 239 return (buf); 240 } 241 242 243 void 244 pvname(pname, vnum) 245 char *pname; 246 char *vnum; 247 { 248 f_print(fout, "%s_%s", locase(pname), vnum); 249 } 250 251 252 /* 253 * print a useful (?) error message, and then die 254 */ 255 void 256 error(msg) 257 char *msg; 258 { 259 printwhere(); 260 f_print(stderr, "%s, line %d: ", infilename, linenum); 261 f_print(stderr, "%s\n", msg); 262 crash(); 263 } 264 265 /* 266 * Something went wrong, unlink any files that we may have created and then 267 * die. 268 */ 269 crash() 270 { 271 int i; 272 273 for (i = 0; i < nfiles; i++) { 274 (void) unlink(outfiles[i]); 275 } 276 exit(1); 277 } 278 279 280 void 281 record_open(file) 282 char *file; 283 { 284 if (nfiles < NFILES) { 285 outfiles[nfiles++] = file; 286 } else { 287 f_print(stderr, "too many files!\n"); 288 crash(); 289 } 290 } 291 292 static char expectbuf[100]; 293 static char *toktostr(); 294 295 /* 296 * error, token encountered was not the expected one 297 */ 298 void 299 expected1(exp1) 300 tok_kind exp1; 301 { 302 s_print(expectbuf, "expected '%s'", 303 toktostr(exp1)); 304 error(expectbuf); 305 } 306 307 /* 308 * error, token encountered was not one of two expected ones 309 */ 310 void 311 expected2(exp1, exp2) 312 tok_kind exp1, exp2; 313 { 314 s_print(expectbuf, "expected '%s' or '%s'", 315 toktostr(exp1), 316 toktostr(exp2)); 317 error(expectbuf); 318 } 319 320 /* 321 * error, token encountered was not one of 3 expected ones 322 */ 323 void 324 expected3(exp1, exp2, exp3) 325 tok_kind exp1, exp2, exp3; 326 { 327 s_print(expectbuf, "expected '%s', '%s' or '%s'", 328 toktostr(exp1), 329 toktostr(exp2), 330 toktostr(exp3)); 331 error(expectbuf); 332 } 333 334 void 335 tabify(f, tab) 336 FILE *f; 337 int tab; 338 { 339 while (tab--) { 340 (void) fputc('\t', f); 341 } 342 } 343 344 345 346 static token tokstrings[] = { 347 {TOK_IDENT, "identifier"}, 348 {TOK_CONST, "const"}, 349 {TOK_RPAREN, ")"}, 350 {TOK_LPAREN, "("}, 351 {TOK_RBRACE, "}"}, 352 {TOK_LBRACE, "{"}, 353 {TOK_LBRACKET, "["}, 354 {TOK_RBRACKET, "]"}, 355 {TOK_STAR, "*"}, 356 {TOK_COMMA, ","}, 357 {TOK_EQUAL, "="}, 358 {TOK_COLON, ":"}, 359 {TOK_SEMICOLON, ";"}, 360 {TOK_UNION, "union"}, 361 {TOK_STRUCT, "struct"}, 362 {TOK_SWITCH, "switch"}, 363 {TOK_CASE, "case"}, 364 {TOK_DEFAULT, "default"}, 365 {TOK_ENUM, "enum"}, 366 {TOK_TYPEDEF, "typedef"}, 367 {TOK_INT, "int"}, 368 {TOK_SHORT, "short"}, 369 {TOK_LONG, "long"}, 370 {TOK_UNSIGNED, "unsigned"}, 371 {TOK_DOUBLE, "double"}, 372 {TOK_FLOAT, "float"}, 373 {TOK_CHAR, "char"}, 374 {TOK_STRING, "string"}, 375 {TOK_OPAQUE, "opaque"}, 376 {TOK_BOOL, "bool"}, 377 {TOK_VOID, "void"}, 378 {TOK_PROGRAM, "program"}, 379 {TOK_VERSION, "version"}, 380 {TOK_EOF, "??????"} 381 }; 382 383 static char * 384 toktostr(kind) 385 tok_kind kind; 386 { 387 token *sp; 388 389 for (sp = tokstrings; sp->kind != TOK_EOF && sp->kind != kind; sp++); 390 return (sp->str); 391 } 392 393 394 395 static 396 printbuf() 397 { 398 char c; 399 int i; 400 int cnt; 401 402 # define TABSIZE 4 403 404 for (i = 0; c = curline[i]; i++) { 405 if (c == '\t') { 406 cnt = 8 - (i % TABSIZE); 407 c = ' '; 408 } else { 409 cnt = 1; 410 } 411 while (cnt--) { 412 (void) fputc(c, stderr); 413 } 414 } 415 } 416 417 418 static 419 printwhere() 420 { 421 int i; 422 char c; 423 int cnt; 424 425 printbuf(); 426 for (i = 0; i < where - curline; i++) { 427 c = curline[i]; 428 if (c == '\t') { 429 cnt = 8 - (i % TABSIZE); 430 } else { 431 cnt = 1; 432 } 433 while (cnt--) { 434 (void) fputc('^', stderr); 435 } 436 } 437 (void) fputc('\n', stderr); 438 } 439