xref: /titanic_51/usr/src/cmd/rpcgen/rpc_hout.c (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  *
22  * Copyright 2001 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
26 /* All Rights Reserved */
27 /*
28  * University Copyright- Copyright (c) 1982, 1986, 1988
29  * The Regents of the University of California
30  * All Rights Reserved
31  *
32  * University Acknowledgment- Portions of this document are derived from
33  * software developed by the University of California, Berkeley, and its
34  * contributors.
35  */
36 
37 #pragma ident	"%Z%%M%	%I%	%E% SMI"
38 
39 /*
40  * rpc_hout.c, Header file outputter for the RPC protocol compiler
41  */
42 #include <stdio.h>
43 #include <ctype.h>
44 #include "rpc_parse.h"
45 #include "rpc_util.h"
46 
47 void storexdrfuncdecl();
48 
49 static char RESULT[] = "clnt_res";
50 
51 static enum rpc_gvc {
52 	PROGRAM,
53 	VERSION,
54 	PROCEDURE
55 };
56 
57 /*
58  * Print the C-version of an xdr definition
59  */
60 void
61 print_datadef(def)
62 	definition *def;
63 {
64 
65 	if (def->def_kind == DEF_PROGRAM)  /* handle data only */
66 		return;
67 
68 	if (def->def_kind != DEF_CONST) {
69 		f_print(fout, "\n");
70 	}
71 	switch (def->def_kind) {
72 	case DEF_STRUCT:
73 		pstructdef(def);
74 		break;
75 	case DEF_UNION:
76 		puniondef(def);
77 		break;
78 	case DEF_ENUM:
79 		penumdef(def);
80 		break;
81 	case DEF_TYPEDEF:
82 		ptypedef(def);
83 		break;
84 	case DEF_PROGRAM:
85 		pprogramdef(def);
86 		break;
87 	case DEF_CONST:
88 		pconstdef(def);
89 		break;
90 	}
91 	if (def->def_kind != DEF_PROGRAM && def->def_kind != DEF_CONST) {
92 		storexdrfuncdecl(def->def_name, def->def_kind != DEF_TYPEDEF ||
93 		    !isvectordef(def->def.ty.old_type, def->def.ty.rel));
94 	}
95 }
96 
97 
98 void
99 print_funcdef(definition *def)
100 {
101 	switch (def->def_kind) {
102 	case DEF_PROGRAM:
103 		f_print(fout, "\n");
104 		pprogramdef(def);
105 		break;
106 	}
107 }
108 
109 /*
110  * store away enough information to allow the XDR functions to be spat
111  * out at the end of the file
112  */
113 void
114 storexdrfuncdecl(char *name, int pointerp)
115 {
116 	xdrfunc *xdrptr;
117 
118 	xdrptr = (xdrfunc *) malloc(sizeof (struct xdrfunc));
119 
120 	xdrptr->name = name;
121 	xdrptr->pointerp = pointerp;
122 	xdrptr->next = NULL;
123 
124 	if (xdrfunc_tail == NULL) {
125 		xdrfunc_head = xdrptr;
126 		xdrfunc_tail = xdrptr;
127 	} else {
128 		xdrfunc_tail->next = xdrptr;
129 		xdrfunc_tail = xdrptr;
130 	}
131 
132 
133 }
134 
135 void
136 print_xdr_func_def(char *name, int pointerp, int i)
137 {
138 	if (i == 2)
139 		f_print(fout, "extern bool_t xdr_%s();\n", name);
140 	else
141 		f_print(fout, "extern  bool_t xdr_%s(XDR *, %s%s);\n", name,
142 		    name, pointerp ? "*" : "");
143 }
144 
145 
146 static
147 pconstdef(definition *def)
148 {
149 	pdefine(def->def_name, def->def.co);
150 }
151 
152 /*
153  * print out the definitions for the arguments of functions in the
154  * header file
155  */
156 static
157 pargdef(definition *def)
158 {
159 	decl_list *l;
160 	version_list *vers;
161 	char *name;
162 	proc_list *plist;
163 
164 	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
165 			for (plist = vers->procs; plist != NULL;
166 			    plist = plist->next) {
167 
168 				if (!newstyle || plist->arg_num < 2) {
169 					continue; /* old style or single args */
170 				}
171 				name = plist->args.argname;
172 				f_print(fout, "struct %s {\n", name);
173 				for (l = plist->args.decls;
174 				    l != NULL; l = l->next) {
175 					pdeclaration(name, &l->decl, 1, ";\n");
176 				}
177 				f_print(fout, "};\n");
178 				f_print(fout, "typedef struct %s %s;\n",
179 					name, name);
180 				storexdrfuncdecl(name, 1);
181 				f_print(fout, "\n");
182 			}
183 		}
184 }
185 
186 
187 static
188 pstructdef(def)
189 	definition *def;
190 {
191 	decl_list *l;
192 	char *name = def->def_name;
193 
194 	f_print(fout, "struct %s {\n", name);
195 	for (l = def->def.st.decls; l != NULL; l = l->next) {
196 		pdeclaration(name, &l->decl, 1, ";\n");
197 	}
198 	f_print(fout, "};\n");
199 	f_print(fout, "typedef struct %s %s;\n", name, name);
200 }
201 
202 static
203 puniondef(def)
204 	definition *def;
205 {
206 	case_list *l;
207 	char *name = def->def_name;
208 	declaration *decl;
209 
210 	f_print(fout, "struct %s {\n", name);
211 	decl = &def->def.un.enum_decl;
212 	if (streq(decl->type, "bool")) {
213 		f_print(fout, "\tbool_t %s;\n", decl->name);
214 	} else {
215 		f_print(fout, "\t%s %s;\n", decl->type, decl->name);
216 	}
217 	f_print(fout, "\tunion {\n");
218 	for (l = def->def.un.cases; l != NULL; l = l->next) {
219 	    if (l->contflag == 0)
220 		pdeclaration(name, &l->case_decl, 2, ";\n");
221 	}
222 	decl = def->def.un.default_decl;
223 	if (decl && !streq(decl->type, "void")) {
224 		pdeclaration(name, decl, 2, ";\n");
225 	}
226 	f_print(fout, "\t} %s_u;\n", name);
227 	f_print(fout, "};\n");
228 	f_print(fout, "typedef struct %s %s;\n", name, name);
229 }
230 
231 static
232 pdefine(name, num)
233 	char *name;
234 	char *num;
235 {
236 	f_print(fout, "#define\t%s %s\n", name, num);
237 }
238 
239 static
240 puldefine(char *name, char *num, enum rpc_gvc which)
241 {
242 	switch (which) {
243 	case PROGRAM:
244 	case VERSION:
245 	case PROCEDURE:
246 		f_print(fout, "#define\t%s\t%s\n", name, num);
247 		break;
248 	default:
249 		break;
250 	}
251 }
252 
253 static
254 define_printed(proc_list *stop, version_list *start)
255 {
256 	version_list *vers;
257 	proc_list *proc;
258 
259 	for (vers = start; vers != NULL; vers = vers->next) {
260 		for (proc = vers->procs; proc != NULL; proc = proc->next) {
261 			if (proc == stop) {
262 				return (0);
263 			} else if (streq(proc->proc_name, stop->proc_name)) {
264 				return (1);
265 			}
266 		}
267 	}
268 	abort();
269 	/* NOTREACHED */
270 }
271 
272 static
273 pfreeprocdef(char * name, char *vers, int mode)
274 {
275 	f_print(fout, "extern int ");
276 	pvname(name, vers);
277 	if (mode == 1)
278 		f_print(fout, "_freeresult(SVCXPRT *, xdrproc_t, caddr_t);\n");
279 	else
280 		f_print(fout, "_freeresult();\n");
281 
282 
283 }
284 
285 static
286 pprogramdef(def)
287 	definition *def;
288 {
289 	version_list *vers;
290 	proc_list *proc;
291 	int i;
292 	char *ext;
293 
294 	pargdef(def);
295 
296 	puldefine(def->def_name, def->def.pr.prog_num, PROGRAM);
297 	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
298 		if (tblflag) {
299 			f_print(fout,
300 				"extern struct rpcgen_table %s_%s_table[];\n",
301 				locase(def->def_name), vers->vers_num);
302 			f_print(fout,
303 				"extern %s_%s_nproc;\n",
304 				locase(def->def_name), vers->vers_num);
305 		}
306 		puldefine(vers->vers_name, vers->vers_num, VERSION);
307 
308 		/*
309 		 * Print out 2 definitions, one for ANSI-C, another for
310 		 * old K & R C
311 		 */
312 
313 		if (!Cflag) {
314 			ext = "extern  ";
315 			for (proc = vers->procs; proc != NULL;
316 			    proc = proc->next) {
317 				if (!define_printed(proc,
318 				    def->def.pr.versions)) {
319 					puldefine(proc->proc_name,
320 					    proc->proc_num, PROCEDURE);
321 				}
322 				f_print(fout, "%s", ext);
323 				pprocdef(proc, vers, NULL, 0, 2);
324 
325 				if (mtflag) {
326 					f_print(fout, "%s", ext);
327 					pprocdef(proc, vers, NULL, 1, 2);
328 				}
329 			}
330 			pfreeprocdef(def->def_name, vers->vers_num, 2);
331 		} else {
332 			for (i = 1; i < 3; i++) {
333 				if (i == 1) {
334 					f_print(fout, "\n#if defined(__STDC__)"
335 						" || defined(__cplusplus)\n");
336 					ext = "extern  ";
337 				} else {
338 					f_print(fout, "\n#else /* K&R C */\n");
339 					ext = "extern  ";
340 				}
341 
342 				for (proc = vers->procs; proc != NULL;
343 				    proc = proc->next) {
344 					if (!define_printed(proc,
345 					    def->def.pr.versions)) {
346 						puldefine(proc->proc_name,
347 						    proc->proc_num, PROCEDURE);
348 					}
349 					f_print(fout, "%s", ext);
350 					pprocdef(proc, vers, "CLIENT *", 0, i);
351 					f_print(fout, "%s", ext);
352 					pprocdef(proc, vers,
353 					    "struct svc_req *", 1, i);
354 				}
355 			pfreeprocdef(def->def_name, vers->vers_num, i);
356 			}
357 			f_print(fout, "#endif /* K&R C */\n");
358 		}
359 	}
360 }
361 
362 pprocdef(proc, vp, addargtype, server_p, mode)
363 	proc_list *proc;
364 	version_list *vp;
365 	char *addargtype;
366 	int server_p;
367 	int mode;
368 {
369 	if (mtflag) {
370 		/* Print MT style stubs */
371 		if (server_p)
372 			f_print(fout, "bool_t ");
373 		else
374 			f_print(fout, "enum clnt_stat ");
375 	} else {
376 		ptype(proc->res_prefix, proc->res_type, 1);
377 		f_print(fout, "* ");
378 	}
379 	if (server_p)
380 		pvname_svc(proc->proc_name, vp->vers_num);
381 	else
382 		pvname(proc->proc_name, vp->vers_num);
383 
384 	/*
385 	 *  mode  1 = ANSI-C, mode 2 = K&R C
386 	 */
387 	if (mode == 1)
388 		parglist(proc, addargtype, server_p);
389 	else
390 		f_print(fout, "();\n");
391 
392 
393 
394 }
395 
396 
397 
398 /* print out argument list of procedure */
399 static
400 parglist(proc, addargtype, server_p)
401 	proc_list *proc;
402 	char *addargtype;
403 	int server_p;
404 {
405 	decl_list *dl;
406 	int oneway = streq(proc->res_type, "oneway");
407 
408 	f_print(fout, "(");
409 	if (proc->arg_num < 2 && newstyle &&
410 	    streq(proc->args.decls->decl.type, "void")) {
411 		/* 0 argument in new style:  do nothing */
412 	} else {
413 		for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
414 			ptype(dl->decl.prefix, dl->decl.type, 1);
415 			if (!newstyle || (dl->decl.rel == REL_POINTER))
416 				f_print(fout, "*");
417 			/* old style passes by reference */
418 			f_print(fout, ", ");
419 		}
420 	}
421 
422 	if (mtflag && !oneway)  {
423 		ptype(proc->res_prefix, proc->res_type, 1);
424 		f_print(fout, "*, ");
425 	}
426 
427 	f_print(fout, "%s);\n", addargtype);
428 
429 }
430 
431 static
432 penumdef(def)
433 	definition *def;
434 {
435 	char *name = def->def_name;
436 	enumval_list *l;
437 	char *last = NULL;
438 	int count = 0;
439 
440 	f_print(fout, "enum %s {\n", name);
441 	for (l = def->def.en.vals; l != NULL; l = l->next) {
442 		f_print(fout, "\t%s", l->name);
443 		if (l->assignment) {
444 			f_print(fout, " = %s", l->assignment);
445 			last = l->assignment;
446 			count = 1;
447 		} else {
448 			if (last == NULL) {
449 				f_print(fout, " = %d", count++);
450 			} else {
451 				f_print(fout, " = %s + %d", last, count++);
452 			}
453 		}
454 		if (l->next)
455 			f_print(fout, ",\n");
456 		else
457 			f_print(fout, "\n");
458 	}
459 	f_print(fout, "};\n");
460 	f_print(fout, "typedef enum %s %s;\n", name, name);
461 }
462 
463 static
464 ptypedef(def)
465 	definition *def;
466 {
467 	char *name = def->def_name;
468 	char *old = def->def.ty.old_type;
469 	char prefix[8];	/* enough to contain "struct ", including NUL */
470 	relation rel = def->def.ty.rel;
471 
472 
473 	if (!streq(name, old)) {
474 		if (streq(old, "string")) {
475 			old = "char";
476 			rel = REL_POINTER;
477 		} else if (streq(old, "opaque")) {
478 			old = "char";
479 		} else if (streq(old, "bool")) {
480 			old = "bool_t";
481 		}
482 		if (undefined2(old, name) && def->def.ty.old_prefix) {
483 			s_print(prefix, "%s ", def->def.ty.old_prefix);
484 		} else {
485 			prefix[0] = 0;
486 		}
487 		f_print(fout, "typedef ");
488 		switch (rel) {
489 		case REL_ARRAY:
490 			f_print(fout, "struct {\n");
491 			f_print(fout, "\tu_int %s_len;\n", name);
492 			f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name);
493 			f_print(fout, "} %s", name);
494 			break;
495 		case REL_POINTER:
496 			f_print(fout, "%s%s *%s", prefix, old, name);
497 			break;
498 		case REL_VECTOR:
499 			f_print(fout, "%s%s %s[%s]", prefix, old, name,
500 				def->def.ty.array_max);
501 			break;
502 		case REL_ALIAS:
503 			f_print(fout, "%s%s %s", prefix, old, name);
504 			break;
505 		}
506 		f_print(fout, ";\n");
507 	}
508 }
509 
510 pdeclaration(name, dec, tab, separator)
511 	char *name;
512 	declaration *dec;
513 	int tab;
514 	char *separator;
515 {
516 	char buf[8];	/* enough to hold "struct ", include NUL */
517 	char *prefix;
518 	char *type;
519 
520 	if (streq(dec->type, "void")) {
521 		return;
522 	}
523 	tabify(fout, tab);
524 	if (streq(dec->type, name) && !dec->prefix) {
525 		f_print(fout, "struct ");
526 	}
527 	if (streq(dec->type, "string")) {
528 		f_print(fout, "char *%s", dec->name);
529 	} else {
530 		prefix = "";
531 		if (streq(dec->type, "bool")) {
532 			type = "bool_t";
533 		} else if (streq(dec->type, "opaque")) {
534 			type = "char";
535 		} else {
536 			if (dec->prefix) {
537 				s_print(buf, "%s ", dec->prefix);
538 				prefix = buf;
539 			}
540 			type = dec->type;
541 		}
542 		switch (dec->rel) {
543 		case REL_ALIAS:
544 			f_print(fout, "%s%s %s", prefix, type, dec->name);
545 			break;
546 		case REL_VECTOR:
547 			f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
548 				dec->array_max);
549 			break;
550 		case REL_POINTER:
551 			f_print(fout, "%s%s *%s", prefix, type, dec->name);
552 			break;
553 		case REL_ARRAY:
554 			f_print(fout, "struct {\n");
555 			tabify(fout, tab);
556 			f_print(fout, "\tu_int %s_len;\n", dec->name);
557 			tabify(fout, tab);
558 			f_print(fout,
559 				"\t%s%s *%s_val;\n", prefix, type, dec->name);
560 			tabify(fout, tab);
561 			f_print(fout, "} %s", dec->name);
562 			break;
563 		}
564 	}
565 	f_print(fout, separator);
566 }
567 
568 static
569 undefined2(type, stop)
570 	char *type;
571 	char *stop;
572 {
573 	list *l;
574 	definition *def;
575 
576 	for (l = defined; l != NULL; l = l->next) {
577 		def = (definition *) l->val;
578 		if (def->def_kind != DEF_PROGRAM) {
579 			if (streq(def->def_name, stop)) {
580 				return (1);
581 			} else if (streq(def->def_name, type)) {
582 				return (0);
583 			}
584 		}
585 	}
586 	return (1);
587 }
588