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