]> git.decadent.org.uk Git - nfs-utils.git/blob - tools/rpcgen/rpc_hout.c
nfs-iostat.py: divide by zero with fresh mount
[nfs-utils.git] / tools / rpcgen / rpc_hout.c
1 /*
2  * Copyright (c) 2009, Sun Microsystems, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * - Redistributions of source code must retain the above copyright notice,
8  *   this list of conditions and the following disclaimer.
9  * - Redistributions in binary form must reproduce the above copyright notice,
10  *   this list of conditions and the following disclaimer in the documentation
11  *   and/or other materials provided with the distribution.
12  * - Neither the name of Sun Microsystems, Inc. nor the names of its
13  *   contributors may be used to endorse or promote products derived
14  *   from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #if 0
30 static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI";
31 #endif
32
33 /*
34  * rpc_hout.c, Header file outputter for the RPC protocol compiler 
35  */
36 #include <stdio.h>
37 #include <ctype.h>
38 #include "rpc_parse.h"
39 #include "rpc_util.h"
40 #include "rpc_output.h"
41
42
43 static int      undefined2(char *type, char *stop);
44 static void     pxdrfuncdecl(char *name, int pointerp);
45 static void     pconstdef(definition *def);
46 static void     pargdef(definition *def);
47 static void     pstructdef(definition *def);
48 static void     puniondef(definition *def);
49 static void     pdefine(char *name, char *num);
50 static void     puldefine(char *name, char *num);
51 static int      define_printed(proc_list *stop, version_list *start);
52 static void     pprogramdef(definition *def);
53 static void     pprocdef(proc_list *proc, version_list *vp,
54                                 char *addargtype, int server_p, int mode);
55 static void     parglist(proc_list *proc, char *addargtype);
56 static void     penumdef(definition *def);
57 static void     ptypedef(definition *def);
58
59 /*
60  * Print the C-version of an xdr definition 
61  */
62 void
63 print_datadef(definition *def)
64 {
65
66         if (def->def_kind == DEF_PROGRAM )  /* handle data only */
67                 return;
68
69         if (def->def_kind != DEF_CONST) {
70                 f_print(fout, "\n");
71         }
72         switch (def->def_kind) {
73         case DEF_STRUCT:
74                 pstructdef(def);
75                 break;
76         case DEF_UNION:
77                 puniondef(def);
78                 break;
79         case DEF_ENUM:
80                 penumdef(def);
81                 break;
82         case DEF_TYPEDEF:
83                 ptypedef(def);
84                 break;
85         case DEF_PROGRAM:
86                 pprogramdef(def);
87                 break;
88         case DEF_CONST:
89                 pconstdef(def);
90                 break;
91         }
92         if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
93           pxdrfuncdecl( def->def_name,
94                        def->def_kind != DEF_TYPEDEF ||
95                        !isvectordef(def->def.ty.old_type, def->def.ty.rel));
96
97         }
98 }
99
100
101 void
102 print_funcdef(definition *def)
103 {
104         switch (def->def_kind) {
105         case DEF_PROGRAM:
106                 f_print(fout, "\n");
107                 pprogramdef(def);
108                 break;
109         default:
110                 break;
111         }
112 }
113
114 static void
115 pxdrfuncdecl(char *name, int pointerp)
116 {
117         f_print(fout,
118         "#ifdef __cplusplus \n"
119         "extern \"C\" bool_t xdr_%s(XDR *, %s%s);\n"
120         "#elif __STDC__ \n"
121         "extern  bool_t xdr_%s(XDR *, %s%s);\n"
122         "#else /* Old Style C */ \n"
123         "bool_t xdr_%s();\n"
124         "#endif /* Old Style C */ \n\n",
125         name, name, pointerp ? "*" : "",
126         name, name, pointerp ? "*" : "",
127         name);
128 }
129
130
131 static void
132 pconstdef(definition *def)
133 {
134         pdefine(def->def_name, def->def.co);
135 }
136
137 /* print out the definitions for the arguments of functions in the 
138    header file 
139 */
140 static  void
141 pargdef(definition *def)
142 {
143         decl_list *l;
144         version_list *vers;
145         char *name;
146         proc_list *plist;
147
148         
149         for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
150                         for(plist = vers->procs; plist != NULL; 
151                             plist = plist->next) {
152                                 
153                                 if (!newstyle || plist->arg_num < 2) {
154                                         continue; /* old style or single args */
155                                 }
156                                 name = plist->args.argname;
157                                 f_print(fout, "struct %s {\n", name);
158                                 for (l = plist->args.decls; 
159                                      l != NULL; l = l->next) {
160                                         pdeclaration(name, &l->decl, 1, ";\n" );
161                                 }
162                                 f_print(fout, "};\n");
163                                 f_print(fout, "typedef struct %s %s;\n", name, name);
164                                 pxdrfuncdecl(name, 0);
165                                 f_print( fout, "\n" );
166                         }
167                 }
168
169 }
170
171
172 static void
173 pstructdef(definition *def)
174 {
175         decl_list *l;
176         char *name = def->def_name;
177
178         f_print(fout, "struct %s {\n", name);
179         for (l = def->def.st.decls; l != NULL; l = l->next) {
180                 pdeclaration(name, &l->decl, 1, ";\n");
181         }
182         f_print(fout, "};\n");
183         f_print(fout, "typedef struct %s %s;\n", name, name);
184 }
185
186 static void
187 puniondef(definition *def)
188 {
189         case_list      *l;
190         char           *name = def->def_name;
191         declaration    *decl;
192
193         f_print(fout, "struct %s {\n", name);
194         decl = &def->def.un.enum_decl;
195         if (streq(decl->type, "bool")) {
196                 f_print(fout, "\tbool_t %s;\n", decl->name);
197         } else {
198                 f_print(fout, "\t%s %s;\n", decl->type, decl->name);
199         }
200         f_print(fout, "\tunion {\n");
201         for (l = def->def.un.cases; l != NULL; l = l->next) {
202                 if (l->contflag == 0)
203                         pdeclaration(name, &l->case_decl, 2, ";\n");
204         }
205         decl = def->def.un.default_decl;
206         if (decl && !streq(decl->type, "void")) {
207                 pdeclaration(name, decl, 2, ";\n");
208         }
209         f_print(fout, "\t} %s_u;\n", name);
210         f_print(fout, "};\n");
211         f_print(fout, "typedef struct %s %s;\n", name, name);
212 }
213
214 static void
215 pdefine(char *name, char *num)
216 {
217         f_print(fout, "#define %s %s\n", name, num);
218 }
219
220 static void
221 puldefine(char *name, char *num)
222 {
223         f_print(fout, "#define %s ((u_int32_t)%s)\n", name, num);
224 }
225
226 static int
227 define_printed(proc_list *stop, version_list *start)
228 {
229         version_list *vers;
230         proc_list *proc;
231
232         for (vers = start; vers != NULL; vers = vers->next) {
233                 for (proc = vers->procs; proc != NULL; proc = proc->next) {
234                         if (proc == stop) {
235                                 return (0);
236                         } else if (streq(proc->proc_name, stop->proc_name)) {
237                                 return (1);
238                         }
239                 }
240         }
241         abort();
242         /* NOTREACHED */
243 }
244
245 static void
246 pprogramdef(definition *def)
247 {
248         version_list   *vers;
249         proc_list      *proc;
250         int             i;
251         char           *ext;
252
253         pargdef(def);
254
255         puldefine(def->def_name, def->def.pr.prog_num);
256         for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
257                 if (tblflag) {
258                         f_print(fout, "extern struct rpcgen_table %s_%s_table[];\n",
259                                 locase(def->def_name), vers->vers_num);
260                         f_print(fout, "extern %s_%s_nproc;\n",
261                                 locase(def->def_name), vers->vers_num);
262                 }
263                 puldefine(vers->vers_name, vers->vers_num);
264
265                 /*
266                  * Print out 3 definitions, one for ANSI-C, another for C++,
267                  * a third for old style C
268                  */
269
270                 for (i = 0; i < 3; i++) {
271                         if (i == 0) {
272                                 f_print(fout, "\n#ifdef __cplusplus\n");
273                                 ext = "extern \"C\" ";
274                         } else if (i == 1) {
275                                 f_print(fout, "\n#elif __STDC__\n");
276                                 ext = "extern  ";
277                         } else {
278                                 f_print(fout, "\n#else /* Old Style C */ \n");
279                                 ext = "extern  ";
280                         }
281
282
283                         for (proc = vers->procs; proc != NULL; proc = proc->next) {
284                                 if (!define_printed(proc, def->def.pr.versions)) {
285                                         puldefine(proc->proc_name, proc->proc_num);
286                                 }
287                                 f_print(fout, "%s", ext);
288                                 pprocdef(proc, vers, "CLIENT *", 0, i);
289                                 f_print(fout, "%s", ext);
290                                 pprocdef(proc, vers, "struct svc_req *", 1, i);
291
292                         }
293
294                 }
295                 f_print(fout, "#endif /* Old Style C */ \n");
296         }
297 }
298
299 static void
300 pprocdef(proc_list *proc, version_list *vp, char *addargtype,
301                                 int server_p, int mode)
302 {
303         ptype(proc->res_prefix, proc->res_type, 1);
304         f_print(fout, "* ");
305         if (server_p)
306                 pvname_svc(proc->proc_name, vp->vers_num);
307         else
308                 pvname(proc->proc_name, vp->vers_num);
309
310         /*
311          * mode  0 == cplusplus, mode  1 = ANSI-C, mode 2 = old style C
312          */
313         if (mode == 0 || mode == 1)
314                 parglist(proc, addargtype);
315         else
316                 f_print(fout, "();\n");
317 }
318
319
320
321 /* print out argument list of procedure */
322 static void
323 parglist(proc_list *proc, char *addargtype)
324 {
325         decl_list      *dl;
326
327         f_print(fout, "(");
328
329         if (proc->arg_num < 2 && newstyle &&
330                 streq(proc->args.decls->decl.type, "void")) {
331                 /* 0 argument in new style:  do nothing */
332         } else {
333                 for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
334                         ptype(dl->decl.prefix, dl->decl.type, 1);
335                         if (!newstyle)
336                                 f_print(fout, "*");     /* old style passes by reference */
337
338                         f_print(fout, ", ");
339                 }
340         }
341
342         f_print(fout, "%s);\n", addargtype);
343 }
344
345 static void
346 penumdef(definition *def)
347 {
348         char *name = def->def_name;
349         enumval_list *l;
350         char *last = NULL;
351         int count = 0;
352
353         f_print(fout, "enum %s {\n", name);
354         for (l = def->def.en.vals; l != NULL; l = l->next) {
355                 f_print(fout, "\t%s", l->name);
356                 if (l->assignment) {
357                         f_print(fout, " = %s", l->assignment);
358                         last = l->assignment;
359                         count = 1;
360                 } else {
361                         if (last == NULL) {
362                                 f_print(fout, " = %d", count++);
363                         } else {
364                                 f_print(fout, " = %s + %d", last, count++);
365                         }
366                 }
367                 f_print(fout, ",\n");
368         }
369         f_print(fout, "};\n");
370         f_print(fout, "typedef enum %s %s;\n", name, name);
371 }
372
373 static void
374 ptypedef(definition *def)
375 {
376         char *name = def->def_name;
377         char *old = def->def.ty.old_type;
378         char prefix[8]; /* enough to contain "struct ", including NUL */
379         relation rel = def->def.ty.rel;
380
381
382         if (!streq(name, old)) {
383                 if (streq(old, "string")) {
384                         old = "char";
385                         rel = REL_POINTER;
386                 } else if (streq(old, "opaque")) {
387                         old = "char";
388                 } else if (streq(old, "bool")) {
389                         old = "bool_t";
390                 }
391                 if (undefined2(old, name) && def->def.ty.old_prefix) {
392                         s_print(prefix, "%s ", def->def.ty.old_prefix);
393                 } else {
394                         prefix[0] = 0;
395                 }
396                 f_print(fout, "typedef ");
397                 switch (rel) {
398                 case REL_ARRAY:
399                         f_print(fout, "struct {\n");
400                         f_print(fout, "\tu_int %s_len;\n", name);
401                         f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name);
402                         f_print(fout, "} %s", name);
403                         break;
404                 case REL_POINTER:
405                         f_print(fout, "%s%s *%s", prefix, old, name);
406                         break;
407                 case REL_VECTOR:
408                         f_print(fout, "%s%s %s[%s]", prefix, old, name,
409                                 def->def.ty.array_max);
410                         break;
411                 case REL_ALIAS:
412                         f_print(fout, "%s%s %s", prefix, old, name);
413                         break;
414                 }
415                 f_print(fout, ";\n");
416         }
417 }
418
419 void
420 pdeclaration(char *name, declaration *dec, int tab, char *separator)
421 {
422         char buf[8];    /* enough to hold "struct ", include NUL */
423         char *prefix;
424         char *type;
425
426         if (streq(dec->type, "void")) {
427                 return;
428         }
429         tabify(fout, tab);
430         if (streq(dec->type, name) && !dec->prefix) {
431                 f_print(fout, "struct ");
432         }
433         if (streq(dec->type, "string")) {
434                 f_print(fout, "char *%s", dec->name);
435         } else {
436                 prefix = "";
437                 if (streq(dec->type, "bool")) {
438                         type = "bool_t";
439                 } else if (streq(dec->type, "opaque")) {
440                         type = "char";
441                 } else {
442                         if (dec->prefix) {
443                                 s_print(buf, "%s ", dec->prefix);
444                                 prefix = buf;
445                         }
446                         type = dec->type;
447                 }
448                 switch (dec->rel) {
449                 case REL_ALIAS:
450                         f_print(fout, "%s%s %s", prefix, type, dec->name);
451                         break;
452                 case REL_VECTOR:
453                         f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
454                                 dec->array_max);
455                         break;
456                 case REL_POINTER:
457                         f_print(fout, "%s%s *%s", prefix, type, dec->name);
458                         break;
459                 case REL_ARRAY:
460                         f_print(fout, "struct {\n");
461                         tabify(fout, tab);
462                         f_print(fout, "\tu_int %s_len;\n", dec->name);
463                         tabify(fout, tab);
464                         f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
465                         tabify(fout, tab);
466                         f_print(fout, "} %s", dec->name);
467                         break;
468                 }
469         }
470         f_print(fout, separator );
471 }
472
473 static int
474 undefined2(char *type, char *stop)
475 {
476         list *l;
477         definition *def;
478
479         for (l = defined; l != NULL; l = l->next) {
480                 def = (definition *) l->val;
481                 if (def->def_kind != DEF_PROGRAM) {
482                         if (streq(def->def_name, stop)) {
483                                 return (1);
484                         } else if (streq(def->def_name, type)) {
485                                 return (0);
486                         }
487                 }
488         }
489         return (1);
490 }