xref: /illumos-gate/usr/src/tools/ndrgen/ndr_gen.c (revision d0e518695adc90b82233b99af7dffbb3d3f92c00)
1*d0e51869Samw /*
2*d0e51869Samw  * CDDL HEADER START
3*d0e51869Samw  *
4*d0e51869Samw  * The contents of this file are subject to the terms of the
5*d0e51869Samw  * Common Development and Distribution License (the "License").
6*d0e51869Samw  * You may not use this file except in compliance with the License.
7*d0e51869Samw  *
8*d0e51869Samw  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*d0e51869Samw  * or http://www.opensolaris.org/os/licensing.
10*d0e51869Samw  * See the License for the specific language governing permissions
11*d0e51869Samw  * and limitations under the License.
12*d0e51869Samw  *
13*d0e51869Samw  * When distributing Covered Code, include this CDDL HEADER in each
14*d0e51869Samw  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*d0e51869Samw  * If applicable, add the following below this CDDL HEADER, with the
16*d0e51869Samw  * fields enclosed by brackets "[]" replaced with your own identifying
17*d0e51869Samw  * information: Portions Copyright [yyyy] [name of copyright owner]
18*d0e51869Samw  *
19*d0e51869Samw  * CDDL HEADER END
20*d0e51869Samw  */
21*d0e51869Samw 
22*d0e51869Samw /*
23*d0e51869Samw  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24*d0e51869Samw  * Use is subject to license terms.
25*d0e51869Samw  */
26*d0e51869Samw 
27*d0e51869Samw #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*d0e51869Samw 
29*d0e51869Samw #include <string.h>
30*d0e51869Samw #include "ndrgen.h"
31*d0e51869Samw #include "y.tab.h"
32*d0e51869Samw 
33*d0e51869Samw 
34*d0e51869Samw static void generate_struct(ndr_typeinfo_t *);
35*d0e51869Samw static void generate_params(ndr_typeinfo_t *);
36*d0e51869Samw static void generate_union(ndr_typeinfo_t *);
37*d0e51869Samw static void generate_arg(ndr_node_t *);
38*d0e51869Samw static void generate_member_macro(char *, char *, ndr_member_t *,
39*d0e51869Samw     ndr_typeinfo_t *);
40*d0e51869Samw static void generate_member_macro_with_arg(char *, char *, ndr_member_t *,
41*d0e51869Samw     ndr_typeinfo_t *, ndr_node_t *);
42*d0e51869Samw static void generate_prototypes(ndr_typeinfo_t *, char *);
43*d0e51869Samw static void generate_member_prototypes(ndr_typeinfo_t *, ndr_member_t *,
44*d0e51869Samw     char *);
45*d0e51869Samw static void generate_member(ndr_typeinfo_t *, ndr_member_t *);
46*d0e51869Samw static void generate_aggregate_common_begin(ndr_typeinfo_t *);
47*d0e51869Samw static void generate_aggregate_common_finish(ndr_typeinfo_t *);
48*d0e51869Samw static void generate_typeinfo_packing(ndr_typeinfo_t *);
49*d0e51869Samw static void generate_typeinfo_typeinfo(ndr_typeinfo_t *, int, char *);
50*d0e51869Samw 
51*d0e51869Samw 
52*d0e51869Samw void
53*d0e51869Samw generate(void)
54*d0e51869Samw {
55*d0e51869Samw 	ndr_typeinfo_t		*ti;
56*d0e51869Samw 	char			fname_type[NDLBUFSZ];
57*d0e51869Samw 
58*d0e51869Samw 	(void) printf("\n");
59*d0e51869Samw 
60*d0e51869Samw 	for (ti = typeinfo_list; ti; ti = ti->next) {
61*d0e51869Samw 		if (ti->is_extern || ti->advice.a_extern) {
62*d0e51869Samw 			type_extern_suffix(ti, fname_type, NDLBUFSZ);
63*d0e51869Samw 			(void) printf(
64*d0e51869Samw 			    "extern struct ndr_typeinfo ndt_%s;\n",
65*d0e51869Samw 			    fname_type);
66*d0e51869Samw 			continue;
67*d0e51869Samw 		}
68*d0e51869Samw 
69*d0e51869Samw 		switch (ti->type_op) {
70*d0e51869Samw 		case STRUCT_KW:
71*d0e51869Samw 			if (ti->advice.a_operation)
72*d0e51869Samw 				generate_params(ti);
73*d0e51869Samw 			else
74*d0e51869Samw 				generate_struct(ti);
75*d0e51869Samw 			break;
76*d0e51869Samw 
77*d0e51869Samw 		case UNION_KW:
78*d0e51869Samw 			generate_union(ti);
79*d0e51869Samw 			break;
80*d0e51869Samw 
81*d0e51869Samw 		case TYPEDEF_KW:
82*d0e51869Samw 			/* silently skip */
83*d0e51869Samw 			continue;
84*d0e51869Samw 
85*d0e51869Samw 		case STRING_KW:
86*d0e51869Samw 		case STAR:
87*d0e51869Samw 		case LB:
88*d0e51869Samw 		case BASIC_TYPE:
89*d0e51869Samw 			if (!ti->is_referenced) {
90*d0e51869Samw 				type_extern_suffix(ti, fname_type, NDLBUFSZ);
91*d0e51869Samw 				(void) printf("extern ndt_%s\n", fname_type);
92*d0e51869Samw 				type_null_decl(ti, fname_type, NDLBUFSZ);
93*d0e51869Samw 				(void) printf("/* %s */\n", fname_type);
94*d0e51869Samw 			}
95*d0e51869Samw 			break;
96*d0e51869Samw 
97*d0e51869Samw 		default:
98*d0e51869Samw 			continue;
99*d0e51869Samw 		}
100*d0e51869Samw 	}
101*d0e51869Samw }
102*d0e51869Samw 
103*d0e51869Samw static void
104*d0e51869Samw generate_struct(ndr_typeinfo_t *ti)
105*d0e51869Samw {
106*d0e51869Samw 	int		i;
107*d0e51869Samw 	ndr_member_t	*mem;
108*d0e51869Samw 
109*d0e51869Samw 	if (ti->advice.a_no_reorder) {
110*d0e51869Samw 		/* just use generate_params(), which can safely do this */
111*d0e51869Samw 		generate_params(ti);
112*d0e51869Samw 		return;
113*d0e51869Samw 	}
114*d0e51869Samw 
115*d0e51869Samw 	generate_aggregate_common_begin(ti);
116*d0e51869Samw 
117*d0e51869Samw 	(void) printf("	/* do all basic elements first */\n");
118*d0e51869Samw 	for (i = 0; i < ti->n_member; i++) {
119*d0e51869Samw 		mem = &ti->member[i];
120*d0e51869Samw 		if (mem->type->type_op != BASIC_TYPE)
121*d0e51869Samw 			continue;
122*d0e51869Samw 
123*d0e51869Samw 		generate_member(ti, mem);
124*d0e51869Samw 	}
125*d0e51869Samw 
126*d0e51869Samw 	(void) printf("\n");
127*d0e51869Samw 	(void) printf("	/* do all constructed elements w/o pointers */\n");
128*d0e51869Samw 	for (i = 0; i < ti->n_member; i++) {
129*d0e51869Samw 		mem = &ti->member[i];
130*d0e51869Samw 		if (mem->type->type_op == BASIC_TYPE)
131*d0e51869Samw 			continue;
132*d0e51869Samw 
133*d0e51869Samw 		if (mem->type->has_pointers)
134*d0e51869Samw 			continue;
135*d0e51869Samw 
136*d0e51869Samw 		generate_member(ti, mem);
137*d0e51869Samw 	}
138*d0e51869Samw 
139*d0e51869Samw 	(void) printf("\n");
140*d0e51869Samw 	(void) printf("	/* do members with pointers in order */\n");
141*d0e51869Samw 	for (i = 0; i < ti->n_member; i++) {
142*d0e51869Samw 		mem = &ti->member[i];
143*d0e51869Samw 		if (mem->type->type_op == BASIC_TYPE)
144*d0e51869Samw 			continue;
145*d0e51869Samw 
146*d0e51869Samw 		if (!mem->type->has_pointers)
147*d0e51869Samw 			continue;
148*d0e51869Samw 
149*d0e51869Samw 		generate_member(ti, mem);
150*d0e51869Samw 	}
151*d0e51869Samw 
152*d0e51869Samw 	generate_aggregate_common_finish(ti);
153*d0e51869Samw }
154*d0e51869Samw 
155*d0e51869Samw static void
156*d0e51869Samw generate_params(ndr_typeinfo_t *ti)
157*d0e51869Samw {
158*d0e51869Samw 	int		i;
159*d0e51869Samw 	ndr_member_t	*mem;
160*d0e51869Samw 
161*d0e51869Samw 	generate_aggregate_common_begin(ti);
162*d0e51869Samw 
163*d0e51869Samw 	(void) printf("	/* do all members in order */\n");
164*d0e51869Samw 	for (i = 0; i < ti->n_member; i++) {
165*d0e51869Samw 		mem = &ti->member[i];
166*d0e51869Samw 
167*d0e51869Samw 		generate_member(ti, mem);
168*d0e51869Samw 	}
169*d0e51869Samw 
170*d0e51869Samw 	generate_aggregate_common_finish(ti);
171*d0e51869Samw }
172*d0e51869Samw 
173*d0e51869Samw static void
174*d0e51869Samw generate_union(ndr_typeinfo_t *ti)
175*d0e51869Samw {
176*d0e51869Samw 	int		i;
177*d0e51869Samw 	ndr_member_t	*mem;
178*d0e51869Samw 	int		have_default = 0;
179*d0e51869Samw 	ndr_node_t	*np;
180*d0e51869Samw 
181*d0e51869Samw 	generate_aggregate_common_begin(ti);
182*d0e51869Samw 
183*d0e51869Samw 	(void) printf("    switch (encl_ref->switch_is) {\n");
184*d0e51869Samw 
185*d0e51869Samw 	for (i = 0; i < ti->n_member; i++) {
186*d0e51869Samw 		mem = &ti->member[i];
187*d0e51869Samw 
188*d0e51869Samw 		if ((np = mem->advice.a_case) != 0) {
189*d0e51869Samw 			(void) printf("    case ");
190*d0e51869Samw 			print_node(np->n_a_arg);
191*d0e51869Samw 			(void) printf(":\n");
192*d0e51869Samw 		} else if ((np = mem->advice.a_default) != 0) {
193*d0e51869Samw 			(void) printf("    default:\n");
194*d0e51869Samw 			if (have_default++) {
195*d0e51869Samw 				compile_error("multiple defaults");
196*d0e51869Samw 			}
197*d0e51869Samw 		} else {
198*d0e51869Samw 			compile_error("syntax error");
199*d0e51869Samw 		}
200*d0e51869Samw 
201*d0e51869Samw 		generate_member(ti, mem);
202*d0e51869Samw 		(void) printf("	break;\n\n");
203*d0e51869Samw 	}
204*d0e51869Samw 
205*d0e51869Samw 	if (!have_default) {
206*d0e51869Samw 		(void) printf("    default:\n");
207*d0e51869Samw 		(void) printf("	NDR_SET_ERROR(encl_ref, "
208*d0e51869Samw 		    "NDR_ERR_SWITCH_VALUE_INVALID);\n");
209*d0e51869Samw 		(void) printf("	return 0;\n");
210*d0e51869Samw 		(void) printf("	break;\n");
211*d0e51869Samw 	}
212*d0e51869Samw 
213*d0e51869Samw 	(void) printf("    }\n");
214*d0e51869Samw 	(void) printf("\n");
215*d0e51869Samw 
216*d0e51869Samw 	generate_aggregate_common_finish(ti);
217*d0e51869Samw }
218*d0e51869Samw 
219*d0e51869Samw static void
220*d0e51869Samw generate_arg(ndr_node_t *np)
221*d0e51869Samw {
222*d0e51869Samw 	if (np) {
223*d0e51869Samw 		if (np->label != IDENTIFIER && np->label != INTEGER)
224*d0e51869Samw 			np = np->n_a_arg;
225*d0e51869Samw 	} else {
226*d0e51869Samw 		/* this is bogus */
227*d0e51869Samw 		np = n_cons(IDENTIFIER, sym_enter("?WHAT?"));
228*d0e51869Samw 	}
229*d0e51869Samw 
230*d0e51869Samw 	if (np->label == IDENTIFIER)
231*d0e51869Samw 		(void) printf("val->%s", np->n_sym->name);
232*d0e51869Samw 	else
233*d0e51869Samw 		print_node(np);
234*d0e51869Samw }
235*d0e51869Samw 
236*d0e51869Samw static void
237*d0e51869Samw generate_member_macro(char *memkind, char *macro, ndr_member_t *mem,
238*d0e51869Samw     ndr_typeinfo_t *ti)
239*d0e51869Samw {
240*d0e51869Samw 	char	fname_type[NDLBUFSZ];
241*d0e51869Samw 
242*d0e51869Samw 	if (!macro)
243*d0e51869Samw 		macro = "";
244*d0e51869Samw 	if (!ti)
245*d0e51869Samw 		ti = mem->type;
246*d0e51869Samw 
247*d0e51869Samw 	type_extern_suffix(ti, fname_type, NDLBUFSZ);
248*d0e51869Samw 
249*d0e51869Samw 	if (memkind) {
250*d0e51869Samw 		(void) printf("	NDR_%sMEMBER%s (%s, %s);\n",
251*d0e51869Samw 		    memkind, macro, fname_type, mem->name);
252*d0e51869Samw 	} else {
253*d0e51869Samw 		(void) printf("	NDR_MEMBER%s (%s, %s, %uUL);\n",
254*d0e51869Samw 		    macro, fname_type, mem->name, mem->pdu_offset);
255*d0e51869Samw 	}
256*d0e51869Samw }
257*d0e51869Samw 
258*d0e51869Samw static void
259*d0e51869Samw generate_member_macro_with_arg(char *memkind, char *macro,
260*d0e51869Samw     ndr_member_t *mem, ndr_typeinfo_t *ti, ndr_node_t *np)
261*d0e51869Samw {
262*d0e51869Samw 	char	fname_type[NDLBUFSZ];
263*d0e51869Samw 
264*d0e51869Samw 	if (!macro)
265*d0e51869Samw 		macro = "_WITH_ARG";
266*d0e51869Samw 	if (!ti)
267*d0e51869Samw 		ti = mem->type;
268*d0e51869Samw 
269*d0e51869Samw 	type_extern_suffix(ti, fname_type, NDLBUFSZ);
270*d0e51869Samw 
271*d0e51869Samw 	if (memkind) {
272*d0e51869Samw 		(void) printf("	NDR_%sMEMBER%s (%s, %s,\n",
273*d0e51869Samw 		    memkind, macro, fname_type, mem->name);
274*d0e51869Samw 	} else {
275*d0e51869Samw 		(void) printf("	NDR_MEMBER%s (%s, %s, %uUL,\n",
276*d0e51869Samw 		    macro, fname_type, mem->name, mem->pdu_offset);
277*d0e51869Samw 	}
278*d0e51869Samw 
279*d0e51869Samw 	(void) printf("\t\t");
280*d0e51869Samw 	generate_arg(np);
281*d0e51869Samw 	(void) printf(");\n");
282*d0e51869Samw }
283*d0e51869Samw 
284*d0e51869Samw static void
285*d0e51869Samw generate_prototypes(ndr_typeinfo_t *ti, char *fname_type)
286*d0e51869Samw {
287*d0e51869Samw 	ndr_member_t *mem;
288*d0e51869Samw 	int i;
289*d0e51869Samw 
290*d0e51869Samw 	if (ti->type_op == STRUCT_KW && ti->advice.a_operation) {
291*d0e51869Samw 		for (i = 0; i < ti->n_member; i++) {
292*d0e51869Samw 			mem = &ti->member[i];
293*d0e51869Samw 
294*d0e51869Samw 			generate_member_prototypes(ti, mem, fname_type);
295*d0e51869Samw 		}
296*d0e51869Samw 	}
297*d0e51869Samw }
298*d0e51869Samw 
299*d0e51869Samw static void
300*d0e51869Samw generate_member_prototypes(ndr_typeinfo_t *ti,
301*d0e51869Samw     ndr_member_t *mem, char *fname_type)
302*d0e51869Samw {
303*d0e51869Samw 	char val_buf[NDLBUFSZ];
304*d0e51869Samw 	ndr_typeinfo_t ptr;
305*d0e51869Samw 
306*d0e51869Samw 	if (mem->type->type_op == UNION_KW) {
307*d0e51869Samw 		if (!mem->advice.a_in && mem->advice.a_out) {
308*d0e51869Samw 			ptr.type_op = STAR;
309*d0e51869Samw 			ptr.type_down = ti;
310*d0e51869Samw 			type_name_decl(&ptr, val_buf, NDLBUFSZ, "val");
311*d0e51869Samw 
312*d0e51869Samw 			(void) printf("\nextern void fixup%s(%s);\n",
313*d0e51869Samw 			    fname_type, val_buf);
314*d0e51869Samw 		}
315*d0e51869Samw 	}
316*d0e51869Samw }
317*d0e51869Samw 
318*d0e51869Samw static void
319*d0e51869Samw generate_member(ndr_typeinfo_t *ti, ndr_member_t *mem)
320*d0e51869Samw {
321*d0e51869Samw 	static char *fixup[] = {
322*d0e51869Samw 		"/*",
323*d0e51869Samw 		" * Cannot use the canned offsets to unmarshall multiple",
324*d0e51869Samw 		" * entry discriminated unions.  The service must provide",
325*d0e51869Samw 		" * this function to patch the offsets at runtime.",
326*d0e51869Samw 		" */"
327*d0e51869Samw 	};
328*d0e51869Samw 
329*d0e51869Samw 	char		fname_type[NDLBUFSZ];
330*d0e51869Samw 	ndr_node_t	*np;
331*d0e51869Samw 	int		is_reference = 0;
332*d0e51869Samw 	char		*memkind = 0;
333*d0e51869Samw 	int		cond_pending = 0;
334*d0e51869Samw 	int		i;
335*d0e51869Samw 
336*d0e51869Samw 	if (ti->advice.a_operation)
337*d0e51869Samw 		memkind = "TOPMOST_";
338*d0e51869Samw 	else if (ti->advice.a_interface)
339*d0e51869Samw 		memkind = "PARAMS_";
340*d0e51869Samw 
341*d0e51869Samw 	if (mem->advice.a_in && !mem->advice.a_out) {
342*d0e51869Samw 		cond_pending = 1;
343*d0e51869Samw 		(void) printf("    if (NDR_DIR_IS_IN) {\n");
344*d0e51869Samw 	}
345*d0e51869Samw 
346*d0e51869Samw 	if (!mem->advice.a_in && mem->advice.a_out) {
347*d0e51869Samw 		cond_pending = 1;
348*d0e51869Samw 		(void) printf("    if (NDR_DIR_IS_OUT) {\n");
349*d0e51869Samw 	}
350*d0e51869Samw 
351*d0e51869Samw 	type_extern_suffix(ti, fname_type, NDLBUFSZ);
352*d0e51869Samw 
353*d0e51869Samw 	switch (mem->type->type_op) {
354*d0e51869Samw 	case BASIC_TYPE:
355*d0e51869Samw 	case STRUCT_KW:
356*d0e51869Samw 		generate_member_macro(memkind, 0, mem, 0);
357*d0e51869Samw 		break;
358*d0e51869Samw 
359*d0e51869Samw 	case UNION_KW:
360*d0e51869Samw 		np = mem->advice.a_switch_is;
361*d0e51869Samw 
362*d0e51869Samw 		if (!mem->advice.a_in && mem->advice.a_out) {
363*d0e51869Samw 			for (i = 0; i < sizeof (fixup)/sizeof (fixup[0]); ++i)
364*d0e51869Samw 				(void) printf("\t%s\n", fixup[i]);
365*d0e51869Samw 
366*d0e51869Samw 			(void) printf("\tfixup%s(val);\n", fname_type);
367*d0e51869Samw 		}
368*d0e51869Samw 
369*d0e51869Samw 		generate_member_macro_with_arg(memkind,
370*d0e51869Samw 		    "_WITH_SWITCH_IS", mem, 0, np);
371*d0e51869Samw 		break;
372*d0e51869Samw 
373*d0e51869Samw 	case STAR:
374*d0e51869Samw 		if (mem->advice.a_reference)
375*d0e51869Samw 			is_reference = 1;
376*d0e51869Samw 		else
377*d0e51869Samw 			is_reference = 0;
378*d0e51869Samw 
379*d0e51869Samw 		np = mem->advice.a_size_is;
380*d0e51869Samw 		if (np) {
381*d0e51869Samw 			generate_member_macro_with_arg(memkind,
382*d0e51869Samw 			    is_reference ?
383*d0e51869Samw 			    "_REF_WITH_SIZE_IS" : "_PTR_WITH_SIZE_IS",
384*d0e51869Samw 			    mem, mem->type->type_down, np);
385*d0e51869Samw 			break;
386*d0e51869Samw 		}
387*d0e51869Samw 
388*d0e51869Samw 		np = mem->advice.a_length_is;
389*d0e51869Samw 		if (np) {
390*d0e51869Samw 			generate_member_macro_with_arg(memkind,
391*d0e51869Samw 			    is_reference ?
392*d0e51869Samw 			    "_REF_WITH_LENGTH_IS" : "_PTR_WITH_LENGTH_IS",
393*d0e51869Samw 			    mem, mem->type->type_down, np);
394*d0e51869Samw 			break;
395*d0e51869Samw 		}
396*d0e51869Samw 
397*d0e51869Samw 		generate_member_macro(memkind,
398*d0e51869Samw 		    is_reference ? "_REF" : "_PTR",
399*d0e51869Samw 		    mem, mem->type->type_down);
400*d0e51869Samw 		break;
401*d0e51869Samw 
402*d0e51869Samw 	case LB:
403*d0e51869Samw 		np = mem->advice.a_size_is;
404*d0e51869Samw 		if (np) {
405*d0e51869Samw 			generate_member_macro_with_arg(memkind,
406*d0e51869Samw 			    "_ARR_WITH_SIZE_IS",
407*d0e51869Samw 			    mem, mem->type->type_down, np);
408*d0e51869Samw 			break;
409*d0e51869Samw 		}
410*d0e51869Samw 
411*d0e51869Samw 		np = mem->advice.a_length_is;
412*d0e51869Samw 		if (np) {
413*d0e51869Samw 			generate_member_macro_with_arg(memkind,
414*d0e51869Samw 			    "_WITH_LENGTH_IS",
415*d0e51869Samw 			    mem, mem->type->type_down, np);
416*d0e51869Samw 			break;
417*d0e51869Samw 		}
418*d0e51869Samw 
419*d0e51869Samw 		generate_member_macro_with_arg(memkind,
420*d0e51869Samw 		    "_ARR_WITH_DIMENSION",
421*d0e51869Samw 		    mem, mem->type->type_down, mem->type->type_dim);
422*d0e51869Samw 		break;
423*d0e51869Samw 
424*d0e51869Samw 	default:
425*d0e51869Samw 		generate_member_macro(memkind, "_???", mem, 0);
426*d0e51869Samw 		break;
427*d0e51869Samw 	}
428*d0e51869Samw 
429*d0e51869Samw 	if (cond_pending)
430*d0e51869Samw 		(void) printf("    }\n");
431*d0e51869Samw }
432*d0e51869Samw 
433*d0e51869Samw static void
434*d0e51869Samw generate_aggregate_common_begin(ndr_typeinfo_t *ti)
435*d0e51869Samw {
436*d0e51869Samw 	char			val_buf[NDLBUFSZ];
437*d0e51869Samw 	char			cast_buf[NDLBUFSZ];
438*d0e51869Samw 	char			fname_type[NDLBUFSZ];
439*d0e51869Samw 	ndr_typeinfo_t		ptr;
440*d0e51869Samw 
441*d0e51869Samw 	type_extern_suffix(ti, fname_type, NDLBUFSZ);
442*d0e51869Samw 	generate_typeinfo_typeinfo(ti, 0, fname_type);
443*d0e51869Samw 	generate_prototypes(ti, fname_type);
444*d0e51869Samw 
445*d0e51869Samw 	(void) printf("\n");
446*d0e51869Samw 	(void) printf("/*\n * ");
447*d0e51869Samw 	show_advice(&ti->advice, 0);
448*d0e51869Samw 	(void) printf(" */\n");
449*d0e51869Samw 	(void) printf("int\n");
450*d0e51869Samw 	(void) printf("ndr_%s (struct ndr_reference *encl_ref)\n",
451*d0e51869Samw 	    fname_type);
452*d0e51869Samw 	(void) printf("{\n");
453*d0e51869Samw 
454*d0e51869Samw 	ptr.type_op = STAR;
455*d0e51869Samw 	ptr.type_down = ti;
456*d0e51869Samw 
457*d0e51869Samw 	type_name_decl(&ptr, val_buf, NDLBUFSZ, "val");
458*d0e51869Samw 	type_null_decl(&ptr, cast_buf, NDLBUFSZ);
459*d0e51869Samw 
460*d0e51869Samw 	(void) printf("	%s = %s encl_ref->datum;\n", val_buf, cast_buf);
461*d0e51869Samw 
462*d0e51869Samw 	(void) printf("	struct ndr_reference myref;\n");
463*d0e51869Samw 	(void) printf("\n");
464*d0e51869Samw 	(void) printf("	(void) bzero(&myref, sizeof (myref));\n");
465*d0e51869Samw 	(void) printf("	myref.enclosing = encl_ref;\n");
466*d0e51869Samw 	(void) printf("	myref.stream = encl_ref->stream;\n");
467*d0e51869Samw 	generate_typeinfo_packing(ti);
468*d0e51869Samw 	(void) printf("\n");
469*d0e51869Samw }
470*d0e51869Samw 
471*d0e51869Samw /* ARGSUSED */
472*d0e51869Samw static void
473*d0e51869Samw generate_aggregate_common_finish(ndr_typeinfo_t *ti)
474*d0e51869Samw {
475*d0e51869Samw 	(void) printf("\n");
476*d0e51869Samw 	(void) printf("	return 1;\n");
477*d0e51869Samw 	(void) printf("}\n");
478*d0e51869Samw }
479*d0e51869Samw 
480*d0e51869Samw /*
481*d0e51869Samw  * Structures are normally 4-byte (dword) aligned but the align directive
482*d0e51869Samw  * can be used to pack on a 2-byte (word) boundary.  An align value of
483*d0e51869Samw  * zero is taken to mean use default (dword) alignment.  Default packing
484*d0e51869Samw  * doesn't need to be flagged.
485*d0e51869Samw  */
486*d0e51869Samw static void
487*d0e51869Samw generate_typeinfo_packing(ndr_typeinfo_t *ti)
488*d0e51869Samw {
489*d0e51869Samw 	ndr_node_t *np;
490*d0e51869Samw 	unsigned long packing;
491*d0e51869Samw 
492*d0e51869Samw 	if ((np = ti->advice.a_align) == NULL)
493*d0e51869Samw 		return;
494*d0e51869Samw 
495*d0e51869Samw 	if ((np = np->n_a_arg) == NULL)
496*d0e51869Samw 		return;
497*d0e51869Samw 
498*d0e51869Samw 	packing = np->n_int;
499*d0e51869Samw 	if ((packing == 0) || (packing == 4)) {
500*d0e51869Samw 		/* default alignment */
501*d0e51869Samw 		return;
502*d0e51869Samw 	}
503*d0e51869Samw 
504*d0e51869Samw 	if (packing != 2) {
505*d0e51869Samw 		fatal_error("invalid align directive: %lu", packing);
506*d0e51869Samw 		/* NOTREACHED */
507*d0e51869Samw 	}
508*d0e51869Samw 
509*d0e51869Samw 	(void) printf("	myref.packed_alignment = %lu;\n", packing);
510*d0e51869Samw }
511*d0e51869Samw 
512*d0e51869Samw static void
513*d0e51869Samw generate_typeinfo_typeinfo(ndr_typeinfo_t *ti, int is_static, char *fname_type)
514*d0e51869Samw {
515*d0e51869Samw 	char		flags[NDLBUFSZ];
516*d0e51869Samw 
517*d0e51869Samw 	*flags = 0;
518*d0e51869Samw 	if (ti->is_conformant)
519*d0e51869Samw 		(void) strlcat(flags, "|NDR_F_CONFORMANT", NDLBUFSZ);
520*d0e51869Samw 
521*d0e51869Samw 	if (ti->type_op == STRUCT_KW) {
522*d0e51869Samw 		if (ti->advice.a_operation)
523*d0e51869Samw 			(void) strlcat(flags, "|NDR_F_OPERATION", NDLBUFSZ);
524*d0e51869Samw 		else
525*d0e51869Samw 			(void) strlcat(flags, "|NDR_F_STRUCT", NDLBUFSZ);
526*d0e51869Samw 	}
527*d0e51869Samw 
528*d0e51869Samw 	if (ti->type_op == UNION_KW) {
529*d0e51869Samw 		if (ti->advice.a_interface)
530*d0e51869Samw 			(void) strlcat(flags, "|NDR_F_INTERFACE", NDLBUFSZ);
531*d0e51869Samw 		else
532*d0e51869Samw 			(void) strlcat(flags, "|NDR_F_UNION", NDLBUFSZ);
533*d0e51869Samw 	}
534*d0e51869Samw 
535*d0e51869Samw 	if (ti->type_op == STRING_KW)
536*d0e51869Samw 		(void) strlcat(flags, "|NDR_F_STRING", NDLBUFSZ);
537*d0e51869Samw 	if (ti->type_op == LB)
538*d0e51869Samw 		(void) strlcat(flags, "|NDR_F_ARRAY", NDLBUFSZ);
539*d0e51869Samw 	if (ti->type_op == STAR)
540*d0e51869Samw 		(void) strlcat(flags, "|NDR_F_POINTER", NDLBUFSZ);
541*d0e51869Samw 
542*d0e51869Samw 	if (*flags == 0)
543*d0e51869Samw 		(void) strlcpy(flags, "NDR_F_NONE", NDLBUFSZ);
544*d0e51869Samw 	else
545*d0e51869Samw 		(void) strlcpy(flags, flags+1, NDLBUFSZ);
546*d0e51869Samw 
547*d0e51869Samw 	(void) printf("\n\n\n");
548*d0e51869Samw 	if (is_static)
549*d0e51869Samw 		(void) printf("static ");
550*d0e51869Samw 
551*d0e51869Samw 	(void) printf("int ndr_%s (struct ndr_reference *encl_ref);\n",
552*d0e51869Samw 	    fname_type);
553*d0e51869Samw 	if (is_static)
554*d0e51869Samw 		(void) printf("static ");
555*d0e51869Samw 
556*d0e51869Samw 	(void) printf("struct ndr_typeinfo ndt_%s = {\n", fname_type);
557*d0e51869Samw 	(void) printf("\t1,		/* NDR version */\n");
558*d0e51869Samw 	(void) printf("\t%d,		/* alignment */\n", ti->alignment);
559*d0e51869Samw 	(void) printf("\t%s,	/* flags */\n", flags);
560*d0e51869Samw 	(void) printf("\tndr_%s,	/* ndr_func */\n", fname_type);
561*d0e51869Samw 	(void) printf("\t%d,		/* pdu_size_fixed_part */\n",
562*d0e51869Samw 	    ti->size_fixed_part);
563*d0e51869Samw 	(void) printf("\t%d,		/* pdu_size_variable_part */\n",
564*d0e51869Samw 	    ti->size_variable_part);
565*d0e51869Samw 
566*d0e51869Samw 	(void) printf("\t%d,		/* c_size_fixed_part */\n",
567*d0e51869Samw 	    ti->size_fixed_part);
568*d0e51869Samw 	(void) printf("\t%d,		/* c_size_variable_part */\n",
569*d0e51869Samw 	    ti->size_variable_part);
570*d0e51869Samw 	(void) printf("};\n\n");
571*d0e51869Samw }
572