1 1.39 tnn /* $NetBSD: rpc_cout.c,v 1.39 2023/08/07 21:12:02 tnn Exp $ */ 2 1.1 glass /* 3 1.1 glass * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 4 1.1 glass * unrestricted use provided that this legend is included on all tape 5 1.1 glass * media and as a part of the software program in whole or part. Users 6 1.1 glass * may copy or modify Sun RPC without charge, but are not authorized 7 1.1 glass * to license or distribute it to anyone else except as part of a product or 8 1.4 pk * program developed by the user or with the express written consent of 9 1.4 pk * Sun Microsystems, Inc. 10 1.4 pk * 11 1.1 glass * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 12 1.1 glass * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 13 1.1 glass * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 14 1.4 pk * 15 1.1 glass * Sun RPC is provided with no support and without any obligation on the 16 1.1 glass * part of Sun Microsystems, Inc. to assist in its use, correction, 17 1.1 glass * modification or enhancement. 18 1.4 pk * 19 1.1 glass * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 20 1.1 glass * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 21 1.1 glass * OR ANY PART THEREOF. 22 1.4 pk * 23 1.1 glass * In no event will Sun Microsystems, Inc. be liable for any lost revenue 24 1.1 glass * or profits or other special, indirect and consequential damages, even if 25 1.1 glass * Sun has been advised of the possibility of such damages. 26 1.4 pk * 27 1.1 glass * Sun Microsystems, Inc. 28 1.1 glass * 2550 Garcia Avenue 29 1.1 glass * Mountain View, California 94043 30 1.1 glass */ 31 1.4 pk 32 1.26 jmc #if HAVE_NBTOOL_CONFIG_H 33 1.26 jmc #include "nbtool_config.h" 34 1.26 jmc #endif 35 1.26 jmc 36 1.11 christos #include <sys/cdefs.h> 37 1.19 tv #if defined(__RCSID) && !defined(lint) 38 1.11 christos #if 0 39 1.4 pk static char sccsid[] = "@(#)rpc_cout.c 1.13 89/02/22 (C) 1987 SMI"; 40 1.11 christos #else 41 1.39 tnn __RCSID("$NetBSD: rpc_cout.c,v 1.39 2023/08/07 21:12:02 tnn Exp $"); 42 1.11 christos #endif 43 1.1 glass #endif 44 1.1 glass 45 1.1 glass /* 46 1.4 pk * rpc_cout.c, XDR routine outputter for the RPC protocol compiler 47 1.1 glass */ 48 1.19 tv #include <ctype.h> 49 1.19 tv #include <err.h> 50 1.1 glass #include <stdio.h> 51 1.5 cgd #include <stdlib.h> 52 1.4 pk #include <string.h> 53 1.11 christos #include "rpc_scan.h" 54 1.4 pk #include "rpc_parse.h" 55 1.1 glass #include "rpc_util.h" 56 1.1 glass 57 1.33 christos static int findtype(definition *, const char *); 58 1.33 christos static int undefined(const char *); 59 1.33 christos static void print_generic_header(const char *, int); 60 1.33 christos static void print_header(definition *); 61 1.33 christos static void print_prog_header(proc_list *); 62 1.33 christos static void print_trailer(void); 63 1.33 christos static void print_ifopen(int, const char *); 64 1.33 christos static void print_ifarg(const char *); 65 1.33 christos static void print_ifsizeof(const char *, const char *); 66 1.33 christos static void print_ifclose(int); 67 1.33 christos static void print_ifstat(int, const char *, const char *, relation, 68 1.33 christos const char *, const char *, const char *); 69 1.33 christos static void emit_enum(definition *); 70 1.33 christos static void emit_program(definition *); 71 1.33 christos static void emit_union(definition *); 72 1.33 christos static void emit_struct(definition *); 73 1.33 christos static void emit_typedef(definition *); 74 1.33 christos static void print_stat(int, declaration *); 75 1.1 glass 76 1.1 glass /* 77 1.4 pk * Emit the C-routine for the given definition 78 1.1 glass */ 79 1.1 glass void 80 1.31 dholland emit(definition *def) 81 1.1 glass { 82 1.4 pk if (def->def_kind == DEF_CONST) { 83 1.4 pk return; 84 1.4 pk } 85 1.4 pk if (def->def_kind == DEF_PROGRAM) { 86 1.4 pk emit_program(def); 87 1.1 glass return; 88 1.1 glass } 89 1.4 pk if (def->def_kind == DEF_TYPEDEF) { 90 1.4 pk /* now we need to handle declarations like struct typedef foo 91 1.4 pk * foo; since we dont want this to be expanded into 2 calls to 92 1.4 pk * xdr_foo */ 93 1.4 pk 94 1.4 pk if (strcmp(def->def.ty.old_type, def->def_name) == 0) 95 1.4 pk return; 96 1.4 pk }; 97 1.4 pk 98 1.1 glass print_header(def); 99 1.7 mycroft 100 1.1 glass switch (def->def_kind) { 101 1.1 glass case DEF_UNION: 102 1.1 glass emit_union(def); 103 1.1 glass break; 104 1.1 glass case DEF_ENUM: 105 1.1 glass emit_enum(def); 106 1.1 glass break; 107 1.1 glass case DEF_STRUCT: 108 1.1 glass emit_struct(def); 109 1.1 glass break; 110 1.1 glass case DEF_TYPEDEF: 111 1.1 glass emit_typedef(def); 112 1.1 glass break; 113 1.11 christos case DEF_PROGRAM: 114 1.11 christos case DEF_CONST: 115 1.34 dholland errx(1, "Internal error at %s:%d: Case %d not handled", 116 1.11 christos __FILE__, __LINE__, def->def_kind); 117 1.11 christos break; 118 1.1 glass } 119 1.1 glass print_trailer(); 120 1.1 glass } 121 1.1 glass 122 1.11 christos static int 123 1.31 dholland findtype(definition *def, const char *type) 124 1.1 glass { 125 1.4 pk 126 1.1 glass if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) { 127 1.1 glass return (0); 128 1.1 glass } else { 129 1.1 glass return (streq(def->def_name, type)); 130 1.1 glass } 131 1.1 glass } 132 1.1 glass 133 1.11 christos static int 134 1.31 dholland undefined(const char *type) 135 1.1 glass { 136 1.1 glass definition *def; 137 1.1 glass 138 1.1 glass def = (definition *) FINDVAL(defined, type, findtype); 139 1.4 pk 140 1.4 pk 141 1.1 glass return (def == NULL); 142 1.1 glass } 143 1.1 glass 144 1.11 christos static void 145 1.31 dholland print_generic_header(const char *procname, int pointerp) 146 1.4 pk { 147 1.4 pk f_print(fout, "\n"); 148 1.4 pk f_print(fout, "bool_t\n"); 149 1.33 christos f_print(fout, "xdr_%s(", procname); 150 1.33 christos f_print(fout, "XDR *xdrs, "); 151 1.33 christos f_print(fout, "%s ", procname); 152 1.33 christos if (pointerp) 153 1.33 christos f_print(fout, "*"); 154 1.33 christos f_print(fout, "objp)\n{\n"); 155 1.4 pk } 156 1.1 glass 157 1.11 christos static void 158 1.31 dholland print_header(definition *def) 159 1.1 glass { 160 1.4 pk print_generic_header(def->def_name, 161 1.4 pk def->def_kind != DEF_TYPEDEF || 162 1.4 pk !isvectordef(def->def.ty.old_type, def->def.ty.rel)); 163 1.4 pk } 164 1.4 pk 165 1.11 christos static void 166 1.31 dholland print_prog_header(proc_list *plist) 167 1.4 pk { 168 1.4 pk print_generic_header(plist->args.argname, 1); 169 1.1 glass } 170 1.1 glass 171 1.11 christos static void 172 1.31 dholland print_trailer(void) 173 1.1 glass { 174 1.1 glass f_print(fout, "\treturn (TRUE);\n"); 175 1.1 glass f_print(fout, "}\n"); 176 1.1 glass } 177 1.1 glass 178 1.1 glass 179 1.11 christos static void 180 1.31 dholland print_ifopen(int indent, const char *name) 181 1.1 glass { 182 1.16 fvdl char _t_kludge[32]; 183 1.16 fvdl /* 184 1.16 fvdl * XXX Solaris seems to strip the _t. No idea why. 185 1.16 fvdl */ 186 1.16 fvdl if (!strcmp(name, "rpcprog_t") || !strcmp(name, "rpcvers_t") || 187 1.16 fvdl !strcmp(name, "rpcproc_t") || !strcmp(name, "rpcprot_t") || 188 1.16 fvdl !strcmp(name, "rpcport_t") || !strcmp(name, "rpcpinline_t")) { 189 1.39 tnn strlcpy(_t_kludge, name, sizeof(_t_kludge)); 190 1.39 tnn char *underscore = strchr(_t_kludge, '_'); 191 1.39 tnn *underscore = 0; 192 1.16 fvdl name = _t_kludge; 193 1.16 fvdl } 194 1.1 glass tabify(fout, indent); 195 1.7 mycroft f_print(fout, "if (!xdr_%s(xdrs", name); 196 1.1 glass } 197 1.1 glass 198 1.11 christos static void 199 1.31 dholland print_ifarg(const char *arg) 200 1.1 glass { 201 1.1 glass f_print(fout, ", %s", arg); 202 1.1 glass } 203 1.1 glass 204 1.11 christos static void 205 1.31 dholland print_ifsizeof(const char *prefix, const char *type) 206 1.1 glass { 207 1.1 glass if (streq(type, "bool")) { 208 1.38 dholland f_print(fout, ", (unsigned int)sizeof(bool_t), (xdrproc_t)xdr_bool"); 209 1.1 glass } else { 210 1.38 dholland f_print(fout, ", (unsigned int)sizeof("); 211 1.1 glass if (undefined(type) && prefix) { 212 1.1 glass f_print(fout, "%s ", prefix); 213 1.1 glass } 214 1.4 pk f_print(fout, "%s), (xdrproc_t)xdr_%s", type, type); 215 1.1 glass } 216 1.1 glass } 217 1.1 glass 218 1.11 christos static void 219 1.31 dholland print_ifclose(int indent) 220 1.1 glass { 221 1.7 mycroft f_print(fout, "))\n"); 222 1.1 glass tabify(fout, indent); 223 1.7 mycroft f_print(fout, "\treturn (FALSE);\n"); 224 1.1 glass } 225 1.1 glass 226 1.11 christos static void 227 1.31 dholland print_ifstat(int indent, const char *prefix, const char *type, relation rel, 228 1.31 dholland const char *amax, const char *objname, const char *name) 229 1.1 glass { 230 1.31 dholland const char *alt = NULL; 231 1.1 glass 232 1.1 glass switch (rel) { 233 1.1 glass case REL_POINTER: 234 1.1 glass print_ifopen(indent, "pointer"); 235 1.29 mrg print_ifarg("(char **)(void *)"); 236 1.1 glass f_print(fout, "%s", objname); 237 1.1 glass print_ifsizeof(prefix, type); 238 1.1 glass break; 239 1.1 glass case REL_VECTOR: 240 1.1 glass if (streq(type, "string")) { 241 1.1 glass alt = "string"; 242 1.4 pk } else 243 1.4 pk if (streq(type, "opaque")) { 244 1.4 pk alt = "opaque"; 245 1.4 pk } 246 1.1 glass if (alt) { 247 1.1 glass print_ifopen(indent, alt); 248 1.1 glass print_ifarg(objname); 249 1.1 glass } else { 250 1.1 glass print_ifopen(indent, "vector"); 251 1.20 christos print_ifarg("(char *)(void *)"); 252 1.1 glass f_print(fout, "%s", objname); 253 1.1 glass } 254 1.1 glass print_ifarg(amax); 255 1.1 glass if (!alt) { 256 1.1 glass print_ifsizeof(prefix, type); 257 1.1 glass } 258 1.1 glass break; 259 1.1 glass case REL_ARRAY: 260 1.1 glass if (streq(type, "string")) { 261 1.1 glass alt = "string"; 262 1.4 pk } else 263 1.4 pk if (streq(type, "opaque")) { 264 1.4 pk alt = "bytes"; 265 1.4 pk } 266 1.1 glass if (streq(type, "string")) { 267 1.1 glass print_ifopen(indent, alt); 268 1.1 glass print_ifarg(objname); 269 1.1 glass } else { 270 1.1 glass if (alt) { 271 1.1 glass print_ifopen(indent, alt); 272 1.1 glass } else { 273 1.1 glass print_ifopen(indent, "array"); 274 1.1 glass } 275 1.29 mrg print_ifarg("(char **)(void *)"); 276 1.1 glass if (*objname == '&') { 277 1.38 dholland f_print(fout, "%s.%s_val, (unsigned int *)%s.%s_len", 278 1.4 pk objname, name, objname, name); 279 1.1 glass } else { 280 1.38 dholland f_print(fout, "&%s->%s_val, (unsigned int *)&%s->%s_len", 281 1.4 pk objname, name, objname, name); 282 1.1 glass } 283 1.1 glass } 284 1.1 glass print_ifarg(amax); 285 1.1 glass if (!alt) { 286 1.1 glass print_ifsizeof(prefix, type); 287 1.1 glass } 288 1.1 glass break; 289 1.1 glass case REL_ALIAS: 290 1.1 glass print_ifopen(indent, type); 291 1.1 glass print_ifarg(objname); 292 1.1 glass break; 293 1.1 glass } 294 1.1 glass print_ifclose(indent); 295 1.1 glass } 296 1.1 glass /* ARGSUSED */ 297 1.11 christos static void 298 1.31 dholland emit_enum(definition *def) 299 1.1 glass { 300 1.20 christos tabify(fout, 1); 301 1.20 christos f_print(fout, "{\n"); 302 1.20 christos tabify(fout, 2); 303 1.20 christos f_print(fout, "enum_t et = (enum_t)*objp;\n"); 304 1.20 christos print_ifopen(2, "enum"); 305 1.20 christos print_ifarg("&et"); 306 1.20 christos print_ifclose(2); 307 1.22 christos tabify(fout, 2); 308 1.22 christos f_print(fout, "*objp = (%s)et;\n", def->def_name); 309 1.20 christos tabify(fout, 1); 310 1.20 christos f_print(fout, "}\n"); 311 1.1 glass } 312 1.1 glass 313 1.11 christos static void 314 1.31 dholland emit_program(definition *def) 315 1.4 pk { 316 1.4 pk decl_list *dl; 317 1.4 pk version_list *vlist; 318 1.4 pk proc_list *plist; 319 1.4 pk 320 1.4 pk for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next) 321 1.4 pk for (plist = vlist->procs; plist != NULL; plist = plist->next) { 322 1.4 pk if (!newstyle || plist->arg_num < 2) 323 1.4 pk continue; /* old style, or single 324 1.4 pk * argument */ 325 1.4 pk print_prog_header(plist); 326 1.4 pk for (dl = plist->args.decls; dl != NULL; 327 1.4 pk dl = dl->next) 328 1.4 pk print_stat(1, &dl->decl); 329 1.4 pk print_trailer(); 330 1.4 pk } 331 1.4 pk } 332 1.4 pk 333 1.1 glass 334 1.11 christos static void 335 1.31 dholland emit_union(definition *def) 336 1.1 glass { 337 1.1 glass declaration *dflt; 338 1.1 glass case_list *cl; 339 1.1 glass declaration *cs; 340 1.4 pk char *object; 341 1.23 yamt static const char vecformat[] = "objp->%s_u.%s"; 342 1.23 yamt static const char format[] = "&objp->%s_u.%s"; 343 1.1 glass 344 1.7 mycroft f_print(fout, "\n"); 345 1.4 pk print_stat(1, &def->def.un.enum_decl); 346 1.1 glass f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name); 347 1.1 glass for (cl = def->def.un.cases; cl != NULL; cl = cl->next) { 348 1.4 pk f_print(fout, "\tcase %s:\n", cl->case_name); 349 1.4 pk if (cl->contflag == 1) /* a continued case statement */ 350 1.4 pk continue; 351 1.1 glass cs = &cl->case_decl; 352 1.1 glass if (!streq(cs->type, "void")) { 353 1.1 glass object = alloc(strlen(def->def_name) + strlen(format) + 354 1.4 pk strlen(cs->name) + 1); 355 1.4 pk if (isvectordef(cs->type, cs->rel)) { 356 1.4 pk s_print(object, vecformat, def->def_name, 357 1.4 pk cs->name); 358 1.4 pk } else { 359 1.4 pk s_print(object, format, def->def_name, 360 1.4 pk cs->name); 361 1.4 pk } 362 1.7 mycroft print_ifstat(2, cs->prefix, cs->type, cs->rel, 363 1.7 mycroft cs->array_max, object, cs->name); 364 1.1 glass free(object); 365 1.1 glass } 366 1.1 glass f_print(fout, "\t\tbreak;\n"); 367 1.1 glass } 368 1.1 glass dflt = def->def.un.default_decl; 369 1.7 mycroft f_print(fout, "\tdefault:\n"); 370 1.1 glass if (dflt != NULL) { 371 1.1 glass if (!streq(dflt->type, "void")) { 372 1.1 glass object = alloc(strlen(def->def_name) + strlen(format) + 373 1.4 pk strlen(dflt->name) + 1); 374 1.4 pk if (isvectordef(dflt->type, dflt->rel)) { 375 1.4 pk s_print(object, vecformat, def->def_name, 376 1.4 pk dflt->name); 377 1.4 pk } else { 378 1.4 pk s_print(object, format, def->def_name, 379 1.4 pk dflt->name); 380 1.4 pk } 381 1.1 glass print_ifstat(2, dflt->prefix, dflt->type, dflt->rel, 382 1.4 pk dflt->array_max, object, dflt->name); 383 1.1 glass free(object); 384 1.1 glass } 385 1.7 mycroft f_print(fout, "\t\tbreak;\n"); 386 1.1 glass } else { 387 1.1 glass f_print(fout, "\t\treturn (FALSE);\n"); 388 1.1 glass } 389 1.4 pk 390 1.1 glass f_print(fout, "\t}\n"); 391 1.1 glass } 392 1.1 glass 393 1.11 christos static void 394 1.31 dholland emit_struct(definition *def) 395 1.1 glass { 396 1.1 glass decl_list *dl; 397 1.4 pk int i, j, size, flag; 398 1.11 christos decl_list *cur = NULL, *psav; 399 1.4 pk bas_type *ptr; 400 1.31 dholland char *sizestr; 401 1.31 dholland const char *plus; 402 1.4 pk char ptemp[256]; 403 1.4 pk int can_inline; 404 1.1 glass 405 1.4 pk 406 1.11 christos if (doinline == 0) { 407 1.20 christos f_print(fout, "\n"); 408 1.4 pk for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 409 1.4 pk print_stat(1, &dl->decl); 410 1.4 pk return; 411 1.1 glass } 412 1.4 pk size = 0; 413 1.4 pk can_inline = 0; 414 1.4 pk for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 415 1.4 pk if ((dl->decl.prefix == NULL) && 416 1.4 pk ((ptr = find_type(dl->decl.type)) != NULL) && 417 1.4 pk ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) { 418 1.4 pk 419 1.4 pk if (dl->decl.rel == REL_ALIAS) 420 1.4 pk size += ptr->length; 421 1.4 pk else { 422 1.4 pk can_inline = 1; 423 1.4 pk break; /* can be inlined */ 424 1.4 pk }; 425 1.4 pk } else { 426 1.11 christos if (size >= doinline) { 427 1.4 pk can_inline = 1; 428 1.4 pk break; /* can be inlined */ 429 1.4 pk } 430 1.4 pk size = 0; 431 1.4 pk } 432 1.11 christos if (size > doinline) 433 1.4 pk can_inline = 1; 434 1.4 pk 435 1.4 pk if (can_inline == 0) { /* can not inline, drop back to old mode */ 436 1.20 christos f_print(fout, "\n"); 437 1.4 pk for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 438 1.4 pk print_stat(1, &dl->decl); 439 1.4 pk return; 440 1.4 pk }; 441 1.4 pk 442 1.7 mycroft /* May cause lint to complain. but ... */ 443 1.12 lukem f_print(fout, "\tint32_t *buf;\n"); 444 1.4 pk 445 1.7 mycroft flag = PUT; 446 1.7 mycroft f_print(fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n"); 447 1.4 pk 448 1.4 pk for (j = 0; j < 2; j++) { 449 1.4 pk i = 0; 450 1.4 pk size = 0; 451 1.4 pk sizestr = NULL; 452 1.4 pk for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */ 453 1.4 pk 454 1.4 pk /* now walk down the list and check for basic types */ 455 1.4 pk if ((dl->decl.prefix == NULL) && ((ptr = find_type(dl->decl.type)) != NULL) && ((dl->decl.rel == REL_ALIAS) || (dl->decl.rel == REL_VECTOR))) { 456 1.4 pk if (i == 0) 457 1.4 pk cur = dl; 458 1.4 pk i++; 459 1.4 pk 460 1.4 pk if (dl->decl.rel == REL_ALIAS) 461 1.4 pk size += ptr->length; 462 1.4 pk else { 463 1.4 pk /* this is required to handle arrays */ 464 1.4 pk 465 1.4 pk if (sizestr == NULL) 466 1.10 mycroft plus = ""; 467 1.4 pk else 468 1.10 mycroft plus = " + "; 469 1.4 pk 470 1.4 pk if (ptr->length != 1) 471 1.10 mycroft s_print(ptemp, "%s%s * %d", plus, dl->decl.array_max, ptr->length); 472 1.4 pk else 473 1.10 mycroft s_print(ptemp, "%s%s", plus, dl->decl.array_max); 474 1.4 pk 475 1.4 pk /* now concatenate to sizestr !!!! */ 476 1.4 pk if (sizestr == NULL) 477 1.4 pk sizestr = strdup(ptemp); 478 1.4 pk else { 479 1.25 itojun char *nsizestr; 480 1.25 itojun 481 1.36 dholland nsizestr = realloc(sizestr, strlen(sizestr) + strlen(ptemp) + 1); 482 1.25 itojun if (nsizestr == NULL) { 483 1.37 kamil err(EXIT_FAILURE, "realloc"); 484 1.25 itojun } 485 1.25 itojun sizestr = nsizestr; 486 1.4 pk sizestr = strcat(sizestr, ptemp); /* build up length of 487 1.4 pk * array */ 488 1.4 pk 489 1.4 pk } 490 1.4 pk } 491 1.4 pk 492 1.4 pk } else { 493 1.14 ross if (i > 0) { 494 1.11 christos if (sizestr == NULL && size < doinline) { 495 1.4 pk /* don't expand into inline 496 1.11 christos * code if size < doinline */ 497 1.4 pk while (cur != dl) { 498 1.7 mycroft print_stat(2, &cur->decl); 499 1.4 pk cur = cur->next; 500 1.4 pk } 501 1.4 pk } else { 502 1.4 pk 503 1.4 pk 504 1.4 pk 505 1.4 pk /* were already looking at a 506 1.4 pk * xdr_inlineable structure */ 507 1.4 pk if (sizestr == NULL) 508 1.7 mycroft f_print(fout, "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);\n", 509 1.4 pk size); 510 1.4 pk else 511 1.4 pk if (size == 0) 512 1.4 pk f_print(fout, 513 1.7 mycroft "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %s * BYTES_PER_XDR_UNIT);\n", 514 1.4 pk sizestr); 515 1.4 pk else 516 1.4 pk f_print(fout, 517 1.7 mycroft "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, (%d + %s) * BYTES_PER_XDR_UNIT);\n", 518 1.4 pk size, sizestr); 519 1.4 pk 520 1.7 mycroft f_print(fout, "\t\tif (buf == NULL) {\n"); 521 1.4 pk 522 1.4 pk psav = cur; 523 1.4 pk while (cur != dl) { 524 1.7 mycroft print_stat(3, &cur->decl); 525 1.4 pk cur = cur->next; 526 1.4 pk } 527 1.4 pk 528 1.7 mycroft f_print(fout, "\t\t} else {\n"); 529 1.4 pk 530 1.4 pk cur = psav; 531 1.4 pk while (cur != dl) { 532 1.4 pk emit_inline(&cur->decl, flag); 533 1.4 pk cur = cur->next; 534 1.4 pk } 535 1.4 pk 536 1.7 mycroft f_print(fout, "\t\t}\n"); 537 1.4 pk } 538 1.14 ross } 539 1.4 pk size = 0; 540 1.4 pk i = 0; 541 1.28 christos if (sizestr) { 542 1.28 christos free(sizestr); 543 1.28 christos sizestr = NULL; 544 1.28 christos } 545 1.7 mycroft print_stat(2, &dl->decl); 546 1.4 pk } 547 1.4 pk 548 1.4 pk } 549 1.14 ross if (i > 0) { 550 1.11 christos if (sizestr == NULL && size < doinline) { 551 1.4 pk /* don't expand into inline code if size < 552 1.11 christos * doinline */ 553 1.4 pk while (cur != dl) { 554 1.7 mycroft print_stat(2, &cur->decl); 555 1.4 pk cur = cur->next; 556 1.4 pk } 557 1.4 pk } else { 558 1.4 pk 559 1.4 pk /* were already looking at a xdr_inlineable 560 1.4 pk * structure */ 561 1.4 pk if (sizestr == NULL) 562 1.7 mycroft f_print(fout, "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);\n", 563 1.4 pk size); 564 1.4 pk else 565 1.4 pk if (size == 0) 566 1.4 pk f_print(fout, 567 1.7 mycroft "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, %s * BYTES_PER_XDR_UNIT);\n", 568 1.4 pk sizestr); 569 1.4 pk else 570 1.4 pk f_print(fout, 571 1.7 mycroft "\t\tbuf = (int32_t *)XDR_INLINE(xdrs, (%d + %s) * BYTES_PER_XDR_UNIT);\n", 572 1.4 pk size, sizestr); 573 1.4 pk 574 1.7 mycroft f_print(fout, "\t\tif (buf == NULL) {\n"); 575 1.4 pk 576 1.4 pk psav = cur; 577 1.4 pk while (cur != NULL) { 578 1.7 mycroft print_stat(3, &cur->decl); 579 1.4 pk cur = cur->next; 580 1.4 pk } 581 1.7 mycroft f_print(fout, "\t\t} else {\n"); 582 1.4 pk 583 1.4 pk cur = psav; 584 1.4 pk while (cur != dl) { 585 1.4 pk emit_inline(&cur->decl, flag); 586 1.4 pk cur = cur->next; 587 1.4 pk } 588 1.4 pk 589 1.7 mycroft f_print(fout, "\t\t}\n"); 590 1.1 glass 591 1.4 pk } 592 1.14 ross } 593 1.7 mycroft if (flag == PUT) { 594 1.7 mycroft flag = GET; 595 1.7 mycroft f_print(fout, "\t} else if (xdrs->x_op == XDR_DECODE) {\n"); 596 1.7 mycroft } 597 1.4 pk } 598 1.7 mycroft 599 1.7 mycroft f_print(fout, "\t} else {\n"); 600 1.1 glass 601 1.4 pk /* now take care of XDR_FREE case */ 602 1.1 glass 603 1.4 pk for (dl = def->def.st.decls; dl != NULL; dl = dl->next) 604 1.7 mycroft print_stat(2, &dl->decl); 605 1.7 mycroft 606 1.7 mycroft f_print(fout, "\t}\n"); 607 1.4 pk } 608 1.1 glass 609 1.11 christos static void 610 1.31 dholland emit_typedef(definition *def) 611 1.1 glass { 612 1.31 dholland const char *prefix = def->def.ty.old_prefix; 613 1.31 dholland const char *type = def->def.ty.old_type; 614 1.31 dholland const char *amax = def->def.ty.array_max; 615 1.1 glass relation rel = def->def.ty.rel; 616 1.1 glass 617 1.20 christos f_print(fout, "\n"); 618 1.1 glass print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name); 619 1.1 glass } 620 1.1 glass 621 1.11 christos static void 622 1.31 dholland print_stat(int indent, declaration *dec) 623 1.31 dholland { 624 1.31 dholland const char *prefix = dec->prefix; 625 1.31 dholland const char *type = dec->type; 626 1.31 dholland const char *amax = dec->array_max; 627 1.1 glass relation rel = dec->rel; 628 1.4 pk char name[256]; 629 1.1 glass 630 1.1 glass if (isvectordef(type, rel)) { 631 1.1 glass s_print(name, "objp->%s", dec->name); 632 1.1 glass } else { 633 1.1 glass s_print(name, "&objp->%s", dec->name); 634 1.1 glass } 635 1.4 pk print_ifstat(indent, prefix, type, rel, amax, name, dec->name); 636 1.4 pk } 637 1.4 pk 638 1.4 pk 639 1.11 christos void 640 1.31 dholland emit_inline(declaration *decl, int flag) 641 1.4 pk { 642 1.4 pk 643 1.4 pk /*check whether an array or not */ 644 1.4 pk 645 1.4 pk switch (decl->rel) { 646 1.4 pk case REL_ALIAS: 647 1.4 pk emit_single_in_line(decl, flag, REL_ALIAS); 648 1.4 pk break; 649 1.4 pk case REL_VECTOR: 650 1.7 mycroft f_print(fout, "\t\t\t{\n"); 651 1.12 lukem f_print(fout, "\t\t\t\tint i;\n"); 652 1.12 lukem f_print(fout, "\t\t\t\t%s *genp;\n", decl->type); 653 1.9 mycroft f_print(fout, "\n"); 654 1.7 mycroft f_print(fout, "\t\t\t\tfor (i = 0, genp = objp->%s;\n", 655 1.7 mycroft decl->name); 656 1.7 mycroft f_print(fout, "\t\t\t\t i < %s; i++) {\n\t\t", 657 1.7 mycroft decl->array_max); 658 1.4 pk emit_single_in_line(decl, flag, REL_VECTOR); 659 1.7 mycroft f_print(fout, "\t\t\t\t}\n\t\t\t}\n"); 660 1.11 christos break; 661 1.11 christos case REL_ARRAY: 662 1.11 christos case REL_POINTER: 663 1.34 dholland errx(1, "Internal error at %s:%d: Case %d not handled", 664 1.11 christos __FILE__, __LINE__, decl->rel); 665 1.4 pk } 666 1.4 pk } 667 1.4 pk 668 1.11 christos void 669 1.31 dholland emit_single_in_line(declaration *decl, int flag, relation rel) 670 1.4 pk { 671 1.31 dholland const char *upp_case; 672 1.31 dholland char *freeable; 673 1.4 pk int freed = 0; 674 1.4 pk 675 1.4 pk if (flag == PUT) 676 1.7 mycroft f_print(fout, "\t\t\tIXDR_PUT_"); 677 1.4 pk else 678 1.4 pk if (rel == REL_ALIAS) 679 1.7 mycroft f_print(fout, "\t\t\tobjp->%s = IXDR_GET_", decl->name); 680 1.4 pk else 681 1.7 mycroft f_print(fout, "\t\t\t*genp++ = IXDR_GET_"); 682 1.4 pk 683 1.31 dholland upp_case = freeable = upcase(decl->type); 684 1.4 pk 685 1.4 pk /* hack - XX */ 686 1.4 pk if (strcmp(upp_case, "INT") == 0) { 687 1.31 dholland free(freeable); 688 1.4 pk freed = 1; 689 1.20 christos upp_case = "INT32"; 690 1.32 christos } else if (strcmp(upp_case, "U_INT") == 0) { 691 1.31 dholland free(freeable); 692 1.4 pk freed = 1; 693 1.20 christos upp_case = "U_INT32"; 694 1.4 pk } 695 1.15 christos if (flag == PUT) { 696 1.4 pk if (rel == REL_ALIAS) 697 1.8 mycroft f_print(fout, "%s(buf, objp->%s);\n", upp_case, decl->name); 698 1.4 pk else 699 1.8 mycroft f_print(fout, "%s(buf, *genp++);\n", upp_case); 700 1.4 pk 701 1.15 christos } else 702 1.4 pk f_print(fout, "%s(buf);\n", upp_case); 703 1.4 pk if (!freed) 704 1.31 dholland free(freeable); 705 1.4 pk 706 1.4 pk } 707 1.4 pk 708 1.4 pk 709 1.13 lukem char * 710 1.31 dholland upcase(const char *str) 711 1.4 pk { 712 1.4 pk char *ptr, *hptr; 713 1.4 pk 714 1.4 pk 715 1.36 dholland ptr = malloc(strlen(str) + 1); 716 1.30 plunky if (ptr == NULL) { 717 1.36 dholland errx(EXIT_FAILURE, "Out of memory"); 718 1.36 dholland } 719 1.4 pk 720 1.4 pk hptr = ptr; 721 1.4 pk while (*str != '\0') 722 1.27 dsl *ptr++ = toupper((unsigned char)*str++); 723 1.4 pk 724 1.4 pk *ptr = '\0'; 725 1.4 pk return (hptr); 726 1.4 pk 727 1.1 glass } 728