4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
32 static void generate_struct(ndr_typeinfo_t
*);
33 static void generate_params(ndr_typeinfo_t
*);
34 static void generate_union(ndr_typeinfo_t
*);
35 static void generate_arg(ndr_node_t
*);
36 static void generate_member_macro(char *, char *, ndr_member_t
*,
38 static void generate_member_macro_with_arg(char *, char *, ndr_member_t
*,
39 ndr_typeinfo_t
*, ndr_node_t
*);
40 static void generate_prototypes(ndr_typeinfo_t
*, char *);
41 static void generate_member_prototypes(ndr_typeinfo_t
*, ndr_member_t
*,
43 static void generate_member(ndr_typeinfo_t
*, ndr_member_t
*);
44 static void generate_aggregate_common_begin(ndr_typeinfo_t
*);
45 static void generate_aggregate_common_finish(ndr_typeinfo_t
*);
46 static void generate_typeinfo_packing(ndr_typeinfo_t
*);
47 static void generate_typeinfo_typeinfo(ndr_typeinfo_t
*, int, char *);
54 char fname_type
[NDLBUFSZ
];
58 for (ti
= typeinfo_list
; ti
; ti
= ti
->next
) {
59 if (ti
->is_extern
|| ti
->advice
.a_extern
) {
60 type_extern_suffix(ti
, fname_type
, NDLBUFSZ
);
62 "extern struct ndr_typeinfo ndt_%s;\n",
67 switch (ti
->type_op
) {
69 if (ti
->advice
.a_operation
)
87 if (!ti
->is_referenced
) {
88 type_extern_suffix(ti
, fname_type
, NDLBUFSZ
);
89 (void) printf("extern ndt_%s\n", fname_type
);
90 type_null_decl(ti
, fname_type
, NDLBUFSZ
);
91 (void) printf("/* %s */\n", fname_type
);
102 generate_struct(ndr_typeinfo_t
*ti
)
107 if (ti
->advice
.a_no_reorder
) {
108 /* just use generate_params(), which can safely do this */
113 generate_aggregate_common_begin(ti
);
115 (void) printf(" /* do all basic elements first */\n");
116 for (i
= 0; i
< ti
->n_member
; i
++) {
117 mem
= &ti
->member
[i
];
118 if (mem
->type
->type_op
!= BASIC_TYPE
)
121 generate_member(ti
, mem
);
125 (void) printf(" /* do all constructed elements w/o pointers */\n");
126 for (i
= 0; i
< ti
->n_member
; i
++) {
127 mem
= &ti
->member
[i
];
128 if (mem
->type
->type_op
== BASIC_TYPE
)
131 if (mem
->type
->has_pointers
)
134 generate_member(ti
, mem
);
138 (void) printf(" /* do members with pointers in order */\n");
139 for (i
= 0; i
< ti
->n_member
; i
++) {
140 mem
= &ti
->member
[i
];
141 if (mem
->type
->type_op
== BASIC_TYPE
)
144 if (!mem
->type
->has_pointers
)
147 generate_member(ti
, mem
);
150 generate_aggregate_common_finish(ti
);
154 generate_params(ndr_typeinfo_t
*ti
)
159 generate_aggregate_common_begin(ti
);
161 (void) printf(" /* do all members in order */\n");
162 for (i
= 0; i
< ti
->n_member
; i
++) {
163 mem
= &ti
->member
[i
];
165 generate_member(ti
, mem
);
168 generate_aggregate_common_finish(ti
);
172 generate_union(ndr_typeinfo_t
*ti
)
176 int have_default
= 0;
179 generate_aggregate_common_begin(ti
);
181 (void) printf(" switch (encl_ref->switch_is) {\n");
183 for (i
= 0; i
< ti
->n_member
; i
++) {
184 mem
= &ti
->member
[i
];
186 if ((np
= mem
->advice
.a_case
) != 0) {
187 (void) printf(" case ");
188 print_node(np
->n_a_arg
);
189 (void) printf(":\n");
190 } else if ((np
= mem
->advice
.a_default
) != 0) {
191 (void) printf(" default:\n");
192 if (have_default
++) {
193 compile_error("multiple defaults");
196 compile_error("syntax error");
199 generate_member(ti
, mem
);
200 (void) printf(" break;\n\n");
204 (void) printf(" default:\n");
205 (void) printf(" NDR_SET_ERROR(encl_ref, "
206 "NDR_ERR_SWITCH_VALUE_INVALID);\n");
207 (void) printf(" return 0;\n");
208 (void) printf(" break;\n");
211 (void) printf(" }\n");
214 generate_aggregate_common_finish(ti
);
218 generate_arg(ndr_node_t
*np
)
220 ndr_node_t
*arg
= np
;
223 compile_error("invalid node pointer <null>");
227 if (np
->label
!= IDENTIFIER
&& np
->label
!= INTEGER
)
234 (void) printf("val->");
235 print_field_attr(np
);
238 if (arg
->label
== IDENTIFIER
)
239 (void) printf("val->%s", arg
->n_sym
->name
);
247 generate_member_macro(char *memkind
, char *macro
, ndr_member_t
*mem
,
250 char fname_type
[NDLBUFSZ
];
257 type_extern_suffix(ti
, fname_type
, NDLBUFSZ
);
260 (void) printf(" NDR_%sMEMBER%s (%s, %s);\n",
261 memkind
, macro
, fname_type
, mem
->name
);
263 (void) printf(" NDR_MEMBER%s (%s, %s, %uUL);\n",
264 macro
, fname_type
, mem
->name
, mem
->pdu_offset
);
269 generate_member_macro_with_arg(char *memkind
, char *macro
,
270 ndr_member_t
*mem
, ndr_typeinfo_t
*ti
, ndr_node_t
*np
)
272 char fname_type
[NDLBUFSZ
];
279 type_extern_suffix(ti
, fname_type
, NDLBUFSZ
);
282 (void) printf(" NDR_%sMEMBER%s (%s, %s,\n",
283 memkind
, macro
, fname_type
, mem
->name
);
285 (void) printf(" NDR_MEMBER%s (%s, %s, %uUL,\n",
286 macro
, fname_type
, mem
->name
, mem
->pdu_offset
);
289 (void) printf("\t\t");
291 (void) printf(");\n");
295 generate_prototypes(ndr_typeinfo_t
*ti
, char *fname_type
)
300 if (ti
->type_op
== STRUCT_KW
&& ti
->advice
.a_operation
) {
301 for (i
= 0; i
< ti
->n_member
; i
++) {
302 mem
= &ti
->member
[i
];
304 generate_member_prototypes(ti
, mem
, fname_type
);
310 generate_member_prototypes(ndr_typeinfo_t
*ti
,
311 ndr_member_t
*mem
, char *fname_type
)
313 char val_buf
[NDLBUFSZ
];
316 if (mem
->type
->type_op
== UNION_KW
) {
317 if (!mem
->advice
.a_in
&& mem
->advice
.a_out
) {
320 type_name_decl(&ptr
, val_buf
, NDLBUFSZ
, "val");
322 (void) printf("\nextern void fixup%s(%s);\n",
323 fname_type
, val_buf
);
329 generate_member(ndr_typeinfo_t
*ti
, ndr_member_t
*mem
)
331 static char *fixup
[] = {
333 " * Cannot use the canned offsets to unmarshall multiple",
334 " * entry discriminated unions. The service must provide",
335 " * this function to patch the offsets at runtime.",
339 char fname_type
[NDLBUFSZ
];
341 int is_reference
= 0;
343 int cond_pending
= 0;
346 if (ti
->advice
.a_operation
)
347 memkind
= "TOPMOST_";
348 else if (ti
->advice
.a_interface
)
351 if (mem
->advice
.a_in
&& !mem
->advice
.a_out
) {
353 (void) printf(" if (NDR_DIR_IS_IN) {\n");
356 if (!mem
->advice
.a_in
&& mem
->advice
.a_out
) {
358 (void) printf(" if (NDR_DIR_IS_OUT) {\n");
361 type_extern_suffix(ti
, fname_type
, NDLBUFSZ
);
363 switch (mem
->type
->type_op
) {
366 generate_member_macro(memkind
, 0, mem
, 0);
370 np
= mem
->advice
.a_switch_is
;
372 if (!mem
->advice
.a_in
&& mem
->advice
.a_out
) {
373 for (i
= 0; i
< sizeof (fixup
)/sizeof (fixup
[0]); ++i
)
374 (void) printf("\t%s\n", fixup
[i
]);
376 (void) printf("\tfixup%s(val);\n", fname_type
);
379 generate_member_macro_with_arg(memkind
,
380 "_WITH_SWITCH_IS", mem
, 0, np
);
384 if (mem
->advice
.a_reference
)
389 np
= mem
->advice
.a_size_is
;
391 generate_member_macro_with_arg(memkind
,
393 "_REF_WITH_SIZE_IS" : "_PTR_WITH_SIZE_IS",
394 mem
, mem
->type
->type_down
, np
);
398 np
= mem
->advice
.a_length_is
;
400 generate_member_macro_with_arg(memkind
,
402 "_REF_WITH_LENGTH_IS" : "_PTR_WITH_LENGTH_IS",
403 mem
, mem
->type
->type_down
, np
);
407 generate_member_macro(memkind
,
408 is_reference
? "_REF" : "_PTR",
409 mem
, mem
->type
->type_down
);
413 np
= mem
->advice
.a_size_is
;
415 generate_member_macro_with_arg(memkind
,
417 mem
, mem
->type
->type_down
, np
);
421 np
= mem
->advice
.a_length_is
;
423 generate_member_macro_with_arg(memkind
,
425 mem
, mem
->type
->type_down
, np
);
429 generate_member_macro_with_arg(memkind
,
430 "_ARR_WITH_DIMENSION",
431 mem
, mem
->type
->type_down
, mem
->type
->type_dim
);
435 generate_member_macro(memkind
, "_???", mem
, 0);
440 (void) printf(" }\n");
444 generate_aggregate_common_begin(ndr_typeinfo_t
*ti
)
446 char val_buf
[NDLBUFSZ
];
447 char cast_buf
[NDLBUFSZ
];
448 char fname_type
[NDLBUFSZ
];
451 type_extern_suffix(ti
, fname_type
, NDLBUFSZ
);
452 generate_typeinfo_typeinfo(ti
, 0, fname_type
);
453 generate_prototypes(ti
, fname_type
);
456 (void) printf("/*\n * ");
457 show_advice(&ti
->advice
, 0);
458 (void) printf(" */\n");
459 (void) printf("int\n");
460 (void) printf("ndr_%s (struct ndr_reference *encl_ref)\n",
462 (void) printf("{\n");
467 type_name_decl(&ptr
, val_buf
, NDLBUFSZ
, "val");
468 type_null_decl(&ptr
, cast_buf
, NDLBUFSZ
);
470 (void) printf(" %s = %s encl_ref->datum;\n", val_buf
, cast_buf
);
472 (void) printf(" struct ndr_reference myref;\n");
474 (void) printf(" (void) bzero(&myref, sizeof (myref));\n");
475 (void) printf(" myref.enclosing = encl_ref;\n");
476 (void) printf(" myref.stream = encl_ref->stream;\n");
477 generate_typeinfo_packing(ti
);
483 generate_aggregate_common_finish(ndr_typeinfo_t
*ti
)
486 (void) printf(" return 1;\n");
487 (void) printf("}\n");
491 * Structures are normally 4-byte (dword) aligned but the align directive
492 * can be used to pack on a 2-byte (word) boundary. An align value of
493 * zero is taken to mean use default (dword) alignment. Default packing
494 * doesn't need to be flagged.
497 generate_typeinfo_packing(ndr_typeinfo_t
*ti
)
500 unsigned long packing
;
502 if ((np
= ti
->advice
.a_align
) == NULL
)
505 if ((np
= np
->n_a_arg
) == NULL
)
509 if ((packing
== 0) || (packing
== 4)) {
510 /* default alignment */
515 fatal_error("invalid align directive: %lu", packing
);
519 (void) printf(" myref.packed_alignment = %lu;\n", packing
);
523 generate_typeinfo_typeinfo(ndr_typeinfo_t
*ti
, int is_static
, char *fname_type
)
525 char flags
[NDLBUFSZ
];
528 if (ti
->is_conformant
)
529 (void) strlcat(flags
, "|NDR_F_CONFORMANT", NDLBUFSZ
);
531 if (ti
->type_op
== STRUCT_KW
) {
532 if (ti
->advice
.a_operation
)
533 (void) strlcat(flags
, "|NDR_F_OPERATION", NDLBUFSZ
);
535 (void) strlcat(flags
, "|NDR_F_STRUCT", NDLBUFSZ
);
538 if (ti
->type_op
== UNION_KW
) {
539 if (ti
->advice
.a_interface
)
540 (void) strlcat(flags
, "|NDR_F_INTERFACE", NDLBUFSZ
);
542 (void) strlcat(flags
, "|NDR_F_UNION", NDLBUFSZ
);
545 if (ti
->type_op
== STRING_KW
)
546 (void) strlcat(flags
, "|NDR_F_STRING", NDLBUFSZ
);
547 if (ti
->type_op
== LB
)
548 (void) strlcat(flags
, "|NDR_F_ARRAY", NDLBUFSZ
);
549 if (ti
->type_op
== STAR
)
550 (void) strlcat(flags
, "|NDR_F_POINTER", NDLBUFSZ
);
553 (void) strlcpy(flags
, "NDR_F_NONE", NDLBUFSZ
);
555 (void) strlcpy(flags
, flags
+1, NDLBUFSZ
);
557 (void) printf("\n\n\n");
559 (void) printf("static ");
561 (void) printf("int ndr_%s (struct ndr_reference *encl_ref);\n",
564 (void) printf("static ");
566 (void) printf("struct ndr_typeinfo ndt_%s = {\n", fname_type
);
567 (void) printf("\t1, /* NDR version */\n");
568 (void) printf("\t%d, /* alignment */\n", ti
->alignment
);
569 (void) printf("\t%s, /* flags */\n", flags
);
570 (void) printf("\tndr_%s, /* ndr_func */\n", fname_type
);
571 (void) printf("\t%d, /* pdu_size_fixed_part */\n",
572 ti
->size_fixed_part
);
573 (void) printf("\t%d, /* pdu_size_variable_part */\n",
574 ti
->size_variable_part
);
576 (void) printf("\t%d, /* c_size_fixed_part */\n",
577 ti
->size_fixed_part
);
578 (void) printf("\t%d, /* c_size_variable_part */\n",
579 ti
->size_variable_part
);
580 (void) printf("};\n\n");