a15b627ba4e3689e90ea038fa8d4905ce7e03814
[openafs.git] / src / rxgen / rpc_cout.c
1 /* @(#)rpc_cout.c       1.1 87/11/04 3.9 RPCSRC */
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.
9  *
10  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
11  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
12  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
13  *
14  * Sun RPC is provided with no support and without any obligation on the
15  * part of Sun Microsystems, Inc. to assist in its use, correction,
16  * modification or enhancement.
17  *
18  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
19  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
20  * OR ANY PART THEREOF.
21  *
22  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
23  * or profits or other special, indirect and consequential damages, even if
24  * Sun has been advised of the possibility of such damages.
25  *
26  * Sun Microsystems, Inc.
27  * 2550 Garcia Avenue
28  * Mountain View, California  94043
29  */
30
31 /*
32  * rpc_cout.c, XDR routine outputter for the RPC protocol compiler
33  * Copyright (C) 1987, Sun Microsystems, Inc.
34  */
35 #include <afsconfig.h>
36 #include <afs/param.h>
37
38 #include <roken.h>
39
40 #include "rpc_scan.h"
41 #include "rpc_parse.h"
42 #include "rpc_util.h"
43
44 /* Static prototypes */
45 static int findtype(definition * def, char *type);
46 static int undefined(char *type);
47 static void print_header(definition * def);
48 static void print_trailer(void);
49 static void print_ifopen(int indent, char *name);
50 static void print_ifarg(char *arg);
51 static void print_ifarg_with_cast(int ptr_to, char *type, char *arg);
52 static void print_ifsizeof(char *prefix, char *type);
53 static void print_ifclose(int indent);
54 static void space(void);
55 static void print_ifstat(int indent, char *prefix, char *type, relation rel,
56                          char *amax, char *objname, char *name);
57 static void emit_enum(definition * def);
58 static void emit_union(definition * def);
59 static void emit_struct(definition * def);
60 static void emit_typedef(definition * def);
61 static void print_stat(declaration * dec);
62 static void print_hout(declaration * dec);
63 static void print_cout(declaration * dec);
64 static void print_rxifopen(char *typename);
65 static void print_rxifarg(char *amp, char *arg, int costant);
66 static void print_rxifsizeof(char *prefix, char *type);
67
68
69 /*
70  * Emit the C-routine for the given definition
71  */
72 void
73 emit(definition * def)
74 {
75     if (def->def_kind == DEF_CONST) {
76         return;
77     }
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     default:
93         break;
94     }
95     print_trailer();
96 }
97
98 static int
99 findtype(definition * def, char *type)
100 {
101     if (def->def_kind == DEF_CONST) {
102         return (0);
103     } else {
104         return (streq(def->def_name, type));
105     }
106 }
107
108 static int
109 undefined(char *type)
110 {
111     definition *def;
112
113     def = (definition *) FINDVAL(defined, type, findtype);
114     return (def == NULL);
115 }
116
117
118 static void
119 print_header(definition * def)
120 {
121     space();
122     f_print(fout, "bool_t\n");
123     f_print(fout, "xdr_%s(XDR *xdrs, ", def->def_name);
124     f_print(fout, "%s ", def->def_name);
125 #if 0
126     if (def->def_kind != DEF_TYPEDEF
127         || !isvectordef(def->def.ty.old_type, def->def.ty.rel)) {
128         f_print(fout, "*");
129     }
130 #else
131     f_print(fout, "*");
132 #endif
133     f_print(fout, "objp)\n");
134     f_print(fout, "{\n");
135 }
136
137 static void
138 print_trailer(void)
139 {
140     f_print(fout, "\treturn (TRUE);\n");
141     f_print(fout, "}\n");
142     space();
143 }
144
145
146 static void
147 print_ifopen(int indent, char *name)
148 {
149     tabify(fout, indent);
150     f_print(fout, "if (!xdr_%s(xdrs", name);
151 }
152
153
154 static void
155 print_ifarg(char *arg)
156 {
157     f_print(fout, ", %s", arg);
158 }
159
160
161 static void
162 print_ifarg_with_cast(int ptr_to, char *type, char *arg)
163 {
164     if (streq(type, "bool")) {
165         f_print(fout, ptr_to ? ", (bool_t *) %s" : ", (bool_t) %s", arg);
166     } else {
167         f_print(fout, ptr_to ? ", (%s *) %s" : ", (%s) %s", type, arg);
168     }
169 }
170
171 static void
172 print_ifsizeof(char *prefix, char *type)
173 {
174     if (streq(type, "bool")) {
175         f_print(fout, ", sizeof(bool_t), (xdrproc_t) xdr_bool");
176     } else {
177         f_print(fout, ", sizeof(");
178         if (undefined(type) && prefix) {
179             f_print(fout, "%s ", prefix);
180         }
181         f_print(fout, "%s), (xdrproc_t) xdr_%s", type, type);
182     }
183 }
184
185 static void
186 print_ifclose(int indent)
187 {
188     f_print(fout, ")) {\n");
189     tabify(fout, indent);
190     f_print(fout, "\treturn (FALSE);\n");
191     tabify(fout, indent);
192     f_print(fout, "}\n");
193 }
194
195 static void
196 space(void)
197 {
198     f_print(fout, "\n\n");
199 }
200
201 static void
202 print_ifarg_val(char *objname, char *name)
203 {
204     if (*objname == '&') {
205         if (brief_flag) {
206             f_print(fout, "%s.val", objname);
207         } else {
208             f_print(fout, "%s.%s_val", objname, name);
209         }
210     } else {
211         if (brief_flag) {
212             f_print(fout, "&%s->val", objname);
213         } else {
214             f_print(fout, "&%s->%s_val", objname, name);
215         }
216     }
217 }
218
219 static void
220 print_ifarg_len(char *objname, char *name)
221 {
222     if (*objname == '&') {
223         if (brief_flag) {
224             f_print(fout, "(u_int *)%s.len", objname);
225         } else {
226             f_print(fout, "(u_int *)%s.%s_len", objname, name);
227         }
228     } else {
229         if (brief_flag) {
230             f_print(fout, "(u_int *)&%s->len", objname);
231         } else {
232             f_print(fout, "(u_int *)&%s->%s_len", objname, name);
233         }
234     }
235 }
236
237 static void
238 print_ifstat(int indent, char *prefix, char *type, relation rel, char *amax,
239              char *objname, char *name)
240 {
241     char *alt = NULL;
242     char *altcast = NULL;
243
244     switch (rel) {
245     case REL_POINTER:
246         print_ifopen(indent, "pointer");
247         print_ifarg_with_cast(1, "char *", objname);
248         print_ifsizeof(prefix, type);
249         break;
250     case REL_VECTOR:
251         if (streq(type, "string")) {
252             alt = "string";
253         } else if (streq(type, "opaque")) {
254             alt = "opaque";
255             altcast = "caddr_t";
256         }
257         if (alt) {
258             print_ifopen(indent, alt);
259             if (altcast) {
260                 print_ifarg_with_cast(0, altcast, objname);
261             } else {
262                 print_ifarg(objname);
263             }
264         } else {
265             print_ifopen(indent, "vector");
266             print_ifarg_with_cast(1, "char", objname);
267         }
268         print_ifarg(amax);
269         if (!alt) {
270             print_ifsizeof(prefix, type);
271         }
272         break;
273     case REL_ARRAY:
274         if (streq(type, "string")) {
275             alt = "string";
276         } else if (streq(type, "opaque")) {
277             alt = "bytes";
278             tabify(fout, indent);
279             f_print(fout, "{\n");
280             ++indent;
281             tabify(fout, indent);
282             f_print(fout, "u_int __len = (u_int) ");
283             f_print(fout, "*(");
284             print_ifarg_len(objname, name);
285             f_print(fout, ");\n");
286         }
287         if (streq(type, "string")) {
288             print_ifopen(indent, alt);
289             print_ifarg(objname);
290         } else {
291             if (alt) {
292                 print_ifopen(indent, alt);
293                 print_ifarg("(char **)");
294             } else {
295                 print_ifopen(indent, "array");
296                 print_ifarg("(caddr_t *)");
297             }
298             print_ifarg_val(objname, name);
299             f_print(fout, ", ");
300             if (streq(type, "opaque")) {
301                 f_print(fout, "&__len");
302             } else {
303                 print_ifarg_len(objname, name);
304             }
305         }
306         print_ifarg(amax);
307         if (!alt) {
308             print_ifsizeof(prefix, type);
309         }
310         break;
311     case REL_ALIAS:
312         print_ifopen(indent, type);
313         print_ifarg(objname);
314         break;
315     }
316     print_ifclose(indent);
317     if (rel == REL_ARRAY && streq(type, "opaque")) {
318         tabify(fout, indent);
319         f_print(fout, "*(");
320         print_ifarg_len(objname, name);
321         f_print(fout, ")");
322         f_print(fout, " = __len;\n");
323         --indent;
324         tabify(fout, indent);
325         f_print(fout, "}\n");
326     }
327
328 }
329
330
331 static void
332 emit_enum(definition * def)
333 {
334     print_ifopen(1, "enum");
335     print_ifarg("(enum_t *)objp");
336     print_ifclose(1);
337 }
338
339
340 static void
341 emit_union(definition * def)
342 {
343     declaration *dflt;
344     case_list *cl;
345     declaration *cs;
346     char *object;
347     char *format = "&objp->%s_u.%s";
348     char *briefformat = "&objp->u.%s";
349
350     print_stat(&def->def.un.enum_decl);
351     f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
352     for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
353         cs = &cl->case_decl;
354         f_print(fout, "\tcase %s:\n", cl->case_name);
355         if (!streq(cs->type, "void")) {
356             object =
357                 alloc(strlen(def->def_name) + strlen(format) +
358                       strlen(cs->name) + 1);
359
360             if (brief_flag)
361                 s_print(object, briefformat, cs->name);
362             else
363                 s_print(object, format, def->def_name, cs->name);
364
365             print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
366                          object, cs->name);
367             free(object);
368         }
369         f_print(fout, "\t\tbreak;\n");
370     }
371     dflt = def->def.un.default_decl;
372     if (dflt != NULL) {
373         if (!streq(dflt->type, "void")) {
374             f_print(fout, "\tdefault:\n");
375             object =
376                 alloc(strlen(def->def_name) + strlen(format) +
377                       strlen(dflt->name) + 1);
378             s_print(object, format, def->def_name, dflt->name);
379             print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
380                          dflt->array_max, object, dflt->name);
381             free(object);
382             f_print(fout, "\t\tbreak;\n");
383         }
384     } else {
385         f_print(fout, "\tdefault:\n");
386         f_print(fout, "\t\treturn (FALSE);\n");
387     }
388     f_print(fout, "\t}\n");
389 }
390
391
392
393 static void
394 emit_struct(definition * def)
395 {
396     decl_list *dl;
397
398     for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {
399         print_stat(&dl->decl);
400     }
401 }
402
403
404
405
406 static void
407 emit_typedef(definition * def)
408 {
409     char *prefix = def->def.ty.old_prefix;
410     char *type = def->def.ty.old_type;
411     char *amax = def->def.ty.array_max;
412     relation rel = def->def.ty.rel;
413
414     print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
415 }
416
417
418
419
420
421 static void
422 print_stat(declaration * dec)
423 {
424     char *prefix = dec->prefix;
425     char *type = dec->type;
426     char *amax = dec->array_max;
427     relation rel = dec->rel;
428     char name[256];
429
430     if (isvectordef(type, rel)) {
431         s_print(name, "objp->%s", dec->name);
432     } else {
433         s_print(name, "&objp->%s", dec->name);
434     }
435     print_ifstat(1, prefix, type, rel, amax, name, dec->name);
436 }
437
438 static void
439 print_hout(declaration * dec)
440 {
441     char prefix[8];
442
443     if (hflag) {
444         if (dec->prefix)
445             s_print(prefix, "%s ", dec->prefix);
446         else
447             prefix[0] = 0;
448         f_print(fout, "\ntypedef ");
449         switch (dec->rel) {
450         case REL_ARRAY:
451             f_print(fout, "struct %s {\n", dec->name);
452             if (brief_flag) {
453                 f_print(fout, "\tu_int %s_len;\n", dec->name);
454                 f_print(fout, "\t%s%s *%s_val;\n", prefix,
455                         dec->type, dec->name);
456             } else {
457                 f_print(fout, "\tu_int %s_len;\n", dec->name);
458                 f_print(fout, "\t%s%s *%s_val;\n", prefix,
459                         dec->type, dec->name);
460             }
461             f_print(fout, "} %s", dec->name);
462             break;
463         default:
464             break;
465         }
466         f_print(fout, ";\n");
467         f_print(fout, "bool_t xdr_%s(XDR *xdrs, %s *objp);\n", dec->name,
468                 dec->name);
469     }
470 }
471
472
473 static void
474 print_cout(declaration * dec)
475 {
476     if (cflag) {
477         space();
478         f_print(fout, "bool_t\n");
479         f_print(fout, "xdr_%s(XDR *xdrs, %s *objp)\n", dec->name, dec->name);
480         f_print(fout, "{\n");
481         print_ifstat(1, dec->prefix, dec->type, dec->rel, dec->array_max,
482                      "objp", dec->name);
483         print_trailer();
484     }
485 }
486
487
488 static void
489 print_rxifopen(char *typename)
490 {
491     sprintf(Proc_list->code, "xdr_%s(&z_xdrs", typename);
492     sprintf(Proc_list->scode, "xdr_%s(z_xdrs", typename);
493 }
494
495
496 static void
497 print_rxifarg(char *amp, char *arg, int costant)
498 {
499     char code[100], scode[100];
500
501     sprintf(code, ", %s%s", amp, arg);
502     if (costant)
503         sprintf(scode, ", %s", arg);
504     else
505         sprintf(scode, ", &%s", arg);
506     strcat(Proc_list->code, code);
507     strcat(Proc_list->scode, scode);
508 }
509
510
511 static void
512 print_rxifsizeof(char *prefix, char *type)
513 {
514     char name[256];
515
516     if (streq(type, "bool")) {
517         strcat(Proc_list->code, ", sizeof(bool_t), xdr_bool");
518         strcat(Proc_list->scode, ", sizeof(bool_t), xdr_bool");
519     } else {
520         strcat(Proc_list->code, ", sizeof(");
521         strcat(Proc_list->scode, ", sizeof(");
522         if (undefined(type) && prefix) {
523             sprintf(name, "%s ", prefix);
524             strcat(Proc_list->code, name);
525             strcat(Proc_list->scode, name);
526         }
527         sprintf(name, "%s), xdr_%s", type, type);
528         strcat(Proc_list->code, name);
529         strcat(Proc_list->scode, name);
530     }
531 }
532
533
534 void
535 print_param(declaration * dec)
536 {
537     char *prefix = dec->prefix;
538     char *type = dec->type;
539     char *amax = dec->array_max;
540     relation rel = dec->rel;
541     char *name = dec->name;
542     char *alt = NULL;
543     char temp[256];
544     char *objname, *amp = "";
545
546     if (rel == REL_POINTER)
547         Proc_list->pl.param_flag |= INDIRECT_PARAM;
548     else {
549         amp = "&";
550         Proc_list->pl.param_flag &= ~INDIRECT_PARAM;
551     }
552     objname = Proc_list->pl.param_name;
553     switch (rel) {
554     case REL_POINTER:
555         print_rxifopen(type);
556         print_rxifarg(amp, objname, 0);
557 /*
558                 print_rxifopen("pointer");
559                 print_rxifarg(amp, "(char **)", 1);
560                 sprintf(temp, "%s", objname);
561                 strcat(Proc_list->code, temp);
562                 strcat(Proc_list->scode, temp);
563                 print_rxifsizeof(prefix, type);
564 */
565         break;
566     case REL_VECTOR:
567         if (streq(type, "string")) {
568             alt = "string";
569         } else if (streq(type, "opaque")) {
570             alt = "opaque";
571         }
572         if (alt)
573             print_rxifopen(alt);
574         else
575             print_rxifopen("vector");
576
577         print_rxifarg(amp, "(char *)", 0);
578         sprintf(temp, "%s", objname);
579         strcat(Proc_list->code, temp);
580         strcat(Proc_list->scode, temp);
581         print_rxifarg("", amax, 1);
582         if (!alt) {
583             print_rxifsizeof(prefix, type);
584         }
585         break;
586     case REL_ARRAY:
587         if (streq(type, "string")) {
588             alt = "string";
589         } else if (streq(type, "opaque")) {
590             alt = "bytes";
591         }
592         if (streq(type, "string")) {
593             print_rxifopen(alt);
594             if ((Proc_list->pl.param_kind == DEF_OUTPARAM)
595                 || (Proc_list->pl.param_kind == DEF_INOUTPARAM)) {
596                 Proc_list->pl.param_flag |= OUT_STRING;
597                 print_rxifarg("", objname, 0);
598             } else
599                 print_rxifarg("(char **) &", objname, 0);
600 /*                      print_rxifarg(amp, objname, 0); */
601             print_rxifarg("", amax, 1);
602             if (!alt) {
603                 print_rxifsizeof(prefix, type);
604             }
605         } else {
606             char typecontents[100];
607
608             print_hout(dec);
609             print_cout(dec);
610             strcpy(temp, dec->name);
611             strcpy(typecontents, dec->name);
612             strcat(typecontents, " *");
613             strcpy(Proc_list->pl.param_type, typecontents);
614             sprintf(typecontents, "%s_%d", Proc_list->pl.param_name,
615                     ++PerProcCounter);
616             strcpy(Proc_list->pl.param_name, typecontents);
617             Proc_list->pl.param_flag |= FREETHIS_PARAM;
618             print_rxifopen(temp);
619             print_rxifarg(amp, name, 0);
620         }
621 /*
622                         if (alt) {
623                                 print_rxifopen(alt);
624                         } else {
625                                 print_rxifopen("array");
626                         }
627                         print_rxifarg(amp, "(char **)", 1);
628                         if (*objname == '&') {
629                                 sprintf(temp, "%s.%s_val, (u_int *)%s.%s_len",
630                                         objname, name, objname, name);
631                         } else {
632                                 sprintf(temp, "&%s->%s_val, (u_int *)&%s->%s_len",
633                                         objname, name, objname, name);
634                         }
635                         strcat(Proc_list->code, temp);
636                         strcat(Proc_list->scode, temp);
637                 }
638                 print_rxifarg("", amax, 1);
639                 if (!alt) {
640                         print_rxifsizeof(prefix, type);
641                 }
642 */
643         break;
644     case REL_ALIAS:
645         print_rxifopen(type);
646         print_rxifarg(amp, objname, 0);
647         break;
648     }
649     strcat(Proc_list->code, ")");
650     strcat(Proc_list->scode, ")");
651 }