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