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