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