1 /* $OpenBSD: rpc_hout.c,v 1.21 2012/12/05 23:20:26 deraadt Exp $ */ 2 /* $NetBSD: rpc_hout.c,v 1.4 1995/06/11 21:49:55 pk Exp $ */ 3 4 /* 5 * Copyright (c) 2010, Oracle America, Inc. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are 9 * met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above 14 * copyright notice, this list of conditions and the following 15 * disclaimer in the documentation and/or other materials 16 * provided with the distribution. 17 * * Neither the name of the "Oracle America, Inc." nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 26 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 28 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 /* 36 * rpc_hout.c, Header file outputter for the RPC protocol compiler 37 */ 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <ctype.h> 41 #include "rpc_parse.h" 42 #include "rpc_util.h" 43 44 static void pconstdef(definition *); 45 static void pargdef(definition *); 46 static void pstructdef(definition *); 47 static void puniondef(definition *); 48 static void pprogramdef(definition *); 49 static void penumdef(definition *); 50 static void ptypedef(definition *); 51 static void pdefine(char *, char *); 52 static void puldefine(char *, char *); 53 static int define_printed(proc_list *, version_list *); 54 static int undefined2(char *, char *); 55 static void parglist(proc_list *, char *); 56 void pxdrfuncdecl(char *, int); 57 void pprocdef(proc_list *, version_list *, char *, int, int); 58 void pdeclaration(char *, declaration *, int, char *); 59 60 /* 61 * Print the C-version of an xdr definition 62 */ 63 void 64 print_datadef(def) 65 definition *def; 66 { 67 68 if (def->def_kind == DEF_PROGRAM) /* handle data only */ 69 return; 70 71 if (def->def_kind != DEF_CONST) 72 fprintf(fout, "\n"); 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 void 102 print_funcdef(def) 103 definition *def; 104 { 105 switch (def->def_kind) { 106 case DEF_PROGRAM: 107 fprintf(fout, "\n"); 108 pprogramdef(def); 109 break; 110 } 111 } 112 113 void 114 pxdrfuncdecl(name, pointerp) 115 char *name; 116 int pointerp; 117 { 118 119 fprintf(fout,"#ifdef __cplusplus\n"); 120 fprintf(fout, "extern \"C\" bool_t xdr_%s(XDR *, %s %s);\n", 121 name, name, pointerp ? ("*") : ""); 122 fprintf(fout,"#elif defined(__STDC__)\n"); 123 fprintf(fout, "extern bool_t xdr_%s(XDR *, %s %s);\n", 124 name, name, pointerp ? ("*") : ""); 125 fprintf(fout,"#else /* Old Style C */\n"); 126 fprintf(fout, "bool_t xdr_%s();\n", name); 127 fprintf(fout,"#endif /* Old Style C */\n\n"); 128 } 129 130 131 static void 132 pconstdef(def) 133 definition *def; 134 { 135 pdefine(def->def_name, def->def.co); 136 } 137 138 /* 139 * print out the definitions for the arguments of functions in the 140 * header file 141 */ 142 static void 143 pargdef(def) 144 definition *def; 145 { 146 decl_list *l; 147 version_list *vers; 148 char *name; 149 proc_list *plist; 150 151 for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { 152 for (plist = vers->procs; plist != NULL; 153 plist = plist->next) { 154 if (!newstyle || plist->arg_num < 2) { 155 continue; /* old style or single args */ 156 } 157 name = plist->args.argname; 158 fprintf(fout, "struct %s {\n", name); 159 for (l = plist->args.decls; 160 l != NULL; l = l->next) { 161 pdeclaration(name, &l->decl, 1, ";\n"); 162 } 163 fprintf(fout, "};\n"); 164 fprintf(fout, "typedef struct %s %s;\n", name, name); 165 pxdrfuncdecl(name, 0); 166 fprintf(fout, "\n"); 167 } 168 } 169 } 170 171 static void 172 pstructdef(def) 173 definition *def; 174 { 175 char *name = def->def_name; 176 decl_list *l; 177 178 fprintf(fout, "struct %s {\n", name); 179 for (l = def->def.st.decls; l != NULL; l = l->next) 180 pdeclaration(name, &l->decl, 1, ";\n"); 181 fprintf(fout, "};\n"); 182 fprintf(fout, "typedef struct %s %s;\n", name, name); 183 } 184 185 static void 186 puniondef(def) 187 definition *def; 188 { 189 case_list *l; 190 char *name = def->def_name; 191 declaration *decl; 192 193 fprintf(fout, "struct %s {\n", name); 194 decl = &def->def.un.enum_decl; 195 if (streq(decl->type, "bool")) { 196 fprintf(fout, "\tbool_t %s;\n", decl->name); 197 } else { 198 fprintf(fout, "\t%s %s;\n", decl->type, decl->name); 199 } 200 fprintf(fout, "\tunion {\n"); 201 for (l = def->def.un.cases; l != NULL; l = l->next) { 202 if (l->contflag == 0) 203 pdeclaration(name, &l->case_decl, 2, ";\n"); 204 } 205 decl = def->def.un.default_decl; 206 if (decl && !streq(decl->type, "void")) { 207 pdeclaration(name, decl, 2, ";\n"); 208 } 209 fprintf(fout, "\t} %s_u;\n", name); 210 fprintf(fout, "};\n"); 211 fprintf(fout, "typedef struct %s %s;\n", name, name); 212 } 213 214 static void 215 pdefine(name, num) 216 char *name; 217 char *num; 218 { 219 fprintf(fout, "#define %s %s\n", name, num); 220 } 221 222 static void 223 puldefine(name, num) 224 char *name; 225 char *num; 226 { 227 fprintf(fout, "#define %s ((u_long)%s)\n", name, num); 228 } 229 230 static int 231 define_printed(stop, start) 232 proc_list *stop; 233 version_list *start; 234 { 235 version_list *vers; 236 proc_list *proc; 237 238 for (vers = start; vers != NULL; vers = vers->next) { 239 for (proc = vers->procs; proc != NULL; proc = proc->next) { 240 if (proc == stop) { 241 return (0); 242 } else if (streq(proc->proc_name, stop->proc_name)) { 243 return (1); 244 } 245 } 246 } 247 abort(); 248 /* NOTREACHED */ 249 } 250 251 static void 252 pprogramdef(def) 253 definition *def; 254 { 255 version_list *vers; 256 proc_list *proc; 257 int i; 258 char *ext; 259 260 pargdef(def); 261 262 puldefine(def->def_name, def->def.pr.prog_num); 263 for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { 264 if (tblflag) { 265 fprintf(fout, "extern struct rpcgen_table %s_%s_table[];\n", 266 locase(def->def_name), vers->vers_num); 267 fprintf(fout, "extern %s_%s_nproc;\n", 268 locase(def->def_name), vers->vers_num); 269 } 270 puldefine(vers->vers_name, vers->vers_num); 271 272 /* 273 * Print out 3 definitions, one for ANSI-C, another for C++, 274 * a third for old style C 275 */ 276 for (i=0; i<3; i++) { 277 if (i==0) { 278 fprintf(fout,"\n#ifdef __cplusplus\n"); 279 ext = "extern \"C\" "; 280 } else if (i==1) { 281 fprintf(fout,"\n#elif defined(__STDC__)\n"); 282 ext = "extern "; 283 } else { 284 fprintf(fout,"\n#else /* Old Style C */\n"); 285 ext = "extern "; 286 } 287 288 for (proc = vers->procs; proc != NULL; proc = proc->next) { 289 if (!define_printed(proc, def->def.pr.versions)) 290 puldefine(proc->proc_name, proc->proc_num); 291 fprintf(fout,"%s",ext); 292 pprocdef(proc, vers, "CLIENT *", 0,i); 293 fprintf(fout,"%s",ext); 294 pprocdef(proc, vers, "struct svc_req *", 1,i); 295 } 296 } 297 fprintf(fout,"#endif /* Old Style C */\n"); 298 } 299 } 300 301 void 302 pprocdef(proc, vp, addargtype, server_p,mode) 303 proc_list *proc; 304 version_list *vp; 305 char *addargtype; 306 int server_p; 307 int mode; 308 { 309 310 ptype(proc->res_prefix, proc->res_type, 1); 311 fprintf(fout, "* "); 312 if (server_p) 313 pvname_svc(proc->proc_name, vp->vers_num); 314 else 315 pvname(proc->proc_name, vp->vers_num); 316 317 /* 318 * mode 0 == cplusplus, mode 1 = ANSI-C, mode 2 = old style C 319 */ 320 if (mode == 0 || mode == 1) 321 parglist(proc, addargtype); 322 else 323 fprintf(fout, "();\n"); 324 } 325 326 /* print out argument list of procedure */ 327 static void 328 parglist(proc, addargtype) 329 proc_list *proc; 330 char *addargtype; 331 { 332 decl_list *dl; 333 334 fprintf(fout,"("); 335 336 if (proc->arg_num < 2 && newstyle && 337 streq(proc->args.decls->decl.type, "void")) { 338 /* 0 argument in new style: do nothing */ 339 } else { 340 for (dl = proc->args.decls; dl != NULL; dl = dl->next) { 341 ptype(dl->decl.prefix, dl->decl.type, 1); 342 if (!newstyle) 343 fprintf(fout, "*"); /* old style passes by reference */ 344 fprintf(fout, ", "); 345 } 346 } 347 fprintf(fout, "%s);\n", addargtype); 348 } 349 350 static void 351 penumdef(def) 352 definition *def; 353 { 354 char *name = def->def_name; 355 enumval_list *l; 356 char *last = NULL; 357 int count = 0; 358 359 fprintf(fout, "enum %s {\n", name); 360 for (l = def->def.en.vals; l != NULL; l = l->next) { 361 fprintf(fout, "\t%s", l->name); 362 if (l->assignment) { 363 fprintf(fout, " = %s", l->assignment); 364 last = l->assignment; 365 count = 1; 366 } else { 367 if (last == NULL) { 368 fprintf(fout, " = %d", count++); 369 } else { 370 fprintf(fout, " = %s + %d", last, count++); 371 } 372 } 373 if (l->next) 374 fprintf(fout, ",\n"); 375 else 376 fprintf(fout, "\n"); 377 } 378 fprintf(fout, "};\n"); 379 fprintf(fout, "typedef enum %s %s;\n", name, name); 380 } 381 382 static void 383 ptypedef(def) 384 definition *def; 385 { 386 char *name = def->def_name; 387 char *old = def->def.ty.old_type; 388 char prefix[8]; /* enough to contain "struct ", including NUL */ 389 relation rel = def->def.ty.rel; 390 391 if (!streq(name, old)) { 392 if (streq(old, "string")) { 393 old = "char"; 394 rel = REL_POINTER; 395 } else if (streq(old, "opaque")) { 396 old = "char"; 397 } else if (streq(old, "bool")) { 398 old = "bool_t"; 399 } 400 if (undefined2(old, name) && def->def.ty.old_prefix) { 401 snprintf(prefix, sizeof prefix, "%s ", def->def.ty.old_prefix); 402 } else { 403 prefix[0] = 0; 404 } 405 fprintf(fout, "typedef "); 406 switch (rel) { 407 case REL_ARRAY: 408 fprintf(fout, "struct {\n"); 409 fprintf(fout, "\tu_int %s_len;\n", name); 410 fprintf(fout, "\t%s%s *%s_val;\n", prefix, old, name); 411 fprintf(fout, "} %s", name); 412 break; 413 case REL_POINTER: 414 fprintf(fout, "%s%s *%s", prefix, old, name); 415 break; 416 case REL_VECTOR: 417 fprintf(fout, "%s%s %s[%s]", prefix, old, name, 418 def->def.ty.array_max); 419 break; 420 case REL_ALIAS: 421 fprintf(fout, "%s%s %s", prefix, old, name); 422 break; 423 } 424 fprintf(fout, ";\n"); 425 } 426 } 427 428 void 429 pdeclaration(name, dec, tab, separator) 430 char *name; 431 declaration *dec; 432 int tab; 433 char *separator; 434 { 435 char buf[8]; /* enough to hold "struct ", include NUL */ 436 char *prefix; 437 char *type; 438 439 if (streq(dec->type, "void")) 440 return; 441 tabify(fout, tab); 442 if (streq(dec->type, name) && !dec->prefix) { 443 fprintf(fout, "struct "); 444 } 445 if (streq(dec->type, "string")) { 446 fprintf(fout, "char *%s", dec->name); 447 } else { 448 prefix = ""; 449 if (streq(dec->type, "bool")) { 450 type = "bool_t"; 451 } else if (streq(dec->type, "opaque")) { 452 type = "char"; 453 } else { 454 if (dec->prefix) { 455 snprintf(buf, sizeof buf, "%s ", dec->prefix); 456 prefix = buf; 457 } 458 type = dec->type; 459 } 460 switch (dec->rel) { 461 case REL_ALIAS: 462 fprintf(fout, "%s%s %s", prefix, type, dec->name); 463 break; 464 case REL_VECTOR: 465 fprintf(fout, "%s%s %s[%s]", prefix, type, dec->name, 466 dec->array_max); 467 break; 468 case REL_POINTER: 469 fprintf(fout, "%s%s *%s", prefix, type, dec->name); 470 break; 471 case REL_ARRAY: 472 fprintf(fout, "struct {\n"); 473 tabify(fout, tab); 474 fprintf(fout, "\tu_int %s_len;\n", dec->name); 475 tabify(fout, tab); 476 fprintf(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name); 477 tabify(fout, tab); 478 fprintf(fout, "} %s", dec->name); 479 break; 480 } 481 } 482 fprintf(fout, "%s", separator); 483 } 484 485 static int 486 undefined2(type, stop) 487 char *type; 488 char *stop; 489 { 490 list *l; 491 definition *def; 492 493 for (l = defined; l != NULL; l = l->next) { 494 def = (definition *) l->val; 495 if (def->def_kind != DEF_PROGRAM) { 496 if (streq(def->def_name, stop)) { 497 return (1); 498 } else if (streq(def->def_name, type)) { 499 return (0); 500 } 501 } 502 } 503 return (1); 504 } 505