1 ###################################################
2 # Samba4 parser generator for IDL structures
3 # Copyright tridge@samba.org 2000-2003
4 # Copyright tpot@samba.org 2001
5 # Copyright jelmer@samba.org 2004
6 # released under the GNU GPL
13 # the list of needed functions
21 #####################################################################
22 # parse a properties list
23 sub ParseProperties
($)
26 foreach my $d (@
{$props}) {
27 if (ref($d) ne "HASH") {
30 foreach my $k (keys %{$d}) {
31 pidl
"[$k($d->{$k})] ";
37 ###################################
38 # find a sibling var in a structure
43 my($fn) = $e->{PARENT
};
45 if ($name =~ /\*(.*)/) {
49 if ($fn->{TYPE
} eq "FUNCTION") {
50 for my $e2 (@
{$fn->{DATA
}}) {
51 if ($e2->{NAME
} eq $name) {
57 for my $e2 (@
{$fn->{ELEMENTS
}}) {
58 if ($e2->{NAME
} eq $name) {
62 die "invalid sibling '$name'";
65 ####################################################################
66 # work out the name of a size_is() variable
67 sub find_size_var
($$$)
71 my($var_prefix) = shift;
73 my($fn) = $e->{PARENT
};
75 if (util
::is_constant
($size)) {
79 if ($size =~ /ndr->|\(/) {
85 if ($size =~ /\*(.*)/) {
90 if ($fn->{TYPE
} ne "FUNCTION") {
91 return $prefix . "r->$size";
94 my $e2 = find_sibling
($e, $size);
96 if (util
::has_property
($e2, "in") && util
::has_property
($e2, "out")) {
97 return $prefix . "$var_prefix$size";
99 if (util
::has_property
($e2, "in")) {
100 return $prefix . "r->in.$size";
102 if (util
::has_property
($e2, "out")) {
103 return $prefix . "r->out.$size";
106 die "invalid variable in $size for element $e->{NAME} in $fn->{NAME}\n";
109 #####################################################################
110 # check that a variable we get from find_size_var isn't a null pointer
111 sub check_null_pointer
($)
114 if ($size =~ /^\*/) {
115 my $size2 = substr($size, 1);
116 pidl
"\tif ($size2 == NULL) return NT_STATUS_INVALID_PARAMETER_MIX;\n";
120 #####################################################################
121 # check that a variable we get from find_size_var isn't a null pointer
122 # void return varient
123 sub check_null_pointer_void
($)
126 if ($size =~ /^\*/) {
127 my $size2 = substr($size, 1);
128 pidl
"\tif ($size2 == NULL) return;\n";
133 #####################################################################
134 # work out is a parse function should be declared static or not
138 if ($fn->{TYPE
} eq "TYPEDEF") {
139 if (util
::has_property
($fn, "public")) {
144 if ($fn->{TYPE
} eq "FUNCTION") {
145 if (util
::has_property
($fn, "public")) {
153 ###################################################################
154 # setup any special flags for an element or structure
158 my $flags = util
::has_property
($e, "flag");
159 if (defined $flags) {
160 pidl
"\t{ uint32_t _flags_save_$e->{TYPE} = ndr->flags;\n";
161 pidl
"\tndr_set_flags(&ndr->flags, $flags);\n";
165 ###################################################################
166 # end any special flags for an element or structure
170 my $flags = util
::has_property
($e, "flag");
171 if (defined $flags) {
172 pidl
"\tndr->flags = _flags_save_$e->{TYPE};\n\t}\n";
177 #####################################################################
178 # work out the correct alignment for a structure
184 for my $e (@
{$s->{ELEMENTS
}}) {
187 if (!util
::need_wire_pointer
($e)
188 && defined $structs{$e->{TYPE
}}) {
189 if ($structs{$e->{TYPE
}}->{DATA
}->{TYPE
} eq "STRUCT") {
190 $a = struct_alignment
($structs{$e->{TYPE
}}->{DATA
});
191 } elsif ($structs{$e->{TYPE
}}->{DATA
}->{TYPE
} eq "UNION") {
192 if (defined $structs{$e->{TYPE
}}->{DATA
}) {
193 $a = union_alignment
($structs{$e->{TYPE
}}->{DATA
});
197 $a = util
::type_align
($e);
208 #####################################################################
209 # work out the correct alignment for a union
216 foreach my $e (@
{$u->{DATA
}}) {
219 if ($e->{TYPE
} eq "EMPTY") {
223 if (!util
::need_wire_pointer
($e)
224 && defined $structs{$e->{DATA
}->{TYPE
}}) {
225 my $s = $structs{$e->{DATA
}->{TYPE
}};
226 if ($s->{DATA
}->{TYPE
} eq "STRUCT") {
227 $a = struct_alignment
($s->{DATA
});
228 } elsif ($s->{DATA
}->{TYPE
} eq "UNION") {
229 $a = union_alignment
($s->{DATA
});
232 $a = util
::type_align
($e->{DATA
});
243 #####################################################################
244 # parse an array - push side
245 sub ParseArrayPush
($$$)
248 my $var_prefix = shift;
249 my $ndr_flags = shift;
251 my $size = find_size_var
($e, util
::array_size
($e), $var_prefix);
253 if (defined $e->{CONFORMANT_SIZE
}) {
254 # the conformant size has already been pushed
255 } elsif (!util
::is_inline_array
($e)) {
256 # we need to emit the array size
257 pidl
"\t\tNDR_CHECK(ndr_push_uint32(ndr, $size));\n";
260 if (my $length = util
::has_property
($e, "length_is")) {
261 $length = find_size_var
($e, $length, $var_prefix);
262 pidl
"\t\tNDR_CHECK(ndr_push_uint32(ndr, 0));\n";
263 pidl
"\t\tNDR_CHECK(ndr_push_uint32(ndr, $length));\n";
267 if (util
::is_scalar_type
($e->{TYPE
})) {
268 pidl
"\t\tNDR_CHECK(ndr_push_array_$e->{TYPE}(ndr, $ndr_flags, $var_prefix$e->{NAME}, $size));\n";
270 pidl
"\t\tNDR_CHECK(ndr_push_array(ndr, $ndr_flags, $var_prefix$e->{NAME}, sizeof($var_prefix$e->{NAME}\[0]), $size, (ndr_push_flags_fn_t)ndr_push_$e->{TYPE}));\n";
274 #####################################################################
276 sub ParseArrayPrint
($$)
279 my $var_prefix = shift;
280 my $size = find_size_var
($e, util
::array_size
($e), $var_prefix);
281 my $length = util
::has_property
($e, "length_is");
283 if (defined $length) {
284 $size = find_size_var
($e, $length, $var_prefix);
287 if (util
::is_scalar_type
($e->{TYPE
})) {
288 pidl
"\t\tndr_print_array_$e->{TYPE}(ndr, \"$e->{NAME}\", $var_prefix$e->{NAME}, $size);\n";
290 pidl
"\t\tndr_print_array(ndr, \"$e->{NAME}\", $var_prefix$e->{NAME}, sizeof($var_prefix$e->{NAME}\[0]), $size, (ndr_print_fn_t)ndr_print_$e->{TYPE});\n";
294 #####################################################################
295 # check the size_is and length_is constraints
296 sub CheckArraySizes
($$)
299 my $var_prefix = shift;
301 if (!defined $e->{CONFORMANT_SIZE
} &&
302 util
::has_property
($e, "size_is")) {
303 my $size = find_size_var
($e, util
::array_size
($e), $var_prefix);
304 pidl
"\tif ($var_prefix$e->{NAME}) {\n";
305 check_null_pointer
($size);
306 pidl
"\t\tNDR_CHECK(ndr_check_array_size(ndr, (void*)&$var_prefix$e->{NAME}, $size));\n";
310 if (my $length = util
::has_property
($e, "length_is")) {
311 $length = find_size_var
($e, $length, $var_prefix);
312 pidl
"\tif ($var_prefix$e->{NAME}) {\n";
313 check_null_pointer
($length);
314 pidl
"\t\tNDR_CHECK(ndr_check_array_length(ndr, (void*)&$var_prefix$e->{NAME}, $length));\n";
320 #####################################################################
321 # parse an array - pull side
322 sub ParseArrayPull
($$$)
325 my $var_prefix = shift;
326 my $ndr_flags = shift;
328 my $size = find_size_var
($e, util
::array_size
($e), $var_prefix);
329 my $alloc_size = $size;
331 # if this is a conformant array then we use that size to allocate, and make sure
332 # we allocate enough to pull the elements
333 if (defined $e->{CONFORMANT_SIZE
}) {
334 $alloc_size = $e->{CONFORMANT_SIZE
};
335 check_null_pointer
($size);
336 pidl
"\tif ($size > $alloc_size) {\n";
337 pidl
"\t\treturn ndr_pull_error(ndr, NDR_ERR_CONFORMANT_SIZE, \"Bad conformant size %u should be %u\", $alloc_size, $size);\n";
339 } elsif (!util
::is_inline_array
($e)) {
340 if ($var_prefix =~ /^r->out/ && $size =~ /^\*r->in/) {
341 my $size2 = substr($size, 1);
342 pidl
"if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_ALLOC(ndr, $size2); }\n";
345 # non fixed arrays encode the size just before the array
346 pidl
"\t\tNDR_CHECK(ndr_pull_array_size(ndr, &$var_prefix$e->{NAME}));\n";
347 $alloc_size = "ndr_get_array_size(ndr, &$var_prefix$e->{NAME})";
350 if ((util
::need_alloc
($e) && !util
::is_fixed_array
($e)) ||
351 ($var_prefix eq "r->in." && util
::has_property
($e, "ref"))) {
352 if (!util
::is_inline_array
($e) || $ndr_flags eq "NDR_SCALARS") {
353 pidl
"\t\tNDR_ALLOC_N(ndr, $var_prefix$e->{NAME}, $alloc_size);\n";
357 if (($var_prefix eq "r->out." && util
::has_property
($e, "ref"))) {
358 if (!util
::is_inline_array
($e) || $ndr_flags eq "NDR_SCALARS") {
359 pidl
"\tif (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {";
360 pidl
"\t\tNDR_ALLOC_N(ndr, $var_prefix$e->{NAME}, $alloc_size);\n";
365 if (my $length = util
::has_property
($e, "length_is")) {
366 pidl
"\t\tNDR_CHECK(ndr_pull_array_length(ndr, &$var_prefix$e->{NAME}));\n";
367 $size = "ndr_get_array_length(ndr, &$var_prefix$e->{NAME})";
370 check_null_pointer
($size);
371 if (util
::is_scalar_type
($e->{TYPE
})) {
372 pidl
"\t\tNDR_CHECK(ndr_pull_array_$e->{TYPE}(ndr, $ndr_flags, $var_prefix$e->{NAME}, $size));\n";
374 pidl
"\t\tNDR_CHECK(ndr_pull_array(ndr, $ndr_flags, (void **)$var_prefix$e->{NAME}, sizeof($var_prefix$e->{NAME}\[0]), $size, (ndr_pull_flags_fn_t)ndr_pull_$e->{TYPE}));\n";
379 #####################################################################
380 # parse scalars in a structure element
381 sub ParseElementPushScalar
($$$)
384 my($var_prefix) = shift;
385 my($ndr_flags) = shift;
386 my $cprefix = util
::c_push_prefix
($e);
387 my $sub_size = util
::has_property
($e, "subcontext");
391 if (my $value = util
::has_property
($e, "value")) {
392 pidl
"\t$cprefix$var_prefix$e->{NAME} = $value;\n";
395 if (util
::has_property
($e, "relative")) {
396 pidl
"\tNDR_CHECK(ndr_push_relative1(ndr, $var_prefix$e->{NAME}));\n";
397 } elsif (util
::is_inline_array
($e)) {
398 ParseArrayPush
($e, "r->", "NDR_SCALARS");
399 } elsif (util
::need_wire_pointer
($e)) {
400 pidl
"\tNDR_CHECK(ndr_push_ptr(ndr, $var_prefix$e->{NAME}));\n";
401 } elsif (util
::need_alloc
($e)) {
402 # no scalar component
403 } elsif (my $switch = util
::has_property
($e, "switch_is")) {
404 ParseElementPushSwitch
($e, $var_prefix, $ndr_flags, $switch);
405 } elsif (defined $sub_size) {
406 if (util
::is_builtin_type
($e->{TYPE
})) {
407 pidl
"\tNDR_CHECK(ndr_push_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_push_fn_t) ndr_push_$e->{TYPE}));\n";
409 pidl
"\tNDR_CHECK(ndr_push_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_push_flags_fn_t) ndr_push_$e->{TYPE}));\n";
411 } elsif (util
::is_builtin_type
($e->{TYPE
})) {
412 pidl
"\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n";
414 pidl
"\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
420 #####################################################################
421 # print scalars in a structure element
422 sub ParseElementPrintScalar
($$)
425 my($var_prefix) = shift;
426 my $cprefix = util
::c_push_prefix
($e);
428 if (util
::has_property
($e, "noprint")) {
432 if (my $value = util
::has_property
($e, "value")) {
433 pidl
"\tif (ndr->flags & LIBNDR_PRINT_SET_VALUES) {\n";
434 pidl
"\t\t$cprefix$var_prefix$e->{NAME} = $value;\n";
438 if (util
::is_fixed_array
($e)) {
439 ParseElementPrintBuffer
($e, $var_prefix);
440 } elsif (util
::has_direct_buffers
($e)) {
441 pidl
"\tndr_print_ptr(ndr, \"$e->{NAME}\", $var_prefix$e->{NAME});\n";
442 pidl
"\tndr->depth++;\n";
443 ParseElementPrintBuffer
($e, $var_prefix);
444 pidl
"\tndr->depth--;\n";
445 } elsif (my $switch = util
::has_property
($e, "switch_is")) {
446 ParseElementPrintSwitch
($e, $var_prefix, $switch);
448 pidl
"\tndr_print_$e->{TYPE}(ndr, \"$e->{NAME}\", $cprefix$var_prefix$e->{NAME});\n";
452 #####################################################################
453 # parse scalars in a structure element - pull size
454 sub ParseElementPullSwitch
($$$$)
457 my($var_prefix) = shift;
458 my($ndr_flags) = shift;
460 my $switch_var = find_size_var
($e, $switch, $var_prefix);
462 my $cprefix = util
::c_pull_prefix
($e);
464 my $utype = $structs{$e->{TYPE
}};
466 check_null_pointer
($switch_var);
468 if (!defined $utype ||
469 !util
::has_property
($utype, "nodiscriminant")) {
470 my $e2 = find_sibling
($e, $switch);
471 my $type_decl = $e2->{TYPE
};
472 pidl
"\tif (($ndr_flags) & NDR_SCALARS) {\n";
473 if (util
::is_enum
($e2->{TYPE
})) {
474 $type_decl = util
::enum_type_decl
($e2);
475 } elsif (util
::is_bitmap
($e2->{TYPE
})) {
476 $type_decl = util
::bitmap_type_decl
($e2);
478 pidl
"\t\t$type_decl _level;\n";
479 pidl
"\t\tNDR_CHECK(ndr_pull_$e2->{TYPE}(ndr, &_level));\n";
480 if ($switch_var =~ /r->in/) {
481 pidl
"\t\tif (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _level != $switch_var) {\n";
483 pidl
"\t\tif (_level != $switch_var) {\n";
485 pidl
"\t\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u in $e->{NAME}\", _level);\n";
487 if ($switch_var =~ /r->/) {
488 pidl
"else { $switch_var = _level; }\n";
493 my $sub_size = util
::has_property
($e, "subcontext");
494 if (defined $sub_size) {
495 pidl
"\tif (($ndr_flags) & NDR_SCALARS) {\n";
496 pidl
"\t\tNDR_CHECK(ndr_pull_subcontext_union_fn(ndr, $sub_size, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_pull_union_fn_t) ndr_pull_$e->{TYPE}));\n";
499 pidl
"\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $switch_var, $cprefix$var_prefix$e->{NAME}));\n";
505 #####################################################################
506 # push switch element
507 sub ParseElementPushSwitch
($$$$)
510 my($var_prefix) = shift;
511 my($ndr_flags) = shift;
513 my $switch_var = find_size_var
($e, $switch, $var_prefix);
514 my $cprefix = util
::c_push_prefix
($e);
516 check_null_pointer
($switch_var);
518 my $utype = $structs{$e->{TYPE
}};
519 if (!defined $utype ||
520 !util
::has_property
($utype, "nodiscriminant")) {
521 my $e2 = find_sibling
($e, $switch);
522 pidl
"\tif (($ndr_flags) & NDR_SCALARS) {\n";
523 pidl
"\t\tNDR_CHECK(ndr_push_$e2->{TYPE}(ndr, $switch_var));\n";
527 my $sub_size = util
::has_property
($e, "subcontext");
528 if (defined $sub_size) {
529 pidl
"\tif(($ndr_flags) & NDR_SCALARS) {\n";
530 pidl
"\t\tNDR_CHECK(ndr_push_subcontext_union_fn(ndr, $sub_size, $switch_var, $cprefix$var_prefix$e->{NAME}, (ndr_push_union_fn_t) ndr_push_$e->{TYPE}));\n";
533 pidl
"\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $switch_var, $cprefix$var_prefix$e->{NAME}));\n";
537 #####################################################################
538 # print scalars in a structure element
539 sub ParseElementPrintSwitch
($$$)
542 my($var_prefix) = shift;
544 my $switch_var = find_size_var
($e, $switch, $var_prefix);
545 my $cprefix = util
::c_push_prefix
($e);
547 check_null_pointer_void
($switch_var);
549 pidl
"\tndr_print_$e->{TYPE}(ndr, \"$e->{NAME}\", $switch_var, $cprefix$var_prefix$e->{NAME});\n";
553 #####################################################################
554 # parse scalars in a structure element - pull size
555 sub ParseElementPullScalar
($$$)
558 my($var_prefix) = shift;
559 my($ndr_flags) = shift;
560 my $cprefix = util
::c_pull_prefix
($e);
561 my $sub_size = util
::has_property
($e, "subcontext");
565 if (util
::is_inline_array
($e)) {
566 ParseArrayPull
($e, "r->", "NDR_SCALARS");
567 } elsif (util
::need_wire_pointer
($e)) {
568 pidl
"\tNDR_CHECK(ndr_pull_ptr(ndr, &_ptr_$e->{NAME}));\n";
569 pidl
"\tif (_ptr_$e->{NAME}) {\n";
570 pidl
"\t\tNDR_ALLOC(ndr, $var_prefix$e->{NAME});\n";
571 if (util
::has_property
($e, "relative")) {
572 pidl
"\t\tNDR_CHECK(ndr_pull_relative1(ndr, $var_prefix$e->{NAME}, _ptr_$e->{NAME}));\n";
575 pidl
"\t\t$var_prefix$e->{NAME} = NULL;\n";
577 } elsif (util
::need_alloc
($e)) {
578 # no scalar component
579 } elsif (my $switch = util
::has_property
($e, "switch_is")) {
580 ParseElementPullSwitch
($e, $var_prefix, $ndr_flags, $switch);
581 } elsif (defined $sub_size) {
582 if (util
::is_builtin_type
($e->{TYPE
})) {
583 pidl
"\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n";
585 pidl
"\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n";
587 } elsif (util
::is_builtin_type
($e->{TYPE
})) {
588 pidl
"\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n";
590 pidl
"\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
592 if (my $range = util
::has_property
($e, "range")) {
593 my ($low, $high) = split(/ /, $range, 2);
594 pidl
"\tif ($var_prefix$e->{NAME} < $low || $var_prefix$e->{NAME} > $high) {\n";
595 pidl
"\t\treturn ndr_pull_error(ndr, NDR_ERR_RANGE, \"value out of range\");\n\t}\n";
601 #####################################################################
602 # parse buffers in a structure element
603 sub ParseElementPushBuffer
($$$)
606 my($var_prefix) = shift;
607 my($ndr_flags) = shift;
608 my $cprefix = util
::c_push_prefix
($e);
609 my $sub_size = util
::has_property
($e, "subcontext");
611 if (util
::is_pure_scalar
($e)) {
617 if (util
::need_wire_pointer
($e)) {
618 pidl
"\tif ($var_prefix$e->{NAME}) {\n";
619 if (util
::has_property
($e, "relative")) {
620 pidl
"\t\tNDR_CHECK(ndr_push_relative2(ndr, $var_prefix$e->{NAME}));\n";
624 if (util
::is_inline_array
($e)) {
625 ParseArrayPush
($e, "r->", "NDR_BUFFERS");
626 } elsif (util
::array_size
($e)) {
627 ParseArrayPush
($e, "r->", "NDR_SCALARS|NDR_BUFFERS");
628 } elsif (my $switch = util
::has_property
($e, "switch_is")) {
629 if ($e->{POINTERS
}) {
630 ParseElementPushSwitch
($e, $var_prefix, "NDR_BUFFERS|NDR_SCALARS", $switch);
632 ParseElementPushSwitch
($e, $var_prefix, "NDR_BUFFERS", $switch);
634 } elsif (defined $sub_size) {
635 if ($e->{POINTERS
}) {
636 if (util
::is_builtin_type
($e->{TYPE
})) {
637 pidl
"\tNDR_CHECK(ndr_push_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_push_fn_t) ndr_push_$e->{TYPE}));\n";
639 pidl
"\tNDR_CHECK(ndr_push_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_push_flags_fn_t) ndr_push_$e->{TYPE}));\n";
642 } elsif (util
::is_builtin_type
($e->{TYPE
})) {
643 pidl
"\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n";
644 } elsif ($e->{POINTERS
}) {
645 pidl
"\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, NDR_SCALARS|NDR_BUFFERS, $cprefix$var_prefix$e->{NAME}));\n";
647 pidl
"\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
650 if (util
::need_wire_pointer
($e)) {
657 #####################################################################
658 # print buffers in a structure element
659 sub ParseElementPrintBuffer
($$)
662 my($var_prefix) = shift;
663 my $cprefix = util
::c_push_prefix
($e);
665 if (util
::need_wire_pointer
($e)) {
666 pidl
"\tif ($var_prefix$e->{NAME}) {\n";
669 if (util
::array_size
($e)) {
670 ParseArrayPrint
($e, $var_prefix)
671 } elsif (my $switch = util
::has_property
($e, "switch_is")) {
672 ParseElementPrintSwitch
($e, $var_prefix, $switch);
674 pidl
"\t\tndr_print_$e->{TYPE}(ndr, \"$e->{NAME}\", $cprefix$var_prefix$e->{NAME});\n";
677 if (util
::need_wire_pointer
($e)) {
683 #####################################################################
684 # parse buffers in a structure element - pull side
685 sub ParseElementPullBuffer
($$$)
688 my($var_prefix) = shift;
689 my($ndr_flags) = shift;
690 my $cprefix = util
::c_pull_prefix
($e);
691 my $sub_size = util
::has_property
($e, "subcontext");
693 if (util
::is_pure_scalar
($e)) {
699 if (util
::need_wire_pointer
($e)) {
700 pidl
"\tif ($var_prefix$e->{NAME}) {\n";
701 if (util
::has_property
($e, "relative")) {
702 pidl
"\t\tstruct ndr_pull_save _relative_save;\n";
703 pidl
"\t\tndr_pull_save(ndr, &_relative_save);\n";
704 pidl
"\t\tNDR_CHECK(ndr_pull_relative2(ndr, $var_prefix$e->{NAME}));\n";
708 if (util
::is_inline_array
($e)) {
709 ParseArrayPull
($e, "r->", "NDR_BUFFERS");
710 } elsif (util
::array_size
($e)) {
711 ParseArrayPull
($e, "r->", "NDR_SCALARS|NDR_BUFFERS");
712 } elsif (my $switch = util
::has_property
($e, "switch_is")) {
713 if ($e->{POINTERS
}) {
714 ParseElementPullSwitch
($e, $var_prefix, "NDR_SCALARS|NDR_BUFFERS", $switch);
716 ParseElementPullSwitch
($e, $var_prefix, "NDR_BUFFERS", $switch);
718 } elsif (defined $sub_size) {
719 if ($e->{POINTERS
}) {
720 if (util
::is_builtin_type
($e->{TYPE
})) {
721 pidl
"\tNDR_CHECK(ndr_pull_subcontext_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_fn_t) ndr_pull_$e->{TYPE}));\n";
723 pidl
"\tNDR_CHECK(ndr_pull_subcontext_flags_fn(ndr, $sub_size, $cprefix$var_prefix$e->{NAME}, (ndr_pull_flags_fn_t) ndr_pull_$e->{TYPE}));\n";
726 } elsif (util
::is_builtin_type
($e->{TYPE
})) {
727 pidl
"\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n";
728 } elsif ($e->{POINTERS
}) {
729 pidl
"\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, NDR_SCALARS|NDR_BUFFERS, $cprefix$var_prefix$e->{NAME}));\n";
731 pidl
"\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
734 if (util
::need_wire_pointer
($e)) {
735 if (util
::has_property
($e, "relative")) {
736 pidl
"\t\tndr_pull_restore(ndr, &_relative_save);\n";
744 #####################################################################
746 sub ParseStructPush
($)
750 if (! defined $struct->{ELEMENTS
}) {
754 start_flags
($struct);
756 # see if the structure contains a conformant array. If it
757 # does, then it must be the last element of the structure, and
758 # we need to push the conformant length early, as it fits on
759 # the wire before the structure (and even before the structure
761 my $e = $struct->{ELEMENTS
}[-1];
762 if (defined $e->{ARRAY_LEN
} && $e->{ARRAY_LEN
} eq "*") {
763 my $size = find_size_var
($e, util
::array_size
($e), "r->");
764 $e->{CONFORMANT_SIZE
} = $size;
765 check_null_pointer
($size);
766 pidl
"\tNDR_CHECK(ndr_push_uint32(ndr, $size));\n";
769 if (defined $e->{TYPE
} && $e->{TYPE
} eq "string"
770 && util
::property_matches
($e, "flag", ".*LIBNDR_FLAG_STR_CONFORMANT.*")) {
771 pidl
"\tNDR_CHECK(ndr_push_uint32(ndr, ndr_string_array_size(ndr, r->$e->{NAME})));\n";
774 pidl
"\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
776 pidl
"\tNDR_CHECK(ndr_push_struct_start(ndr));\n";
778 my $align = struct_alignment
($struct);
779 pidl
"\tNDR_CHECK(ndr_push_align(ndr, $align));\n";
781 foreach my $e (@
{$struct->{ELEMENTS
}}) {
782 ParseElementPushScalar
($e, "r->", "NDR_SCALARS");
786 pidl
"\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n";
787 foreach my $e (@
{$struct->{ELEMENTS
}}) {
788 ParseElementPushBuffer
($e, "r->", "NDR_BUFFERS");
791 pidl
"\tndr_push_struct_end(ndr);\n";
799 #####################################################################
800 # generate a push function for an enum
804 my($type_fn) = util
::enum_type_fn
($enum);
808 pidl
"\tNDR_CHECK(ndr_push_$type_fn(ndr, r));\n";
813 #####################################################################
814 # generate a pull function for an enum
818 my($type_fn) = util
::enum_type_fn
($enum);
820 pidl
"\t$type_fn v;\n";
822 pidl
"\tNDR_CHECK(ndr_pull_$type_fn(ndr, &v));\n";
828 #####################################################################
829 # generate a print function for an enum
830 sub ParseEnumPrint
($)
834 pidl
"\tconst char *val = NULL;\n\n";
838 pidl
"\tswitch (r) {\n";
839 my $els = \@
{$enum->{ELEMENTS
}};
840 foreach my $i (0 .. $#{$els}) {
843 if ($e =~ /^(.*)=/) {
846 pidl
"\t\tcase $e: val = \"$e\"; break;\n";
849 pidl
"\t}\n\n\tndr_print_enum(ndr, name, \"$enum->{TYPE}\", val, r);\n";
855 #####################################################################
856 # generate a push function for a bitmap
857 sub ParseBitmapPush
($)
860 my($type_fn) = util
::bitmap_type_fn
($bitmap);
862 start_flags
($bitmap);
864 pidl
"\tNDR_CHECK(ndr_push_$type_fn(ndr, r));\n";
869 #####################################################################
870 # generate a pull function for an bitmap
871 sub ParseBitmapPull
($)
874 my($type_fn) = util
::bitmap_type_fn
($bitmap);
876 pidl
"\t$type_fn v;\n";
877 start_flags
($bitmap);
878 pidl
"\tNDR_CHECK(ndr_pull_$type_fn(ndr, &v));\n";
884 #####################################################################
885 # generate a print function for an bitmap
886 sub ParseBintmapPrintElement
($$)
890 my($type_decl) = util
::bitmap_type_decl
($bitmap);
891 my($type_fn) = util
::bitmap_type_fn
($bitmap);
892 my($name) = $bitmap->{PARENT
}->{NAME
};
895 if ($e =~ /^(\w+) .*$/) {
898 die "Bitmap: \"$name\" invalid Flag: \"$e\"";
901 pidl
"\tndr_print_bitmap_flag(ndr, sizeof($type_decl), \"$flag\", $flag, r);\n";
904 #####################################################################
905 # generate a print function for an bitmap
906 sub ParseBitmapPrint
($)
909 my($type_decl) = util
::bitmap_type_decl
($bitmap);
910 my($type_fn) = util
::bitmap_type_fn
($bitmap);
912 start_flags
($bitmap);
914 pidl
"\tndr_print_$type_fn(ndr, name, r);\n";
916 pidl
"\tndr->depth++;\n";
917 foreach my $e (@
{$bitmap->{ELEMENTS
}}) {
918 ParseBintmapPrintElement
($e, $bitmap);
920 pidl
"\tndr->depth--;\n";
925 #####################################################################
926 # generate a struct print function
927 sub ParseStructPrint
($)
931 if (! defined $struct->{ELEMENTS
}) {
935 start_flags
($struct);
937 pidl
"\tndr->depth++;\n";
938 foreach my $e (@
{$struct->{ELEMENTS
}}) {
939 ParseElementPrintScalar
($e, "r->");
941 pidl
"\tndr->depth--;\n";
946 #####################################################################
947 # parse a struct - pull side
948 sub ParseStructPull
($)
953 if (! defined $struct->{ELEMENTS
}) {
957 # see if the structure contains a conformant array. If it
958 # does, then it must be the last element of the structure, and
959 # we need to pull the conformant length early, as it fits on
960 # the wire before the structure (and even before the structure
962 my $e = $struct->{ELEMENTS
}[-1];
963 if (defined $e->{ARRAY_LEN
} && $e->{ARRAY_LEN
} eq "*") {
967 if (defined $e->{TYPE
} && $e->{TYPE
} eq "string"
968 && util
::property_matches
($e, "flag", ".*LIBNDR_FLAG_STR_CONFORMANT.*")) {
972 if (defined $conform_e) {
974 pidl
"\tuint32_t _conformant_size;\n";
975 $conform_e->{CONFORMANT_SIZE
} = "_conformant_size";
978 # declare any internal pointers we need
979 foreach my $e (@
{$struct->{ELEMENTS
}}) {
980 if (util
::need_wire_pointer
($e)) {
981 pidl
"\tuint32_t _ptr_$e->{NAME};\n";
985 start_flags
($struct);
987 pidl
"\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
989 pidl
"\tNDR_CHECK(ndr_pull_struct_start(ndr));\n";
991 if (defined $conform_e) {
992 pidl
"\tNDR_CHECK(ndr_pull_uint32(ndr, &$conform_e->{CONFORMANT_SIZE}));\n";
995 my $align = struct_alignment
($struct);
996 pidl
"\tNDR_CHECK(ndr_pull_align(ndr, $align));\n";
998 foreach my $e (@
{$struct->{ELEMENTS
}}) {
999 ParseElementPullScalar
($e, "r->", "NDR_SCALARS");
1003 pidl
"\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n";
1004 foreach my $e (@
{$struct->{ELEMENTS
}}) {
1005 ParseElementPullBuffer
($e, "r->", "NDR_BUFFERS");
1008 foreach my $e (@
{$struct->{ELEMENTS
}}) {
1009 CheckArraySizes
($e, "r->");
1012 pidl
"\tndr_pull_struct_end(ndr);\n";
1019 #####################################################################
1020 # calculate size of ndr struct
1021 sub ParseStructNdrSize
($)
1024 my $static = fn_prefix
($t);
1027 pidl
"size_t ndr_size_$t->{NAME}(const struct $t->{NAME} *r, int flags)\n";
1029 if (my $flags = util
::has_property
($t, "flag")) {
1030 pidl
"\tflags |= $flags;\n";
1032 pidl
"\treturn ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_$t->{NAME});\n";
1036 #####################################################################
1037 # parse a union - push side
1038 sub ParseUnionPush
($)
1041 my $have_default = 0;
1045 pidl
"\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
1047 pidl
"\tNDR_CHECK(ndr_push_struct_start(ndr));\n";
1049 # my $align = union_alignment($e);
1050 # pidl "\tNDR_CHECK(ndr_push_align(ndr, $align));\n";
1052 pidl
"\tswitch (level) {\n";
1053 foreach my $el (@
{$e->{DATA
}}) {
1054 if ($el->{CASE
} eq "default") {
1055 pidl
"\tdefault:\n";
1058 pidl
"\tcase $el->{CASE}:\n";
1060 if ($el->{TYPE
} eq "UNION_ELEMENT") {
1061 ParseElementPushScalar
($el->{DATA
}, "r->", "NDR_SCALARS");
1063 pidl
"\tbreak;\n\n";
1065 if (! $have_default) {
1066 pidl
"\tdefault:\n";
1067 pidl
"\t\treturn ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n";
1071 pidl
"\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n";
1072 pidl
"\tswitch (level) {\n";
1073 foreach my $el (@
{$e->{DATA
}}) {
1074 if ($el->{CASE
} eq "default") {
1075 pidl
"\tdefault:\n";
1077 pidl
"\tcase $el->{CASE}:\n";
1079 if ($el->{TYPE
} eq "UNION_ELEMENT") {
1080 ParseElementPushBuffer
($el->{DATA
}, "r->", "NDR_BUFFERS");
1082 pidl
"\tbreak;\n\n";
1084 if (! $have_default) {
1085 pidl
"\tdefault:\n";
1086 pidl
"\t\treturn ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n";
1089 pidl
"\tndr_push_struct_end(ndr);\n";
1094 #####################################################################
1096 sub ParseUnionPrint
($)
1099 my $have_default = 0;
1103 pidl
"\tswitch (level) {\n";
1104 foreach my $el (@
{$e->{DATA
}}) {
1105 if ($el->{CASE
} eq "default") {
1107 pidl
"\tdefault:\n";
1109 pidl
"\tcase $el->{CASE}:\n";
1111 if ($el->{TYPE
} eq "UNION_ELEMENT") {
1112 ParseElementPrintScalar
($el->{DATA
}, "r->");
1114 pidl
"\tbreak;\n\n";
1116 if (! $have_default) {
1117 pidl
"\tdefault:\n\t\tndr_print_bad_level(ndr, name, level);\n";
1124 #####################################################################
1125 # parse a union - pull side
1126 sub ParseUnionPull
($)
1129 my $have_default = 0;
1133 pidl
"\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
1135 pidl
"\tNDR_CHECK(ndr_pull_struct_start(ndr));\n";
1137 # my $align = union_alignment($e);
1138 # pidl "\tNDR_CHECK(ndr_pull_align(ndr, $align));\n";
1140 pidl
"\tswitch (level) {\n";
1141 foreach my $el (@
{$e->{DATA
}}) {
1142 if ($el->{CASE
} eq "default") {
1143 pidl
"\tdefault: {\n";
1146 pidl
"\tcase $el->{CASE}: {\n";
1148 if ($el->{TYPE
} eq "UNION_ELEMENT") {
1149 my $e2 = $el->{DATA
};
1150 if ($e2->{POINTERS
}) {
1151 pidl
"\t\tuint32_t _ptr_$e2->{NAME};\n";
1153 ParseElementPullScalar
($el->{DATA
}, "r->", "NDR_SCALARS");
1155 pidl
"\tbreak; }\n\n";
1157 if (! $have_default) {
1158 pidl
"\tdefault:\n";
1159 pidl
"\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n";
1163 pidl
"\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n";
1164 pidl
"\tswitch (level) {\n";
1165 foreach my $el (@
{$e->{DATA
}}) {
1166 if ($el->{CASE
} eq "default") {
1167 pidl
"\tdefault:\n";
1169 pidl
"\tcase $el->{CASE}:\n";
1171 if ($el->{TYPE
} eq "UNION_ELEMENT") {
1172 ParseElementPullBuffer
($el->{DATA
}, "r->", "NDR_BUFFERS");
1174 pidl
"\tbreak;\n\n";
1176 if (! $have_default) {
1177 pidl
"\tdefault:\n";
1178 pidl
"\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n";
1181 pidl
"\tndr_pull_struct_end(ndr);\n";
1187 #####################################################################
1189 sub ParseTypePush
($)
1193 if (ref($data) eq "HASH") {
1194 ($data->{TYPE
} eq "STRUCT") &&
1195 ParseStructPush
($data);
1196 ($data->{TYPE
} eq "UNION") &&
1197 ParseUnionPush
($data);
1198 ($data->{TYPE
} eq "ENUM") &&
1199 ParseEnumPush
($data);
1200 ($data->{TYPE
} eq "BITMAP") &&
1201 ParseBitmapPush
($data);
1205 #####################################################################
1206 # generate a print function for a type
1207 sub ParseTypePrint
($)
1211 if (ref($data) eq "HASH") {
1212 ($data->{TYPE
} eq "STRUCT") &&
1213 ParseStructPrint
($data);
1214 ($data->{TYPE
} eq "UNION") &&
1215 ParseUnionPrint
($data);
1216 ($data->{TYPE
} eq "ENUM") &&
1217 ParseEnumPrint
($data);
1218 ($data->{TYPE
} eq "BITMAP") &&
1219 ParseBitmapPrint
($data);
1223 #####################################################################
1225 sub ParseTypePull
($)
1229 if (ref($data) eq "HASH") {
1230 ($data->{TYPE
} eq "STRUCT") &&
1231 ParseStructPull
($data);
1232 ($data->{TYPE
} eq "UNION") &&
1233 ParseUnionPull
($data);
1234 ($data->{TYPE
} eq "ENUM") &&
1235 ParseEnumPull
($data);
1236 ($data->{TYPE
} eq "BITMAP") &&
1237 ParseBitmapPull
($data);
1241 #####################################################################
1242 # parse a typedef - push side
1243 sub ParseTypedefPush
($)
1246 my $static = fn_prefix
($e);
1248 if (! needed
::is_needed
("push_$e->{NAME}")) {
1249 # print "push_$e->{NAME} not needed\n";
1253 if (defined($e->{PROPERTIES
}) && !defined($e->{DATA
}->{PROPERTIES
})) {
1254 $e->{DATA
}->{PROPERTIES
} = $e->{PROPERTIES
};
1257 if ($e->{DATA
}->{TYPE
} eq "STRUCT") {
1258 pidl
$static . "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, struct $e->{NAME} *r)";
1260 ParseTypePush
($e->{DATA
});
1261 pidl
"\treturn NT_STATUS_OK;\n";
1265 if ($e->{DATA
}->{TYPE
} eq "UNION") {
1266 pidl
$static . "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, int level, union $e->{NAME} *r)";
1268 ParseTypePush
($e->{DATA
});
1269 pidl
"\treturn NT_STATUS_OK;\n";
1273 if ($e->{DATA
}->{TYPE
} eq "ENUM") {
1274 pidl
$static . "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, enum $e->{NAME} r)";
1276 ParseTypePush
($e->{DATA
});
1277 pidl
"\treturn NT_STATUS_OK;\n";
1281 if ($e->{DATA
}->{TYPE
} eq "BITMAP") {
1282 my $type_decl = util
::bitmap_type_fn
($e->{DATA
});
1283 pidl
$static . "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, $type_decl r)";
1285 ParseTypePush
($e->{DATA
});
1286 pidl
"\treturn NT_STATUS_OK;\n";
1292 #####################################################################
1293 # parse a typedef - pull side
1294 sub ParseTypedefPull
($)
1297 my $static = fn_prefix
($e);
1299 if (defined($e->{PROPERTIES
}) && !defined($e->{DATA
}->{PROPERTIES
})) {
1300 $e->{DATA
}->{PROPERTIES
} = $e->{PROPERTIES
};
1303 if (! needed
::is_needed
("pull_$e->{NAME}")) {
1304 # print "pull_$e->{NAME} not needed\n";
1308 if ($e->{DATA
}->{TYPE
} eq "STRUCT") {
1309 pidl
$static . "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, struct $e->{NAME} *r)";
1311 ParseTypePull
($e->{DATA
});
1312 pidl
"\treturn NT_STATUS_OK;\n";
1316 if ($e->{DATA
}->{TYPE
} eq "UNION") {
1317 pidl
$static . "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, int level, union $e->{NAME} *r)";
1319 ParseTypePull
($e->{DATA
});
1320 pidl
"\treturn NT_STATUS_OK;\n";
1324 if ($e->{DATA
}->{TYPE
} eq "ENUM") {
1325 pidl
$static . "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, enum $e->{NAME} *r)";
1327 ParseTypePull
($e->{DATA
});
1328 pidl
"\treturn NT_STATUS_OK;\n";
1332 if ($e->{DATA
}->{TYPE
} eq "BITMAP") {
1333 my $type_decl = util
::bitmap_type_fn
($e->{DATA
});
1334 pidl
$static . "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, $type_decl *r)";
1336 ParseTypePull
($e->{DATA
});
1337 pidl
"\treturn NT_STATUS_OK;\n";
1343 #####################################################################
1344 # parse a typedef - print side
1345 sub ParseTypedefPrint
($)
1349 if (defined($e->{PROPERTIES
}) && !defined($e->{DATA
}->{PROPERTIES
})) {
1350 $e->{DATA
}->{PROPERTIES
} = $e->{PROPERTIES
};
1353 if ($e->{DATA
}->{TYPE
} eq "STRUCT") {
1354 pidl
"void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, struct $e->{NAME} *r)";
1356 pidl
"\tndr_print_struct(ndr, name, \"$e->{NAME}\");\n";
1357 ParseTypePrint
($e->{DATA
});
1361 if ($e->{DATA
}->{TYPE
} eq "UNION") {
1362 pidl
"void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, int level, union $e->{NAME} *r)";
1364 pidl
"\tndr_print_union(ndr, name, level, \"$e->{NAME}\");\n";
1365 ParseTypePrint
($e->{DATA
});
1369 if ($e->{DATA
}->{TYPE
} eq "ENUM") {
1370 pidl
"void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, enum $e->{NAME} r)";
1372 ParseTypePrint
($e->{DATA
});
1376 if ($e->{DATA
}->{TYPE
} eq "BITMAP") {
1377 my $type_decl = util
::bitmap_type_fn
($e->{DATA
});
1378 pidl
"void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, $type_decl r)";
1380 ParseTypePrint
($e->{DATA
});
1385 #####################################################################
1386 ## calculate the size of a structure
1387 sub ParseTypedefNdrSize
($)
1390 if (! needed
::is_needed
("ndr_size_$t->{NAME}")) {
1394 ($t->{DATA
}->{TYPE
} eq "STRUCT") &&
1395 ParseStructNdrSize
($t);
1398 #####################################################################
1399 # parse a function - print side
1400 sub ParseFunctionPrint
($)
1404 pidl
"void ndr_print_$fn->{NAME}(struct ndr_print *ndr, const char *name, int flags, struct $fn->{NAME} *r)";
1406 pidl
"\tndr_print_struct(ndr, name, \"$fn->{NAME}\");\n";
1407 pidl
"\tndr->depth++;\n";
1409 pidl
"\tif (flags & NDR_SET_VALUES) {\n";
1410 pidl
"\t\tndr->flags |= LIBNDR_PRINT_SET_VALUES;\n";
1413 pidl
"\tif (flags & NDR_IN) {\n";
1414 pidl
"\t\tndr_print_struct(ndr, \"in\", \"$fn->{NAME}\");\n";
1415 pidl
"\tndr->depth++;\n";
1416 foreach my $e (@
{$fn->{DATA
}}) {
1417 if (util
::has_property
($e, "in")) {
1418 ParseElementPrintScalar
($e, "r->in.");
1421 pidl
"\tndr->depth--;\n";
1424 pidl
"\tif (flags & NDR_OUT) {\n";
1425 pidl
"\t\tndr_print_struct(ndr, \"out\", \"$fn->{NAME}\");\n";
1426 pidl
"\tndr->depth++;\n";
1427 foreach my $e (@
{$fn->{DATA
}}) {
1428 if (util
::has_property
($e, "out")) {
1429 ParseElementPrintScalar
($e, "r->out.");
1432 if ($fn->{RETURN_TYPE
} && $fn->{RETURN_TYPE
} ne "void") {
1433 if (util
::is_scalar_type
($fn->{RETURN_TYPE
})) {
1434 pidl
"\tndr_print_$fn->{RETURN_TYPE}(ndr, \"result\", r->out.result);\n";
1436 pidl
"\tndr_print_$fn->{RETURN_TYPE}(ndr, \"result\", &r->out.result);\n";
1439 pidl
"\tndr->depth--;\n";
1442 pidl
"\tndr->depth--;\n";
1447 #####################################################################
1448 # parse a function element
1449 sub ParseFunctionElementPush
($$)
1454 if (util
::array_size
($e)) {
1455 if (util
::need_wire_pointer
($e)) {
1456 pidl
"\tNDR_CHECK(ndr_push_ptr(ndr, r->$inout.$e->{NAME}));\n";
1457 pidl
"\tif (r->$inout.$e->{NAME}) {\n";
1458 ParseArrayPush
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1461 ParseArrayPush
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1464 ParseElementPushScalar
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1465 if ($e->{POINTERS
}) {
1466 ParseElementPushBuffer
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1471 #####################################################################
1473 sub ParseFunctionPush
($)
1476 my $static = fn_prefix
($fn);
1478 pidl
$static . "NTSTATUS ndr_push_$fn->{NAME}(struct ndr_push *ndr, int flags, struct $fn->{NAME} *r)\n{\n";
1480 pidl
"\n\tif (!(flags & NDR_IN)) goto ndr_out;\n\n";
1482 foreach my $e (@
{$fn->{DATA
}}) {
1483 if (util
::has_property
($e, "in")) {
1484 ParseFunctionElementPush
($e, "in");
1488 pidl
"\nndr_out:\n";
1489 pidl
"\tif (!(flags & NDR_OUT)) goto done;\n\n";
1491 foreach my $e (@
{$fn->{DATA
}}) {
1492 if (util
::has_property
($e, "out")) {
1493 ParseFunctionElementPush
($e, "out");
1497 if ($fn->{RETURN_TYPE
} && $fn->{RETURN_TYPE
} ne "void") {
1498 pidl
"\tNDR_CHECK(ndr_push_$fn->{RETURN_TYPE}(ndr, r->out.result));\n";
1502 pidl
"\n\treturn NT_STATUS_OK;\n}\n\n";
1505 #####################################################################
1506 # parse a function element
1507 sub ParseFunctionElementPull
($$)
1512 if (util
::array_size
($e)) {
1513 if (util
::need_wire_pointer
($e)) {
1514 pidl
"\tNDR_CHECK(ndr_pull_ptr(ndr, &_ptr_$e->{NAME}));\n";
1515 pidl
"\tr->$inout.$e->{NAME} = NULL;\n";
1516 pidl
"\tif (_ptr_$e->{NAME}) {\n";
1517 } elsif ($inout eq "out" && util
::has_property
($e, "ref")) {
1518 pidl
"\tif (r->$inout.$e->{NAME}) {\n";
1522 ParseArrayPull
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1525 if ($inout eq "out" && util
::has_property
($e, "ref")) {
1526 pidl
"\tif (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {\n";
1527 pidl
"\tNDR_ALLOC(ndr, r->out.$e->{NAME});\n";
1530 if ($inout eq "in" && util
::has_property
($e, "ref")) {
1531 pidl
"\tNDR_ALLOC(ndr, r->in.$e->{NAME});\n";
1534 ParseElementPullScalar
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1535 if ($e->{POINTERS
}) {
1536 ParseElementPullBuffer
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1542 ############################################################
1543 # allocate ref variables
1544 sub AllocateRefVars
($)
1547 my $asize = util
::array_size
($e);
1549 # note that if the variable is also an "in"
1550 # variable then we copy the initial value from
1553 if (!defined $asize) {
1554 # its a simple variable
1555 pidl
"\tNDR_ALLOC(ndr, r->out.$e->{NAME});\n";
1556 if (util
::has_property
($e, "in")) {
1557 pidl
"\t*r->out.$e->{NAME} = *r->in.$e->{NAME};\n";
1559 pidl
"\tZERO_STRUCTP(r->out.$e->{NAME});\n";
1565 my $size = find_size_var
($e, $asize, "r->out.");
1566 check_null_pointer
($size);
1567 pidl
"\tNDR_ALLOC_N(ndr, r->out.$e->{NAME}, $size);\n";
1568 if (util
::has_property
($e, "in")) {
1569 pidl
"\tmemcpy(r->out.$e->{NAME},r->in.$e->{NAME},$size * sizeof(*r->in.$e->{NAME}));\n";
1571 pidl
"\tmemset(r->out.$e->{NAME}, 0, $size * sizeof(*r->out.$e->{NAME}));\n";
1576 #####################################################################
1578 sub ParseFunctionPull
($)
1581 my $static = fn_prefix
($fn);
1583 # pull function args
1584 pidl
$static . "NTSTATUS ndr_pull_$fn->{NAME}(struct ndr_pull *ndr, int flags, struct $fn->{NAME} *r)\n{\n";
1586 # declare any internal pointers we need
1587 foreach my $e (@
{$fn->{DATA
}}) {
1588 if (util
::need_wire_pointer
($e)) {
1589 pidl
"\tuint32_t _ptr_$e->{NAME};\n";
1593 pidl
"\n\tif (!(flags & NDR_IN)) goto ndr_out;\n\n";
1595 # auto-init the out section of a structure. I originally argued that
1596 # this was a bad idea as it hides bugs, but coping correctly
1597 # with initialisation and not wiping ref vars is turning
1598 # out to be too tricky (tridge)
1599 foreach my $e (@
{$fn->{DATA
}}) {
1600 if (util
::has_property
($e, "out")) {
1601 pidl
"\tZERO_STRUCT(r->out);\n\n";
1606 foreach my $e (@
{$fn->{DATA
}}) {
1607 if (util
::has_property
($e, "in")) {
1608 ParseFunctionElementPull
($e, "in");
1610 # we need to allocate any reference output variables, so that
1611 # a dcerpc backend can be sure they are non-null
1612 if (util
::has_property
($e, "out") && util
::has_property
($e, "ref")) {
1613 AllocateRefVars
($e);
1617 foreach my $e (@
{$fn->{DATA
}}) {
1618 if (util
::has_property
($e, "in")) {
1619 CheckArraySizes
($e, "r->in.");
1623 pidl
"\nndr_out:\n";
1624 pidl
"\tif (!(flags & NDR_OUT)) goto done;\n\n";
1626 foreach my $e (@
{$fn->{DATA
}}) {
1627 if (util
::has_property
($e, "out")) {
1628 ParseFunctionElementPull
($e, "out");
1632 foreach my $e (@
{$fn->{DATA
}}) {
1633 if (util
::has_property
($e, "out")) {
1634 CheckArraySizes
($e, "r->out.");
1638 if ($fn->{RETURN_TYPE
} && $fn->{RETURN_TYPE
} ne "void") {
1639 pidl
"\tNDR_CHECK(ndr_pull_$fn->{RETURN_TYPE}(ndr, &r->out.result));\n";
1643 pidl
"\n\treturn NT_STATUS_OK;\n}\n\n";
1646 #####################################################################
1647 # produce a function call table
1648 sub FunctionTable
($)
1650 my($interface) = shift;
1651 my($data) = $interface->{INHERITED_DATA
};
1653 my $uname = uc $interface->{NAME
};
1655 foreach my $d (@
{$data}) {
1656 if ($d->{TYPE
} eq "FUNCTION") { $count++; }
1659 return if ($count == 0);
1661 pidl
"static const struct dcerpc_interface_call $interface->{NAME}\_calls[] = {\n";
1662 foreach my $d (@
{$data}) {
1663 if ($d->{TYPE
} eq "FUNCTION") {
1665 pidl
"\t\t\"$d->{NAME}\",\n";
1666 pidl
"\t\tsizeof(struct $d->{NAME}),\n";
1667 pidl
"\t\t(ndr_push_flags_fn_t) ndr_push_$d->{NAME},\n";
1668 pidl
"\t\t(ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},\n";
1669 pidl
"\t\t(ndr_print_function_t) ndr_print_$d->{NAME}\n";
1673 pidl
"\t{ NULL, 0, NULL, NULL }\n};\n\n";
1675 # If no endpoint is set, default to the interface name as a named pipe
1676 if (! defined $interface->{PROPERTIES
}->{endpoint
}) {
1677 $interface->{PROPERTIES
}->{endpoint
} = "\"ncacn_np:[\\\\pipe\\\\" . $interface->{NAME
} . "]\"";
1680 my @e = split / /, $interface->{PROPERTIES
}->{endpoint
};
1681 my $endpoint_count = $#e + 1;
1683 pidl
"static const char * const $interface->{NAME}\_endpoint_strings[] = {\n";
1684 foreach my $ep (@e) {
1689 pidl
"static const struct dcerpc_endpoint_list $interface->{NAME}\_endpoints = {\n";
1690 pidl
"\t$endpoint_count, $interface->{NAME}\_endpoint_strings\n";
1693 pidl
"\nconst struct dcerpc_interface_table dcerpc_table_$interface->{NAME} = {\n";
1694 pidl
"\t\"$interface->{NAME}\",\n";
1695 pidl
"\tDCERPC_$uname\_UUID,\n";
1696 pidl
"\tDCERPC_$uname\_VERSION,\n";
1697 pidl
"\tDCERPC_$uname\_HELPSTRING,\n";
1699 pidl
"\t$interface->{NAME}\_calls,\n";
1700 pidl
"\t&$interface->{NAME}\_endpoints\n";
1703 pidl
"static NTSTATUS dcerpc_ndr_$interface->{NAME}_init(void)\n";
1705 pidl
"\treturn librpc_register_interface(&dcerpc_table_$interface->{NAME});\n";
1709 #####################################################################
1710 # parse the interface definitions
1711 sub ParseInterface
($)
1713 my($interface) = shift;
1714 my($data) = $interface->{DATA
};
1716 foreach my $d (@
{$data}) {
1717 if ($d->{TYPE
} eq "DECLARE") {
1718 $structs{$d->{NAME
}} = $d;
1720 if ($d->{TYPE
} eq "TYPEDEF") {
1721 $structs{$d->{NAME
}} = $d;
1725 foreach my $d (@
{$data}) {
1726 ($d->{TYPE
} eq "TYPEDEF") &&
1727 ParseTypedefPush
($d);
1728 ($d->{TYPE
} eq "FUNCTION") &&
1729 ParseFunctionPush
($d);
1731 foreach my $d (@
{$data}) {
1732 ($d->{TYPE
} eq "TYPEDEF") &&
1733 ParseTypedefPull
($d);
1734 ($d->{TYPE
} eq "FUNCTION") &&
1735 ParseFunctionPull
($d);
1737 foreach my $d (@
{$data}) {
1738 if ($d->{TYPE
} eq "TYPEDEF" &&
1739 !util
::has_property
($d, "noprint")) {
1740 ParseTypedefPrint
($d);
1742 if ($d->{TYPE
} eq "FUNCTION" &&
1743 !util
::has_property
($d, "noprint")) {
1744 ParseFunctionPrint
($d);
1748 foreach my $d (@
{$data}) {
1749 ($d->{TYPE
} eq "TYPEDEF") &&
1750 ParseTypedefNdrSize
($d);
1753 FunctionTable
($interface);
1756 sub RegistrationFunction
($$)
1759 my $filename = shift;
1761 $filename =~ /.*\/ndr_
(.*).c
/;
1763 pidl
"NTSTATUS dcerpc_$basename\_init(void)\n";
1765 pidl
"\tNTSTATUS status = NT_STATUS_OK;\n";
1766 foreach my $interface (@
{$idl}) {
1767 next if $interface->{TYPE
} ne "INTERFACE";
1769 my $data = $interface->{INHERITED_DATA
};
1771 foreach my $d (@
{$data}) {
1772 if ($d->{TYPE
} eq "FUNCTION") { $count++; }
1775 next if ($count == 0);
1777 pidl
"\tstatus = dcerpc_ndr_$interface->{NAME}_init();\n";
1778 pidl
"\tif (NT_STATUS_IS_ERR(status)) {\n";
1779 pidl
"\t\treturn status;\n";
1782 pidl
"\treturn status;\n";
1786 #####################################################################
1787 # parse a parsed IDL structure back into an IDL file
1791 my($filename) = shift;
1792 my $h_filename = $filename;
1794 if ($h_filename =~ /(.*)\.c/) {
1795 $h_filename = "$1.h";
1798 open(OUT
, ">$filename") || die "can't open $filename";
1800 pidl
"/* parser auto-generated by pidl */\n\n";
1801 pidl
"#include \"includes.h\"\n";
1802 pidl
"#include \"$h_filename\"\n\n";
1804 foreach my $x (@
{$idl}) {
1805 if ($x->{TYPE
} eq "INTERFACE") {
1806 needed
::BuildNeeded
($x);
1811 RegistrationFunction
($idl, $filename);