ac73b2c03565039f6e48039c24d392f00d01679a
[openafs.git] / src / rxgen / rpc_hout.c
1 /* @(#)rpc_hout.c       1.2 87/11/30 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_hout.c, Header file 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 <string.h>
41 #include <ctype.h>
42
43 #ifdef HAVE_STDLIB_H
44 #include <stdlib.h>
45 #endif
46 #ifdef HAVE_UNISTD_H
47 #include <unistd.h>
48 #endif
49
50 #include "rpc_scan.h"
51 #include "rpc_parse.h"
52 #include "rpc_util.h"
53
54 /* Static declarations */
55 static void pconstdef(definition * def);
56 static void pstructdef(definition * def);
57 static void puniondef(definition * def);
58 static void puldefine(char *name, char *num);
59 static int define_printed(proc_list * stop, version_list * start);
60 static void pprogramdef(definition * def);
61 static void psproc1(definition * defp, int callTconnF, char *type,
62                     char *prefix, int iomask);
63 static void psprocdef(definition * defp);
64 static void penumdef(definition * def);
65 static void ptypedef(definition * def);
66 static void pdeclaration(char *name, declaration * dec, int tab);
67 static int undefined2(char *type, char *stop);
68
69 /*
70  * Print the C-version of an xdr definition
71  */
72 void
73 print_datadef(definition * def)
74 {
75     if (Sflag)
76         scan_print = 0;
77     if ((def->def_kind != DEF_CONST) && (!IsRxgenDefinition(def))) {
78         f_print(fout, "\n");
79     }
80     switch (def->def_kind) {
81     case DEF_CUSTOMIZED:
82     case DEF_STRUCT:
83         pstructdef(def);
84         break;
85     case DEF_UNION:
86         puniondef(def);
87         break;
88     case DEF_ENUM:
89         penumdef(def);
90         break;
91     case DEF_TYPEDEF:
92         ptypedef(def);
93         break;
94     case DEF_PROGRAM:
95         pprogramdef(def);
96         break;
97     case DEF_PROC:
98         psprocdef(def);
99         break;
100     case DEF_CONST:
101         pconstdef(def);
102         break;
103     default:
104         break;
105     }
106     if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST
107         && (!IsRxgenDefinition(def))) {
108         f_print(fout, "bool_t xdr_%s(XDR *xdrs, %s *objp);\n", def->def_name,
109                 def->def_name);
110     }
111     if (def->def_kind != DEF_CONST && (!IsRxgenDefinition(def))) {
112         f_print(fout, "\n");
113     }
114     if (Sflag)
115         scan_print = 1;
116 }
117
118 static void
119 pconstdef(definition * def)
120 {
121     pdefine(def->def_name, def->def.co);
122 }
123
124 static void
125 pstructdef(definition * def)
126 {
127     decl_list *l;
128     char *name = def->def_name;
129
130     f_print(fout, "struct %s {\n", name);
131     for (l = def->def.st.decls; l != NULL; l = l->next) {
132         pdeclaration(name, &l->decl, 1);
133     }
134     f_print(fout, "};\n");
135     f_print(fout, "typedef struct %s %s;\n", name, name);
136 }
137
138 static void
139 puniondef(definition * def)
140 {
141     case_list *l;
142     char *name = def->def_name;
143     declaration *decl;
144
145     f_print(fout, "struct %s {\n", name);
146     decl = &def->def.un.enum_decl;
147     if (streq(decl->type, "bool")) {
148         f_print(fout, "\tbool_t %s;\n", decl->name);
149     } else {
150         f_print(fout, "\t%s %s;\n", decl->type, decl->name);
151     }
152     f_print(fout, "\tunion {\n");
153     for (l = def->def.un.cases; l != NULL; l = l->next) {
154         pdeclaration(name, &l->case_decl, 2);
155     }
156     decl = def->def.un.default_decl;
157     if (decl && !streq(decl->type, "void")) {
158         pdeclaration(name, decl, 2);
159     }
160     if (brief_flag) {
161         f_print(fout, "\t} u;\n");
162     } else {
163         f_print(fout, "\t} %s_u;\n", name);
164     }
165     f_print(fout, "};\n");
166     f_print(fout, "typedef struct %s %s;\n", name, name);
167     STOREVAL(&uniondef_defined, def);
168 }
169
170
171 void
172 pdefine(char *name, char *num)
173 {
174     f_print(fout, "#define %s %s\n", name, num);
175 }
176
177 static void
178 puldefine(char *name, char *num)
179 {
180     f_print(fout, "#define %s ((afs_uint32)%s)\n", name, num);
181 }
182
183 static int
184 define_printed(proc_list * stop, version_list * start)
185 {
186     version_list *vers;
187     proc_list *proc;
188
189     for (vers = start; vers != NULL; vers = vers->next) {
190         for (proc = vers->procs; proc != NULL; proc = proc->next) {
191             if (proc == stop) {
192                 return (0);
193             } else if (streq(proc->proc_name, stop->proc_name)) {
194                 return (1);
195             }
196         }
197     }
198     abort();
199     return 0;/* NOTREACHED */
200 }
201
202
203 static void
204 pprogramdef(definition * def)
205 {
206     version_list *vers;
207     proc_list *proc;
208
209     puldefine(def->def_name, def->def.pr.prog_num);
210     for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
211         puldefine(vers->vers_name, vers->vers_num);
212         for (proc = vers->procs; proc != NULL; proc = proc->next) {
213             if (!define_printed(proc, def->def.pr.versions)) {
214                 puldefine(proc->proc_name, proc->proc_num);
215             }
216             pprocdef(proc, vers);
217         }
218     }
219 }
220
221 static void
222 psproc1(definition * defp, int callTconnF, char *type, char *prefix,
223         int iomask)
224 {
225     proc1_list *plist;
226
227     f_print(fout, "\nextern %s %s%s%s(\n", type, prefix, defp->pc.proc_prefix,
228             defp->pc.proc_name);
229
230     if (callTconnF == 1) {
231         f_print(fout, "\t/*IN */ struct rx_call *z_call");
232     } else if (callTconnF == 2) {
233         f_print(fout, "\tstruct ubik_client *aclient, afs_int32 aflags");
234     } else {
235         f_print(fout, "\t/*IN */ struct rx_connection *z_conn");
236     }
237
238     for (plist = defp->pc.plists; plist; plist = plist->next) {
239         if (plist->component_kind == DEF_PARAM
240             && (iomask & (1 << plist->pl.param_kind))) {
241             switch (plist->pl.param_kind) {
242             case DEF_INPARAM:
243                 f_print(fout, ",\n\t/*IN */ ");
244                 break;
245             case DEF_OUTPARAM:
246                 f_print(fout, ",\n\t/*OUT*/ ");
247                 break;
248             case DEF_INOUTPARAM:
249                 f_print(fout, ",\n\t/*I/O*/ ");
250                 break;
251             default:
252                 break;
253             }
254             if (plist->pl.param_flag & OUT_STRING) {
255                 f_print(fout, "%s *%s", plist->pl.param_type,
256                         plist->pl.param_name);
257             } else {
258                 f_print(fout, "%s %s", plist->pl.param_type,
259                         plist->pl.param_name);
260             }
261         }
262     }
263     f_print(fout, ");\n");
264 }
265
266 static void
267 psprocdef(definition * defp)
268 {
269     int split_flag = defp->pc.split_flag;
270     int multi_flag = defp->pc.multi_flag;
271
272     if (split_flag || multi_flag) {
273         psproc1(defp, 1, "int", "Start",
274                 (1 << DEF_INPARAM) | (1 << DEF_INOUTPARAM));
275         psproc1(defp, 1, "int", "End",
276                 (1 << DEF_OUTPARAM) | (1 << DEF_INOUTPARAM));
277     }
278     if (!(!multi_flag && split_flag))
279         psproc1(defp, 0, "int", "", 0xFFFFFFFF);
280
281     if (uflag && !kflag)
282         psproc1(defp, 2, "int", "ubik_", 0xFFFFFFFF);
283
284     if (*ServerPrefix)
285         psproc1(defp, 1, "afs_int32", ServerPrefix, 0xFFFFFFFF);
286 }
287
288
289 void
290 pprocdef(proc_list * proc, version_list * vp)
291 {
292     f_print(fout, "extern ");
293     if (proc->res_prefix) {
294         if (streq(proc->res_prefix, "enum")) {
295             f_print(fout, "enum ");
296         } else {
297             f_print(fout, "struct ");
298         }
299     }
300     if (streq(proc->res_type, "bool")) {
301         f_print(fout, "bool_t *");
302     } else if (streq(proc->res_type, "string")) {
303         f_print(fout, "char **");
304     } else {
305         f_print(fout, "%s *", fixtype(proc->res_type));
306     }
307     pvname(proc->proc_name, vp->vers_num);
308     f_print(fout, "();\n");
309 }
310
311 static void
312 penumdef(definition * def)
313 {
314     char *name = def->def_name;
315     enumval_list *l;
316     char *last = NULL;
317     int count = 0;
318
319     f_print(fout, "enum %s {\n", name);
320     for (l = def->def.en.vals; l != NULL; l = l->next) {
321         f_print(fout, "\t%s", l->name);
322         if (l->assignment) {
323             f_print(fout, " = %s", l->assignment);
324             last = l->assignment;
325             count = 1;
326         } else {
327             if (last == NULL) {
328                 f_print(fout, " = %d", count++);
329             } else {
330                 f_print(fout, " = %s + %d", last, count++);
331             }
332         }
333         f_print(fout, ",\n");
334     }
335     f_print(fout, "};\n");
336     f_print(fout, "typedef enum %s %s;\n", name, name);
337 }
338
339 static void
340 ptypedef(definition * def)
341 {
342     char *name = def->def_name;
343     char *old = def->def.ty.old_type;
344     char prefix[8];             /* enough to contain "struct ", including NUL */
345     relation rel = def->def.ty.rel;
346
347
348     if (!streq(name, old)) {
349         if (streq(old, "string")) {
350             old = "char";
351             rel = REL_POINTER;
352         } else if (!brief_flag && streq(old, "opaque")) {
353             old = "char";
354         } else if (streq(old, "bool")) {
355             old = "bool_t";
356         }
357         if (undefined2(old, name) && def->def.ty.old_prefix) {
358             s_print(prefix, "%s ", def->def.ty.old_prefix);
359         } else {
360             prefix[0] = 0;
361         }
362         f_print(fout, "typedef ");
363         switch (rel) {
364         case REL_ARRAY:
365             if (brief_flag) {
366                 if (streq(old, "opaque")) {
367                     f_print(fout, "struct rx_opaque %s", name);
368                 } else {
369                     f_print(fout, "struct {\n");
370                     f_print(fout, "\tu_int len;\n");
371                     f_print(fout, "\t%s%s *val;\n", prefix, old);
372                     f_print(fout, "} %s", name);
373                 }
374             } else {
375                 f_print(fout, "struct %s {\n", name);
376                 f_print(fout, "\tu_int %s_len;\n", name);
377                 f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name);
378                 f_print(fout, "} %s", name);
379             }
380             break;
381         case REL_POINTER:
382             f_print(fout, "%s%s *%s", prefix, old, name);
383             break;
384         case REL_VECTOR:
385             f_print(fout, "%s%s %s[%s]", prefix, old, name,
386                     def->def.ty.array_max);
387             break;
388         case REL_ALIAS:
389             f_print(fout, "%s%s %s", prefix, old, name);
390             break;
391         }
392         def->pc.rel = rel;
393         STOREVAL(&typedef_defined, def);
394         f_print(fout, ";\n");
395     }
396 }
397
398
399 static void
400 pdeclaration(char *name, declaration * dec, int tab)
401 {
402     char buf[8];                /* enough to hold "struct ", include NUL */
403     char *prefix;
404     char *type;
405
406     if (streq(dec->type, "void")) {
407         return;
408     }
409     tabify(fout, tab);
410     if (streq(dec->type, name) && !dec->prefix) {
411         f_print(fout, "struct ");
412     }
413     if (streq(dec->type, "string")) {
414         f_print(fout, "char *%s", dec->name);
415     } else {
416         prefix = "";
417         if (streq(dec->type, "bool")) {
418             type = "bool_t";
419         } else if (streq(dec->type, "opaque")) {
420             type = "char";
421         } else {
422             if (dec->prefix) {
423                 s_print(buf, "%s ", dec->prefix);
424                 prefix = buf;
425             }
426             type = dec->type;
427         }
428         switch (dec->rel) {
429         case REL_ALIAS:
430             f_print(fout, "%s%s %s", prefix, type, dec->name);
431             break;
432         case REL_VECTOR:
433             f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
434                     dec->array_max);
435             break;
436         case REL_POINTER:
437             f_print(fout, "%s%s *%s", prefix, type, dec->name);
438             break;
439         case REL_ARRAY:
440             if (brief_flag) {
441                 if (streq(dec->type, "opaque")) {
442                     f_print(fout, "struct rx_opaque %s",dec->name);
443                 } else {
444                     f_print(fout, "struct {\n");
445                     tabify(fout, tab);
446                     f_print(fout, "\tu_int len;\n");
447                     tabify(fout, tab);
448                     f_print(fout, "\t%s%s *val;\n", prefix, type);
449                     tabify(fout, tab);
450                     f_print(fout, "} %s", dec->name);
451                 }
452             } else {
453                 f_print(fout, "struct %s {\n", dec->name);
454                 tabify(fout, tab);
455                 f_print(fout, "\tu_int %s_len;\n", dec->name);
456                 tabify(fout, tab);
457                 f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
458                 tabify(fout, tab);
459                 f_print(fout, "} %s", dec->name);
460             }
461             break;
462         }
463     }
464     f_print(fout, ";\n");
465 }
466
467
468
469 static int
470 undefined2(char *type, char *stop)
471 {
472     list *l;
473     definition *def;
474
475     for (l = defined; l != NULL; l = l->next) {
476         def = (definition *) l->val;
477         if (def->def_kind != DEF_PROGRAM) {
478             if (streq(def->def_name, stop)) {
479                 return (1);
480             } else if (streq(def->def_name, type)) {
481                 return (0);
482             }
483         }
484     }
485     return (1);
486 }