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