38bd0b4e737f7ffd67d3d251a316ddf71c224925
[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
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42 #include "rpc_scan.h"
43 #include "rpc_parse.h"
44 #include "rpc_util.h"
45
46 /* Static prototypes */
47 static int findtype(definition * def, char *type);
48 static int undefined(char *type);
49 static void print_header(definition * def);
50 static void print_trailer(void);
51 static void print_ifopen(int indent, char *name);
52 static void print_ifarg(char *arg);
53 static void print_ifsizeof(char *prefix, char *type);
54 static void print_ifclose(int indent);
55 static void space(void);
56 static void print_ifstat(int indent, char *prefix, char *type, relation rel,
57                          char *amax, char *objname, char *name);
58 static void emit_enum(definition * def);
59 static void emit_union(definition * def);
60 static void emit_struct(definition * def);
61 static void emit_typedef(definition * def);
62 static void print_stat(declaration * dec);
63 static void print_hout(declaration * dec);
64 static void print_cout(declaration * dec);
65 static void print_rxifopen(char *typename);
66 static void print_rxifarg(char *amp, char *arg, int costant);
67 static void print_rxifsizeof(char *prefix, char *type);
68
69
70 /*
71  * Emit the C-routine for the given definition 
72  */
73 void
74 emit(definition * def)
75 {
76     if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
77         return;
78     }
79     print_header(def);
80     switch (def->def_kind) {
81     case DEF_UNION:
82         emit_union(def);
83         break;
84     case DEF_ENUM:
85         emit_enum(def);
86         break;
87     case DEF_STRUCT:
88         emit_struct(def);
89         break;
90     case DEF_TYPEDEF:
91         emit_typedef(def);
92         break;
93     default:
94         break;
95     }
96     print_trailer();
97 }
98
99 static int
100 findtype(definition * def, char *type)
101 {
102     if (def->def_kind == DEF_PROGRAM || def->def_kind == DEF_CONST) {
103         return (0);
104     } else {
105         return (streq(def->def_name, type));
106     }
107 }
108
109 static int
110 undefined(char *type)
111 {
112     definition *def;
113
114     def = (definition *) FINDVAL(defined, type, findtype);
115     return (def == NULL);
116 }
117
118
119 static void
120 print_header(definition * def)
121 {
122     space();
123     f_print(fout, "bool_t\n");
124     f_print(fout, "xdr_%s(XDR *xdrs, ", def->def_name);
125     f_print(fout, "%s ", def->def_name);
126 #if 0
127     if (def->def_kind != DEF_TYPEDEF
128         || !isvectordef(def->def.ty.old_type, def->def.ty.rel)) {
129         f_print(fout, "*");
130     }
131 #else
132     f_print(fout, "*");
133 #endif
134     f_print(fout, "objp)\n");
135     f_print(fout, "{\n");
136 }
137
138 static void
139 print_trailer(void)
140 {
141     f_print(fout, "\treturn (TRUE);\n");
142     f_print(fout, "}\n");
143     space();
144 }
145
146
147 static void
148 print_ifopen(int indent, char *name)
149 {
150     tabify(fout, indent);
151     f_print(fout, "if (!xdr_%s(xdrs", name);
152 }
153
154
155 static void
156 print_ifarg(char *arg)
157 {
158     f_print(fout, ", %s", arg);
159 }
160
161
162 static void
163 print_ifsizeof(char *prefix, char *type)
164 {
165     if (streq(type, "bool")) {
166         f_print(fout, ", sizeof(bool_t), (xdrproc_t) xdr_bool");
167     } else {
168         f_print(fout, ", sizeof(");
169         if (undefined(type) && prefix) {
170             f_print(fout, "%s ", prefix);
171         }
172         f_print(fout, "%s), (xdrproc_t) xdr_%s", type, type);
173     }
174 }
175
176 static void
177 print_ifclose(int indent)
178 {
179     f_print(fout, ")) {\n");
180     tabify(fout, indent);
181     f_print(fout, "\treturn (FALSE);\n");
182     tabify(fout, indent);
183     f_print(fout, "}\n");
184 }
185
186 static void
187 space(void)
188 {
189     f_print(fout, "\n\n");
190 }
191
192 static void
193 print_ifstat(int indent, char *prefix, char *type, relation rel, char *amax,
194              char *objname, char *name)
195 {
196     char *alt = NULL;
197
198     switch (rel) {
199     case REL_POINTER:
200         print_ifopen(indent, "pointer");
201         print_ifarg("(char **)");
202         f_print(fout, "%s", objname);
203         print_ifsizeof(prefix, type);
204         break;
205     case REL_VECTOR:
206         if (streq(type, "string")) {
207             alt = "string";
208         } else if (streq(type, "opaque")) {
209             alt = "opaque";
210         }
211         if (alt) {
212             print_ifopen(indent, alt);
213             print_ifarg(objname);
214         } else {
215             print_ifopen(indent, "vector");
216             print_ifarg("(char *)");
217             f_print(fout, "%s", objname);
218         }
219         print_ifarg(amax);
220         if (!alt) {
221             print_ifsizeof(prefix, type);
222         }
223         break;
224     case REL_ARRAY:
225         if (streq(type, "string")) {
226             alt = "string";
227         } else if (streq(type, "opaque")) {
228             alt = "bytes";
229         }
230         if (streq(type, "string")) {
231             print_ifopen(indent, alt);
232             print_ifarg(objname);
233         } else {
234             if (alt) {
235                 print_ifopen(indent, alt);
236             } else {
237                 print_ifopen(indent, "array");
238             }
239             print_ifarg("(char **)");
240             if (*objname == '&') {
241                 f_print(fout, "%s.%s_val, (u_int *)%s.%s_len", objname, name,
242                         objname, name);
243             } else {
244                 f_print(fout, "&%s->%s_val, (u_int *)&%s->%s_len", objname,
245                         name, objname, name);
246             }
247         }
248         print_ifarg(amax);
249         if (!alt) {
250             print_ifsizeof(prefix, type);
251         }
252         break;
253     case REL_ALIAS:
254         print_ifopen(indent, type);
255         print_ifarg(objname);
256         break;
257     }
258     print_ifclose(indent);
259 }
260
261
262 static void
263 emit_enum(definition * def)
264 {
265     print_ifopen(1, "enum");
266     print_ifarg("(enum_t *)objp");
267     print_ifclose(1);
268 }
269
270
271 static void
272 emit_union(definition * def)
273 {
274     declaration *dflt;
275     case_list *cl;
276     declaration *cs;
277     char *object;
278     char *format = "&objp->%s_u.%s";
279
280     print_stat(&def->def.un.enum_decl);
281     f_print(fout, "\tswitch (objp->%s) {\n", def->def.un.enum_decl.name);
282     for (cl = def->def.un.cases; cl != NULL; cl = cl->next) {
283         cs = &cl->case_decl;
284         f_print(fout, "\tcase %s:\n", cl->case_name);
285         if (!streq(cs->type, "void")) {
286             object =
287                 alloc(strlen(def->def_name) + strlen(format) +
288                       strlen(cs->name) + 1);
289             s_print(object, format, def->def_name, cs->name);
290             print_ifstat(2, cs->prefix, cs->type, cs->rel, cs->array_max,
291                          object, cs->name);
292             free(object);
293         }
294         f_print(fout, "\t\tbreak;\n");
295     }
296     dflt = def->def.un.default_decl;
297     if (dflt != NULL) {
298         if (!streq(dflt->type, "void")) {
299             f_print(fout, "\tdefault:\n");
300             object =
301                 alloc(strlen(def->def_name) + strlen(format) +
302                       strlen(dflt->name) + 1);
303             s_print(object, format, def->def_name, dflt->name);
304             print_ifstat(2, dflt->prefix, dflt->type, dflt->rel,
305                          dflt->array_max, object, dflt->name);
306             free(object);
307             f_print(fout, "\t\tbreak;\n");
308         }
309     } else {
310         f_print(fout, "\tdefault:\n");
311         f_print(fout, "\t\treturn (FALSE);\n");
312     }
313     f_print(fout, "\t}\n");
314 }
315
316
317
318 static void
319 emit_struct(definition * def)
320 {
321     decl_list *dl;
322
323     for (dl = def->def.st.decls; dl != NULL; dl = dl->next) {
324         print_stat(&dl->decl);
325     }
326 }
327
328
329
330
331 static void
332 emit_typedef(definition * def)
333 {
334     char *prefix = def->def.ty.old_prefix;
335     char *type = def->def.ty.old_type;
336     char *amax = def->def.ty.array_max;
337     relation rel = def->def.ty.rel;
338
339     print_ifstat(1, prefix, type, rel, amax, "objp", def->def_name);
340 }
341
342
343
344
345
346 static void
347 print_stat(declaration * dec)
348 {
349     char *prefix = dec->prefix;
350     char *type = dec->type;
351     char *amax = dec->array_max;
352     relation rel = dec->rel;
353     char name[256];
354
355     if (isvectordef(type, rel)) {
356         s_print(name, "objp->%s", dec->name);
357     } else {
358         s_print(name, "&objp->%s", dec->name);
359     }
360     print_ifstat(1, prefix, type, rel, amax, name, dec->name);
361 }
362
363 static void
364 print_hout(declaration * dec)
365 {
366     char prefix[8];
367
368     if (hflag) {
369         if (dec->prefix)
370             s_print(prefix, "%s ", dec->prefix);
371         else
372             prefix[0] = 0;
373         f_print(fout, "\ntypedef ");
374         switch (dec->rel) {
375         case REL_ARRAY:
376             f_print(fout, "struct %s {\n", dec->name);
377             f_print(fout, "\tu_int %s_len;\n", dec->name);
378             f_print(fout, "\t%s%s *%s_val;\n", prefix, dec->type, dec->name);
379             f_print(fout, "} %s", dec->name);
380             break;
381         default:
382             break;
383         }
384         f_print(fout, ";\n");
385         f_print(fout, "bool_t xdr_%s(XDR *xdrs, %s *objp);\n", dec->name,
386                 dec->name);
387     }
388 }
389
390
391 static void
392 print_cout(declaration * dec)
393 {
394     if (cflag) {
395         space();
396         f_print(fout, "bool_t\n");
397         f_print(fout, "xdr_%s(XDR *xdrs, %s *objp)\n", dec->name, dec->name);
398         f_print(fout, "{\n");
399         print_ifstat(1, dec->prefix, dec->type, dec->rel, dec->array_max,
400                      "objp", dec->name);
401         print_trailer();
402     }
403 }
404
405
406 static void
407 print_rxifopen(char *typename)
408 {
409     sprintf(Proc_list->code, "xdr_%s(&z_xdrs", typename);
410     sprintf(Proc_list->scode, "xdr_%s(z_xdrs", typename);
411 }
412
413
414 static void
415 print_rxifarg(char *amp, char *arg, int costant)
416 {
417     char code[100], scode[100];
418
419     sprintf(code, ", %s%s", amp, arg);
420     if (costant)
421         sprintf(scode, ", %s", arg);
422     else
423         sprintf(scode, ", &%s", arg);
424     strcat(Proc_list->code, code);
425     strcat(Proc_list->scode, scode);
426 }
427
428
429 static void
430 print_rxifsizeof(char *prefix, char *type)
431 {
432     char name[256];
433
434     if (streq(type, "bool")) {
435         strcat(Proc_list->code, ", sizeof(bool_t), xdr_bool");
436         strcat(Proc_list->scode, ", sizeof(bool_t), xdr_bool");
437     } else {
438         strcat(Proc_list->code, ", sizeof(");
439         strcat(Proc_list->scode, ", sizeof(");
440         if (undefined(type) && prefix) {
441             sprintf(name, "%s ", prefix);
442             strcat(Proc_list->code, name);
443             strcat(Proc_list->scode, name);
444         }
445         sprintf(name, "%s), xdr_%s", type, type);
446         strcat(Proc_list->code, name);
447         strcat(Proc_list->scode, name);
448     }
449 }
450
451
452 void
453 print_param(declaration * dec)
454 {
455     char *prefix = dec->prefix;
456     char *type = dec->type;
457     char *amax = dec->array_max;
458     relation rel = dec->rel;
459     char *name = dec->name;
460     char *alt = NULL;
461     char temp[256];
462     char *objname, *amp = "";
463
464     if (rel == REL_POINTER)
465         Proc_list->pl.param_flag |= INDIRECT_PARAM;
466     else {
467         amp = "&";
468         Proc_list->pl.param_flag &= ~INDIRECT_PARAM;
469     }
470     objname = Proc_list->pl.param_name;
471     switch (rel) {
472     case REL_POINTER:
473         print_rxifopen(type);
474         print_rxifarg(amp, objname, 0);
475 /*
476                 print_rxifopen("pointer");
477                 print_rxifarg(amp, "(char **)", 1);
478                 sprintf(temp, "%s", objname);
479                 strcat(Proc_list->code, temp);
480                 strcat(Proc_list->scode, temp);
481                 print_rxifsizeof(prefix, type);
482 */
483         break;
484     case REL_VECTOR:
485         if (streq(type, "string")) {
486             alt = "string";
487         } else if (streq(type, "opaque")) {
488             alt = "opaque";
489         }
490         if (alt) {
491             print_rxifopen(alt);
492             print_rxifarg(amp, objname, 0);
493         } else {
494             print_rxifopen("vector");
495             print_rxifarg(amp, "(char *)", 0);
496             sprintf(temp, "%s", objname);
497             strcat(Proc_list->code, temp);
498             strcat(Proc_list->scode, temp);
499         }
500         print_rxifarg("", amax, 1);
501         if (!alt) {
502             print_rxifsizeof(prefix, type);
503         }
504         break;
505     case REL_ARRAY:
506         if (streq(type, "string")) {
507             alt = "string";
508         } else if (streq(type, "opaque")) {
509             alt = "bytes";
510         }
511         if (streq(type, "string")) {
512             print_rxifopen(alt);
513             if ((Proc_list->pl.param_kind == DEF_OUTPARAM)
514                 || (Proc_list->pl.param_kind == DEF_INOUTPARAM)) {
515                 Proc_list->pl.param_flag |= OUT_STRING;
516                 print_rxifarg("", objname, 0);
517             } else
518                 print_rxifarg("&", objname, 0);
519 /*                      print_rxifarg(amp, objname, 0); */
520             print_rxifarg("", amax, 1);
521             if (!alt) {
522                 print_rxifsizeof(prefix, type);
523             }
524         } else {
525             char typecontents[100];
526
527             print_hout(dec);
528             print_cout(dec);
529             strcpy(temp, dec->name);
530             strcpy(typecontents, dec->name);
531             strcat(typecontents, " *");
532             strcpy(Proc_list->pl.param_type, typecontents);
533             sprintf(typecontents, "%s_%d", Proc_list->pl.param_name,
534                     ++PerProcCounter);
535             strcpy(Proc_list->pl.param_name, typecontents);
536             Proc_list->pl.param_flag |= FREETHIS_PARAM;
537             print_rxifopen(temp);
538             print_rxifarg(amp, name, 0);
539         }
540 /*
541                         if (alt) {
542                                 print_rxifopen(alt);
543                         } else {
544                                 print_rxifopen("array");
545                         }
546                         print_rxifarg(amp, "(char **)", 1);
547                         if (*objname == '&') {
548                                 sprintf(temp, "%s.%s_val, (u_int *)%s.%s_len",
549                                         objname, name, objname, name);
550                         } else {
551                                 sprintf(temp, "&%s->%s_val, (u_int *)&%s->%s_len",
552                                         objname, name, objname, name);
553                         }
554                         strcat(Proc_list->code, temp);
555                         strcat(Proc_list->scode, temp);
556                 }
557                 print_rxifarg("", amax, 1);
558                 if (!alt) {
559                         print_rxifsizeof(prefix, type);
560                 }
561 */
562         break;
563     case REL_ALIAS:
564         print_rxifopen(type);
565         print_rxifarg(amp, objname, 0);
566         break;
567     }
568     strcat(Proc_list->code, ")");
569     strcat(Proc_list->scode, ")");
570 }