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