30ec519e15fd4e96c99b59774a93f7de867aaf8c
[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         }
279         if (streq(type, "string")) {
280             print_ifopen(indent, alt);
281             print_ifarg(objname);
282         } else {
283             if (alt) {
284                 print_ifopen(indent, alt);
285                 print_ifarg("(char **)");
286             } else {
287                 print_ifopen(indent, "array");
288                 print_ifarg("(caddr_t *)");
289             }
290             print_ifarg_val(objname, name);
291             f_print(fout, ", ");
292             print_ifarg_len(objname, name);
293         }
294         print_ifarg(amax);
295         if (!alt) {
296             print_ifsizeof(prefix, type);
297         }
298         break;
299     case REL_ALIAS:
300         print_ifopen(indent, type);
301         print_ifarg(objname);
302         break;
303     }
304     print_ifclose(indent);
305 }
306
307
308 static void
309 emit_enum(definition * def)
310 {
311     print_ifopen(1, "enum");
312     print_ifarg("(enum_t *)objp");
313     print_ifclose(1);
314 }
315
316
317 static void
318 emit_union(definition * def)
319 {
320     declaration *dflt;
321     case_list *cl;
322     declaration *cs;
323     char *object;
324     char *format = "&objp->%s_u.%s";
325     char *briefformat = "&objp->u.%s";
326
327     print_stat(&def->def.un.enum_decl);
328     f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
329     for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
330         cs = &cl->case_decl;
331         f_print(fout, "\tcase %s:\n", cl->case_name);
332         if (!streq(cs->type, "void")) {
333             object =
334                 alloc(strlen(def->def_name) + strlen(format) +
335                       strlen(cs->name) + 1);
336
337             if (brief_flag)
338                 s_print(object, briefformat, cs->name);
339             else
340                 s_print(object, format, def->def_name, cs->name);
341
342             print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
343                          object, cs->name);
344             free(object);
345         }
346         f_print(fout, "\t\tbreak;\n");
347     }
348     dflt = def->def.un.default_decl;
349     if (dflt != NULL) {
350         if (!streq(dflt->type, "void")) {
351             f_print(fout, "\tdefault:\n");
352             object =
353                 alloc(strlen(def->def_name) + strlen(format) +
354                       strlen(dflt->name) + 1);
355             s_print(object, format, def->def_name, dflt->name);
356             print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
357                          dflt->array_max, object, dflt->name);
358             free(object);
359             f_print(fout, "\t\tbreak;\n");
360         }
361     } else {
362         f_print(fout, "\tdefault:\n");
363         f_print(fout, "\t\treturn (FALSE);\n");
364     }
365     f_print(fout, "\t}\n");
366 }
367
368
369
370 static void
371 emit_struct(definition * def)
372 {
373     decl_list *dl;
374
375     for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {
376         print_stat(&dl->decl);
377     }
378 }
379
380
381
382
383 static void
384 emit_typedef(definition * def)
385 {
386     char *prefix = def->def.ty.old_prefix;
387     char *type = def->def.ty.old_type;
388     char *amax = def->def.ty.array_max;
389     relation rel = def->def.ty.rel;
390
391     print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
392 }
393
394
395
396
397
398 static void
399 print_stat(declaration * dec)
400 {
401     char *prefix = dec->prefix;
402     char *type = dec->type;
403     char *amax = dec->array_max;
404     relation rel = dec->rel;
405     char name[256];
406
407     if (isvectordef(type, rel)) {
408         s_print(name, "objp->%s", dec->name);
409     } else {
410         s_print(name, "&objp->%s", dec->name);
411     }
412     print_ifstat(1, prefix, type, rel, amax, name, dec->name);
413 }
414
415 static void
416 print_hout(declaration * dec)
417 {
418     char prefix[8];
419
420     if (hflag) {
421         if (dec->prefix)
422             s_print(prefix, "%s ", dec->prefix);
423         else
424             prefix[0] = 0;
425         f_print(fout, "\ntypedef ");
426         switch (dec->rel) {
427         case REL_ARRAY:
428             f_print(fout, "struct %s {\n", dec->name);
429             if (brief_flag) {
430                 f_print(fout, "\tu_int %s_len;\n", dec->name);
431                 f_print(fout, "\t%s%s *%s_val;\n", prefix,
432                         dec->type, dec->name);
433             } else {
434                 f_print(fout, "\tu_int %s_len;\n", dec->name);
435                 f_print(fout, "\t%s%s *%s_val;\n", prefix,
436                         dec->type, dec->name);
437             }
438             f_print(fout, "} %s", dec->name);
439             break;
440         default:
441             break;
442         }
443         f_print(fout, ";\n");
444         f_print(fout, "bool_t xdr_%s(XDR *xdrs, %s *objp);\n", dec->name,
445                 dec->name);
446     }
447 }
448
449
450 static void
451 print_cout(declaration * dec)
452 {
453     if (cflag) {
454         space();
455         f_print(fout, "bool_t\n");
456         f_print(fout, "xdr_%s(XDR *xdrs, %s *objp)\n", dec->name, dec->name);
457         f_print(fout, "{\n");
458         print_ifstat(1, dec->prefix, dec->type, dec->rel, dec->array_max,
459                      "objp", dec->name);
460         print_trailer();
461     }
462 }
463
464
465 static void
466 print_rxifopen(char *typename)
467 {
468     sprintf(Proc_list->code, "xdr_%s(&z_xdrs", typename);
469     sprintf(Proc_list->scode, "xdr_%s(z_xdrs", typename);
470 }
471
472
473 static void
474 print_rxifarg(char *amp, char *arg, int costant)
475 {
476     char code[100], scode[100];
477
478     sprintf(code, ", %s%s", amp, arg);
479     if (costant)
480         sprintf(scode, ", %s", arg);
481     else
482         sprintf(scode, ", &%s", arg);
483     strcat(Proc_list->code, code);
484     strcat(Proc_list->scode, scode);
485 }
486
487
488 static void
489 print_rxifsizeof(char *prefix, char *type)
490 {
491     char name[256];
492
493     if (streq(type, "bool")) {
494         strcat(Proc_list->code, ", sizeof(bool_t), xdr_bool");
495         strcat(Proc_list->scode, ", sizeof(bool_t), xdr_bool");
496     } else {
497         strcat(Proc_list->code, ", sizeof(");
498         strcat(Proc_list->scode, ", sizeof(");
499         if (undefined(type) && prefix) {
500             sprintf(name, "%s ", prefix);
501             strcat(Proc_list->code, name);
502             strcat(Proc_list->scode, name);
503         }
504         sprintf(name, "%s), xdr_%s", type, type);
505         strcat(Proc_list->code, name);
506         strcat(Proc_list->scode, name);
507     }
508 }
509
510
511 void
512 print_param(declaration * dec)
513 {
514     char *prefix = dec->prefix;
515     char *type = dec->type;
516     char *amax = dec->array_max;
517     relation rel = dec->rel;
518     char *name = dec->name;
519     char *alt = NULL;
520     char temp[256];
521     char *objname, *amp = "";
522
523     if (rel == REL_POINTER)
524         Proc_list->pl.param_flag |= INDIRECT_PARAM;
525     else {
526         amp = "&";
527         Proc_list->pl.param_flag &= ~INDIRECT_PARAM;
528     }
529     objname = Proc_list->pl.param_name;
530     switch (rel) {
531     case REL_POINTER:
532         print_rxifopen(type);
533         print_rxifarg(amp, objname, 0);
534 /*
535                 print_rxifopen("pointer");
536                 print_rxifarg(amp, "(char **)", 1);
537                 sprintf(temp, "%s", objname);
538                 strcat(Proc_list->code, temp);
539                 strcat(Proc_list->scode, temp);
540                 print_rxifsizeof(prefix, type);
541 */
542         break;
543     case REL_VECTOR:
544         if (streq(type, "string")) {
545             alt = "string";
546         } else if (streq(type, "opaque")) {
547             alt = "opaque";
548         }
549         if (alt)
550             print_rxifopen(alt);
551         else
552             print_rxifopen("vector");
553
554         print_rxifarg(amp, "(char *)", 0);
555         sprintf(temp, "%s", objname);
556         strcat(Proc_list->code, temp);
557         strcat(Proc_list->scode, temp);
558         print_rxifarg("", amax, 1);
559         if (!alt) {
560             print_rxifsizeof(prefix, type);
561         }
562         break;
563     case REL_ARRAY:
564         if (streq(type, "string")) {
565             alt = "string";
566         } else if (streq(type, "opaque")) {
567             alt = "bytes";
568         }
569         if (streq(type, "string")) {
570             print_rxifopen(alt);
571             if ((Proc_list->pl.param_kind == DEF_OUTPARAM)
572                 || (Proc_list->pl.param_kind == DEF_INOUTPARAM)) {
573                 Proc_list->pl.param_flag |= OUT_STRING;
574                 print_rxifarg("", objname, 0);
575             } else
576                 print_rxifarg("(char **) &", objname, 0);
577 /*                      print_rxifarg(amp, objname, 0); */
578             print_rxifarg("", amax, 1);
579             if (!alt) {
580                 print_rxifsizeof(prefix, type);
581             }
582         } else {
583             char typecontents[100];
584
585             print_hout(dec);
586             print_cout(dec);
587             strcpy(temp, dec->name);
588             strcpy(typecontents, dec->name);
589             strcat(typecontents, " *");
590             strcpy(Proc_list->pl.param_type, typecontents);
591             sprintf(typecontents, "%s_%d", Proc_list->pl.param_name,
592                     ++PerProcCounter);
593             strcpy(Proc_list->pl.param_name, typecontents);
594             Proc_list->pl.param_flag |= FREETHIS_PARAM;
595             print_rxifopen(temp);
596             print_rxifarg(amp, name, 0);
597         }
598 /*
599                         if (alt) {
600                                 print_rxifopen(alt);
601                         } else {
602                                 print_rxifopen("array");
603                         }
604                         print_rxifarg(amp, "(char **)", 1);
605                         if (*objname == '&') {
606                                 sprintf(temp, "%s.%s_val, (u_int *)%s.%s_len",
607                                         objname, name, objname, name);
608                         } else {
609                                 sprintf(temp, "&%s->%s_val, (u_int *)&%s->%s_len",
610                                         objname, name, objname, name);
611                         }
612                         strcat(Proc_list->code, temp);
613                         strcat(Proc_list->scode, temp);
614                 }
615                 print_rxifarg("", amax, 1);
616                 if (!alt) {
617                         print_rxifsizeof(prefix, type);
618                 }
619 */
620         break;
621     case REL_ALIAS:
622         print_rxifopen(type);
623         print_rxifarg(amp, objname, 0);
624         break;
625     }
626     strcat(Proc_list->code, ")");
627     strcat(Proc_list->scode, ")");
628 }