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