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