xref: /netbsd-src/usr.bin/rpcgen/rpc_hout.c (revision 7944f94c110fc487c61b5c41bbd803b04eba69b0)
1*7944f94cSdholland /*	$NetBSD: rpc_hout.c,v 1.25 2016/01/23 02:33:09 dholland Exp $	*/
28f0abce1Sglass /*
38f0abce1Sglass  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
48f0abce1Sglass  * unrestricted use provided that this legend is included on all tape
58f0abce1Sglass  * media and as a part of the software program in whole or part.  Users
68f0abce1Sglass  * may copy or modify Sun RPC without charge, but are not authorized
78f0abce1Sglass  * to license or distribute it to anyone else except as part of a product or
871a0fb45Spk  * program developed by the user or with the express written consent of
971a0fb45Spk  * Sun Microsystems, Inc.
108f0abce1Sglass  *
118f0abce1Sglass  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
128f0abce1Sglass  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
138f0abce1Sglass  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
148f0abce1Sglass  *
158f0abce1Sglass  * Sun RPC is provided with no support and without any obligation on the
168f0abce1Sglass  * part of Sun Microsystems, Inc. to assist in its use, correction,
178f0abce1Sglass  * modification or enhancement.
188f0abce1Sglass  *
198f0abce1Sglass  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
208f0abce1Sglass  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
218f0abce1Sglass  * OR ANY PART THEREOF.
228f0abce1Sglass  *
238f0abce1Sglass  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
248f0abce1Sglass  * or profits or other special, indirect and consequential damages, even if
258f0abce1Sglass  * Sun has been advised of the possibility of such damages.
268f0abce1Sglass  *
278f0abce1Sglass  * Sun Microsystems, Inc.
288f0abce1Sglass  * 2550 Garcia Avenue
298f0abce1Sglass  * Mountain View, California  94043
308f0abce1Sglass  */
318f0abce1Sglass 
32b2f78261Sjmc #if HAVE_NBTOOL_CONFIG_H
33b2f78261Sjmc #include "nbtool_config.h"
34b2f78261Sjmc #endif
35b2f78261Sjmc 
3693579481Schristos #include <sys/cdefs.h>
379fbd8888Stv #if defined(__RCSID) && !defined(lint)
3893579481Schristos #if 0
3971a0fb45Spk static char sccsid[] = "@(#)rpc_hout.c 1.12 89/02/22 (C) 1987 SMI";
4093579481Schristos #else
41*7944f94cSdholland __RCSID("$NetBSD: rpc_hout.c,v 1.25 2016/01/23 02:33:09 dholland Exp $");
4293579481Schristos #endif
4371a0fb45Spk #endif
448f0abce1Sglass 
458f0abce1Sglass /*
468f0abce1Sglass  * rpc_hout.c, Header file outputter for the RPC protocol compiler
478f0abce1Sglass  */
488f0abce1Sglass #include <ctype.h>
499fbd8888Stv #include <err.h>
509fbd8888Stv #include <stdio.h>
5193579481Schristos #include "rpc_scan.h"
528f0abce1Sglass #include "rpc_parse.h"
5371a0fb45Spk #include "rpc_util.h"
548f0abce1Sglass 
550213edf0Schristos static void pconstdef(definition *);
560213edf0Schristos static void pargdef(definition *);
570213edf0Schristos static void pstructdef(definition *);
580213edf0Schristos static void puniondef(definition *);
590213edf0Schristos static void pdefine(const char *, const char *);
600213edf0Schristos static void puldefine(const char *, const char *);
610213edf0Schristos static int define_printed(proc_list *, version_list *);
620213edf0Schristos static void pprogramdef(definition *);
630213edf0Schristos static void penumdef(definition *);
640213edf0Schristos static void ptypedef(definition *);
650213edf0Schristos static int undefined2(const char *, const char *);
660213edf0Schristos static void cplusplusstart(void);
670213edf0Schristos static void cplusplusend(void);
688f0abce1Sglass 
698f0abce1Sglass /*
708f0abce1Sglass  * Print the C-version of an xdr definition
718f0abce1Sglass  */
728f0abce1Sglass void
print_datadef(definition * def)73e9067f11Sdholland print_datadef(definition *def)
748f0abce1Sglass {
7571a0fb45Spk 
7671a0fb45Spk 	if (def->def_kind == DEF_PROGRAM)	/* handle data only */
7771a0fb45Spk 		return;
7871a0fb45Spk 
798f0abce1Sglass 	if (def->def_kind != DEF_CONST) {
808f0abce1Sglass 		f_print(fout, "\n");
818f0abce1Sglass 	}
828f0abce1Sglass 	switch (def->def_kind) {
838f0abce1Sglass 	case DEF_STRUCT:
848f0abce1Sglass 		pstructdef(def);
858f0abce1Sglass 		break;
868f0abce1Sglass 	case DEF_UNION:
878f0abce1Sglass 		puniondef(def);
888f0abce1Sglass 		break;
898f0abce1Sglass 	case DEF_ENUM:
908f0abce1Sglass 		penumdef(def);
918f0abce1Sglass 		break;
928f0abce1Sglass 	case DEF_TYPEDEF:
938f0abce1Sglass 		ptypedef(def);
948f0abce1Sglass 		break;
958f0abce1Sglass 	case DEF_PROGRAM:
968f0abce1Sglass 		pprogramdef(def);
978f0abce1Sglass 		break;
988f0abce1Sglass 	case DEF_CONST:
998f0abce1Sglass 		pconstdef(def);
1008f0abce1Sglass 		break;
1018f0abce1Sglass 	}
1028f0abce1Sglass }
10371a0fb45Spk 
10471a0fb45Spk void
print_progdef(definition * def)1050213edf0Schristos print_progdef(definition *def)
10671a0fb45Spk {
10771a0fb45Spk 	switch (def->def_kind) {
10871a0fb45Spk 	case DEF_PROGRAM:
1098f0abce1Sglass 		f_print(fout, "\n");
11071a0fb45Spk 		pprogramdef(def);
11171a0fb45Spk 		break;
11293579481Schristos 	case DEF_CONST:
11393579481Schristos 	case DEF_TYPEDEF:
11493579481Schristos 	case DEF_ENUM:
11593579481Schristos 	case DEF_UNION:
11693579481Schristos 	case DEF_STRUCT:
11793579481Schristos 		break;
1188f0abce1Sglass 	}
1198f0abce1Sglass }
1208f0abce1Sglass 
12193579481Schristos void
print_funcdef(definition * def,int * did)1220213edf0Schristos print_funcdef(definition *def, int *did)
1230213edf0Schristos {
1240213edf0Schristos 	switch (def->def_kind) {
1250213edf0Schristos 	case DEF_PROGRAM:
1260213edf0Schristos 	case DEF_CONST:
1270213edf0Schristos 		break;
1280213edf0Schristos 	case DEF_TYPEDEF:
1290213edf0Schristos 	case DEF_ENUM:
1300213edf0Schristos 	case DEF_UNION:
1310213edf0Schristos 	case DEF_STRUCT:
1320213edf0Schristos 		if (!*did) {
1330213edf0Schristos 		    f_print(fout, "\n");
1340213edf0Schristos 		    cplusplusstart();
1350213edf0Schristos 		    *did = 1;
1360213edf0Schristos 		}
1370213edf0Schristos 		pxdrfuncdecl(def->def_name,
1380213edf0Schristos 		    def->def_kind != DEF_TYPEDEF ||
1390213edf0Schristos 		    !isvectordef(def->def.ty.old_type, def->def.ty.rel));
1400213edf0Schristos 		break;
1410213edf0Schristos 	}
1420213edf0Schristos }
1430213edf0Schristos 
1440213edf0Schristos void
print_funcend(int did)1450213edf0Schristos print_funcend(int did) {
1460213edf0Schristos 	if (did) {
1470213edf0Schristos 		cplusplusend();
1480213edf0Schristos 	}
1490213edf0Schristos }
1500213edf0Schristos 
1510213edf0Schristos void
pxdrfuncdecl(const char * name,int pointerp)152e9067f11Sdholland pxdrfuncdecl(const char *name, int pointerp)
15371a0fb45Spk {
15471a0fb45Spk 
1550213edf0Schristos 	f_print(fout, "bool_t xdr_%s(XDR *, %s%s);\n", name,
15671a0fb45Spk 	    name, pointerp ? (" *") : "");
15771a0fb45Spk }
15871a0fb45Spk 
15971a0fb45Spk 
16093579481Schristos static void
pconstdef(definition * def)161e9067f11Sdholland pconstdef(definition *def)
1628f0abce1Sglass {
1638f0abce1Sglass 	pdefine(def->def_name, def->def.co);
1648f0abce1Sglass }
165e9067f11Sdholland 
16671a0fb45Spk /* print out the definitions for the arguments of functions in the
16771a0fb45Spk    header file
16871a0fb45Spk */
16993579481Schristos static void
pargdef(definition * def)170e9067f11Sdholland pargdef(definition *def)
17171a0fb45Spk {
17271a0fb45Spk 	decl_list *l;
17371a0fb45Spk 	version_list *vers;
17471a0fb45Spk 	char   *name;
17571a0fb45Spk 	proc_list *plist;
1760213edf0Schristos 	int did;
17771a0fb45Spk 
17871a0fb45Spk 
17971a0fb45Spk 	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
1800213edf0Schristos 		for (plist = vers->procs; plist != NULL; plist = plist->next) {
18171a0fb45Spk 			if (!newstyle || plist->arg_num < 2) {
18271a0fb45Spk 				continue;	/* old style or single args */
18371a0fb45Spk 			}
18471a0fb45Spk 			name = plist->args.argname;
18571a0fb45Spk 			f_print(fout, "struct %s {\n", name);
18671a0fb45Spk 			for (l = plist->args.decls;
18771a0fb45Spk 			    l != NULL; l = l->next) {
18871a0fb45Spk 				pdeclaration(name, &l->decl, 1, ";\n");
18971a0fb45Spk 			}
19071a0fb45Spk 			f_print(fout, "};\n");
19171a0fb45Spk 			f_print(fout, "typedef struct %s %s;\n", name, name);
19271a0fb45Spk 		}
19371a0fb45Spk 	}
1940213edf0Schristos 	did = 0;
1950213edf0Schristos 	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
19629aa8e74Skamil 		for (plist = vers->procs; plist != NULL; plist = plist->next) {
1970213edf0Schristos 			if (!newstyle || plist->arg_num < 2) {
1980213edf0Schristos 				continue;	/* old style or single args */
1990213edf0Schristos 			}
20029aa8e74Skamil 
2010213edf0Schristos 			if (!did) {
2020213edf0Schristos 				cplusplusstart();
2030213edf0Schristos 				did = 1;
2040213edf0Schristos 			}
2050213edf0Schristos 			pxdrfuncdecl(plist->args.argname, 1);
2060213edf0Schristos 		}
2070213edf0Schristos 	}
2080213edf0Schristos 	if (did) {
2090213edf0Schristos 		cplusplusend();
2100213edf0Schristos 	}
21171a0fb45Spk 
21271a0fb45Spk }
21371a0fb45Spk 
21471a0fb45Spk 
21593579481Schristos static void
pstructdef(definition * def)216e9067f11Sdholland pstructdef(definition *def)
2178f0abce1Sglass {
2188f0abce1Sglass 	decl_list *l;
219e9067f11Sdholland 	const char *name = def->def_name;
2208f0abce1Sglass 
2218f0abce1Sglass 	f_print(fout, "struct %s {\n", name);
2228f0abce1Sglass 	for (l = def->def.st.decls; l != NULL; l = l->next) {
22371a0fb45Spk 		pdeclaration(name, &l->decl, 1, ";\n");
2248f0abce1Sglass 	}
2258f0abce1Sglass 	f_print(fout, "};\n");
2268f0abce1Sglass 	f_print(fout, "typedef struct %s %s;\n", name, name);
2278f0abce1Sglass }
2288f0abce1Sglass 
22993579481Schristos static void
puniondef(definition * def)230e9067f11Sdholland puniondef(definition *def)
2318f0abce1Sglass {
2328f0abce1Sglass 	case_list *l;
233e9067f11Sdholland 	const char *name = def->def_name;
2348f0abce1Sglass 	declaration *decl;
2358f0abce1Sglass 
2368f0abce1Sglass 	f_print(fout, "struct %s {\n", name);
2378f0abce1Sglass 	decl = &def->def.un.enum_decl;
2388f0abce1Sglass 	if (streq(decl->type, "bool")) {
2398f0abce1Sglass 		f_print(fout, "\tbool_t %s;\n", decl->name);
2408f0abce1Sglass 	} else {
2418f0abce1Sglass 		f_print(fout, "\t%s %s;\n", decl->type, decl->name);
2428f0abce1Sglass 	}
2438f0abce1Sglass 	f_print(fout, "\tunion {\n");
2448f0abce1Sglass 	for (l = def->def.un.cases; l != NULL; l = l->next) {
24571a0fb45Spk 		if (l->contflag == 0)
24671a0fb45Spk 			pdeclaration(name, &l->case_decl, 2, ";\n");
2478f0abce1Sglass 	}
2488f0abce1Sglass 	decl = def->def.un.default_decl;
2498f0abce1Sglass 	if (decl && !streq(decl->type, "void")) {
25071a0fb45Spk 		pdeclaration(name, decl, 2, ";\n");
2518f0abce1Sglass 	}
2528f0abce1Sglass 	f_print(fout, "\t} %s_u;\n", name);
2538f0abce1Sglass 	f_print(fout, "};\n");
2548f0abce1Sglass 	f_print(fout, "typedef struct %s %s;\n", name, name);
2558f0abce1Sglass }
2568f0abce1Sglass 
25793579481Schristos static void
pdefine(const char * name,const char * num)258e9067f11Sdholland pdefine(const char *name, const char *num)
2598f0abce1Sglass {
2608f0abce1Sglass 	f_print(fout, "#define %s %s\n", name, num);
2618f0abce1Sglass }
2628f0abce1Sglass 
26393579481Schristos static void
puldefine(const char * name,const char * num)264e9067f11Sdholland puldefine(const char *name, const char *num)
2658f0abce1Sglass {
26621a52aabSfvdl 	f_print(fout, "#define %s %s\n", name, num);
2678f0abce1Sglass }
2688f0abce1Sglass 
26993579481Schristos static int
define_printed(proc_list * stop,version_list * start)270e9067f11Sdholland define_printed(proc_list *stop, version_list *start)
2718f0abce1Sglass {
2728f0abce1Sglass 	version_list *vers;
2738f0abce1Sglass 	proc_list *proc;
2748f0abce1Sglass 
2758f0abce1Sglass 	for (vers = start; vers != NULL; vers = vers->next) {
2768f0abce1Sglass 		for (proc = vers->procs; proc != NULL; proc = proc->next) {
2778f0abce1Sglass 			if (proc == stop) {
2788f0abce1Sglass 				return (0);
27999071d1bSlukem 			} else
28099071d1bSlukem 				if (streq(proc->proc_name, stop->proc_name)) {
2818f0abce1Sglass 					return (1);
2828f0abce1Sglass 				}
2838f0abce1Sglass 		}
2848f0abce1Sglass 	}
285ceecfabaSdholland 	errx(1, "Internal error at %s:%d: procedure not found",
28693579481Schristos 	    __FILE__, __LINE__);
2878f0abce1Sglass 	/* NOTREACHED */
2888f0abce1Sglass }
2898f0abce1Sglass 
29093579481Schristos static void
cplusplusstart(void)2910213edf0Schristos cplusplusstart(void)
2920213edf0Schristos {
2930213edf0Schristos 	if (BSDflag)
2940213edf0Schristos 		f_print(fout, "__BEGIN_DECLS\n");
2950213edf0Schristos 	else
2960213edf0Schristos 		f_print(fout, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
2970213edf0Schristos }
2980213edf0Schristos 
2990213edf0Schristos static void
cplusplusend(void)3000213edf0Schristos cplusplusend(void)
3010213edf0Schristos {
3020213edf0Schristos 	if (BSDflag)
3030213edf0Schristos 		f_print(fout, "__END_DECLS\n");
3040213edf0Schristos 	else
3050213edf0Schristos 		f_print(fout, "#ifdef __cplusplus\n};\n#endif\n");
3060213edf0Schristos }
3070213edf0Schristos 
3080213edf0Schristos static void
pprogramdef(definition * def)309e9067f11Sdholland pprogramdef(definition *def)
3108f0abce1Sglass {
3118f0abce1Sglass 	version_list *vers;
3128f0abce1Sglass 	proc_list *proc;
31371a0fb45Spk 
31471a0fb45Spk 	pargdef(def);
3158f0abce1Sglass 
3168f0abce1Sglass 	puldefine(def->def_name, def->def.pr.prog_num);
3178f0abce1Sglass 	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
31871a0fb45Spk 		if (tblflag) {
31971a0fb45Spk 			f_print(fout, "extern struct rpcgen_table %s_%s_table[];\n",
32071a0fb45Spk 			    locase(def->def_name), vers->vers_num);
32171a0fb45Spk 			f_print(fout, "extern %s_%s_nproc;\n",
32271a0fb45Spk 			    locase(def->def_name), vers->vers_num);
32371a0fb45Spk 		}
3248f0abce1Sglass 		puldefine(vers->vers_name, vers->vers_num);
3258f0abce1Sglass 		for (proc = vers->procs; proc != NULL; proc = proc->next) {
3268f0abce1Sglass 			if (!define_printed(proc, def->def.pr.versions)) {
3278f0abce1Sglass 				puldefine(proc->proc_name, proc->proc_num);
3288f0abce1Sglass 			}
3290213edf0Schristos 		}
3308f0abce1Sglass 	}
33171a0fb45Spk 
3320213edf0Schristos 	/*
3330213edf0Schristos 	 * Print out 3 definitions, one for ANSI-C, another for C++, a
3340213edf0Schristos 	 * third for old style C
3350213edf0Schristos 	 */
3360213edf0Schristos 	f_print(fout, "\n");
3370213edf0Schristos 	cplusplusstart();
3380213edf0Schristos 	for (vers = def->def.pr.versions; vers != NULL; vers = vers->next) {
3390213edf0Schristos 		for (proc = vers->procs; proc != NULL; proc = proc->next) {
3400213edf0Schristos 			pprocdef(proc, vers, "CLIENT *", 0);
3410213edf0Schristos 			pprocdef(proc, vers, "struct svc_req *", 1);
34271a0fb45Spk 		}
3438f0abce1Sglass 	}
3440213edf0Schristos 	cplusplusend();
3458f0abce1Sglass }
3468f0abce1Sglass 
34793579481Schristos void
pprocdef(proc_list * proc,version_list * vp,const char * addargtype,int server_p)348e9067f11Sdholland pprocdef(proc_list *proc, version_list *vp, const char *addargtype,
3490213edf0Schristos      int server_p)
3508f0abce1Sglass {
351b1bad8f6Smycroft 	decl_list *dl;
35271a0fb45Spk 
353b1bad8f6Smycroft 	if (Mflag) {
354b1bad8f6Smycroft 		if (server_p)
355b1bad8f6Smycroft 			f_print(fout, "bool_t ");
356b1bad8f6Smycroft 		else
357b1bad8f6Smycroft 			f_print(fout, "enum clnt_stat ");
358b1bad8f6Smycroft 	} else {
35971a0fb45Spk 		ptype(proc->res_prefix, proc->res_type, 1);
36071a0fb45Spk 		f_print(fout, "*");
361b1bad8f6Smycroft 	}
36271a0fb45Spk 	if (server_p)
36371a0fb45Spk 		pvname_svc(proc->proc_name, vp->vers_num);
36471a0fb45Spk 	else
3658f0abce1Sglass 		pvname(proc->proc_name, vp->vers_num);
36671a0fb45Spk 
36771a0fb45Spk 	f_print(fout, "(");
36871a0fb45Spk 	if (proc->arg_num < 2 && newstyle &&
36971a0fb45Spk 	    streq(proc->args.decls->decl.type, "void")) {
37071a0fb45Spk 		/* 0 argument in new style:  do nothing */
37171a0fb45Spk 	} else {
37271a0fb45Spk 		for (dl = proc->args.decls; dl != NULL; dl = dl->next) {
37371a0fb45Spk 			ptype(dl->decl.prefix, dl->decl.type, 1);
37471a0fb45Spk 			if (!newstyle)
375b1bad8f6Smycroft 				f_print(fout, "*");
37671a0fb45Spk 			f_print(fout, ", ");
37771a0fb45Spk 		}
37871a0fb45Spk 	}
379b1bad8f6Smycroft 	if (Mflag) {
380b1bad8f6Smycroft 		if (streq(proc->res_type, "void"))
381b1bad8f6Smycroft 			f_print(fout, "char");
382b1bad8f6Smycroft 		else
383b1bad8f6Smycroft 			ptype(proc->res_prefix, proc->res_type, 0);
384b1bad8f6Smycroft 		if (!isvectordef(proc->res_type, REL_ALIAS))
385b1bad8f6Smycroft 			f_print(fout, "*");
386b1bad8f6Smycroft 		f_print(fout, ", ");
387b1bad8f6Smycroft 	}
38871a0fb45Spk 	f_print(fout, "%s);\n", addargtype);
38971a0fb45Spk }
390b1bad8f6Smycroft 
39171a0fb45Spk 
39293579481Schristos static void
penumdef(definition * def)393e9067f11Sdholland penumdef(definition *def)
3948f0abce1Sglass {
395e9067f11Sdholland 	const char *name = def->def_name;
3968f0abce1Sglass 	enumval_list *l;
397e9067f11Sdholland 	const char *last = NULL;
3988f0abce1Sglass 	int count = 0;
399e9067f11Sdholland 	const char *first = "";
4008f0abce1Sglass 
4018f0abce1Sglass 	f_print(fout, "enum %s {\n", name);
4028f0abce1Sglass 	for (l = def->def.en.vals; l != NULL; l = l->next) {
403ed811ba9Schristos 		f_print(fout, "%s\t%s", first, l->name);
4048f0abce1Sglass 		if (l->assignment) {
4058f0abce1Sglass 			f_print(fout, " = %s", l->assignment);
4068f0abce1Sglass 			last = l->assignment;
4078f0abce1Sglass 			count = 1;
4088f0abce1Sglass 		} else {
4098f0abce1Sglass 			if (last == NULL) {
4108f0abce1Sglass 				f_print(fout, " = %d", count++);
4118f0abce1Sglass 			} else {
4128f0abce1Sglass 				f_print(fout, " = %s + %d", last, count++);
4138f0abce1Sglass 			}
4148f0abce1Sglass 		}
415ed811ba9Schristos 		first = ",\n";
4168f0abce1Sglass 	}
417ed811ba9Schristos 	f_print(fout, "\n};\n");
4188f0abce1Sglass 	f_print(fout, "typedef enum %s %s;\n", name, name);
4198f0abce1Sglass }
4208f0abce1Sglass 
42193579481Schristos static void
ptypedef(definition * def)422e9067f11Sdholland ptypedef(definition *def)
4238f0abce1Sglass {
424e9067f11Sdholland 	const char *name = def->def_name;
425e9067f11Sdholland 	const char *old = def->def.ty.old_type;
4268f0abce1Sglass 	char    prefix[8];	/* enough to contain "struct ", including NUL */
4278f0abce1Sglass 	relation rel = def->def.ty.rel;
4288f0abce1Sglass 
4298f0abce1Sglass 
4308f0abce1Sglass 	if (!streq(name, old)) {
4318f0abce1Sglass 		if (streq(old, "string")) {
4328f0abce1Sglass 			old = "char";
4338f0abce1Sglass 			rel = REL_POINTER;
43499071d1bSlukem 		} else
43599071d1bSlukem 			if (streq(old, "opaque")) {
4368f0abce1Sglass 				old = "char";
43799071d1bSlukem 			} else
43899071d1bSlukem 				if (streq(old, "bool")) {
4398f0abce1Sglass 					old = "bool_t";
4408f0abce1Sglass 				}
4418f0abce1Sglass 		if (undefined2(old, name) && def->def.ty.old_prefix) {
4428f0abce1Sglass 			s_print(prefix, "%s ", def->def.ty.old_prefix);
4438f0abce1Sglass 		} else {
4448f0abce1Sglass 			prefix[0] = 0;
4458f0abce1Sglass 		}
4468f0abce1Sglass 		f_print(fout, "typedef ");
4478f0abce1Sglass 		switch (rel) {
4488f0abce1Sglass 		case REL_ARRAY:
4498f0abce1Sglass 			f_print(fout, "struct {\n");
450*7944f94cSdholland 			f_print(fout, "\tunsigned int %s_len;\n", name);
4518f0abce1Sglass 			f_print(fout, "\t%s%s *%s_val;\n", prefix, old, name);
4528f0abce1Sglass 			f_print(fout, "} %s", name);
4538f0abce1Sglass 			break;
4548f0abce1Sglass 		case REL_POINTER:
4558f0abce1Sglass 			f_print(fout, "%s%s *%s", prefix, old, name);
4568f0abce1Sglass 			break;
4578f0abce1Sglass 		case REL_VECTOR:
4588f0abce1Sglass 			f_print(fout, "%s%s %s[%s]", prefix, old, name,
4598f0abce1Sglass 			    def->def.ty.array_max);
4608f0abce1Sglass 			break;
4618f0abce1Sglass 		case REL_ALIAS:
4628f0abce1Sglass 			f_print(fout, "%s%s %s", prefix, old, name);
4638f0abce1Sglass 			break;
4648f0abce1Sglass 		}
4658f0abce1Sglass 		f_print(fout, ";\n");
4668f0abce1Sglass 	}
4678f0abce1Sglass }
4688f0abce1Sglass 
46993579481Schristos void
pdeclaration(const char * name,declaration * dec,int tab,const char * separator)470e9067f11Sdholland pdeclaration(const char *name, declaration *dec, int tab,
471e9067f11Sdholland 	     const char *separator)
4728f0abce1Sglass {
4738f0abce1Sglass 	char    buf[8];		/* enough to hold "struct ", include NUL */
474e9067f11Sdholland 	const char *prefix;
475e9067f11Sdholland 	const char *type;
4768f0abce1Sglass 
4778f0abce1Sglass 	if (streq(dec->type, "void")) {
4788f0abce1Sglass 		return;
4798f0abce1Sglass 	}
4808f0abce1Sglass 	tabify(fout, tab);
4818f0abce1Sglass 	if (streq(dec->type, name) && !dec->prefix) {
4828f0abce1Sglass 		f_print(fout, "struct ");
4838f0abce1Sglass 	}
4848f0abce1Sglass 	if (streq(dec->type, "string")) {
4858f0abce1Sglass 		f_print(fout, "char *%s", dec->name);
4868f0abce1Sglass 	} else {
4878f0abce1Sglass 		prefix = "";
4888f0abce1Sglass 		if (streq(dec->type, "bool")) {
4898f0abce1Sglass 			type = "bool_t";
49099071d1bSlukem 		} else
49199071d1bSlukem 			if (streq(dec->type, "opaque")) {
4928f0abce1Sglass 				type = "char";
4938f0abce1Sglass 			} else {
4948f0abce1Sglass 				if (dec->prefix) {
4958f0abce1Sglass 					s_print(buf, "%s ", dec->prefix);
4968f0abce1Sglass 					prefix = buf;
4978f0abce1Sglass 				}
4988f0abce1Sglass 				type = dec->type;
4998f0abce1Sglass 			}
5008f0abce1Sglass 		switch (dec->rel) {
5018f0abce1Sglass 		case REL_ALIAS:
5028f0abce1Sglass 			f_print(fout, "%s%s %s", prefix, type, dec->name);
5038f0abce1Sglass 			break;
5048f0abce1Sglass 		case REL_VECTOR:
5058f0abce1Sglass 			f_print(fout, "%s%s %s[%s]", prefix, type, dec->name,
5068f0abce1Sglass 			    dec->array_max);
5078f0abce1Sglass 			break;
5088f0abce1Sglass 		case REL_POINTER:
5098f0abce1Sglass 			f_print(fout, "%s%s *%s", prefix, type, dec->name);
5108f0abce1Sglass 			break;
5118f0abce1Sglass 		case REL_ARRAY:
5128f0abce1Sglass 			f_print(fout, "struct {\n");
5138f0abce1Sglass 			tabify(fout, tab);
514*7944f94cSdholland 			f_print(fout, "\tunsigned int %s_len;\n", dec->name);
5158f0abce1Sglass 			tabify(fout, tab);
5168f0abce1Sglass 			f_print(fout, "\t%s%s *%s_val;\n", prefix, type, dec->name);
5178f0abce1Sglass 			tabify(fout, tab);
5188f0abce1Sglass 			f_print(fout, "} %s", dec->name);
5198f0abce1Sglass 			break;
5208f0abce1Sglass 		}
5218f0abce1Sglass 	}
522135600f9Sis 	f_print(fout, "%s", separator);
5238f0abce1Sglass }
5248f0abce1Sglass 
52593579481Schristos static int
undefined2(const char * type,const char * stop)526e9067f11Sdholland undefined2(const char *type, const char *stop)
5278f0abce1Sglass {
5288f0abce1Sglass 	list   *l;
5298f0abce1Sglass 	definition *def;
5308f0abce1Sglass 
5318f0abce1Sglass 	for (l = defined; l != NULL; l = l->next) {
5328f0abce1Sglass 		def = (definition *) l->val;
5338f0abce1Sglass 		if (def->def_kind != DEF_PROGRAM) {
5348f0abce1Sglass 			if (streq(def->def_name, stop)) {
5358f0abce1Sglass 				return (1);
53699071d1bSlukem 			} else
53799071d1bSlukem 				if (streq(def->def_name, type)) {
5388f0abce1Sglass 					return (0);
5398f0abce1Sglass 				}
5408f0abce1Sglass 		}
5418f0abce1Sglass 	}
5428f0abce1Sglass 	return (1);
5438f0abce1Sglass }
544