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