rxgen: Properly generate brief union default arm
[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     f_print(fout, "*");
126     f_print(fout, "objp)\n");
127     f_print(fout, "{\n");
128 }
129
130 static void
131 print_trailer(void)
132 {
133     f_print(fout, "\treturn (TRUE);\n");
134     f_print(fout, "}\n");
135     space();
136 }
137
138
139 static void
140 print_ifopen(int indent, char *name)
141 {
142     tabify(fout, indent);
143     f_print(fout, "if (!xdr_%s(xdrs", name);
144 }
145
146
147 static void
148 print_ifarg(char *arg)
149 {
150     f_print(fout, ", %s", arg);
151 }
152
153
154 static void
155 print_ifarg_with_cast(int ptr_to, char *type, char *arg)
156 {
157     if (streq(type, "bool")) {
158         f_print(fout, ptr_to ? ", (bool_t *) %s" : ", (bool_t) %s", arg);
159     } else {
160         f_print(fout, ptr_to ? ", (%s *) %s" : ", (%s) %s", type, arg);
161     }
162 }
163
164 static void
165 print_ifsizeof(char *prefix, char *type)
166 {
167     if (streq(type, "bool")) {
168         f_print(fout, ", sizeof(bool_t), (xdrproc_t) xdr_bool");
169     } else {
170         f_print(fout, ", sizeof(");
171         if (undefined(type) && prefix) {
172             f_print(fout, "%s ", prefix);
173         }
174         f_print(fout, "%s), (xdrproc_t) xdr_%s", type, type);
175     }
176 }
177
178 static void
179 print_ifclose(int indent)
180 {
181     f_print(fout, ")) {\n");
182     tabify(fout, indent);
183     f_print(fout, "\treturn (FALSE);\n");
184     tabify(fout, indent);
185     f_print(fout, "}\n");
186 }
187
188 static void
189 space(void)
190 {
191     f_print(fout, "\n\n");
192 }
193
194 static void
195 print_ifarg_val(char *objname, char *name)
196 {
197     if (*objname == '&') {
198         if (brief_flag) {
199             f_print(fout, "%s.val", objname);
200         } else {
201             f_print(fout, "%s.%s_val", objname, name);
202         }
203     } else {
204         if (brief_flag) {
205             f_print(fout, "&%s->val", objname);
206         } else {
207             f_print(fout, "&%s->%s_val", objname, name);
208         }
209     }
210 }
211
212 static void
213 print_ifarg_len(char *objname, char *name)
214 {
215     if (*objname == '&') {
216         if (brief_flag) {
217             f_print(fout, "%s.len", objname);
218         } else {
219             f_print(fout, "%s.%s_len", objname, name);
220         }
221     } else {
222         if (brief_flag) {
223             f_print(fout, "&%s->len", objname);
224         } else {
225             f_print(fout, "&%s->%s_len", objname, name);
226         }
227     }
228 }
229
230 static void
231 print_ifstat(int indent, char *prefix, char *type, relation rel, char *amax,
232              char *objname, char *name)
233 {
234     char *alt = NULL;
235     char *altcast = NULL;
236
237     switch (rel) {
238     case REL_POINTER:
239         print_ifopen(indent, "pointer");
240         print_ifarg_with_cast(1, "char *", objname);
241         print_ifsizeof(prefix, type);
242         break;
243     case REL_VECTOR:
244         if (streq(type, "string")) {
245             alt = "string";
246         } else if (streq(type, "opaque")) {
247             alt = "opaque";
248             altcast = "caddr_t";
249         }
250         if (alt) {
251             print_ifopen(indent, alt);
252             if (altcast) {
253                 print_ifarg_with_cast(0, altcast, objname);
254             } else {
255                 print_ifarg(objname);
256             }
257         } else {
258             print_ifopen(indent, "vector");
259             print_ifarg_with_cast(1, "char", objname);
260         }
261         print_ifarg(amax);
262         if (!alt) {
263             print_ifsizeof(prefix, type);
264         }
265         break;
266     case REL_ARRAY:
267         if (streq(type, "string")) {
268             alt = "string";
269         } else if (streq(type, "opaque")) {
270             alt = "bytes";
271             tabify(fout, indent);
272             f_print(fout, "{\n");
273             ++indent;
274             tabify(fout, indent);
275             f_print(fout, "u_int __len = (u_int) ");
276             f_print(fout, "*(");
277             print_ifarg_len(objname, name);
278             f_print(fout, ");\n");
279         }
280         if (streq(type, "string")) {
281             print_ifopen(indent, alt);
282             print_ifarg(objname);
283         } else {
284             if (alt) {
285                 print_ifopen(indent, alt);
286                 print_ifarg("(char **)");
287             } else {
288                 print_ifopen(indent, "array");
289                 print_ifarg("(caddr_t *)");
290             }
291             print_ifarg_val(objname, name);
292             f_print(fout, ", ");
293             if (streq(type, "opaque")) {
294                 f_print(fout, "&__len");
295             } else {
296                 print_ifarg_len(objname, name);
297             }
298         }
299         print_ifarg(amax);
300         if (!alt) {
301             print_ifsizeof(prefix, type);
302         }
303         break;
304     case REL_ALIAS:
305         print_ifopen(indent, type);
306         print_ifarg(objname);
307         break;
308     }
309     print_ifclose(indent);
310     if (rel == REL_ARRAY && streq(type, "opaque")) {
311         tabify(fout, indent);
312         f_print(fout, "*(");
313         print_ifarg_len(objname, name);
314         f_print(fout, ")");
315         f_print(fout, " = __len;\n");
316         --indent;
317         tabify(fout, indent);
318         f_print(fout, "}\n");
319     }
320
321 }
322
323
324 static void
325 emit_enum(definition * def)
326 {
327     print_ifopen(1, "enum");
328     print_ifarg("(enum_t *)objp");
329     print_ifclose(1);
330 }
331
332
333 static void
334 emit_union(definition * def)
335 {
336     declaration *dflt;
337     case_list *cl;
338     declaration *cs;
339     char *object;
340     char *format = "&objp->%s_u.%s";
341     char *briefformat = "&objp->u.%s";
342
343     print_stat(&def->def.un.enum_decl);
344     f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
345     for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
346         cs = &cl->case_decl;
347         f_print(fout, "\tcase %s:\n", cl->case_name);
348         if (!streq(cs->type, "void")) {
349             object =
350                 alloc(strlen(def->def_name) + strlen(format) +
351                       strlen(cs->name) + 1);
352
353             if (brief_flag)
354                 s_print(object, briefformat, cs->name);
355             else
356                 s_print(object, format, def->def_name, cs->name);
357
358             print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
359                          object, cs->name);
360             free(object);
361         }
362         f_print(fout, "\t\tbreak;\n");
363     }
364     dflt = def->def.un.default_decl;
365     if (dflt != NULL) {
366         if (!streq(dflt->type, "void")) {
367             f_print(fout, "\tdefault:\n");
368             object =
369                 alloc(strlen(def->def_name) + strlen(format) +
370                       strlen(dflt->name) + 1);
371             if (brief_flag)
372                 s_print(object, briefformat, dflt->name);
373             else
374                 s_print(object, format, def->def_name, dflt->name);
375             print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
376                          dflt->array_max, object, dflt->name);
377             free(object);
378             f_print(fout, "\t\tbreak;\n");
379         }
380     } else {
381         f_print(fout, "\tdefault:\n");
382         f_print(fout, "\t\treturn (FALSE);\n");
383     }
384     f_print(fout, "\t}\n");
385 }
386
387
388
389 static void
390 emit_struct(definition * def)
391 {
392     decl_list *dl;
393
394     for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {
395         print_stat(&dl->decl);
396     }
397 }
398
399
400
401
402 static void
403 emit_typedef(definition * def)
404 {
405     char *prefix = def->def.ty.old_prefix;
406     char *type = def->def.ty.old_type;
407     char *amax = def->def.ty.array_max;
408     relation rel = def->def.ty.rel;
409
410     print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
411 }
412
413
414
415
416
417 static void
418 print_stat(declaration * dec)
419 {
420     char *prefix = dec->prefix;
421     char *type = dec->type;
422     char *amax = dec->array_max;
423     relation rel = dec->rel;
424     char name[256];
425
426     if (isvectordef(type, rel)) {
427         s_print(name, "objp->%s", dec->name);
428     } else {
429         s_print(name, "&objp->%s", dec->name);
430     }
431     print_ifstat(1, prefix, type, rel, amax, name, dec->name);
432 }
433
434 static void
435 print_hout(declaration * dec)
436 {
437     char prefix[8];
438
439     if (hflag) {
440         if (dec->prefix)
441             s_print(prefix, "%s ", dec->prefix);
442         else
443             prefix[0] = 0;
444         f_print(fout, "\ntypedef ");
445         switch (dec->rel) {
446         case REL_ARRAY:
447             f_print(fout, "struct %s {\n", dec->name);
448             if (brief_flag) {
449                 f_print(fout, "\tu_int %s_len;\n", dec->name);
450                 f_print(fout, "\t%s%s *%s_val;\n", prefix,
451                         dec->type, dec->name);
452             } else {
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             }
457             f_print(fout, "} %s", dec->name);
458             break;
459         default:
460             break;
461         }
462         f_print(fout, ";\n");
463         f_print(fout, "bool_t xdr_%s(XDR *xdrs, %s *objp);\n", dec->name,
464                 dec->name);
465     }
466 }
467
468
469 static void
470 print_cout(declaration * dec)
471 {
472     if (cflag) {
473         space();
474         f_print(fout, "bool_t\n");
475         f_print(fout, "xdr_%s(XDR *xdrs, %s *objp)\n", dec->name, dec->name);
476         f_print(fout, "{\n");
477         print_ifstat(1, dec->prefix, dec->type, dec->rel, dec->array_max,
478                      "objp", dec->name);
479         print_trailer();
480     }
481 }
482
483
484 static void
485 print_rxifopen(char *typename)
486 {
487     sprintf(Proc_list->code, "xdr_%s(&z_xdrs", typename);
488     sprintf(Proc_list->scode, "xdr_%s(z_xdrs", typename);
489 }
490
491
492 static void
493 print_rxifarg(char *amp, char *arg, int costant)
494 {
495     char code[100], scode[100];
496
497     sprintf(code, ", %s%s", amp, arg);
498     if (costant)
499         sprintf(scode, ", %s", arg);
500     else
501         sprintf(scode, ", &%s", arg);
502     strcat(Proc_list->code, code);
503     strcat(Proc_list->scode, scode);
504 }
505
506
507 static void
508 print_rxifsizeof(char *prefix, char *type)
509 {
510     char name[256];
511
512     if (streq(type, "bool")) {
513         strcat(Proc_list->code, ", sizeof(bool_t), xdr_bool");
514         strcat(Proc_list->scode, ", sizeof(bool_t), xdr_bool");
515     } else {
516         strcat(Proc_list->code, ", sizeof(");
517         strcat(Proc_list->scode, ", sizeof(");
518         if (undefined(type) && prefix) {
519             sprintf(name, "%s ", prefix);
520             strcat(Proc_list->code, name);
521             strcat(Proc_list->scode, name);
522         }
523         sprintf(name, "%s), xdr_%s", type, type);
524         strcat(Proc_list->code, name);
525         strcat(Proc_list->scode, name);
526     }
527 }
528
529
530 void
531 print_param(declaration * dec)
532 {
533     char *prefix = dec->prefix;
534     char *type = dec->type;
535     char *amax = dec->array_max;
536     relation rel = dec->rel;
537     char *name = dec->name;
538     char *alt = NULL;
539     char temp[256];
540     char *objname, *amp = "";
541
542     if (rel == REL_POINTER)
543         Proc_list->pl.param_flag |= INDIRECT_PARAM;
544     else {
545         amp = "&";
546         Proc_list->pl.param_flag &= ~INDIRECT_PARAM;
547     }
548     objname = Proc_list->pl.param_name;
549     switch (rel) {
550     case REL_POINTER:
551         print_rxifopen(type);
552         print_rxifarg(amp, objname, 0);
553 /*
554                 print_rxifopen("pointer");
555                 print_rxifarg(amp, "(char **)", 1);
556                 sprintf(temp, "%s", objname);
557                 strcat(Proc_list->code, temp);
558                 strcat(Proc_list->scode, temp);
559                 print_rxifsizeof(prefix, type);
560 */
561         break;
562     case REL_VECTOR:
563         if (streq(type, "string")) {
564             alt = "string";
565         } else if (streq(type, "opaque")) {
566             alt = "opaque";
567         }
568         if (alt)
569             print_rxifopen(alt);
570         else
571             print_rxifopen("vector");
572
573         print_rxifarg(amp, "(char *)", 0);
574         sprintf(temp, "%s", objname);
575         strcat(Proc_list->code, temp);
576         strcat(Proc_list->scode, temp);
577         print_rxifarg("", amax, 1);
578         if (!alt) {
579             print_rxifsizeof(prefix, type);
580         }
581         break;
582     case REL_ARRAY:
583         if (streq(type, "string")) {
584             alt = "string";
585         } else if (streq(type, "opaque")) {
586             alt = "bytes";
587         }
588         if (streq(type, "string")) {
589             print_rxifopen(alt);
590             if ((Proc_list->pl.param_kind == DEF_OUTPARAM)
591                 || (Proc_list->pl.param_kind == DEF_INOUTPARAM)) {
592                 Proc_list->pl.param_flag |= OUT_STRING;
593                 print_rxifarg("", objname, 0);
594             } else
595                 print_rxifarg("(char **) &", objname, 0);
596 /*                      print_rxifarg(amp, objname, 0); */
597             print_rxifarg("", amax, 1);
598             if (!alt) {
599                 print_rxifsizeof(prefix, type);
600             }
601         } else {
602             char typecontents[100];
603
604             print_hout(dec);
605             print_cout(dec);
606             strcpy(temp, dec->name);
607             strcpy(typecontents, dec->name);
608             strcat(typecontents, " *");
609             strcpy(Proc_list->pl.param_type, typecontents);
610             sprintf(typecontents, "%s_%d", Proc_list->pl.param_name,
611                     ++PerProcCounter);
612             strcpy(Proc_list->pl.param_name, typecontents);
613             Proc_list->pl.param_flag |= FREETHIS_PARAM;
614             print_rxifopen(temp);
615             print_rxifarg(amp, name, 0);
616         }
617 /*
618                         if (alt) {
619                                 print_rxifopen(alt);
620                         } else {
621                                 print_rxifopen("array");
622                         }
623                         print_rxifarg(amp, "(char **)", 1);
624                         if (*objname == '&') {
625                                 sprintf(temp, "%s.%s_val, (u_int *)%s.%s_len",
626                                         objname, name, objname, name);
627                         } else {
628                                 sprintf(temp, "&%s->%s_val, (u_int *)&%s->%s_len",
629                                         objname, name, objname, name);
630                         }
631                         strcat(Proc_list->code, temp);
632                         strcat(Proc_list->scode, temp);
633                 }
634                 print_rxifarg("", amax, 1);
635                 if (!alt) {
636                         print_rxifsizeof(prefix, type);
637                 }
638 */
639         break;
640     case REL_ALIAS:
641         print_rxifopen(type);
642         print_rxifarg(amp, objname, 0);
643         break;
644     }
645     strcat(Proc_list->code, ")");
646     strcat(Proc_list->scode, ")");
647 }