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