kernel/{hammer2,tmpfs}: Fix ENOTDIR/EISDIR logic.
[dragonfly.git] / usr.bin / rpcgen / rpc_cout.c
blobb61427d8201a01e613e9324d09ac4b75082127b9
1 /*
2 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3 * unrestricted use provided that this legend is included on all tape
4 * media and as a part of the software program in whole or part. Users
5 * may copy or modify Sun RPC without charge, but are not authorized
6 * to license or distribute it to anyone else except as part of a product or
7 * program developed by the user.
9 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13 * Sun RPC is provided with no support and without any obligation on the
14 * part of Sun Microsystems, Inc. to assist in its use, correction,
15 * modification or enhancement.
17 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19 * OR ANY PART THEREOF.
21 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22 * or profits or other special, indirect and consequential damages, even if
23 * Sun has been advised of the possibility of such damages.
25 * Sun Microsystems, Inc.
26 * 2550 Garcia Avenue
27 * Mountain View, California 94043
29 * @(#)rpc_cout.c 1.14 93/07/05 SMI; 1.13 89/02/22 (C) 1987 SMI
30 * $FreeBSD: src/usr.bin/rpcgen/rpc_cout.c,v 1.17 2007/11/20 01:46:12 jb Exp $
34 * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
35 * Copyright (C) 1987, Sun Microsystems, Inc.
37 #include <ctype.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include "rpc_parse.h"
41 #include "rpc_scan.h"
42 #include "rpc_util.h"
44 static void print_header(definition *);
45 static void print_trailer(void);
46 static void print_stat(int , declaration *);
47 static void emit_enum(definition *);
48 static void emit_program(definition *);
49 static void emit_union(definition *);
50 static void emit_struct(definition *);
51 static void emit_typedef(definition *);
52 static void emit_inline(int, declaration *, int);
53 static void emit_single_in_line(int, declaration *, int, relation);
54 static char *upcase(const char *);
57 * Emit the C-routine for the given definition
59 void
60 emit(definition *def)
62 if (def->def_kind == DEF_CONST)
63 return;
64 if (def->def_kind == DEF_PROGRAM) {
65 emit_program(def);
66 return;
68 if (def->def_kind == DEF_TYPEDEF) {
70 * now we need to handle declarations like
71 * struct typedef foo foo;
72 * since we dont want this to be expanded into 2 calls to xdr_foo
75 if (strcmp(def->def.ty.old_type, def->def_name) == 0)
76 return;
78 print_header(def);
79 switch (def->def_kind) {
80 case DEF_UNION:
81 emit_union(def);
82 break;
83 case DEF_ENUM:
84 emit_enum(def);
85 break;
86 case DEF_STRUCT:
87 emit_struct(def);
88 break;
89 case DEF_TYPEDEF:
90 emit_typedef(def);
91 break;
92 /* DEF_CONST and DEF_PROGRAM have already been handled */
93 default:
94 break;
96 print_trailer();
99 static int
100 findtype(definition *def, const char *type)
103 if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST)
104 return(0);
105 else
106 return(streq(def->def_name, type));
109 static int
110 undefined(const char *type)
112 definition *def;
114 def = (definition *) FINDVAL(defined, type, findtype);
115 return(def == NULL);
119 static void
120 print_generic_header(const char *procname, int pointerp)
122 f_print(fout, "\n");
123 f_print(fout, "bool_t\n");
124 f_print(fout, "xdr_%s(", procname);
125 f_print(fout, "XDR *xdrs, ");
126 f_print(fout, "%s ", procname);
127 if (pointerp)
128 f_print(fout, "*");
129 f_print(fout, "objp)\n{\n\n");
132 static void
133 print_header(definition *def)
135 print_generic_header(def->def_name,
136 def->def_kind != DEF_TYPEDEF || !isvectordef(def->def.ty.old_type,
137 def->def.ty.rel));
138 /* Now add Inline support */
140 if (inline_size == 0)
141 return;
142 /* May cause lint to complain. but ... */
143 f_print(fout, "\tlong *buf;\n\n");
146 static void
147 print_prog_header(proc_list *plist)
149 print_generic_header(plist->args.argname, 1);
152 static void
153 print_trailer(void)
155 f_print(fout, "\treturn (TRUE);\n");
156 f_print(fout, "}\n");
160 static void
161 print_ifopen(int indent, const char *name)
163 tabify(fout, indent);
164 f_print(fout, "if (!xdr_%s(xdrs", name);
167 static void
168 print_ifarg(const char *arg)
170 f_print(fout, ", %s", arg);
173 static void
174 print_ifsizeof(int indent, const char *prefix, const char *type)
176 if (indent) {
177 f_print(fout, ",\n");
178 tabify(fout, indent);
179 } else {
180 f_print(fout, ", ");
182 if (streq(type, "bool")) {
183 f_print(fout, "sizeof (bool_t), (xdrproc_t) xdr_bool");
184 } else {
185 f_print(fout, "sizeof (");
186 if (undefined(type) && prefix)
187 f_print(fout, "%s ", prefix);
188 f_print(fout, "%s), (xdrproc_t) xdr_%s", type, type);
192 static void
193 print_ifclose(int indent, int brace)
195 f_print(fout, "))\n");
196 tabify(fout, indent);
197 f_print(fout, "\treturn (FALSE);\n");
198 if (brace)
199 f_print(fout, "\t}\n");
202 static void
203 print_ifstat(int indent, const char *prefix, const char *type, relation rel,
204 const char *amax, const char *objname, const char *name)
206 const char *alt = NULL;
207 int brace = 0;
209 switch (rel) {
210 case REL_POINTER:
211 brace = 1;
212 f_print(fout, "\t{\n");
213 f_print(fout, "\t%s **pp = %s;\n", type, objname);
214 print_ifopen(indent, "pointer");
215 print_ifarg("(char **)");
216 f_print(fout, "pp");
217 print_ifsizeof(0, prefix, type);
218 break;
219 case REL_VECTOR:
220 if (streq(type, "string"))
221 alt = "string";
222 else if (streq(type, "opaque"))
223 alt = "opaque";
225 if (alt) {
226 print_ifopen(indent, alt);
227 print_ifarg(objname);
228 } else {
229 print_ifopen(indent, "vector");
230 print_ifarg("(char *)");
231 f_print(fout, "%s", objname);
233 print_ifarg(amax);
234 if (!alt)
235 print_ifsizeof(indent + 1, prefix, type);
236 break;
237 case REL_ARRAY:
238 if (streq(type, "string"))
239 alt = "string";
240 else if (streq(type, "opaque"))
241 alt = "bytes";
243 if (streq(type, "string")) {
244 print_ifopen(indent, alt);
245 print_ifarg(objname);
246 } else {
247 if (alt)
248 print_ifopen(indent, alt);
249 else
250 print_ifopen(indent, "array");
251 print_ifarg("(char **)");
252 if (*objname == '&') {
253 f_print(fout, "%s.%s_val, (u_int *) %s.%s_len",
254 objname, name, objname, name);
255 } else {
256 f_print(fout,
257 "&%s->%s_val, (u_int *) &%s->%s_len",
258 objname, name, objname, name);
261 print_ifarg(amax);
262 if (!alt)
263 print_ifsizeof(indent + 1, prefix, type);
264 break;
265 case REL_ALIAS:
266 print_ifopen(indent, type);
267 print_ifarg(objname);
268 break;
270 print_ifclose(indent, brace);
273 /* ARGSUSED */
274 static void
275 emit_enum(definition *def __unused)
277 print_ifopen(1, "enum");
278 print_ifarg("(enum_t *)objp");
279 print_ifclose(1, 0);
282 static void
283 emit_program(definition *def)
285 decl_list *dl;
286 version_list *vlist;
287 proc_list *plist;
289 for (vlist = def->def.pr.versions; vlist != NULL; vlist = vlist->next)
290 for (plist = vlist->procs; plist != NULL; plist = plist->next) {
291 if (!newstyle || plist->arg_num < 2)
292 continue; /* old style, or single argument */
293 print_prog_header(plist);
294 for (dl = plist->args.decls; dl != NULL;
295 dl = dl->next)
296 print_stat(1, &dl->decl);
297 print_trailer();
302 static void
303 emit_union(definition *def)
305 declaration *dflt;
306 case_list *cl;
307 declaration *cs;
308 char *object;
309 const char *vecformat = "objp->%s_u.%s";
310 const char *format = "&objp->%s_u.%s";
312 print_stat(1, &def->def.un.enum_decl);
313 f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
314 for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
316 f_print(fout, "\tcase %s:\n", cl->case_name);
317 if (cl->contflag == 1) /* a continued case statement */
318 continue;
319 cs = &cl->case_decl;
320 if (!streq(cs->type, "void")) {
321 object = xmalloc(strlen(def->def_name) +
322 strlen(format) + strlen(cs->name) + 1);
323 if (isvectordef (cs->type, cs->rel)) {
324 s_print(object, vecformat, def->def_name,
325 cs->name);
326 } else {
327 s_print(object, format, def->def_name,
328 cs->name);
330 print_ifstat(2, cs->prefix, cs->type, cs->rel,
331 cs->array_max, object, cs->name);
332 free(object);
334 f_print(fout, "\t\tbreak;\n");
336 dflt = def->def.un.default_decl;
337 if (dflt != NULL) {
338 if (!streq(dflt->type, "void")) {
339 f_print(fout, "\tdefault:\n");
340 object = xmalloc(strlen(def->def_name) +
341 strlen(format) + strlen(dflt->name) + 1);
342 if (isvectordef (dflt->type, dflt->rel)) {
343 s_print(object, vecformat, def->def_name,
344 dflt->name);
345 } else {
346 s_print(object, format, def->def_name,
347 dflt->name);
350 print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
351 dflt->array_max, object, dflt->name);
352 free(object);
353 f_print(fout, "\t\tbreak;\n");
354 } else {
355 f_print(fout, "\tdefault:\n");
356 f_print(fout, "\t\tbreak;\n");
358 } else {
359 f_print(fout, "\tdefault:\n");
360 f_print(fout, "\t\treturn (FALSE);\n");
363 f_print(fout, "\t}\n");
366 static void
367 inline_struct(definition *def, int flag)
369 decl_list *dl;
370 int i, size;
371 decl_list *cur, *psav;
372 bas_type *ptr;
373 char *sizestr;
374 const char *plus;
375 char ptemp[256];
376 int indent = 1;
378 cur = NULL;
379 if (flag == PUT)
380 f_print(fout, "\n\tif (xdrs->x_op == XDR_ENCODE) {\n");
381 else
382 f_print(fout, "\t\treturn (TRUE);\n"
383 "\t} else if (xdrs->x_op == XDR_DECODE) {\n");
385 i = 0;
386 size = 0;
387 sizestr = NULL;
388 for (dl = def->def.st.decls; dl != NULL; dl = dl->next) { /* xxx */
389 /* now walk down the list and check for basic types */
390 if ((dl->decl.prefix == NULL) &&
391 ((ptr = find_type(dl->decl.type)) != NULL) &&
392 ((dl->decl.rel == REL_ALIAS) ||
393 (dl->decl.rel == REL_VECTOR))){
394 if (i == 0)
395 cur = dl;
396 i++;
398 if (dl->decl.rel == REL_ALIAS) {
399 size += ptr->length;
400 } else {
401 /* this code is required to handle arrays */
402 if (sizestr == NULL)
403 plus = "";
404 else
405 plus = " + ";
407 if (ptr->length != 1)
408 s_print(ptemp, "%s%s * %d",
409 plus, dl->decl.array_max,
410 ptr->length);
411 else
412 s_print(ptemp, "%s%s", plus,
413 dl->decl.array_max);
415 /* now concatenate to sizestr !!!! */
416 if (sizestr == NULL) {
417 sizestr = xstrdup(ptemp);
418 } else {
419 sizestr = xrealloc(sizestr,
420 strlen(sizestr)
421 +strlen(ptemp)+1);
422 sizestr = strcat(sizestr, ptemp);
423 /* build up length of array */
426 } else {
427 if (i > 0) {
428 if (sizestr == NULL && size < inline_size) {
430 * don't expand into inline code
431 * if size < inline_size
433 while (cur != dl) {
434 print_stat(indent + 1,
435 &cur->decl);
436 cur = cur->next;
438 } else {
439 /* were already looking at a xdr_inlineable structure */
440 tabify(fout, indent + 1);
441 if (sizestr == NULL)
442 f_print(fout, "buf = XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);",
443 size);
444 else {
445 if (size == 0)
446 f_print(fout,
447 "buf = XDR_INLINE(xdrs, (%s) * BYTES_PER_XDR_UNIT);",
448 sizestr);
449 else
450 f_print(fout,
451 "buf = XDR_INLINE(xdrs, (%d + (%s)) * BYTES_PER_XDR_UNIT);",
452 size, sizestr);
455 f_print(fout, "\n");
456 tabify(fout, indent + 1);
457 f_print(fout,
458 "if (buf == NULL) {\n");
460 psav = cur;
461 while (cur != dl) {
462 print_stat(indent + 2, &cur->decl);
463 cur = cur->next;
466 f_print(fout, "\n\t\t} else {\n");
468 cur = psav;
469 while (cur != dl) {
470 emit_inline(indent + 2, &cur->decl, flag);
471 cur = cur->next;
474 tabify(fout, indent + 1);
475 f_print(fout, "}\n");
478 size = 0;
479 i = 0;
480 sizestr = NULL;
481 print_stat(indent + 1, &dl->decl);
485 if (i > 0) {
486 if (sizestr == NULL && size < inline_size) {
487 /* don't expand into inline code if size < inline_size */
488 while (cur != dl) {
489 print_stat(indent + 1, &cur->decl);
490 cur = cur->next;
492 } else {
493 /* were already looking at a xdr_inlineable structure */
494 if (sizestr == NULL)
495 f_print(fout, "\t\tbuf = XDR_INLINE(xdrs, %d * BYTES_PER_XDR_UNIT);",
496 size);
497 else {
498 if (size == 0)
499 f_print(fout,
500 "\t\tbuf = XDR_INLINE(xdrs, (%s) * BYTES_PER_XDR_UNIT);",
501 sizestr);
502 else
503 f_print(fout,
504 "\t\tbuf = XDR_INLINE(xdrs, (%d + (%s)) * BYTES_PER_XDR_UNIT);",
505 size, sizestr);
508 f_print(fout, "\n\t\tif (buf == NULL) {\n");
509 psav = cur;
510 while (cur != NULL) {
511 print_stat(indent + 2, &cur->decl);
512 cur = cur->next;
514 f_print(fout, "\t\t} else {\n");
516 cur = psav;
517 while (cur != dl) {
518 emit_inline(indent + 2, &cur->decl, flag);
519 cur = cur->next;
521 f_print(fout, "\t\t}\n");
526 static void
527 emit_struct(definition *def)
529 decl_list *dl;
530 int j, size, flag;
531 bas_type *ptr;
532 int can_inline;
534 if (inline_size == 0) {
535 /* No xdr_inlining at all */
536 for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
537 print_stat(1, &dl->decl);
538 return;
541 for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {
542 if (dl->decl.rel == REL_VECTOR){
543 f_print(fout, "\tint i;\n");
544 break;
548 size = 0;
549 can_inline = 0;
551 * Make a first pass and see if inling is possible.
553 for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {
554 if ((dl->decl.prefix == NULL) &&
555 ((ptr = find_type(dl->decl.type)) != NULL) &&
556 ((dl->decl.rel == REL_ALIAS)||
557 (dl->decl.rel == REL_VECTOR))) {
558 if (dl->decl.rel == REL_ALIAS)
559 size += ptr->length;
560 else {
561 can_inline = 1;
562 break; /* can be inlined */
564 } else {
565 if (size >= inline_size) {
566 can_inline = 1;
567 break; /* can be inlined */
569 size = 0;
572 if (size >= inline_size)
573 can_inline = 1;
575 if (can_inline == 0) { /* can not inline, drop back to old mode */
576 for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
577 print_stat(1, &dl->decl);
578 return;
581 flag = PUT;
582 for (j = 0; j < 2; j++){
583 inline_struct(def, flag);
584 if (flag == PUT)
585 flag = GET;
588 f_print(fout, "\t\treturn (TRUE);\n\t}\n\n");
590 /* now take care of XDR_FREE case */
592 for (dl = def->def.st.decls; dl != NULL; dl = dl->next)
593 print_stat(1, &dl->decl);
597 static void
598 emit_typedef(definition *def)
600 const char *prefix = def->def.ty.old_prefix;
601 const char *type = def->def.ty.old_type;
602 const char *amax = def->def.ty.array_max;
603 relation rel = def->def.ty.rel;
605 print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
608 static void
609 print_stat(int indent, declaration *dec)
611 const char *prefix = dec->prefix;
612 const char *type = dec->type;
613 const char *amax = dec->array_max;
614 relation rel = dec->rel;
615 char name[256];
617 if (isvectordef(type, rel))
618 s_print(name, "objp->%s", dec->name);
619 else
620 s_print(name, "&objp->%s", dec->name);
621 print_ifstat(indent, prefix, type, rel, amax, name, dec->name);
625 static void
626 emit_inline(int indent, declaration *decl, int flag)
628 switch (decl->rel) {
629 case REL_ALIAS :
630 emit_single_in_line(indent, decl, flag, REL_ALIAS);
631 break;
632 case REL_VECTOR :
633 tabify(fout, indent);
634 f_print(fout, "{\n");
635 tabify(fout, indent + 1);
636 f_print(fout, "%s *genp;\n\n", decl->type);
637 tabify(fout, indent + 1);
638 f_print(fout, "for (i = 0, genp = objp->%s;\n", decl->name);
639 tabify(fout, indent + 2);
640 f_print(fout, "i < %s; i++) {\n", decl->array_max);
641 emit_single_in_line(indent + 2, decl, flag, REL_VECTOR);
642 tabify(fout, indent + 1);
643 f_print(fout, "}\n");
644 tabify(fout, indent);
645 f_print(fout, "}\n");
646 break;
647 default:
648 break;
652 static void
653 emit_single_in_line(int indent, declaration *decl, int flag, relation rel)
655 char *upp_case;
657 tabify(fout, indent);
658 if (flag == PUT)
659 f_print(fout, "IXDR_PUT_");
660 else if (rel == REL_ALIAS)
661 f_print(fout, "objp->%s = IXDR_GET_", decl->name);
662 else
663 f_print(fout, "*genp++ = IXDR_GET_");
665 upp_case = upcase(decl->type);
667 /* hack - XX */
668 if (strcmp(upp_case, "INT") == 0)
670 free(upp_case);
671 upp_case = strdup("LONG");
674 if (strcmp(upp_case, "U_INT") == 0)
676 free(upp_case);
677 upp_case = strdup("U_LONG");
679 if (flag == PUT) {
680 if (rel == REL_ALIAS)
681 f_print(fout, "%s(buf, objp->%s);\n", upp_case,
682 decl->name);
683 else
684 f_print(fout, "%s(buf, *genp++);\n", upp_case);
685 } else {
686 f_print(fout, "%s(buf);\n", upp_case);
688 free(upp_case);
691 static char *
692 upcase(const char *str)
694 char *ptr, *hptr;
696 ptr = xmalloc(strlen(str)+1);
698 hptr = ptr;
699 while (*str != '\0')
700 *ptr++ = toupper(*str++);
702 *ptr = '\0';
703 return(hptr);