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