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 <strings.h>
30*d0e51869Samw #include <string.h>
31*d0e51869Samw #include "ndrgen.h"
32*d0e51869Samw #include "y.tab.h"
33*d0e51869Samw
34*d0e51869Samw
35*d0e51869Samw #define ALLOW_NOTHING 0
36*d0e51869Samw #define ALLOW_VARSIZE 1
37*d0e51869Samw #define ALLOW_INOUT 2
38*d0e51869Samw #define ALLOW_CASE 4
39*d0e51869Samw #define ALLOW_NO_UNIONS 8 /* for topmost structures */
40*d0e51869Samw #define ALLOW_NO_SWITCH 16
41*d0e51869Samw
42*d0e51869Samw struct tup {
43*d0e51869Samw struct tup *up;
44*d0e51869Samw ndr_typeinfo_t *ti;
45*d0e51869Samw };
46*d0e51869Samw
47*d0e51869Samw static void type_ident_decl(ndr_typeinfo_t *, char *, size_t, char *);
48*d0e51869Samw static void type_ident_decl1(struct tup *, char *, size_t, char *);
49*d0e51869Samw static void analyze_typeinfo_list(void);
50*d0e51869Samw static void analyze_typeinfo_typedef(ndr_typeinfo_t *);
51*d0e51869Samw static void analyze_typeinfo_struct(ndr_typeinfo_t *);
52*d0e51869Samw static void analyze_typeinfo_union(ndr_typeinfo_t *);
53*d0e51869Samw static void analyze_typeinfo_aggregate_finish(ndr_typeinfo_t *);
54*d0e51869Samw static void analyze_member(ndr_node_t *, ndr_member_t *, unsigned long *, int);
55*d0e51869Samw static void seed_basic_types(void);
56*d0e51869Samw static void seed_construct_types(void);
57*d0e51869Samw static void append_typeinfo(ndr_typeinfo_t *);
58*d0e51869Samw static ndr_typeinfo_t *bind_typeinfo(ndr_typeinfo_t *);
59*d0e51869Samw static ndr_typeinfo_t *find_typeinfo_by_name(ndr_node_t *);
60*d0e51869Samw static void determine_advice(ndr_advice_t *, ndr_node_t *);
61*d0e51869Samw static ndr_node_t *find_advice(ndr_node_t *advice_list, int label);
62*d0e51869Samw
63*d0e51869Samw
64*d0e51869Samw void
analyze(void)65*d0e51869Samw analyze(void)
66*d0e51869Samw {
67*d0e51869Samw seed_basic_types();
68*d0e51869Samw seed_construct_types();
69*d0e51869Samw
70*d0e51869Samw analyze_typeinfo_list();
71*d0e51869Samw }
72*d0e51869Samw
73*d0e51869Samw void
show_typeinfo_list(void)74*d0e51869Samw show_typeinfo_list(void)
75*d0e51869Samw {
76*d0e51869Samw ndr_typeinfo_t *ti;
77*d0e51869Samw ndr_typeinfo_t *tdti;
78*d0e51869Samw int i;
79*d0e51869Samw ndr_member_t *mem;
80*d0e51869Samw char *p;
81*d0e51869Samw char fname_type[NDLBUFSZ];
82*d0e51869Samw
83*d0e51869Samw for (ti = typeinfo_list; ti; ti = ti->next) {
84*d0e51869Samw switch (ti->type_op) {
85*d0e51869Samw case STRUCT_KW:
86*d0e51869Samw p = "struct";
87*d0e51869Samw break;
88*d0e51869Samw
89*d0e51869Samw case UNION_KW:
90*d0e51869Samw p = "union";
91*d0e51869Samw break;
92*d0e51869Samw
93*d0e51869Samw case TYPEDEF_KW:
94*d0e51869Samw p = "typedef";
95*d0e51869Samw break;
96*d0e51869Samw
97*d0e51869Samw case STRING_KW:
98*d0e51869Samw case STAR:
99*d0e51869Samw case LB:
100*d0e51869Samw case BASIC_TYPE:
101*d0e51869Samw type_extern_suffix(ti, fname_type, NDLBUFSZ);
102*d0e51869Samw if (ti->is_extern) {
103*d0e51869Samw (void) printf("extern ndr_%s()\n",
104*d0e51869Samw fname_type);
105*d0e51869Samw } else if (!ti->is_referenced) {
106*d0e51869Samw (void) printf("implied ndr_%s\n", fname_type);
107*d0e51869Samw }
108*d0e51869Samw continue;
109*d0e51869Samw
110*d0e51869Samw default:
111*d0e51869Samw (void) printf("show_typeinfo skipping %d\n",
112*d0e51869Samw ti->type_op);
113*d0e51869Samw continue;
114*d0e51869Samw }
115*d0e51869Samw
116*d0e51869Samw (void) printf("\n\n");
117*d0e51869Samw show_advice(&ti->advice, 0);
118*d0e51869Samw (void) printf("%s %s {\n", p, ti->type_name->n_sym->name);
119*d0e51869Samw
120*d0e51869Samw for (i = 0; i < ti->n_member; i++) {
121*d0e51869Samw mem = &ti->member[i];
122*d0e51869Samw show_advice(&mem->advice, 2);
123*d0e51869Samw type_extern_suffix(mem->type, fname_type, NDLBUFSZ);
124*d0e51869Samw (void) printf(" %-16s ndr_%-13s",
125*d0e51869Samw mem->name, fname_type);
126*d0e51869Samw
127*d0e51869Samw tdti = mem->type;
128*d0e51869Samw (void) printf(" fsiz=%d vsiz=%d algn=%d off=%d\n",
129*d0e51869Samw tdti->size_fixed_part,
130*d0e51869Samw tdti->size_variable_part,
131*d0e51869Samw tdti->alignment,
132*d0e51869Samw mem->pdu_offset);
133*d0e51869Samw }
134*d0e51869Samw
135*d0e51869Samw (void) printf("} fsiz=%d vsiz=%d algn=%d comp=%d ptrs=%d\n",
136*d0e51869Samw ti->size_fixed_part,
137*d0e51869Samw ti->size_variable_part,
138*d0e51869Samw ti->alignment,
139*d0e51869Samw ti->complete,
140*d0e51869Samw ti->has_pointers);
141*d0e51869Samw }
142*d0e51869Samw }
143*d0e51869Samw
144*d0e51869Samw void
type_extern_suffix(ndr_typeinfo_t * tsti,char * funcbuf,size_t buflen)145*d0e51869Samw type_extern_suffix(ndr_typeinfo_t *tsti, char *funcbuf, size_t buflen)
146*d0e51869Samw {
147*d0e51869Samw ndr_typeinfo_t *ti;
148*d0e51869Samw char *p_fb = funcbuf;
149*d0e51869Samw
150*d0e51869Samw *p_fb = 0;
151*d0e51869Samw
152*d0e51869Samw for (ti = tsti; ti; ti = ti->type_down) {
153*d0e51869Samw switch (ti->type_op) {
154*d0e51869Samw case BASIC_TYPE:
155*d0e51869Samw case STRUCT_KW:
156*d0e51869Samw case TYPEDEF_KW:
157*d0e51869Samw case UNION_KW:
158*d0e51869Samw (void) snprintf(p_fb, buflen, "_%s",
159*d0e51869Samw ti->type_name->n_sym->name);
160*d0e51869Samw break;
161*d0e51869Samw
162*d0e51869Samw case STAR:
163*d0e51869Samw (void) strlcpy(p_fb, "p", buflen);
164*d0e51869Samw break;
165*d0e51869Samw
166*d0e51869Samw case LB:
167*d0e51869Samw if (ti->type_dim) {
168*d0e51869Samw (void) snprintf(p_fb, buflen, "a%ld",
169*d0e51869Samw ti->type_dim->n_int);
170*d0e51869Samw } else {
171*d0e51869Samw (void) snprintf(p_fb, buflen, "ac");
172*d0e51869Samw }
173*d0e51869Samw break;
174*d0e51869Samw
175*d0e51869Samw case STRING_KW:
176*d0e51869Samw (void) strlcpy(p_fb, "s", buflen);
177*d0e51869Samw break;
178*d0e51869Samw
179*d0e51869Samw default:
180*d0e51869Samw (void) snprintf(p_fb, buflen, "?<%d>", ti->type_op);
181*d0e51869Samw break;
182*d0e51869Samw }
183*d0e51869Samw while (*p_fb)
184*d0e51869Samw p_fb++;
185*d0e51869Samw }
186*d0e51869Samw }
187*d0e51869Samw
188*d0e51869Samw static void
type_ident_decl1(struct tup * tup,char * funcbuf,size_t buflen,char * ident)189*d0e51869Samw type_ident_decl1(struct tup *tup, char *funcbuf, size_t buflen, char *ident)
190*d0e51869Samw {
191*d0e51869Samw ndr_typeinfo_t *ti;
192*d0e51869Samw char fb[NDLBUFSZ];
193*d0e51869Samw char *p;
194*d0e51869Samw
195*d0e51869Samw if (!tup) {
196*d0e51869Samw (void) strlcpy(funcbuf, ident, buflen);
197*d0e51869Samw return;
198*d0e51869Samw }
199*d0e51869Samw ti = tup->ti;
200*d0e51869Samw
201*d0e51869Samw switch (ti->type_op) {
202*d0e51869Samw case BASIC_TYPE:
203*d0e51869Samw case TYPEDEF_KW:
204*d0e51869Samw type_ident_decl1(tup->up, fb, NDLBUFSZ, ident);
205*d0e51869Samw (void) snprintf(funcbuf, buflen, "%s%s%s%s",
206*d0e51869Samw "", ti->type_name->n_sym->name, *fb ? " " : "", fb);
207*d0e51869Samw break;
208*d0e51869Samw
209*d0e51869Samw case STRUCT_KW:
210*d0e51869Samw type_ident_decl1(tup->up, fb, NDLBUFSZ, ident);
211*d0e51869Samw (void) snprintf(funcbuf, buflen, "%s%s%s%s",
212*d0e51869Samw "struct ", ti->type_name->n_sym->name, *fb ? " " : "", fb);
213*d0e51869Samw break;
214*d0e51869Samw
215*d0e51869Samw case UNION_KW:
216*d0e51869Samw type_ident_decl1(tup->up, fb, NDLBUFSZ, ident);
217*d0e51869Samw (void) snprintf(funcbuf, buflen, "%s%s%s%s",
218*d0e51869Samw "union ", ti->type_name->n_sym->name, *fb ? " " : "", fb);
219*d0e51869Samw break;
220*d0e51869Samw
221*d0e51869Samw case STAR:
222*d0e51869Samw *funcbuf = '*';
223*d0e51869Samw type_ident_decl1(tup->up, funcbuf+1, buflen - 1, ident);
224*d0e51869Samw break;
225*d0e51869Samw
226*d0e51869Samw case LB:
227*d0e51869Samw p = fb;
228*d0e51869Samw *p++ = '(';
229*d0e51869Samw type_ident_decl1(tup->up, p, NDLBUFSZ - 1, ident);
230*d0e51869Samw if (*p == '*') {
231*d0e51869Samw p = fb;
232*d0e51869Samw (void) strlcat(p, ")", NDLBUFSZ);
233*d0e51869Samw }
234*d0e51869Samw if (ti->type_dim) {
235*d0e51869Samw (void) snprintf(funcbuf, buflen, "%s[%ld]",
236*d0e51869Samw p, ti->type_dim->n_int);
237*d0e51869Samw } else {
238*d0e51869Samw (void) snprintf(funcbuf, buflen,
239*d0e51869Samw "%s[NDR_ANYSIZE_DIM]", p);
240*d0e51869Samw }
241*d0e51869Samw break;
242*d0e51869Samw
243*d0e51869Samw case STRING_KW:
244*d0e51869Samw p = fb;
245*d0e51869Samw *p++ = '(';
246*d0e51869Samw type_ident_decl1(tup->up, p, NDLBUFSZ - 1, ident);
247*d0e51869Samw if (*p == '*') {
248*d0e51869Samw p = fb;
249*d0e51869Samw (void) strlcat(p, ")", NDLBUFSZ);
250*d0e51869Samw }
251*d0e51869Samw (void) snprintf(funcbuf, buflen, "%s[NDR_STRING_DIM]", p);
252*d0e51869Samw break;
253*d0e51869Samw
254*d0e51869Samw default:
255*d0e51869Samw compile_error("unknown type or keyword <%d>", ti->type_op);
256*d0e51869Samw break;
257*d0e51869Samw }
258*d0e51869Samw }
259*d0e51869Samw
260*d0e51869Samw static void
type_ident_decl(ndr_typeinfo_t * tsti,char * funcbuf,size_t buflen,char * ident)261*d0e51869Samw type_ident_decl(ndr_typeinfo_t *tsti, char *funcbuf, size_t buflen, char *ident)
262*d0e51869Samw {
263*d0e51869Samw ndr_typeinfo_t *ti;
264*d0e51869Samw struct tup tup_tab[40];
265*d0e51869Samw struct tup *tup;
266*d0e51869Samw struct tup *up = 0;
267*d0e51869Samw int n_tt = 0;
268*d0e51869Samw
269*d0e51869Samw for (ti = tsti; ti; ti = ti->type_down, n_tt++) {
270*d0e51869Samw tup = &tup_tab[n_tt];
271*d0e51869Samw tup->up = up;
272*d0e51869Samw tup->ti = ti;
273*d0e51869Samw up = tup;
274*d0e51869Samw }
275*d0e51869Samw
276*d0e51869Samw type_ident_decl1(up, funcbuf, buflen, ident);
277*d0e51869Samw }
278*d0e51869Samw
279*d0e51869Samw void
type_null_decl(ndr_typeinfo_t * tsti,char * funcbuf,size_t buflen)280*d0e51869Samw type_null_decl(ndr_typeinfo_t *tsti, char *funcbuf, size_t buflen)
281*d0e51869Samw {
282*d0e51869Samw funcbuf[0] = '(';
283*d0e51869Samw type_ident_decl(tsti, funcbuf+1, buflen, "");
284*d0e51869Samw (void) strlcat(funcbuf, ")", buflen);
285*d0e51869Samw }
286*d0e51869Samw
287*d0e51869Samw void
type_name_decl(ndr_typeinfo_t * tsti,char * funcbuf,size_t buflen,char * name)288*d0e51869Samw type_name_decl(ndr_typeinfo_t *tsti, char *funcbuf, size_t buflen, char *name)
289*d0e51869Samw {
290*d0e51869Samw type_ident_decl(tsti, funcbuf, buflen, name);
291*d0e51869Samw }
292*d0e51869Samw
293*d0e51869Samw void
show_advice(ndr_advice_t * adv,int indent)294*d0e51869Samw show_advice(ndr_advice_t *adv, int indent)
295*d0e51869Samw {
296*d0e51869Samw int i;
297*d0e51869Samw int n = 0;
298*d0e51869Samw
299*d0e51869Samw for (i = 0; i < N_ADVICE; i++) {
300*d0e51869Samw if (!adv->a_nodes[i])
301*d0e51869Samw continue;
302*d0e51869Samw
303*d0e51869Samw if (n++ == 0)
304*d0e51869Samw (void) printf("%-*s[", indent, "");
305*d0e51869Samw else
306*d0e51869Samw (void) printf(" ");
307*d0e51869Samw
308*d0e51869Samw print_node(adv->a_nodes[i]);
309*d0e51869Samw }
310*d0e51869Samw
311*d0e51869Samw if (n)
312*d0e51869Samw (void) printf("]\n");
313*d0e51869Samw }
314*d0e51869Samw
315*d0e51869Samw static void
analyze_typeinfo_list(void)316*d0e51869Samw analyze_typeinfo_list(void)
317*d0e51869Samw {
318*d0e51869Samw ndr_typeinfo_t *ti;
319*d0e51869Samw
320*d0e51869Samw for (ti = typeinfo_list; ti; ti = ti->next) {
321*d0e51869Samw switch (ti->type_op) {
322*d0e51869Samw case STRUCT_KW:
323*d0e51869Samw analyze_typeinfo_struct(ti);
324*d0e51869Samw break;
325*d0e51869Samw
326*d0e51869Samw case UNION_KW:
327*d0e51869Samw analyze_typeinfo_union(ti);
328*d0e51869Samw break;
329*d0e51869Samw
330*d0e51869Samw case TYPEDEF_KW:
331*d0e51869Samw analyze_typeinfo_typedef(ti);
332*d0e51869Samw break;
333*d0e51869Samw }
334*d0e51869Samw }
335*d0e51869Samw }
336*d0e51869Samw
337*d0e51869Samw static void
analyze_typeinfo_typedef(ndr_typeinfo_t * ti)338*d0e51869Samw analyze_typeinfo_typedef(ndr_typeinfo_t *ti)
339*d0e51869Samw {
340*d0e51869Samw ndr_node_t *mem_np;
341*d0e51869Samw ndr_member_t *mem;
342*d0e51869Samw int i;
343*d0e51869Samw int allow;
344*d0e51869Samw unsigned long offset;
345*d0e51869Samw
346*d0e51869Samw assert(ti->type_op == TYPEDEF_KW);
347*d0e51869Samw
348*d0e51869Samw /*
349*d0e51869Samw * Snarf the advice.
350*d0e51869Samw */
351*d0e51869Samw determine_advice(&ti->advice, ti->definition->n_c_advice);
352*d0e51869Samw
353*d0e51869Samw /*
354*d0e51869Samw * Convert the members to table.
355*d0e51869Samw * Determine layout metrics along the way.
356*d0e51869Samw */
357*d0e51869Samw mem_np = ti->definition->n_c_members;
358*d0e51869Samw i = 0;
359*d0e51869Samw offset = 0;
360*d0e51869Samw assert(i < ti->n_member);
361*d0e51869Samw mem = &ti->member[i];
362*d0e51869Samw
363*d0e51869Samw allow = ALLOW_NO_SWITCH;
364*d0e51869Samw
365*d0e51869Samw analyze_member(mem_np, mem,
366*d0e51869Samw &offset, /* progress offset */
367*d0e51869Samw allow); /* see above */
368*d0e51869Samw
369*d0e51869Samw assert(1 == ti->n_member);
370*d0e51869Samw
371*d0e51869Samw analyze_typeinfo_aggregate_finish(ti);
372*d0e51869Samw
373*d0e51869Samw /* Align offset to determine overall size */
374*d0e51869Samw while (offset & ti->alignment)
375*d0e51869Samw offset++;
376*d0e51869Samw
377*d0e51869Samw ti->size_fixed_part = offset;
378*d0e51869Samw }
379*d0e51869Samw
380*d0e51869Samw static void
analyze_typeinfo_struct(ndr_typeinfo_t * ti)381*d0e51869Samw analyze_typeinfo_struct(ndr_typeinfo_t *ti)
382*d0e51869Samw {
383*d0e51869Samw ndr_node_t *mem_np;
384*d0e51869Samw ndr_member_t *mem;
385*d0e51869Samw int i;
386*d0e51869Samw int allow;
387*d0e51869Samw unsigned long offset;
388*d0e51869Samw
389*d0e51869Samw assert(ti->type_op == STRUCT_KW);
390*d0e51869Samw
391*d0e51869Samw /*
392*d0e51869Samw * Snarf the advice. Only recognize [operation()] for
393*d0e51869Samw * struct definitions.
394*d0e51869Samw */
395*d0e51869Samw determine_advice(&ti->advice, ti->definition->n_c_advice);
396*d0e51869Samw
397*d0e51869Samw /*
398*d0e51869Samw * Convert the members from list to table.
399*d0e51869Samw * Determine layout metrics along the way.
400*d0e51869Samw */
401*d0e51869Samw mem_np = ti->definition->n_c_members;
402*d0e51869Samw i = 0;
403*d0e51869Samw offset = 0;
404*d0e51869Samw for (; mem_np; i++, mem_np = mem_np->n_next) {
405*d0e51869Samw assert(i < ti->n_member);
406*d0e51869Samw mem = &ti->member[i];
407*d0e51869Samw
408*d0e51869Samw if (!ti->advice.a_operation /* no var-size in op param */ &&
409*d0e51869Samw i == ti->n_member-1) /* only last mem may be var-size */
410*d0e51869Samw allow = ALLOW_VARSIZE;
411*d0e51869Samw else
412*d0e51869Samw allow = 0;
413*d0e51869Samw
414*d0e51869Samw analyze_member(mem_np, mem, &offset, allow);
415*d0e51869Samw }
416*d0e51869Samw assert(i == ti->n_member);
417*d0e51869Samw
418*d0e51869Samw analyze_typeinfo_aggregate_finish(ti); /* align,complete,ptrs,etc */
419*d0e51869Samw
420*d0e51869Samw /* Align offset to determine overall size */
421*d0e51869Samw while (offset & ti->alignment)
422*d0e51869Samw offset++;
423*d0e51869Samw
424*d0e51869Samw ti->size_fixed_part = offset;
425*d0e51869Samw
426*d0e51869Samw /* If last member is var-sized, so is this struct */
427*d0e51869Samw mem = &ti->member[ti->n_member-1];
428*d0e51869Samw ti->size_variable_part = mem->type->size_variable_part;
429*d0e51869Samw
430*d0e51869Samw if (ti->size_variable_part)
431*d0e51869Samw ti->is_conformant = 1;
432*d0e51869Samw }
433*d0e51869Samw
434*d0e51869Samw static void
analyze_typeinfo_union(ndr_typeinfo_t * ti)435*d0e51869Samw analyze_typeinfo_union(ndr_typeinfo_t *ti)
436*d0e51869Samw {
437*d0e51869Samw ndr_node_t *mem_np;
438*d0e51869Samw ndr_member_t *mem;
439*d0e51869Samw int i;
440*d0e51869Samw unsigned long offset;
441*d0e51869Samw unsigned long size;
442*d0e51869Samw
443*d0e51869Samw assert(ti->type_op == UNION_KW);
444*d0e51869Samw
445*d0e51869Samw /*
446*d0e51869Samw * Snarf the advice. None supported for union definitions.
447*d0e51869Samw * Only [switch_is()] supported for union instances.
448*d0e51869Samw */
449*d0e51869Samw determine_advice(&ti->advice, ti->definition->n_c_advice);
450*d0e51869Samw
451*d0e51869Samw /*
452*d0e51869Samw * Convert the members from list to table.
453*d0e51869Samw * Determine layout metrics along the way.
454*d0e51869Samw */
455*d0e51869Samw mem_np = ti->definition->n_c_members;
456*d0e51869Samw i = 0;
457*d0e51869Samw size = 0;
458*d0e51869Samw for (; mem_np; i++, mem_np = mem_np->n_next) {
459*d0e51869Samw assert(i < ti->n_member);
460*d0e51869Samw mem = &ti->member[i];
461*d0e51869Samw
462*d0e51869Samw offset = 0; /* all members offset=0 */
463*d0e51869Samw analyze_member(mem_np, mem,
464*d0e51869Samw &offset,
465*d0e51869Samw ALLOW_CASE+ALLOW_NO_UNIONS); /* var-size disallowed */
466*d0e51869Samw
467*d0e51869Samw if (size < mem->type->size_fixed_part)
468*d0e51869Samw size = mem->type->size_fixed_part;
469*d0e51869Samw }
470*d0e51869Samw assert(i == ti->n_member);
471*d0e51869Samw
472*d0e51869Samw analyze_typeinfo_aggregate_finish(ti); /* align,complete,ptrs,etc */
473*d0e51869Samw
474*d0e51869Samw /* align size to determine overall size */
475*d0e51869Samw while (size & ti->alignment)
476*d0e51869Samw size++;
477*d0e51869Samw
478*d0e51869Samw ti->size_fixed_part = size;
479*d0e51869Samw }
480*d0e51869Samw
481*d0e51869Samw static void
analyze_typeinfo_aggregate_finish(ndr_typeinfo_t * ti)482*d0e51869Samw analyze_typeinfo_aggregate_finish(ndr_typeinfo_t *ti)
483*d0e51869Samw {
484*d0e51869Samw int i;
485*d0e51869Samw ndr_member_t *mem;
486*d0e51869Samw int complete = 1;
487*d0e51869Samw int has_pointers = 0;
488*d0e51869Samw
489*d0e51869Samw for (i = 0; i < ti->n_member; i++) {
490*d0e51869Samw mem = &ti->member[i];
491*d0e51869Samw
492*d0e51869Samw complete &= mem->type->complete;
493*d0e51869Samw has_pointers |= mem->type->has_pointers;
494*d0e51869Samw ti->alignment |= mem->type->alignment;
495*d0e51869Samw }
496*d0e51869Samw
497*d0e51869Samw ti->complete = complete;
498*d0e51869Samw ti->has_pointers = has_pointers;
499*d0e51869Samw }
500*d0e51869Samw
501*d0e51869Samw static void
analyze_member(ndr_node_t * mem_np,ndr_member_t * mem,unsigned long * offsetp,int allow)502*d0e51869Samw analyze_member(ndr_node_t *mem_np, ndr_member_t *mem,
503*d0e51869Samw unsigned long *offsetp, int allow)
504*d0e51869Samw {
505*d0e51869Samw int i, n_decl_ops;
506*d0e51869Samw ndr_node_t *decl_ops[NDLBUFSZ];
507*d0e51869Samw ndr_typeinfo_t *type_down;
508*d0e51869Samw ndr_typeinfo_t proto_ti;
509*d0e51869Samw ndr_node_t *np;
510*d0e51869Samw
511*d0e51869Samw /*
512*d0e51869Samw * Set line_number for error reporting (so we know where to look)
513*d0e51869Samw */
514*d0e51869Samw line_number = mem_np->line_number;
515*d0e51869Samw
516*d0e51869Samw /*
517*d0e51869Samw * Simple parts of member
518*d0e51869Samw */
519*d0e51869Samw mem->definition = mem_np;
520*d0e51869Samw determine_advice(&mem->advice, mem_np->n_m_advice);
521*d0e51869Samw
522*d0e51869Samw /*
523*d0e51869Samw * The node list for the declarator is in outside-to-inside
524*d0e51869Samw * order. It is also decorated with the LP nodes for
525*d0e51869Samw * precedence, which are in our way at this point.
526*d0e51869Samw *
527*d0e51869Samw * These two loops reverse the list, which is easier
528*d0e51869Samw * to analyze. For example, the declaration:
529*d0e51869Samw *
530*d0e51869Samw * ulong * (id[100]);
531*d0e51869Samw *
532*d0e51869Samw * will have the node list (=> indicates n_d_descend):
533*d0e51869Samw *
534*d0e51869Samw * ulong => STAR => LP => LB[100] => id
535*d0e51869Samw *
536*d0e51869Samw * and the conversion will result in type info (=> indicates
537*d0e51869Samw * type_down):
538*d0e51869Samw *
539*d0e51869Samw * id => LB[100] => STAR => ulong
540*d0e51869Samw *
541*d0e51869Samw * which is closer to how you would pronounce the declaration:
542*d0e51869Samw *
543*d0e51869Samw * id is an array size 100 of pointers to ulong.
544*d0e51869Samw */
545*d0e51869Samw
546*d0e51869Samw /* first pass -- turn the list into a table */
547*d0e51869Samw n_decl_ops = 0;
548*d0e51869Samw for (np = mem_np->n_m_decl; np; np = np->n_d_descend) {
549*d0e51869Samw if (np->label == IDENTIFIER) {
550*d0e51869Samw break; /* done */
551*d0e51869Samw }
552*d0e51869Samw
553*d0e51869Samw if (np->label == LP)
554*d0e51869Samw continue; /* ignore precedence nodes */
555*d0e51869Samw
556*d0e51869Samw decl_ops[n_decl_ops++] = np;
557*d0e51869Samw }
558*d0e51869Samw if (!np) {
559*d0e51869Samw compile_error("declaration error");
560*d0e51869Samw print_node(mem_np->n_m_decl);
561*d0e51869Samw (void) printf("\n");
562*d0e51869Samw } else {
563*d0e51869Samw mem->name = np->n_sym->name;
564*d0e51869Samw }
565*d0e51869Samw
566*d0e51869Samw /* second pass -- turn the table into push-back list */
567*d0e51869Samw type_down = find_typeinfo_by_name(mem_np->n_m_type);
568*d0e51869Samw
569*d0e51869Samw if (type_down->type_op == TYPEDEF_KW)
570*d0e51869Samw type_down = type_down->member[0].type;
571*d0e51869Samw
572*d0e51869Samw if (mem->advice.a_string) {
573*d0e51869Samw bzero(&proto_ti, sizeof (proto_ti));
574*d0e51869Samw proto_ti.type_op = STRING_KW;
575*d0e51869Samw proto_ti.type_down = type_down;
576*d0e51869Samw type_down = bind_typeinfo(&proto_ti);
577*d0e51869Samw }
578*d0e51869Samw
579*d0e51869Samw for (i = n_decl_ops; i-- > 0; ) {
580*d0e51869Samw np = decl_ops[i];
581*d0e51869Samw
582*d0e51869Samw bzero(&proto_ti, sizeof (proto_ti));
583*d0e51869Samw
584*d0e51869Samw proto_ti.type_op = np->label;
585*d0e51869Samw proto_ti.type_down = type_down;
586*d0e51869Samw
587*d0e51869Samw switch (np->label) {
588*d0e51869Samw case LB:
589*d0e51869Samw proto_ti.type_dim = np->n_d_dim;
590*d0e51869Samw break;
591*d0e51869Samw }
592*d0e51869Samw
593*d0e51869Samw /*
594*d0e51869Samw * bind_typeinfo() reuses (interns) typeinfo's to
595*d0e51869Samw * make later code generation easier. It will report
596*d0e51869Samw * some errors.
597*d0e51869Samw */
598*d0e51869Samw type_down = bind_typeinfo(&proto_ti);
599*d0e51869Samw }
600*d0e51869Samw
601*d0e51869Samw /* bind the member to its type info */
602*d0e51869Samw mem->type = type_down;
603*d0e51869Samw type_down->is_referenced = 1; /* we handle first-level indirection */
604*d0e51869Samw
605*d0e51869Samw /*
606*d0e51869Samw * Now, apply the type info to the member layout metrics.
607*d0e51869Samw */
608*d0e51869Samw
609*d0e51869Samw /* alignment */
610*d0e51869Samw while (*offsetp & type_down->alignment)
611*d0e51869Samw ++*offsetp;
612*d0e51869Samw
613*d0e51869Samw mem->pdu_offset = *offsetp;
614*d0e51869Samw
615*d0e51869Samw *offsetp += type_down->size_fixed_part;
616*d0e51869Samw
617*d0e51869Samw if (mem->advice.a_length_is)
618*d0e51869Samw compile_error("[length_is()] is not supported");
619*d0e51869Samw
620*d0e51869Samw if (mem->advice.a_transmit_as)
621*d0e51869Samw compile_error("[transmit_as()] is not supported");
622*d0e51869Samw
623*d0e51869Samw if (mem->advice.a_arg_is)
624*d0e51869Samw compile_error("[arg_is()] is not supported");
625*d0e51869Samw
626*d0e51869Samw /*
627*d0e51869Samw * Disallow
628*d0e51869Samw * [case(x)] TYPE xxx;
629*d0e51869Samw * [default] TYPE xxx;
630*d0e51869Samw *
631*d0e51869Samw * These only make sense within unions.
632*d0e51869Samw */
633*d0e51869Samw if (allow & ALLOW_CASE) {
634*d0e51869Samw int n = 0;
635*d0e51869Samw
636*d0e51869Samw if (mem->advice.a_case)
637*d0e51869Samw n++;
638*d0e51869Samw if (mem->advice.a_default)
639*d0e51869Samw n++;
640*d0e51869Samw
641*d0e51869Samw if (n == 0)
642*d0e51869Samw compile_error("no [case/default] advice");
643*d0e51869Samw else if (n > 1)
644*d0e51869Samw compile_error("too many [case/default] advice");
645*d0e51869Samw } else {
646*d0e51869Samw if (mem->advice.a_case && mem->advice.a_default)
647*d0e51869Samw compile_error("[case/default] advice not allowed");
648*d0e51869Samw }
649*d0e51869Samw
650*d0e51869Samw /*
651*d0e51869Samw * Disallow
652*d0e51869Samw * [operation(x)] TYPE foo;
653*d0e51869Samw * [interface(x)] TYPE foo;
654*d0e51869Samw * [uuid(x)] TYPE foo;
655*d0e51869Samw *
656*d0e51869Samw * The [operation()] advice may only appear on a struct to
657*d0e51869Samw * indicate that the structure is a top-most (parameter)
658*d0e51869Samw * structure, and the opcode associated with the parameters.
659*d0e51869Samw */
660*d0e51869Samw if (mem->advice.a_operation)
661*d0e51869Samw compile_error("[operation()] advice not allowed");
662*d0e51869Samw
663*d0e51869Samw if (mem->advice.a_interface)
664*d0e51869Samw compile_error("[interface()] advice not allowed");
665*d0e51869Samw
666*d0e51869Samw if (mem->advice.a_uuid)
667*d0e51869Samw compile_error("[uuid()] advice not allowed");
668*d0e51869Samw
669*d0e51869Samw /*
670*d0e51869Samw * Allow
671*d0e51869Samw * [switch_is(x)] union foo xxx;
672*d0e51869Samw *
673*d0e51869Samw * Disallow [switch_is] on anything which is not a union.
674*d0e51869Samw */
675*d0e51869Samw if (mem->advice.a_switch_is && type_down->type_op != UNION_KW) {
676*d0e51869Samw compile_error("[switch_is()] advice not allowed");
677*d0e51869Samw }
678*d0e51869Samw
679*d0e51869Samw /*
680*d0e51869Samw * Allow
681*d0e51869Samw * [size_is(x)] TYPE * ptr;
682*d0e51869Samw * [size_is(x)] TYPE arr[];
683*d0e51869Samw *
684*d0e51869Samw * Disallow [size_is()] on anything other than pointer and
685*d0e51869Samw * variable length array.
686*d0e51869Samw */
687*d0e51869Samw if (mem->advice.a_size_is &&
688*d0e51869Samw type_down->type_op != STAR &&
689*d0e51869Samw !(type_down->type_op == LB &&
690*d0e51869Samw type_down->type_dim == 0)) {
691*d0e51869Samw compile_error("[size_is()] advice not allowed");
692*d0e51869Samw }
693*d0e51869Samw
694*d0e51869Samw /*
695*d0e51869Samw * Allow
696*d0e51869Samw * [string] char * ptr_string;
697*d0e51869Samw *
698*d0e51869Samw * Disallow [string] on anything else. The determination
699*d0e51869Samw * of size (for the outer header) on anything else is
700*d0e51869Samw * impossible.
701*d0e51869Samw */
702*d0e51869Samw if (mem->advice.a_string && type_down->type_op != STAR) {
703*d0e51869Samw compile_error("[string] advice not allowed");
704*d0e51869Samw }
705*d0e51869Samw
706*d0e51869Samw if (type_down->type_op == LB &&
707*d0e51869Samw type_down->type_dim == 0) { /* var-length array of some sort */
708*d0e51869Samw
709*d0e51869Samw int n = 0;
710*d0e51869Samw
711*d0e51869Samw /*
712*d0e51869Samw * Requires [size_is()] directive
713*d0e51869Samw * [size_is(x)] TYPE array[]
714*d0e51869Samw */
715*d0e51869Samw
716*d0e51869Samw if (mem->advice.a_size_is)
717*d0e51869Samw n++;
718*d0e51869Samw
719*d0e51869Samw if (!n)
720*d0e51869Samw compile_error("var-size missing sizing directive");
721*d0e51869Samw else if (n > 1)
722*d0e51869Samw compile_error("var-size too many sizing directives");
723*d0e51869Samw }
724*d0e51869Samw
725*d0e51869Samw /*
726*d0e51869Samw * Nested unions and struct members, other than the last one,
727*d0e51869Samw * cannot contain variable sized members.
728*d0e51869Samw */
729*d0e51869Samw if (type_down->size_variable_part && !(allow & ALLOW_VARSIZE)) {
730*d0e51869Samw compile_error("var-size member not allowed");
731*d0e51869Samw }
732*d0e51869Samw
733*d0e51869Samw /*
734*d0e51869Samw * Disallow unions in operations (i.e. [operation()] struct ...),
735*d0e51869Samw * The switch_is() value is not reliably available. DCE/RPC
736*d0e51869Samw * automatically synthesizes an encapsulated union for
737*d0e51869Samw * these situations, which we have to do by hand:
738*d0e51869Samw *
739*d0e51869Samw * struct { long switch_value; union foo x; } synth;
740*d0e51869Samw *
741*d0e51869Samw * We also can not allow unions within unions because
742*d0e51869Samw * there is no way to pass the separate [switch_is(x)] selector.
743*d0e51869Samw */
744*d0e51869Samw if (type_down->type_op == UNION_KW) {
745*d0e51869Samw if (allow & ALLOW_NO_UNIONS) {
746*d0e51869Samw compile_error("unencapsulated union not allowed");
747*d0e51869Samw } else if (!mem->advice.a_switch_is &&
748*d0e51869Samw !(allow & ALLOW_NO_SWITCH)) {
749*d0e51869Samw compile_error("union instance without selector");
750*d0e51869Samw }
751*d0e51869Samw }
752*d0e51869Samw }
753*d0e51869Samw
754*d0e51869Samw static void
seed_basic_types(void)755*d0e51869Samw seed_basic_types(void)
756*d0e51869Samw {
757*d0e51869Samw ndr_symbol_t *sym;
758*d0e51869Samw ndr_typeinfo_t *ti;
759*d0e51869Samw ndr_typeinfo_t proto_ti;
760*d0e51869Samw
761*d0e51869Samw for (sym = symbol_list; sym; sym = sym->next) {
762*d0e51869Samw if (!sym->kw)
763*d0e51869Samw continue;
764*d0e51869Samw
765*d0e51869Samw if (sym->kw->token != BASIC_TYPE)
766*d0e51869Samw continue;
767*d0e51869Samw
768*d0e51869Samw ti = ndr_alloc(1, sizeof (ndr_typeinfo_t));
769*d0e51869Samw
770*d0e51869Samw ti->type_op = BASIC_TYPE;
771*d0e51869Samw ti->definition = &sym->s_node;
772*d0e51869Samw ti->type_name = &sym->s_node;
773*d0e51869Samw ti->size_fixed_part = sym->kw->value;
774*d0e51869Samw ti->alignment = ti->size_fixed_part - 1;
775*d0e51869Samw ti->complete = 1;
776*d0e51869Samw ti->is_extern = 1;
777*d0e51869Samw
778*d0e51869Samw append_typeinfo(ti);
779*d0e51869Samw
780*d0e51869Samw bzero(&proto_ti, sizeof (proto_ti));
781*d0e51869Samw proto_ti.type_op = STRING_KW;
782*d0e51869Samw proto_ti.type_down = ti;
783*d0e51869Samw
784*d0e51869Samw ti = bind_typeinfo(&proto_ti);
785*d0e51869Samw ti->is_extern = 1;
786*d0e51869Samw }
787*d0e51869Samw }
788*d0e51869Samw
789*d0e51869Samw static void
seed_construct_types(void)790*d0e51869Samw seed_construct_types(void)
791*d0e51869Samw {
792*d0e51869Samw ndr_node_t *construct;
793*d0e51869Samw ndr_node_t *np;
794*d0e51869Samw unsigned n_member;
795*d0e51869Samw ndr_typeinfo_t *ti;
796*d0e51869Samw
797*d0e51869Samw construct = construct_list;
798*d0e51869Samw for (; construct; construct = construct->n_next) {
799*d0e51869Samw ti = ndr_alloc(1, sizeof (ndr_typeinfo_t));
800*d0e51869Samw
801*d0e51869Samw ti->type_op = construct->label;
802*d0e51869Samw ti->definition = construct;
803*d0e51869Samw
804*d0e51869Samw switch (ti->type_op) {
805*d0e51869Samw case TYPEDEF_KW:
806*d0e51869Samw case STRUCT_KW:
807*d0e51869Samw case UNION_KW:
808*d0e51869Samw ti->type_name = construct->n_c_typename;
809*d0e51869Samw
810*d0e51869Samw np = construct->n_c_members;
811*d0e51869Samw n_member = 0;
812*d0e51869Samw for (; np; np = np->n_next)
813*d0e51869Samw n_member++;
814*d0e51869Samw
815*d0e51869Samw ti->n_member = n_member;
816*d0e51869Samw if (n_member > 0)
817*d0e51869Samw ti->member = ndr_alloc(n_member,
818*d0e51869Samw sizeof (ndr_member_t));
819*d0e51869Samw break;
820*d0e51869Samw
821*d0e51869Samw default:
822*d0e51869Samw fatal_error("seed_construct unknown %d\n", ti->type_op);
823*d0e51869Samw break;
824*d0e51869Samw }
825*d0e51869Samw
826*d0e51869Samw determine_advice(&ti->advice, construct->n_c_advice);
827*d0e51869Samw
828*d0e51869Samw ti->is_referenced = 1; /* always generate */
829*d0e51869Samw
830*d0e51869Samw append_typeinfo(ti);
831*d0e51869Samw }
832*d0e51869Samw }
833*d0e51869Samw
834*d0e51869Samw static void
append_typeinfo(ndr_typeinfo_t * ti)835*d0e51869Samw append_typeinfo(ndr_typeinfo_t *ti)
836*d0e51869Samw {
837*d0e51869Samw ndr_typeinfo_t **pp;
838*d0e51869Samw
839*d0e51869Samw for (pp = &typeinfo_list; *pp; pp = &(*pp)->next)
840*d0e51869Samw ;
841*d0e51869Samw
842*d0e51869Samw *pp = ti;
843*d0e51869Samw ti->next = 0;
844*d0e51869Samw }
845*d0e51869Samw
846*d0e51869Samw static ndr_typeinfo_t *
bind_typeinfo(ndr_typeinfo_t * proto_ti)847*d0e51869Samw bind_typeinfo(ndr_typeinfo_t *proto_ti)
848*d0e51869Samw {
849*d0e51869Samw ndr_typeinfo_t *ti;
850*d0e51869Samw ndr_typeinfo_t *tdti = proto_ti->type_down;
851*d0e51869Samw
852*d0e51869Samw for (ti = typeinfo_list; ti; ti = ti->next) {
853*d0e51869Samw if (ti->type_op != proto_ti->type_op)
854*d0e51869Samw continue;
855*d0e51869Samw
856*d0e51869Samw switch (ti->type_op) {
857*d0e51869Samw case STAR:
858*d0e51869Samw if (ti->type_down != proto_ti->type_down)
859*d0e51869Samw continue;
860*d0e51869Samw break;
861*d0e51869Samw
862*d0e51869Samw case STRING_KW:
863*d0e51869Samw if (ti->type_down != proto_ti->type_down)
864*d0e51869Samw continue;
865*d0e51869Samw break;
866*d0e51869Samw
867*d0e51869Samw case LB:
868*d0e51869Samw if (ti->type_down != proto_ti->type_down)
869*d0e51869Samw continue;
870*d0e51869Samw if (ti->type_dim != proto_ti->type_dim)
871*d0e51869Samw continue;
872*d0e51869Samw break;
873*d0e51869Samw
874*d0e51869Samw case BASIC_TYPE:
875*d0e51869Samw case STRUCT_KW:
876*d0e51869Samw case TYPEDEF_KW:
877*d0e51869Samw case UNION_KW:
878*d0e51869Samw if (ti->type_name != proto_ti->type_name)
879*d0e51869Samw continue;
880*d0e51869Samw break;
881*d0e51869Samw
882*d0e51869Samw default:
883*d0e51869Samw fatal_error("bind_typeinfo unknown %d\n", ti->type_op);
884*d0e51869Samw break;
885*d0e51869Samw }
886*d0e51869Samw
887*d0e51869Samw return (ti);
888*d0e51869Samw }
889*d0e51869Samw
890*d0e51869Samw ti = ndr_alloc(1, sizeof (ndr_typeinfo_t));
891*d0e51869Samw
892*d0e51869Samw *ti = *proto_ti;
893*d0e51869Samw append_typeinfo(ti);
894*d0e51869Samw
895*d0e51869Samw switch (ti->type_op) {
896*d0e51869Samw case STAR:
897*d0e51869Samw ti->size_fixed_part = 4;
898*d0e51869Samw ti->alignment = 3;
899*d0e51869Samw ti->complete = 1;
900*d0e51869Samw ti->has_pointers = 1;
901*d0e51869Samw break;
902*d0e51869Samw
903*d0e51869Samw case STRING_KW:
904*d0e51869Samw case LB:
905*d0e51869Samw if (tdti->complete) {
906*d0e51869Samw ti->alignment = tdti->alignment;
907*d0e51869Samw if (tdti->size_variable_part) {
908*d0e51869Samw compile_error("array of var-size type");
909*d0e51869Samw } else if (ti->type_dim) {
910*d0e51869Samw ti->size_fixed_part = tdti->size_fixed_part *
911*d0e51869Samw ti->type_dim->n_int;
912*d0e51869Samw } else {
913*d0e51869Samw ti->size_variable_part = tdti->size_fixed_part;
914*d0e51869Samw ti->is_conformant = 1;
915*d0e51869Samw }
916*d0e51869Samw } else {
917*d0e51869Samw compile_error("array of incomplete type");
918*d0e51869Samw }
919*d0e51869Samw
920*d0e51869Samw ti->has_pointers = tdti->has_pointers;
921*d0e51869Samw ti->complete = 1;
922*d0e51869Samw break;
923*d0e51869Samw
924*d0e51869Samw default:
925*d0e51869Samw compile_error("bind_type internal error op=%d", ti->type_op);
926*d0e51869Samw break;
927*d0e51869Samw }
928*d0e51869Samw
929*d0e51869Samw /*
930*d0e51869Samw * Disallow
931*d0e51869Samw * union foo *ptrfoo;
932*d0e51869Samw * There is no way to pass the selector (switch_is)in
933*d0e51869Samw */
934*d0e51869Samw if (ti->type_op == STAR && ti->type_down->type_op == UNION_KW) {
935*d0e51869Samw compile_error("pointers to unions not allowed");
936*d0e51869Samw }
937*d0e51869Samw
938*d0e51869Samw /*
939*d0e51869Samw * Disallow
940*d0e51869Samw * union foo fooarr[n];
941*d0e51869Samw * Each element needs a distinct selector
942*d0e51869Samw */
943*d0e51869Samw if (ti->type_op == LB && ti->type_down->type_op == UNION_KW) {
944*d0e51869Samw compile_error("arrays of unions not allowed");
945*d0e51869Samw }
946*d0e51869Samw
947*d0e51869Samw return (ti);
948*d0e51869Samw }
949*d0e51869Samw
950*d0e51869Samw static ndr_typeinfo_t *
find_typeinfo_by_name(ndr_node_t * typename)951*d0e51869Samw find_typeinfo_by_name(ndr_node_t *typename)
952*d0e51869Samw {
953*d0e51869Samw ndr_typeinfo_t *ti;
954*d0e51869Samw
955*d0e51869Samw for (ti = typeinfo_list; ti; ti = ti->next) {
956*d0e51869Samw if (ti->type_name == typename)
957*d0e51869Samw return (ti);
958*d0e51869Samw }
959*d0e51869Samw
960*d0e51869Samw compile_error("unknown type %s", typename->n_sym->name);
961*d0e51869Samw
962*d0e51869Samw /* fake BASIC_TYPE */
963*d0e51869Samw ti = ndr_alloc(1, sizeof (ndr_typeinfo_t));
964*d0e51869Samw ti->type_op = BASIC_TYPE;
965*d0e51869Samw ti->definition = typename;
966*d0e51869Samw ti->type_name = typename;
967*d0e51869Samw ti->size_fixed_part = 0;
968*d0e51869Samw ti->alignment = 0;
969*d0e51869Samw
970*d0e51869Samw append_typeinfo(ti);
971*d0e51869Samw return (ti);
972*d0e51869Samw }
973*d0e51869Samw
974*d0e51869Samw static void
determine_advice(ndr_advice_t * advice,ndr_node_t * advice_list)975*d0e51869Samw determine_advice(ndr_advice_t *advice, ndr_node_t *advice_list)
976*d0e51869Samw {
977*d0e51869Samw /* alias for basic types */
978*d0e51869Samw advice->a_transmit_as = find_advice(advice_list, TRANSMIT_AS_KW);
979*d0e51869Samw
980*d0e51869Samw /* arg used for size, union, or generic purpose */
981*d0e51869Samw advice->a_arg_is = find_advice(advice_list, ARG_IS_KW);
982*d0e51869Samw
983*d0e51869Samw /* operation parameter in/out stuff */
984*d0e51869Samw advice->a_operation = find_advice(advice_list, OPERATION_KW);
985*d0e51869Samw advice->a_in = find_advice(advice_list, IN_KW);
986*d0e51869Samw advice->a_out = find_advice(advice_list, OUT_KW);
987*d0e51869Samw
988*d0e51869Samw /* size stuff */
989*d0e51869Samw advice->a_string = find_advice(advice_list, STRING_KW);
990*d0e51869Samw advice->a_size_is = find_advice(advice_list, SIZE_IS_KW);
991*d0e51869Samw advice->a_length_is = find_advice(advice_list, LENGTH_IS_KW);
992*d0e51869Samw
993*d0e51869Samw /* union stuff */
994*d0e51869Samw advice->a_case = find_advice(advice_list, CASE_KW);
995*d0e51869Samw advice->a_default = find_advice(advice_list, DEFAULT_KW);
996*d0e51869Samw advice->a_switch_is = find_advice(advice_list, SWITCH_IS_KW);
997*d0e51869Samw
998*d0e51869Samw /* interface stuff */
999*d0e51869Samw advice->a_interface = find_advice(advice_list, INTERFACE_KW);
1000*d0e51869Samw advice->a_uuid = find_advice(advice_list, UUID_KW);
1001*d0e51869Samw advice->a_no_reorder = find_advice(advice_list, _NO_REORDER_KW);
1002*d0e51869Samw advice->a_extern = find_advice(advice_list, EXTERN_KW);
1003*d0e51869Samw
1004*d0e51869Samw advice->a_reference = find_advice(advice_list, REFERENCE_KW);
1005*d0e51869Samw advice->a_align = find_advice(advice_list, ALIGN_KW);
1006*d0e51869Samw }
1007*d0e51869Samw
1008*d0e51869Samw static ndr_node_t *
find_advice(ndr_node_t * advice_list,int label)1009*d0e51869Samw find_advice(ndr_node_t *advice_list, int label)
1010*d0e51869Samw {
1011*d0e51869Samw ndr_node_t *np;
1012*d0e51869Samw
1013*d0e51869Samw for (np = advice_list; np; np = np->n_next)
1014*d0e51869Samw if (np->label == label)
1015*d0e51869Samw break;
1016*d0e51869Samw
1017*d0e51869Samw return (np);
1018*d0e51869Samw }
1019*d0e51869Samw
1020*d0e51869Samw void
member_fixup(ndr_node_t * member_np)1021*d0e51869Samw member_fixup(ndr_node_t *member_np)
1022*d0e51869Samw {
1023*d0e51869Samw ndr_node_t *np;
1024*d0e51869Samw
1025*d0e51869Samw for (np = member_np->n_m_decl; np; np = np->n_d_descend)
1026*d0e51869Samw if (np->label == IDENTIFIER)
1027*d0e51869Samw break;
1028*d0e51869Samw
1029*d0e51869Samw member_np->n_m_name = np;
1030*d0e51869Samw }
1031*d0e51869Samw
1032*d0e51869Samw void
construct_fixup(ndr_node_t * construct_np)1033*d0e51869Samw construct_fixup(ndr_node_t *construct_np)
1034*d0e51869Samw {
1035*d0e51869Samw construct_np->n_c_typename->n_sym->typedefn = construct_np;
1036*d0e51869Samw }
1037