1 /* $OpenBSD: rpc_hout.c,v 1.22 2016/12/20 22:19:08 krw 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 default: 93 break; 94 } 95 if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) { 96 pxdrfuncdecl(def->def_name, 97 def->def_kind != DEF_TYPEDEF || 98 !isvectordef(def->def.ty.old_type, def->def.ty.rel)); 99 } 100 } 101 102 103 void 104 print_funcdef(def) 105 definition *def; 106 { 107 switch (def->def_kind) { 108 case DEF_PROGRAM: 109 fprintf(fout, "\n"); 110 pprogramdef(def); 111 break; 112 default: 113 break; 114 } 115 } 116 117 void 118 pxdrfuncdecl(name, pointerp) 119 char *name; 120 int pointerp; 121 { 122 123 fprintf(fout,"#ifdef __cplusplus\n"); 124 fprintf(fout, "extern \"C\" bool_t xdr_%s(XDR *, %s %s);\n", 125 name, name, pointerp ? ("*") : ""); 126 fprintf(fout,"#elif defined(__STDC__)\n"); 127 fprintf(fout, "extern bool_t xdr_%s(XDR *, %s %s);\n", 128 name, name, pointerp ? ("*") : ""); 129 fprintf(fout,"#else /* Old Style C */\n"); 130 fprintf(fout, "bool_t xdr_%s();\n", name); 131 fprintf(fout,"#endif /* Old Style C */\n\n"); 132 } 133 134 135 static void 136 pconstdef(def) 137 definition *def; 138 { 139 pdefine(def->def_name, def->def.co); 140 } 141 142 /* 143 * print out the definitions for the arguments of functions in the 144 * header file 145 */ 146 static void 147 pargdef(def) 148 definition *def; 149 { 150 decl_list *l; 151 version_list *vers; 152 char *name; 153 proc_list *plist; 154 155 for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { 156 for (plist = vers->procs; plist != NULL; 157 plist = plist->next) { 158 if (!newstyle || plist->arg_num < 2) { 159 continue; /* old style or single args */ 160 } 161 name = plist->args.argname; 162 fprintf(fout, "struct %s {\n", name); 163 for (l = plist->args.decls; 164 l != NULL; l = l->next) { 165 pdeclaration(name, &l->decl, 1, ";\n"); 166 } 167 fprintf(fout, "};\n"); 168 fprintf(fout, "typedef struct %s %s;\n", name, name); 169 pxdrfuncdecl(name, 0); 170 fprintf(fout, "\n"); 171 } 172 } 173 } 174 175 static void 176 pstructdef(def) 177 definition *def; 178 { 179 char *name = def->def_name; 180 decl_list *l; 181 182 fprintf(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 fprintf(fout, "};\n"); 186 fprintf(fout, "typedef struct %s %s;\n", name, name); 187 } 188 189 static void 190 puniondef(def) 191 definition *def; 192 { 193 case_list *l; 194 char *name = def->def_name; 195 declaration *decl; 196 197 fprintf(fout, "struct %s {\n", name); 198 decl = &def->def.un.enum_decl; 199 if (streq(decl->type, "bool")) { 200 fprintf(fout, "\tbool_t %s;\n", decl->name); 201 } else { 202 fprintf(fout, "\t%s %s;\n", decl->type, decl->name); 203 } 204 fprintf(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 fprintf(fout, "\t} %s_u;\n", name); 214 fprintf(fout, "};\n"); 215 fprintf(fout, "typedef struct %s %s;\n", name, name); 216 } 217 218 static void 219 pdefine(name, num) 220 char *name; 221 char *num; 222 { 223 fprintf(fout, "#define %s %s\n", name, num); 224 } 225 226 static void 227 puldefine(name, num) 228 char *name; 229 char *num; 230 { 231 fprintf(fout, "#define %s ((u_long)%s)\n", name, num); 232 } 233 234 static int 235 define_printed(stop, start) 236 proc_list *stop; 237 version_list *start; 238 { 239 version_list *vers; 240 proc_list *proc; 241 242 for (vers = start; vers != NULL; vers = vers->next) { 243 for (proc = vers->procs; proc != NULL; proc = proc->next) { 244 if (proc == stop) { 245 return (0); 246 } else if (streq(proc->proc_name, stop->proc_name)) { 247 return (1); 248 } 249 } 250 } 251 abort(); 252 /* NOTREACHED */ 253 } 254 255 static void 256 pprogramdef(def) 257 definition *def; 258 { 259 version_list *vers; 260 proc_list *proc; 261 int i; 262 char *ext; 263 264 pargdef(def); 265 266 puldefine(def->def_name, def->def.pr.prog_num); 267 for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) { 268 if (tblflag) { 269 fprintf(fout, "extern struct rpcgen_table %s_%s_table[];\n", 270 locase(def->def_name), vers->vers_num); 271 fprintf(fout, "extern %s_%s_nproc;\n", 272 locase(def->def_name), vers->vers_num); 273 } 274 puldefine(vers->vers_name, vers->vers_num); 275 276 /* 277 * Print out 3 definitions, one for ANSI-C, another for C++, 278 * a third for old style C 279 */ 280 for (i=0; i<3; i++) { 281 if (i==0) { 282 fprintf(fout,"\n#ifdef __cplusplus\n"); 283 ext = "extern \"C\" "; 284 } else if (i==1) { 285 fprintf(fout,"\n#elif defined(__STDC__)\n"); 286 ext = "extern "; 287 } else { 288 fprintf(fout,"\n#else /* Old Style C */\n"); 289 ext = "extern "; 290 } 291 292 for (proc = vers->procs; proc != NULL; proc = proc->next) { 293 if (!define_printed(proc, def->def.pr.versions)) 294 puldefine(proc->proc_name, proc->proc_num); 295 fprintf(fout,"%s",ext); 296 pprocdef(proc, vers, "CLIENT *", 0,i); 297 fprintf(fout,"%s",ext); 298 pprocdef(proc, vers, "struct svc_req *", 1,i); 299 } 300 } 301 fprintf(fout,"#endif /* Old Style C */\n"); 302 } 303 } 304 305 void 306 pprocdef(proc, vp, addargtype, server_p,mode) 307 proc_list *proc; 308 version_list *vp; 309 char *addargtype; 310 int server_p; 311 int mode; 312 { 313 314 ptype(proc->res_prefix, proc->res_type, 1); 315 fprintf(fout, "* "); 316 if (server_p) 317 pvname_svc(proc->proc_name, vp->vers_num); 318 else 319 pvname(proc->proc_name, vp->vers_num); 320 321 /* 322 * mode 0 == cplusplus, mode 1 = ANSI-C, mode 2 = old style C 323 */ 324 if (mode == 0 || mode == 1) 325 parglist(proc, addargtype); 326 else 327 fprintf(fout, "();\n"); 328 } 329 330 /* print out argument list of procedure */ 331 static void 332 parglist(proc, addargtype) 333 proc_list *proc; 334 char *addargtype; 335 { 336 decl_list *dl; 337 338 fprintf(fout,"("); 339 340 if (proc->arg_num < 2 && newstyle && 341 streq(proc->args.decls->decl.type, "void")) { 342 /* 0 argument in new style: do nothing */ 343 } else { 344 for (dl = proc->args.decls; dl != NULL; dl = dl->next) { 345 ptype(dl->decl.prefix, dl->decl.type, 1); 346 if (!newstyle) 347 fprintf(fout, "*"); /* old style passes by reference */ 348 fprintf(fout, ", "); 349 } 350 } 351 fprintf(fout, "%s);\n", addargtype); 352 } 353 354 static void 355 penumdef(def) 356 definition *def; 357 { 358 char *name = def->def_name; 359 enumval_list *l; 360 char *last = NULL; 361 int count = 0; 362 363 fprintf(fout, "enum %s {\n", name); 364 for (l = def->def.en.vals; l != NULL; l = l->next) { 365 fprintf(fout, "\t%s", l->name); 366 if (l->assignment) { 367 fprintf(fout, " = %s", l->assignment); 368 last = l->assignment; 369 count = 1; 370 } else { 371 if (last == NULL) { 372 fprintf(fout, " = %d", count++); 373 } else { 374 fprintf(fout, " = %s + %d", last, count++); 375 } 376 } 377 if (l->next) 378 fprintf(fout, ",\n"); 379 else 380 fprintf(fout, "\n"); 381 } 382 fprintf(fout, "};\n"); 383 fprintf(fout, "typedef enum %s %s;\n", name, name); 384 } 385 386 static void 387 ptypedef(def) 388 definition *def; 389 { 390 char *name = def->def_name; 391 char *old = def->def.ty.old_type; 392 char prefix[8]; /* enough to contain "struct ", including NUL */ 393 relation rel = def->def.ty.rel; 394 395 if (!streq(name, old)) { 396 if (streq(old, "string")) { 397 old = "char"; 398 rel = REL_POINTER; 399 } else if (streq(old, "opaque")) { 400 old = "char"; 401 } else if (streq(old, "bool")) { 402 old = "bool_t"; 403 } 404 if (undefined2(old, name) && def->def.ty.old_prefix) { 405 snprintf(prefix, sizeof prefix, "%s ", def->def.ty.old_prefix); 406 } else { 407 prefix[0] = 0; 408 } 409 fprintf(fout, "typedef "); 410 switch (rel) { 411 case REL_ARRAY: 412 fprintf(fout, "struct {\n"); 413 fprintf(fout, "\tu_int %s_len;\n", name); 414 fprintf(fout, "\t%s%s *%s_val;\n", prefix, old, name); 415 fprintf(fout, "} %s", name); 416 break; 417 case REL_POINTER: 418 fprintf(fout, "%s%s *%s", prefix, old, name); 419 break; 420 case REL_VECTOR: 421 fprintf(fout, "%s%s %s[%s]", prefix, old, name, 422 def->def.ty.array_max); 423 break; 424 case REL_ALIAS: 425 fprintf(fout, "%s%s %s", prefix, old, name); 426 break; 427 } 428 fprintf(fout, ";\n"); 429 } 430 } 431 432 void 433 pdeclaration(name, dec, tab, separator) 434 char *name; 435 declaration *dec; 436 int tab; 437 char *separator; 438 { 439 char buf[8]; /* enough to hold "struct ", include NUL */ 440 char *prefix; 441 char *type; 442 443 if (streq(dec->type, "void")) 444 return; 445 tabify(fout, tab); 446 if (streq(dec->type, name) && !dec->prefix) { 447 fprintf(fout, "struct "); 448 } 449 if (streq(dec->type, "string")) { 450 fprintf(fout, "char *%s", dec->name); 451 } else { 452 prefix = ""; 453 if (streq(dec->type, "bool")) { 454 type = "bool_t"; 455 } else if (streq(dec->type, "opaque")) { 456 type = "char"; 457 } else { 458 if (dec->prefix) { 459 snprintf(buf, sizeof buf, "%s ", dec->prefix); 460 prefix = buf; 461 } 462 type = dec->type; 463 } 464 switch (dec->rel) { 465 case REL_ALIAS: 466 fprintf(fout, "%s%s %s", prefix, type, dec->name); 467 break; 468 case REL_VECTOR: 469 fprintf(fout, "%s%s %s[%s]", prefix, type, dec->name, 470 dec->array_max); 471 break; 472 case REL_POINTER: 473 fprintf(fout, "%s%s *%s", prefix, type, dec->name); 474 break; 475 case REL_ARRAY: 476 fprintf(fout, "struct {\n"); 477 tabify(fout, tab); 478 fprintf(fout, "\tu_int %s_len;\n", dec->name); 479 tabify(fout, tab); 480 fprintf(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name); 481 tabify(fout, tab); 482 fprintf(fout, "} %s", dec->name); 483 break; 484 } 485 } 486 fprintf(fout, "%s", separator); 487 } 488 489 static int 490 undefined2(type, stop) 491 char *type; 492 char *stop; 493 { 494 list *l; 495 definition *def; 496 497 for (l = defined; l != NULL; l = l->next) { 498 def = (definition *) l->val; 499 if (def->def_kind != DEF_PROGRAM) { 500 if (streq(def->def_name, stop)) { 501 return (1); 502 } else if (streq(def->def_name, type)) { 503 return (0); 504 } 505 } 506 } 507 return (1); 508 } 509