rpc_hout.c revision 1.16 1 /* $NetBSD: rpc_hout.c,v 1.16 2002/01/29 10:20:36 tv Exp $ */
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 or with the express written consent of
9 * Sun Microsystems, Inc.
10 *
11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
14 *
15 * Sun RPC is provided with no support and without any obligation on the
16 * part of Sun Microsystems, Inc. to assist in its use, correction,
17 * modification or enhancement.
18 *
19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21 * OR ANY PART THEREOF.
22 *
23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24 * or profits or other special, indirect and consequential damages, even if
25 * Sun has been advised of the possibility of such damages.
26 *
27 * Sun Microsystems, Inc.
28 * 2550 Garcia Avenue
29 * Mountain View, California 94043
30 */
31
32 #include <sys/cdefs.h>
33 #ifndef lint
34 #if 0
35 static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI";
36 #else
37 __RCSID("$NetBSD: rpc_hout.c,v 1.16 2002/01/29 10:20:36 tv Exp $");
38 #endif
39 #endif
40
41 /*
42 * rpc_hout.c, Header file outputter for the RPC protocol compiler
43 */
44 #include <stdio.h>
45 #include <ctype.h>
46 #include "rpc_scan.h"
47 #include "rpc_parse.h"
48 #include "rpc_util.h"
49
50 #if HAVE_ERR_H
51 #include <err.h>
52 #endif
53
54 static void pconstdef __P((definition *));
55 static void pargdef __P((definition *));
56 static void pstructdef __P((definition *));
57 static void puniondef __P((definition *));
58 static void pdefine __P((char *, char *));
59 static void puldefine __P((char *, char *));
60 static int define_printed __P((proc_list *, version_list *));
61 static void pprogramdef __P((definition *));
62 static void penumdef __P((definition *));
63 static void ptypedef __P((definition *));
64 static int undefined2 __P((char *, char *));
65
66 /*
67 * Print the C-version of an xdr definition
68 */
69 void
70 print_datadef(def)
71 definition *def;
72 {
73
74 if (def->def_kind == DEF_PROGRAM) /* handle data only */
75 return;
76
77 if (def->def_kind != DEF_CONST) {
78 f_print(fout, "\n");
79 }
80 switch (def->def_kind) {
81 case DEF_STRUCT:
82 pstructdef(def);
83 break;
84 case DEF_UNION:
85 puniondef(def);
86 break;
87 case DEF_ENUM:
88 penumdef(def);
89 break;
90 case DEF_TYPEDEF:
91 ptypedef(def);
92 break;
93 case DEF_PROGRAM:
94 pprogramdef(def);
95 break;
96 case DEF_CONST:
97 pconstdef(def);
98 break;
99 }
100 if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
101 pxdrfuncdecl(def->def_name,
102 def->def_kind != DEF_TYPEDEF ||
103 !isvectordef(def->def.ty.old_type, def->def.ty.rel));
104
105 }
106 }
107
108
109 void
110 print_funcdef(def)
111 definition *def;
112 {
113 switch (def->def_kind) {
114 case DEF_PROGRAM:
115 f_print(fout, "\n");
116 pprogramdef(def);
117 break;
118 case DEF_CONST:
119 case DEF_TYPEDEF:
120 case DEF_ENUM:
121 case DEF_UNION:
122 case DEF_STRUCT:
123 break;
124 }
125 }
126
127 void
128 pxdrfuncdecl(name, pointerp)
129 char *name;
130 int pointerp;
131 {
132
133 f_print(fout, "#ifdef __cplusplus\n");
134 f_print(fout, "extern \"C\" bool_t xdr_%s(XDR *, %s%s);\n",
135 name,
136 name, pointerp ? (" *") : "");
137 f_print(fout, "#elif __STDC__\n");
138 f_print(fout, "extern bool_t xdr_%s(XDR *, %s%s);\n",
139 name,
140 name, pointerp ? (" *") : "");
141 f_print(fout, "#else /* Old Style C */\n");
142 f_print(fout, "bool_t xdr_%s();\n", name);
143 f_print(fout, "#endif /* Old Style C */\n\n");
144 }
145
146
147 static void
148 pconstdef(def)
149 definition *def;
150 {
151 pdefine(def->def_name, def->def.co);
152 }
153 /* print out the definitions for the arguments of functions in the
154 header file
155 */
156 static void
157 pargdef(def)
158 definition *def;
159 {
160 decl_list *l;
161 version_list *vers;
162 char *name;
163 proc_list *plist;
164
165
166 for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
167 for (plist = vers->procs; plist != NULL;
168 plist = plist->next) {
169
170 if (!newstyle || plist->arg_num < 2) {
171 continue; /* old style or single args */
172 }
173 name = plist->args.argname;
174 f_print(fout, "struct %s {\n", name);
175 for (l = plist->args.decls;
176 l != NULL; l = l->next) {
177 pdeclaration(name, &l->decl, 1, ";\n");
178 }
179 f_print(fout, "};\n");
180 f_print(fout, "typedef struct %s %s;\n", name, name);
181 pxdrfuncdecl(name, 1);
182 f_print(fout, "\n");
183 }
184 }
185
186 }
187
188
189 static void
190 pstructdef(def)
191 definition *def;
192 {
193 decl_list *l;
194 char *name = def->def_name;
195
196 f_print(fout, "struct %s {\n", name);
197 for (l = def->def.st.decls; l != NULL; l = l->next) {
198 pdeclaration(name, &l->decl, 1, ";\n");
199 }
200 f_print(fout, "};\n");
201 f_print(fout, "typedef struct %s %s;\n", name, name);
202 }
203
204 static void
205 puniondef(def)
206 definition *def;
207 {
208 case_list *l;
209 char *name = def->def_name;
210 declaration *decl;
211
212 f_print(fout, "struct %s {\n", name);
213 decl = &def->def.un.enum_decl;
214 if (streq(decl->type, "bool")) {
215 f_print(fout, "\tbool_t %s;\n", decl->name);
216 } else {
217 f_print(fout, "\t%s %s;\n", decl->type, decl->name);
218 }
219 f_print(fout, "\tunion {\n");
220 for (l = def->def.un.cases; l != NULL; l = l->next) {
221 if (l->contflag == 0)
222 pdeclaration(name, &l->case_decl, 2, ";\n");
223 }
224 decl = def->def.un.default_decl;
225 if (decl && !streq(decl->type, "void")) {
226 pdeclaration(name, decl, 2, ";\n");
227 }
228 f_print(fout, "\t} %s_u;\n", name);
229 f_print(fout, "};\n");
230 f_print(fout, "typedef struct %s %s;\n", name, name);
231 }
232
233 static void
234 pdefine(name, num)
235 char *name;
236 char *num;
237 {
238 f_print(fout, "#define %s %s\n", name, num);
239 }
240
241 static void
242 puldefine(name, num)
243 char *name;
244 char *num;
245 {
246 f_print(fout, "#define %s %s\n", name, num);
247 }
248
249 static int
250 define_printed(stop, start)
251 proc_list *stop;
252 version_list *start;
253 {
254 version_list *vers;
255 proc_list *proc;
256
257 for (vers = start; vers != NULL; vers = vers->next) {
258 for (proc = vers->procs; proc != NULL; proc = proc->next) {
259 if (proc == stop) {
260 return (0);
261 } else
262 if (streq(proc->proc_name, stop->proc_name)) {
263 return (1);
264 }
265 }
266 }
267 errx(1, "Internal error %s, %d: procedure not found\n",
268 __FILE__, __LINE__);
269 /* NOTREACHED */
270 }
271
272 static void
273 pprogramdef(def)
274 definition *def;
275 {
276 version_list *vers;
277 proc_list *proc;
278 int i;
279 char *ext;
280
281 pargdef(def);
282
283 puldefine(def->def_name, def->def.pr.prog_num);
284 for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
285 if (tblflag) {
286 f_print(fout, "extern struct rpcgen_table %s_%s_table[];\n",
287 locase(def->def_name), vers->vers_num);
288 f_print(fout, "extern %s_%s_nproc;\n",
289 locase(def->def_name), vers->vers_num);
290 }
291 puldefine(vers->vers_name, vers->vers_num);
292
293 /* Print out 3 definitions, one for ANSI-C, another for C++, a
294 * third for old style C */
295
296 for (i = 0; i < 3; i++) {
297 if (i == 0) {
298 f_print(fout, "\n#ifdef __cplusplus\n");
299 ext = "extern \"C\" ";
300 } else
301 if (i == 1) {
302 f_print(fout, "\n#elif __STDC__\n");
303 ext = "extern ";
304 } else {
305 f_print(fout, "\n#else /* Old Style C */\n");
306 ext = "extern ";
307 }
308
309
310 for (proc = vers->procs; proc != NULL; proc = proc->next) {
311 if (!define_printed(proc, def->def.pr.versions)) {
312 puldefine(proc->proc_name, proc->proc_num);
313 }
314 f_print(fout, "%s", ext);
315 pprocdef(proc, vers, "CLIENT *", 0, i);
316 f_print(fout, "%s", ext);
317 pprocdef(proc, vers, "struct svc_req *", 1, i);
318
319 }
320
321 }
322 f_print(fout, "#endif /* Old Style C */\n");
323 }
324 }
325
326 void
327 pprocdef(proc, vp, addargtype, server_p, mode)
328 proc_list *proc;
329 version_list *vp;
330 char *addargtype;
331 int server_p;
332 int mode;
333 {
334 decl_list *dl;
335
336 if (Mflag) {
337 if (server_p)
338 f_print(fout, "bool_t ");
339 else
340 f_print(fout, "enum clnt_stat ");
341 } else {
342 ptype(proc->res_prefix, proc->res_type, 1);
343 f_print(fout, "*");
344 }
345 if (server_p)
346 pvname_svc(proc->proc_name, vp->vers_num);
347 else
348 pvname(proc->proc_name, vp->vers_num);
349
350 /*
351 * mode 0 == cplusplus, mode 1 = ANSI-C, mode 2 = old style C
352 */
353 if (mode == 0 || mode == 1) {
354 f_print(fout, "(");
355 if (proc->arg_num < 2 && newstyle &&
356 streq(proc->args.decls->decl.type, "void")) {
357 /* 0 argument in new style: do nothing */
358 } else {
359 for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
360 ptype(dl->decl.prefix, dl->decl.type, 1);
361 if (!newstyle)
362 f_print(fout, "*");
363 f_print(fout, ", ");
364 }
365 }
366 if (Mflag) {
367 if (streq(proc->res_type, "void"))
368 f_print(fout, "char");
369 else
370 ptype(proc->res_prefix, proc->res_type, 0);
371 if (!isvectordef(proc->res_type, REL_ALIAS))
372 f_print(fout, "*");
373 f_print(fout, ", ");
374 }
375 f_print(fout, "%s);\n", addargtype);
376 }
377 else
378 f_print(fout, "();\n");
379 }
380
381
382 static void
383 penumdef(def)
384 definition *def;
385 {
386 char *name = def->def_name;
387 enumval_list *l;
388 char *last = NULL;
389 int count = 0;
390
391 f_print(fout, "enum %s {\n", name);
392 for (l = def->def.en.vals; l != NULL; l = l->next) {
393 f_print(fout, "\t%s", l->name);
394 if (l->assignment) {
395 f_print(fout, " = %s", l->assignment);
396 last = l->assignment;
397 count = 1;
398 } else {
399 if (last == NULL) {
400 f_print(fout, " = %d", count++);
401 } else {
402 f_print(fout, " = %s + %d", last, count++);
403 }
404 }
405 f_print(fout, ",\n");
406 }
407 f_print(fout, "};\n");
408 f_print(fout, "typedef enum %s %s;\n", name, name);
409 }
410
411 static void
412 ptypedef(def)
413 definition *def;
414 {
415 char *name = def->def_name;
416 char *old = def->def.ty.old_type;
417 char prefix[8]; /* enough to contain "struct ", including NUL */
418 relation rel = def->def.ty.rel;
419
420
421 if (!streq(name, old)) {
422 if (streq(old, "string")) {
423 old = "char";
424 rel = REL_POINTER;
425 } else
426 if (streq(old, "opaque")) {
427 old = "char";
428 } else
429 if (streq(old, "bool")) {
430 old = "bool_t";
431 }
432 if (undefined2(old, name) && def->def.ty.old_prefix) {
433 s_print(prefix, "%s ", def->def.ty.old_prefix);
434 } else {
435 prefix[0] = 0;
436 }
437 f_print(fout, "typedef ");
438 switch (rel) {
439 case REL_ARRAY:
440 f_print(fout, "struct {\n");
441 f_print(fout, "\tu_int %s_len;\n", name);
442 f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name);
443 f_print(fout, "} %s", name);
444 break;
445 case REL_POINTER:
446 f_print(fout, "%s%s *%s", prefix, old, name);
447 break;
448 case REL_VECTOR:
449 f_print(fout, "%s%s %s[%s]", prefix, old, name,
450 def->def.ty.array_max);
451 break;
452 case REL_ALIAS:
453 f_print(fout, "%s%s %s", prefix, old, name);
454 break;
455 }
456 f_print(fout, ";\n");
457 }
458 }
459
460 void
461 pdeclaration(name, dec, tab, separator)
462 char *name;
463 declaration *dec;
464 int tab;
465 char *separator;
466 {
467 char buf[8]; /* enough to hold "struct ", include NUL */
468 char *prefix;
469 char *type;
470
471 if (streq(dec->type, "void")) {
472 return;
473 }
474 tabify(fout, tab);
475 if (streq(dec->type, name) && !dec->prefix) {
476 f_print(fout, "struct ");
477 }
478 if (streq(dec->type, "string")) {
479 f_print(fout, "char *%s", dec->name);
480 } else {
481 prefix = "";
482 if (streq(dec->type, "bool")) {
483 type = "bool_t";
484 } else
485 if (streq(dec->type, "opaque")) {
486 type = "char";
487 } else {
488 if (dec->prefix) {
489 s_print(buf, "%s ", dec->prefix);
490 prefix = buf;
491 }
492 type = dec->type;
493 }
494 switch (dec->rel) {
495 case REL_ALIAS:
496 f_print(fout, "%s%s %s", prefix, type, dec->name);
497 break;
498 case REL_VECTOR:
499 f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
500 dec->array_max);
501 break;
502 case REL_POINTER:
503 f_print(fout, "%s%s *%s", prefix, type, dec->name);
504 break;
505 case REL_ARRAY:
506 f_print(fout, "struct {\n");
507 tabify(fout, tab);
508 f_print(fout, "\tu_int %s_len;\n", dec->name);
509 tabify(fout, tab);
510 f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
511 tabify(fout, tab);
512 f_print(fout, "} %s", dec->name);
513 break;
514 }
515 }
516 f_print(fout, "%s", separator);
517 }
518
519 static int
520 undefined2(type, stop)
521 char *type;
522 char *stop;
523 {
524 list *l;
525 definition *def;
526
527 for (l = defined; l != NULL; l = l->next) {
528 def = (definition *) l->val;
529 if (def->def_kind != DEF_PROGRAM) {
530 if (streq(def->def_name, stop)) {
531 return (1);
532 } else
533 if (streq(def->def_name, type)) {
534 return (0);
535 }
536 }
537 }
538 return (1);
539 }
540