1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 * 22 * Copyright 2001 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 26 /* All Rights Reserved */ 27 /* 28 * University Copyright- Copyright (c) 1982, 1986, 1988 29 * The Regents of the University of California 30 * All Rights Reserved 31 * 32 * University Acknowledgment- Portions of this document are derived from 33 * software developed by the University of California, Berkeley, and its 34 * contributors. 35 */ 36 37 #pragma ident "%Z%%M% %I% %E% SMI" 38 39 /* 40 * rpc_hout.c, Header file outputter for the RPC protocol compiler 41 */ 42 #include <stdio.h> 43 #include <ctype.h> 44 #include "rpc_parse.h" 45 #include "rpc_util.h" 46 47 void storexdrfuncdecl(); 48 49 static char RESULT[] = "clnt_res"; 50 51 static enum rpc_gvc { 52 PROGRAM, 53 VERSION, 54 PROCEDURE 55 }; 56 57 /* 58 * Print the C-version of an xdr definition 59 */ 60 void 61 print_datadef(def) 62 definition *def; 63 { 64 65 if (def->def_kind == DEF_PROGRAM) /* handle data only */ 66 return; 67 68 if (def->def_kind != DEF_CONST) { 69 f_print(fout, "\n"); 70 } 71 switch (def->def_kind) { 72 case DEF_STRUCT: 73 pstructdef(def); 74 break; 75 case DEF_UNION: 76 puniondef(def); 77 break; 78 case DEF_ENUM: 79 penumdef(def); 80 break; 81 case DEF_TYPEDEF: 82 ptypedef(def); 83 break; 84 case DEF_PROGRAM: 85 pprogramdef(def); 86 break; 87 case DEF_CONST: 88 pconstdef(def); 89 break; 90 } 91 if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) { 92 storexdrfuncdecl(def->def_name, def->def_kind != DEF_TYPEDEF || 93 !isvectordef(def->def.ty.old_type, def->def.ty.rel)); 94 } 95 } 96 97 98 void 99 print_funcdef(definition *def) 100 { 101 switch (def->def_kind) { 102 case DEF_PROGRAM: 103 f_print(fout, "\n"); 104 pprogramdef(def); 105 break; 106 } 107 } 108 109 /* 110 * store away enough information to allow the XDR functions to be spat 111 * out at the end of the file 112 */ 113 void 114 storexdrfuncdecl(char *name, int pointerp) 115 { 116 xdrfunc *xdrptr; 117 118 xdrptr = (xdrfunc *) malloc(sizeof (struct xdrfunc)); 119 120 xdrptr->name = name; 121 xdrptr->pointerp = pointerp; 122 xdrptr->next = NULL; 123 124 if (xdrfunc_tail == NULL) { 125 xdrfunc_head = xdrptr; 126 xdrfunc_tail = xdrptr; 127 } else { 128 xdrfunc_tail->next = xdrptr; 129 xdrfunc_tail = xdrptr; 130 } 131 132 133 } 134 135 void 136 print_xdr_func_def(char *name, int pointerp, int i) 137 { 138 if (i == 2) 139 f_print(fout, "extern bool_t xdr_%s();\n", name); 140 else 141 f_print(fout, "extern bool_t xdr_%s(XDR *, %s%s);\n", name, 142 name, pointerp ? "*" : ""); 143 } 144 145 146 static 147 pconstdef(definition *def) 148 { 149 pdefine(def->def_name, def->def.co); 150 } 151 152 /* 153 * print out the definitions for the arguments of functions in the 154 * header file 155 */ 156 static 157 pargdef(definition *def) 158 { 159 decl_list *l; 160 version_list *vers; 161 char *name; 162 proc_list *plist; 163 164 for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { 165 for (plist = vers->procs; plist != NULL; 166 plist = plist->next) { 167 168 if (!newstyle || plist->arg_num < 2) { 169 continue; /* old style or single args */ 170 } 171 name = plist->args.argname; 172 f_print(fout, "struct %s {\n", name); 173 for (l = plist->args.decls; 174 l != NULL; l = l->next) { 175 pdeclaration(name, &l->decl, 1, ";\n"); 176 } 177 f_print(fout, "};\n"); 178 f_print(fout, "typedef struct %s %s;\n", 179 name, name); 180 storexdrfuncdecl(name, 1); 181 f_print(fout, "\n"); 182 } 183 } 184 } 185 186 187 static 188 pstructdef(def) 189 definition *def; 190 { 191 decl_list *l; 192 char *name = def->def_name; 193 194 f_print(fout, "struct %s {\n", name); 195 for (l = def->def.st.decls; l != NULL; l = l->next) { 196 pdeclaration(name, &l->decl, 1, ";\n"); 197 } 198 f_print(fout, "};\n"); 199 f_print(fout, "typedef struct %s %s;\n", name, name); 200 } 201 202 static 203 puniondef(def) 204 definition *def; 205 { 206 case_list *l; 207 char *name = def->def_name; 208 declaration *decl; 209 210 f_print(fout, "struct %s {\n", name); 211 decl = &def->def.un.enum_decl; 212 if (streq(decl->type, "bool")) { 213 f_print(fout, "\tbool_t %s;\n", decl->name); 214 } else { 215 f_print(fout, "\t%s %s;\n", decl->type, decl->name); 216 } 217 f_print(fout, "\tunion {\n"); 218 for (l = def->def.un.cases; l != NULL; l = l->next) { 219 if (l->contflag == 0) 220 pdeclaration(name, &l->case_decl, 2, ";\n"); 221 } 222 decl = def->def.un.default_decl; 223 if (decl && !streq(decl->type, "void")) { 224 pdeclaration(name, decl, 2, ";\n"); 225 } 226 f_print(fout, "\t} %s_u;\n", name); 227 f_print(fout, "};\n"); 228 f_print(fout, "typedef struct %s %s;\n", name, name); 229 } 230 231 static 232 pdefine(name, num) 233 char *name; 234 char *num; 235 { 236 f_print(fout, "#define\t%s %s\n", name, num); 237 } 238 239 static 240 puldefine(char *name, char *num, enum rpc_gvc which) 241 { 242 switch (which) { 243 case PROGRAM: 244 case VERSION: 245 case PROCEDURE: 246 f_print(fout, "#define\t%s\t%s\n", name, num); 247 break; 248 default: 249 break; 250 } 251 } 252 253 static 254 define_printed(proc_list *stop, version_list *start) 255 { 256 version_list *vers; 257 proc_list *proc; 258 259 for (vers = start; vers != NULL; vers = vers->next) { 260 for (proc = vers->procs; proc != NULL; proc = proc->next) { 261 if (proc == stop) { 262 return (0); 263 } else if (streq(proc->proc_name, stop->proc_name)) { 264 return (1); 265 } 266 } 267 } 268 abort(); 269 /* NOTREACHED */ 270 } 271 272 static 273 pfreeprocdef(char * name, char *vers, int mode) 274 { 275 f_print(fout, "extern int "); 276 pvname(name, vers); 277 if (mode == 1) 278 f_print(fout, "_freeresult(SVCXPRT *, xdrproc_t, caddr_t);\n"); 279 else 280 f_print(fout, "_freeresult();\n"); 281 282 283 } 284 285 static 286 pprogramdef(def) 287 definition *def; 288 { 289 version_list *vers; 290 proc_list *proc; 291 int i; 292 char *ext; 293 294 pargdef(def); 295 296 puldefine(def->def_name, def->def.pr.prog_num, PROGRAM); 297 for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { 298 if (tblflag) { 299 f_print(fout, 300 "extern struct rpcgen_table %s_%s_table[];\n", 301 locase(def->def_name), vers->vers_num); 302 f_print(fout, 303 "extern %s_%s_nproc;\n", 304 locase(def->def_name), vers->vers_num); 305 } 306 puldefine(vers->vers_name, vers->vers_num, VERSION); 307 308 /* 309 * Print out 2 definitions, one for ANSI-C, another for 310 * old K & R C 311 */ 312 313 if (!Cflag) { 314 ext = "extern "; 315 for (proc = vers->procs; proc != NULL; 316 proc = proc->next) { 317 if (!define_printed(proc, 318 def->def.pr.versions)) { 319 puldefine(proc->proc_name, 320 proc->proc_num, PROCEDURE); 321 } 322 f_print(fout, "%s", ext); 323 pprocdef(proc, vers, NULL, 0, 2); 324 325 if (mtflag) { 326 f_print(fout, "%s", ext); 327 pprocdef(proc, vers, NULL, 1, 2); 328 } 329 } 330 pfreeprocdef(def->def_name, vers->vers_num, 2); 331 } else { 332 for (i = 1; i < 3; i++) { 333 if (i == 1) { 334 f_print(fout, "\n#if defined(__STDC__)" 335 " || defined(__cplusplus)\n"); 336 ext = "extern "; 337 } else { 338 f_print(fout, "\n#else /* K&R C */\n"); 339 ext = "extern "; 340 } 341 342 for (proc = vers->procs; proc != NULL; 343 proc = proc->next) { 344 if (!define_printed(proc, 345 def->def.pr.versions)) { 346 puldefine(proc->proc_name, 347 proc->proc_num, PROCEDURE); 348 } 349 f_print(fout, "%s", ext); 350 pprocdef(proc, vers, "CLIENT *", 0, i); 351 f_print(fout, "%s", ext); 352 pprocdef(proc, vers, 353 "struct svc_req *", 1, i); 354 } 355 pfreeprocdef(def->def_name, vers->vers_num, i); 356 } 357 f_print(fout, "#endif /* K&R C */\n"); 358 } 359 } 360 } 361 362 pprocdef(proc, vp, addargtype, server_p, mode) 363 proc_list *proc; 364 version_list *vp; 365 char *addargtype; 366 int server_p; 367 int mode; 368 { 369 if (mtflag) { 370 /* Print MT style stubs */ 371 if (server_p) 372 f_print(fout, "bool_t "); 373 else 374 f_print(fout, "enum clnt_stat "); 375 } else { 376 ptype(proc->res_prefix, proc->res_type, 1); 377 f_print(fout, "* "); 378 } 379 if (server_p) 380 pvname_svc(proc->proc_name, vp->vers_num); 381 else 382 pvname(proc->proc_name, vp->vers_num); 383 384 /* 385 * mode 1 = ANSI-C, mode 2 = K&R C 386 */ 387 if (mode == 1) 388 parglist(proc, addargtype, server_p); 389 else 390 f_print(fout, "();\n"); 391 392 393 394 } 395 396 397 398 /* print out argument list of procedure */ 399 static 400 parglist(proc, addargtype, server_p) 401 proc_list *proc; 402 char *addargtype; 403 int server_p; 404 { 405 decl_list *dl; 406 int oneway = streq(proc->res_type, "oneway"); 407 408 f_print(fout, "("); 409 if (proc->arg_num < 2 && newstyle && 410 streq(proc->args.decls->decl.type, "void")) { 411 /* 0 argument in new style: do nothing */ 412 } else { 413 for (dl = proc->args.decls; dl != NULL; dl = dl->next) { 414 ptype(dl->decl.prefix, dl->decl.type, 1); 415 if (!newstyle || (dl->decl.rel == REL_POINTER)) 416 f_print(fout, "*"); 417 /* old style passes by reference */ 418 f_print(fout, ", "); 419 } 420 } 421 422 if (mtflag && !oneway) { 423 ptype(proc->res_prefix, proc->res_type, 1); 424 f_print(fout, "*, "); 425 } 426 427 f_print(fout, "%s);\n", addargtype); 428 429 } 430 431 static 432 penumdef(def) 433 definition *def; 434 { 435 char *name = def->def_name; 436 enumval_list *l; 437 char *last = NULL; 438 int count = 0; 439 440 f_print(fout, "enum %s {\n", name); 441 for (l = def->def.en.vals; l != NULL; l = l->next) { 442 f_print(fout, "\t%s", l->name); 443 if (l->assignment) { 444 f_print(fout, " = %s", l->assignment); 445 last = l->assignment; 446 count = 1; 447 } else { 448 if (last == NULL) { 449 f_print(fout, " = %d", count++); 450 } else { 451 f_print(fout, " = %s + %d", last, count++); 452 } 453 } 454 if (l->next) 455 f_print(fout, ",\n"); 456 else 457 f_print(fout, "\n"); 458 } 459 f_print(fout, "};\n"); 460 f_print(fout, "typedef enum %s %s;\n", name, name); 461 } 462 463 static 464 ptypedef(def) 465 definition *def; 466 { 467 char *name = def->def_name; 468 char *old = def->def.ty.old_type; 469 char prefix[8]; /* enough to contain "struct ", including NUL */ 470 relation rel = def->def.ty.rel; 471 472 473 if (!streq(name, old)) { 474 if (streq(old, "string")) { 475 old = "char"; 476 rel = REL_POINTER; 477 } else if (streq(old, "opaque")) { 478 old = "char"; 479 } else if (streq(old, "bool")) { 480 old = "bool_t"; 481 } 482 if (undefined2(old, name) && def->def.ty.old_prefix) { 483 s_print(prefix, "%s ", def->def.ty.old_prefix); 484 } else { 485 prefix[0] = 0; 486 } 487 f_print(fout, "typedef "); 488 switch (rel) { 489 case REL_ARRAY: 490 f_print(fout, "struct {\n"); 491 f_print(fout, "\tu_int %s_len;\n", name); 492 f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name); 493 f_print(fout, "} %s", name); 494 break; 495 case REL_POINTER: 496 f_print(fout, "%s%s *%s", prefix, old, name); 497 break; 498 case REL_VECTOR: 499 f_print(fout, "%s%s %s[%s]", prefix, old, name, 500 def->def.ty.array_max); 501 break; 502 case REL_ALIAS: 503 f_print(fout, "%s%s %s", prefix, old, name); 504 break; 505 } 506 f_print(fout, ";\n"); 507 } 508 } 509 510 pdeclaration(name, dec, tab, separator) 511 char *name; 512 declaration *dec; 513 int tab; 514 char *separator; 515 { 516 char buf[8]; /* enough to hold "struct ", include NUL */ 517 char *prefix; 518 char *type; 519 520 if (streq(dec->type, "void")) { 521 return; 522 } 523 tabify(fout, tab); 524 if (streq(dec->type, name) && !dec->prefix) { 525 f_print(fout, "struct "); 526 } 527 if (streq(dec->type, "string")) { 528 f_print(fout, "char *%s", dec->name); 529 } else { 530 prefix = ""; 531 if (streq(dec->type, "bool")) { 532 type = "bool_t"; 533 } else if (streq(dec->type, "opaque")) { 534 type = "char"; 535 } else { 536 if (dec->prefix) { 537 s_print(buf, "%s ", dec->prefix); 538 prefix = buf; 539 } 540 type = dec->type; 541 } 542 switch (dec->rel) { 543 case REL_ALIAS: 544 f_print(fout, "%s%s %s", prefix, type, dec->name); 545 break; 546 case REL_VECTOR: 547 f_print(fout, "%s%s %s[%s]", prefix, type, dec->name, 548 dec->array_max); 549 break; 550 case REL_POINTER: 551 f_print(fout, "%s%s *%s", prefix, type, dec->name); 552 break; 553 case REL_ARRAY: 554 f_print(fout, "struct {\n"); 555 tabify(fout, tab); 556 f_print(fout, "\tu_int %s_len;\n", dec->name); 557 tabify(fout, tab); 558 f_print(fout, 559 "\t%s%s *%s_val;\n", prefix, type, dec->name); 560 tabify(fout, tab); 561 f_print(fout, "} %s", dec->name); 562 break; 563 } 564 } 565 f_print(fout, separator); 566 } 567 568 static 569 undefined2(type, stop) 570 char *type; 571 char *stop; 572 { 573 list *l; 574 definition *def; 575 576 for (l = defined; l != NULL; l = l->next) { 577 def = (definition *) l->val; 578 if (def->def_kind != DEF_PROGRAM) { 579 if (streq(def->def_name, stop)) { 580 return (1); 581 } else if (streq(def->def_name, type)) { 582 return (0); 583 } 584 } 585 } 586 return (1); 587 } 588