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