1 /* $OpenBSD: rpc_hout.c,v 1.6 2001/07/18 22:26:00 deraadt Exp $ */ 2 /* $NetBSD: rpc_hout.c,v 1.4 1995/06/11 21:49:55 pk Exp $ */ 3 /* 4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 5 * unrestricted use provided that this legend is included on all tape 6 * media and as a part of the software program in whole or part. Users 7 * may copy or modify Sun RPC without charge, but are not authorized 8 * to license or distribute it to anyone else except as part of a product or 9 * program developed by the user or with the express written consent of 10 * Sun Microsystems, Inc. 11 * 12 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 13 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 14 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 15 * 16 * Sun RPC is provided with no support and without any obligation on the 17 * part of Sun Microsystems, Inc. to assist in its use, correction, 18 * modification or enhancement. 19 * 20 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 21 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 22 * OR ANY PART THEREOF. 23 * 24 * In no event will Sun Microsystems, Inc. be liable for any lost revenue 25 * or profits or other special, indirect and consequential damages, even if 26 * Sun has been advised of the possibility of such damages. 27 * 28 * Sun Microsystems, Inc. 29 * 2550 Garcia Avenue 30 * Mountain View, California 94043 31 */ 32 33 #ifndef lint 34 static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI"; 35 #endif 36 37 /* 38 * rpc_hout.c, Header file outputter for the RPC protocol compiler 39 */ 40 #include <sys/cdefs.h> 41 #include <stdio.h> 42 #include <ctype.h> 43 #include "rpc_parse.h" 44 #include "rpc_util.h" 45 46 static pconstdef __P((definition *)); 47 static pargdef __P((definition *)); 48 static pstructdef __P((definition *)); 49 static puniondef __P((definition *)); 50 static pprogramdef __P((definition *)); 51 static penumdef __P((definition *)); 52 static ptypedef __P((definition *)); 53 static pdefine __P((char *, char *)); 54 static puldefine __P((char *, char *)); 55 static define_printed __P((proc_list *, version_list *)); 56 static undefined2 __P((char *, char *)); 57 static parglist __P((proc_list *, char *)); 58 59 /* 60 * Print the C-version of an xdr definition 61 */ 62 void 63 print_datadef(def) 64 definition *def; 65 { 66 67 if (def->def_kind == DEF_PROGRAM ) /* handle data only */ 68 return; 69 70 if (def->def_kind != DEF_CONST) { 71 f_print(fout, "\n"); 72 } 73 switch (def->def_kind) { 74 case DEF_STRUCT: 75 pstructdef(def); 76 break; 77 case DEF_UNION: 78 puniondef(def); 79 break; 80 case DEF_ENUM: 81 penumdef(def); 82 break; 83 case DEF_TYPEDEF: 84 ptypedef(def); 85 break; 86 case DEF_PROGRAM: 87 pprogramdef(def); 88 break; 89 case DEF_CONST: 90 pconstdef(def); 91 break; 92 } 93 if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) { 94 pxdrfuncdecl( def->def_name, 95 def->def_kind != DEF_TYPEDEF || 96 !isvectordef(def->def.ty.old_type, def->def.ty.rel)); 97 98 } 99 } 100 101 102 void 103 print_funcdef(def) 104 definition *def; 105 { 106 switch (def->def_kind) { 107 case DEF_PROGRAM: 108 f_print(fout, "\n"); 109 pprogramdef(def); 110 break; 111 } 112 } 113 114 pxdrfuncdecl( name, pointerp ) 115 char* name; 116 int pointerp; 117 { 118 119 f_print(fout,"#ifdef __cplusplus\n"); 120 f_print(fout, "extern \"C\" bool_t xdr_%s(XDR *, %s%s);\n", 121 name, 122 name, pointerp ? ("*") : ""); 123 f_print(fout,"#elif defined(__STDC__)\n"); 124 f_print(fout, "extern bool_t xdr_%s(XDR *, %s%s);\n", 125 name, 126 name, pointerp ? ("*") : ""); 127 f_print(fout,"#else /* Old Style C */\n"); 128 f_print(fout, "bool_t xdr_%s();\n", name); 129 f_print(fout,"#endif /* Old Style C */\n\n"); 130 } 131 132 133 static 134 pconstdef(def) 135 definition *def; 136 { 137 pdefine(def->def_name, def->def.co); 138 } 139 140 /* print out the definitions for the arguments of functions in the 141 header file 142 */ 143 static 144 pargdef(def) 145 definition *def; 146 { 147 decl_list *l; 148 version_list *vers; 149 char *name; 150 proc_list *plist; 151 152 153 for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { 154 for(plist = vers->procs; plist != NULL; 155 plist = plist->next) { 156 157 if (!newstyle || plist->arg_num < 2) { 158 continue; /* old style or single args */ 159 } 160 name = plist->args.argname; 161 f_print(fout, "struct %s {\n", name); 162 for (l = plist->args.decls; 163 l != NULL; l = l->next) { 164 pdeclaration(name, &l->decl, 1, ";\n" ); 165 } 166 f_print(fout, "};\n"); 167 f_print(fout, "typedef struct %s %s;\n", name, name); 168 pxdrfuncdecl( name,NULL ); 169 f_print( fout, "\n" ); 170 } 171 } 172 173 } 174 175 176 static 177 pstructdef(def) 178 definition *def; 179 { 180 decl_list *l; 181 char *name = def->def_name; 182 183 f_print(fout, "struct %s {\n", name); 184 for (l = def->def.st.decls; l != NULL; l = l->next) { 185 pdeclaration(name, &l->decl, 1, ";\n"); 186 } 187 f_print(fout, "};\n"); 188 f_print(fout, "typedef struct %s %s;\n", name, name); 189 } 190 191 static 192 puniondef(def) 193 definition *def; 194 { 195 case_list *l; 196 char *name = def->def_name; 197 declaration *decl; 198 199 f_print(fout, "struct %s {\n", name); 200 decl = &def->def.un.enum_decl; 201 if (streq(decl->type, "bool")) { 202 f_print(fout, "\tbool_t %s;\n", decl->name); 203 } else { 204 f_print(fout, "\t%s %s;\n", decl->type, decl->name); 205 } 206 f_print(fout, "\tunion {\n"); 207 for (l = def->def.un.cases; l != NULL; l = l->next) { 208 if(l->contflag == 0) 209 pdeclaration(name, &l->case_decl, 2, ";\n" ); 210 } 211 decl = def->def.un.default_decl; 212 if (decl && !streq(decl->type, "void")) { 213 pdeclaration(name, decl, 2, ";\n" ); 214 } 215 f_print(fout, "\t} %s_u;\n", name); 216 f_print(fout, "};\n"); 217 f_print(fout, "typedef struct %s %s;\n", name, name); 218 } 219 220 static 221 pdefine(name, num) 222 char *name; 223 char *num; 224 { 225 f_print(fout, "#define %s %s\n", name, num); 226 } 227 228 static 229 puldefine(name, num) 230 char *name; 231 char *num; 232 { 233 f_print(fout, "#define %s ((u_long)%s)\n", name, num); 234 } 235 236 static 237 define_printed(stop, start) 238 proc_list *stop; 239 version_list *start; 240 { 241 version_list *vers; 242 proc_list *proc; 243 244 for (vers = start; vers != NULL; vers = vers->next) { 245 for (proc = vers->procs; proc != NULL; proc = proc->next) { 246 if (proc == stop) { 247 return (0); 248 } else if (streq(proc->proc_name, stop->proc_name)) { 249 return (1); 250 } 251 } 252 } 253 abort(); 254 /* NOTREACHED */ 255 } 256 257 static 258 pprogramdef(def) 259 definition *def; 260 { 261 version_list *vers; 262 proc_list *proc; 263 int i; 264 char *ext; 265 266 pargdef(def); 267 268 puldefine(def->def_name, def->def.pr.prog_num); 269 for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { 270 if (tblflag) { 271 f_print(fout, "extern struct rpcgen_table %s_%s_table[];\n", 272 locase(def->def_name), vers->vers_num); 273 f_print(fout, "extern %s_%s_nproc;\n", 274 locase(def->def_name), vers->vers_num); 275 } 276 puldefine(vers->vers_name, vers->vers_num); 277 278 /* 279 * Print out 3 definitions, one for ANSI-C, another for C++, 280 * a third for old style C 281 */ 282 283 for(i=0;i<3;i++){ 284 if(i==0){ 285 f_print(fout,"\n#ifdef __cplusplus\n"); 286 ext="extern \"C\" "; 287 }else if ( i== 1){ 288 f_print(fout,"\n#elif defined(__STDC__)\n"); 289 ext="extern " ; 290 }else{ 291 f_print(fout,"\n#else /* Old Style C */\n"); 292 ext="extern "; 293 } 294 295 296 for (proc = vers->procs; proc != NULL; proc = proc->next) { 297 if (!define_printed(proc, def->def.pr.versions)) { 298 puldefine(proc->proc_name, proc->proc_num); 299 } 300 f_print(fout,"%s",ext); 301 pprocdef(proc, vers, "CLIENT *", 0,i); 302 f_print(fout,"%s",ext); 303 pprocdef(proc, vers, "struct svc_req *", 1,i); 304 305 } 306 307 } 308 f_print(fout,"#endif /* Old Style C */\n"); 309 } 310 } 311 312 pprocdef(proc, vp, addargtype, server_p,mode) 313 proc_list *proc; 314 version_list *vp; 315 char* addargtype; 316 int server_p; 317 int mode; 318 { 319 320 ptype( proc->res_prefix, proc->res_type, 1 ); 321 f_print( fout, "* " ); 322 if( server_p ) 323 pvname_svc(proc->proc_name, vp->vers_num); 324 else 325 pvname(proc->proc_name, vp->vers_num); 326 327 /* 328 * mode 0 == cplusplus, mode 1 = ANSI-C, mode 2 = old style C 329 */ 330 if(mode == 0 || mode ==1) 331 parglist( proc, addargtype ); 332 else 333 f_print(fout, "();\n"); 334 } 335 336 337 /* print out argument list of procedure */ 338 static 339 parglist(proc, addargtype) 340 proc_list *proc; 341 char* addargtype; 342 { 343 decl_list *dl; 344 345 f_print(fout,"("); 346 347 if( proc->arg_num < 2 && newstyle && 348 streq( proc->args.decls->decl.type, "void")) { 349 /* 0 argument in new style: do nothing */ 350 } else { 351 for (dl = proc->args.decls; dl != NULL; dl = dl->next) { 352 ptype( dl->decl.prefix, dl->decl.type, 1 ); 353 if( !newstyle ) 354 f_print( fout, "*" ); /* old style passes by reference */ 355 356 f_print( fout, ", " ); 357 } 358 } 359 360 f_print(fout, "%s);\n", addargtype); 361 } 362 363 static 364 penumdef(def) 365 definition *def; 366 { 367 char *name = def->def_name; 368 enumval_list *l; 369 char *last = NULL; 370 int count = 0; 371 372 f_print(fout, "enum %s {\n", name); 373 for (l = def->def.en.vals; l != NULL; l = l->next) { 374 f_print(fout, "\t%s", l->name); 375 if (l->assignment) { 376 f_print(fout, " = %s", l->assignment); 377 last = l->assignment; 378 count = 1; 379 } else { 380 if (last == NULL) { 381 f_print(fout, " = %d", count++); 382 } else { 383 f_print(fout, " = %s + %d", last, count++); 384 } 385 } 386 if (l->next) 387 f_print(fout, ",\n"); 388 else 389 f_print(fout, "\n"); 390 } 391 f_print(fout, "};\n"); 392 f_print(fout, "typedef enum %s %s;\n", name, name); 393 } 394 395 static 396 ptypedef(def) 397 definition *def; 398 { 399 char *name = def->def_name; 400 char *old = def->def.ty.old_type; 401 char prefix[8]; /* enough to contain "struct ", including NUL */ 402 relation rel = def->def.ty.rel; 403 404 405 if (!streq(name, old)) { 406 if (streq(old, "string")) { 407 old = "char"; 408 rel = REL_POINTER; 409 } else if (streq(old, "opaque")) { 410 old = "char"; 411 } else if (streq(old, "bool")) { 412 old = "bool_t"; 413 } 414 if (undefined2(old, name) && def->def.ty.old_prefix) { 415 s_print(prefix, "%s ", def->def.ty.old_prefix); 416 } else { 417 prefix[0] = 0; 418 } 419 f_print(fout, "typedef "); 420 switch (rel) { 421 case REL_ARRAY: 422 f_print(fout, "struct {\n"); 423 f_print(fout, "\tu_int %s_len;\n", name); 424 f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name); 425 f_print(fout, "} %s", name); 426 break; 427 case REL_POINTER: 428 f_print(fout, "%s%s *%s", prefix, old, name); 429 break; 430 case REL_VECTOR: 431 f_print(fout, "%s%s %s[%s]", prefix, old, name, 432 def->def.ty.array_max); 433 break; 434 case REL_ALIAS: 435 f_print(fout, "%s%s %s", prefix, old, name); 436 break; 437 } 438 f_print(fout, ";\n"); 439 } 440 } 441 442 pdeclaration(name, dec, tab, separator) 443 char *name; 444 declaration *dec; 445 int tab; 446 char *separator; 447 { 448 char buf[8]; /* enough to hold "struct ", include NUL */ 449 char *prefix; 450 char *type; 451 452 if (streq(dec->type, "void")) { 453 return; 454 } 455 tabify(fout, tab); 456 if (streq(dec->type, name) && !dec->prefix) { 457 f_print(fout, "struct "); 458 } 459 if (streq(dec->type, "string")) { 460 f_print(fout, "char *%s", dec->name); 461 } else { 462 prefix = ""; 463 if (streq(dec->type, "bool")) { 464 type = "bool_t"; 465 } else if (streq(dec->type, "opaque")) { 466 type = "char"; 467 } else { 468 if (dec->prefix) { 469 s_print(buf, "%s ", dec->prefix); 470 prefix = buf; 471 } 472 type = dec->type; 473 } 474 switch (dec->rel) { 475 case REL_ALIAS: 476 f_print(fout, "%s%s %s", prefix, type, dec->name); 477 break; 478 case REL_VECTOR: 479 f_print(fout, "%s%s %s[%s]", prefix, type, dec->name, 480 dec->array_max); 481 break; 482 case REL_POINTER: 483 f_print(fout, "%s%s *%s", prefix, type, dec->name); 484 break; 485 case REL_ARRAY: 486 f_print(fout, "struct {\n"); 487 tabify(fout, tab); 488 f_print(fout, "\tu_int %s_len;\n", dec->name); 489 tabify(fout, tab); 490 f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name); 491 tabify(fout, tab); 492 f_print(fout, "} %s", dec->name); 493 break; 494 } 495 } 496 f_print(fout, separator ); 497 } 498 499 static 500 undefined2(type, stop) 501 char *type; 502 char *stop; 503 { 504 list *l; 505 definition *def; 506 507 for (l = defined; l != NULL; l = l->next) { 508 def = (definition *) l->val; 509 if (def->def_kind != DEF_PROGRAM) { 510 if (streq(def->def_name, stop)) { 511 return (1); 512 } else if (streq(def->def_name, type)) { 513 return (0); 514 } 515 } 516 } 517 return (1); 518 } 519