8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / tools / ndrgen / ndr_gen.c
blobe131002e1b3a30224badd44e2364ed6e73780116
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #include <string.h>
28 #include "ndrgen.h"
29 #include "y.tab.h"
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 *,
37 ndr_typeinfo_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 *,
42 char *);
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 *);
50 void
51 generate(void)
53 ndr_typeinfo_t *ti;
54 char fname_type[NDLBUFSZ];
56 (void) printf("\n");
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);
61 (void) printf(
62 "extern struct ndr_typeinfo ndt_%s;\n",
63 fname_type);
64 continue;
67 switch (ti->type_op) {
68 case STRUCT_KW:
69 if (ti->advice.a_operation)
70 generate_params(ti);
71 else
72 generate_struct(ti);
73 break;
75 case UNION_KW:
76 generate_union(ti);
77 break;
79 case TYPEDEF_KW:
80 /* silently skip */
81 continue;
83 case STRING_KW:
84 case STAR:
85 case LB:
86 case BASIC_TYPE:
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);
93 break;
95 default:
96 continue;
101 static void
102 generate_struct(ndr_typeinfo_t *ti)
104 int i;
105 ndr_member_t *mem;
107 if (ti->advice.a_no_reorder) {
108 /* just use generate_params(), which can safely do this */
109 generate_params(ti);
110 return;
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)
119 continue;
121 generate_member(ti, mem);
124 (void) printf("\n");
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)
129 continue;
131 if (mem->type->has_pointers)
132 continue;
134 generate_member(ti, mem);
137 (void) printf("\n");
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)
142 continue;
144 if (!mem->type->has_pointers)
145 continue;
147 generate_member(ti, mem);
150 generate_aggregate_common_finish(ti);
153 static void
154 generate_params(ndr_typeinfo_t *ti)
156 int i;
157 ndr_member_t *mem;
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);
171 static void
172 generate_union(ndr_typeinfo_t *ti)
174 int i;
175 ndr_member_t *mem;
176 int have_default = 0;
177 ndr_node_t *np;
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");
195 } else {
196 compile_error("syntax error");
199 generate_member(ti, mem);
200 (void) printf(" break;\n\n");
203 if (!have_default) {
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");
212 (void) printf("\n");
214 generate_aggregate_common_finish(ti);
217 static void
218 generate_arg(ndr_node_t *np)
220 ndr_node_t *arg = np;
222 if (np == NULL) {
223 compile_error("invalid node pointer <null>");
224 return;
227 if (np->label != IDENTIFIER && np->label != INTEGER)
228 arg = np->n_a_arg;
230 switch (np->label) {
231 case SIZE_IS_KW:
232 case LENGTH_IS_KW:
233 case SWITCH_IS_KW:
234 (void) printf("val->");
235 print_field_attr(np);
236 break;
237 default:
238 if (arg->label == IDENTIFIER)
239 (void) printf("val->%s", arg->n_sym->name);
240 else
241 print_node(arg);
242 break;
246 static void
247 generate_member_macro(char *memkind, char *macro, ndr_member_t *mem,
248 ndr_typeinfo_t *ti)
250 char fname_type[NDLBUFSZ];
252 if (!macro)
253 macro = "";
254 if (!ti)
255 ti = mem->type;
257 type_extern_suffix(ti, fname_type, NDLBUFSZ);
259 if (memkind) {
260 (void) printf(" NDR_%sMEMBER%s (%s, %s);\n",
261 memkind, macro, fname_type, mem->name);
262 } else {
263 (void) printf(" NDR_MEMBER%s (%s, %s, %uUL);\n",
264 macro, fname_type, mem->name, mem->pdu_offset);
268 static void
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];
274 if (!macro)
275 macro = "_WITH_ARG";
276 if (!ti)
277 ti = mem->type;
279 type_extern_suffix(ti, fname_type, NDLBUFSZ);
281 if (memkind) {
282 (void) printf(" NDR_%sMEMBER%s (%s, %s,\n",
283 memkind, macro, fname_type, mem->name);
284 } else {
285 (void) printf(" NDR_MEMBER%s (%s, %s, %uUL,\n",
286 macro, fname_type, mem->name, mem->pdu_offset);
289 (void) printf("\t\t");
290 generate_arg(np);
291 (void) printf(");\n");
294 static void
295 generate_prototypes(ndr_typeinfo_t *ti, char *fname_type)
297 ndr_member_t *mem;
298 int i;
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);
309 static void
310 generate_member_prototypes(ndr_typeinfo_t *ti,
311 ndr_member_t *mem, char *fname_type)
313 char val_buf[NDLBUFSZ];
314 ndr_typeinfo_t ptr;
316 if (mem->type->type_op == UNION_KW) {
317 if (!mem->advice.a_in && mem->advice.a_out) {
318 ptr.type_op = STAR;
319 ptr.type_down = ti;
320 type_name_decl(&ptr, val_buf, NDLBUFSZ, "val");
322 (void) printf("\nextern void fixup%s(%s);\n",
323 fname_type, val_buf);
328 static void
329 generate_member(ndr_typeinfo_t *ti, ndr_member_t *mem)
331 static char *fixup[] = {
332 "/*",
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.",
336 " */"
339 char fname_type[NDLBUFSZ];
340 ndr_node_t *np;
341 int is_reference = 0;
342 char *memkind = 0;
343 int cond_pending = 0;
344 int i;
346 if (ti->advice.a_operation)
347 memkind = "TOPMOST_";
348 else if (ti->advice.a_interface)
349 memkind = "PARAMS_";
351 if (mem->advice.a_in && !mem->advice.a_out) {
352 cond_pending = 1;
353 (void) printf(" if (NDR_DIR_IS_IN) {\n");
356 if (!mem->advice.a_in && mem->advice.a_out) {
357 cond_pending = 1;
358 (void) printf(" if (NDR_DIR_IS_OUT) {\n");
361 type_extern_suffix(ti, fname_type, NDLBUFSZ);
363 switch (mem->type->type_op) {
364 case BASIC_TYPE:
365 case STRUCT_KW:
366 generate_member_macro(memkind, 0, mem, 0);
367 break;
369 case UNION_KW:
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);
381 break;
383 case STAR:
384 if (mem->advice.a_reference)
385 is_reference = 1;
386 else
387 is_reference = 0;
389 np = mem->advice.a_size_is;
390 if (np) {
391 generate_member_macro_with_arg(memkind,
392 is_reference ?
393 "_REF_WITH_SIZE_IS" : "_PTR_WITH_SIZE_IS",
394 mem, mem->type->type_down, np);
395 break;
398 np = mem->advice.a_length_is;
399 if (np) {
400 generate_member_macro_with_arg(memkind,
401 is_reference ?
402 "_REF_WITH_LENGTH_IS" : "_PTR_WITH_LENGTH_IS",
403 mem, mem->type->type_down, np);
404 break;
407 generate_member_macro(memkind,
408 is_reference ? "_REF" : "_PTR",
409 mem, mem->type->type_down);
410 break;
412 case LB:
413 np = mem->advice.a_size_is;
414 if (np) {
415 generate_member_macro_with_arg(memkind,
416 "_ARR_WITH_SIZE_IS",
417 mem, mem->type->type_down, np);
418 break;
421 np = mem->advice.a_length_is;
422 if (np) {
423 generate_member_macro_with_arg(memkind,
424 "_WITH_LENGTH_IS",
425 mem, mem->type->type_down, np);
426 break;
429 generate_member_macro_with_arg(memkind,
430 "_ARR_WITH_DIMENSION",
431 mem, mem->type->type_down, mem->type->type_dim);
432 break;
434 default:
435 generate_member_macro(memkind, "_???", mem, 0);
436 break;
439 if (cond_pending)
440 (void) printf(" }\n");
443 static void
444 generate_aggregate_common_begin(ndr_typeinfo_t *ti)
446 char val_buf[NDLBUFSZ];
447 char cast_buf[NDLBUFSZ];
448 char fname_type[NDLBUFSZ];
449 ndr_typeinfo_t ptr;
451 type_extern_suffix(ti, fname_type, NDLBUFSZ);
452 generate_typeinfo_typeinfo(ti, 0, fname_type);
453 generate_prototypes(ti, fname_type);
455 (void) printf("\n");
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",
461 fname_type);
462 (void) printf("{\n");
464 ptr.type_op = STAR;
465 ptr.type_down = ti;
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");
473 (void) printf("\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);
478 (void) printf("\n");
481 /* ARGSUSED */
482 static void
483 generate_aggregate_common_finish(ndr_typeinfo_t *ti)
485 (void) printf("\n");
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.
496 static void
497 generate_typeinfo_packing(ndr_typeinfo_t *ti)
499 ndr_node_t *np;
500 unsigned long packing;
502 if ((np = ti->advice.a_align) == NULL)
503 return;
505 if ((np = np->n_a_arg) == NULL)
506 return;
508 packing = np->n_int;
509 if ((packing == 0) || (packing == 4)) {
510 /* default alignment */
511 return;
514 if (packing != 2) {
515 fatal_error("invalid align directive: %lu", packing);
516 /* NOTREACHED */
519 (void) printf(" myref.packed_alignment = %lu;\n", packing);
522 static void
523 generate_typeinfo_typeinfo(ndr_typeinfo_t *ti, int is_static, char *fname_type)
525 char flags[NDLBUFSZ];
527 *flags = 0;
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);
534 else
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);
541 else
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);
552 if (*flags == 0)
553 (void) strlcpy(flags, "NDR_F_NONE", NDLBUFSZ);
554 else
555 (void) strlcpy(flags, flags+1, NDLBUFSZ);
557 (void) printf("\n\n\n");
558 if (is_static)
559 (void) printf("static ");
561 (void) printf("int ndr_%s (struct ndr_reference *encl_ref);\n",
562 fname_type);
563 if (is_static)
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");