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