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