1 ###################################################
2 # Samba4 NDR 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
34 "error_status_t" => 4,
43 foreach my $k (keys %type_alignments) {
49 ALIGN
=> $type_alignments{$k}
58 return 1 if (defined($typedefs{$type}) and $typedefs{$type}->{DATA
}->{TYPE
} eq "SCALAR");
59 return 1 if (util
::is_enum
($type));
60 return 1 if (util
::is_bitmap
($type));
69 return undef unless $e->{POINTERS
};
71 return "ref" if (util
::has_property
($e, "ref"));
72 return "ptr" if (util
::has_property
($e, "ptr"));
73 return "unique" if (util
::has_property
($e, "unique"));
74 return "relative" if (util
::has_property
($e, "relative"));
79 # determine if an element needs a reference pointer on the wire
80 # in its NDR representation
81 sub need_wire_pointer
($)
86 return 0 unless ($pt = pointer_type
($e));
95 # determine if an element is a pure scalar. pure scalars do not
96 # have a "buffers" section in NDR
100 if (util
::has_property
($e, "ref")) {
103 if (is_scalar_type
($e->{TYPE
}) &&
105 !util
::array_size
($e)) {
111 # see if a variable needs to be allocated by the NDR subsystem on pull
116 if (util
::has_property
($e, "ref")) {
120 if ($e->{POINTERS
} || util
::array_size
($e)) {
128 # determine the C prefix used to refer to a variable when passing to a push
129 # function. This will be '*' for pointers to scalar types, '' for scalar
130 # types and normal pointers and '&' for pass-by-reference structures
135 if ($e->{TYPE
} =~ "string") {
139 if (is_scalar_type
($e->{TYPE
}) &&
143 if (!is_scalar_type
($e->{TYPE
}) &&
145 !util
::array_size
($e)) {
152 # determine the C prefix used to refer to a variable when passing to a pull
158 if (!$e->{POINTERS
} && !util
::array_size
($e)) {
162 if ($e->{TYPE
} =~ "string") {
174 #####################################################################
175 # parse a properties list
176 sub ParseProperties
($)
179 foreach my $d (@
{$props}) {
180 if (ref($d) ne "HASH") {
183 foreach my $k (keys %{$d}) {
184 pidl
"[$k($d->{$k})] ";
190 ###################################
191 # find a sibling var in a structure
196 my($fn) = $e->{PARENT
};
198 if ($name =~ /\*(.*)/) {
202 if ($fn->{TYPE
} eq "FUNCTION") {
203 for my $e2 (@
{$fn->{ELEMENTS
}}) {
204 if ($e2->{NAME
} eq $name) {
210 for my $e2 (@
{$fn->{ELEMENTS
}}) {
211 if ($e2->{NAME
} eq $name) {
215 die "invalid sibling '$name'";
218 ####################################################################
219 # work out the name of a size_is() variable
224 my($var_prefix) = shift;
226 my($fn) = $e->{PARENT
};
228 if (util
::is_constant
($size)) {
232 if ($size =~ /ndr->|\(/) {
238 if ($size =~ /\*(.*)/) {
243 if ($fn->{TYPE
} ne "FUNCTION") {
244 return $prefix . "r->$size";
247 my $e2 = find_sibling
($e, $size);
249 if (util
::has_property
($e2, "in") && util
::has_property
($e2, "out")) {
250 return $prefix . "$var_prefix$size";
252 if (util
::has_property
($e2, "in")) {
253 return $prefix . "r->in.$size";
255 if (util
::has_property
($e2, "out")) {
256 return $prefix . "r->out.$size";
259 die "invalid variable in $size for element $e->{NAME} in $fn->{NAME}\n";
262 #####################################################################
263 # check that a variable we get from ParseExpr isn't a null pointer
264 sub check_null_pointer
($)
267 if ($size =~ /^\*/) {
268 my $size2 = substr($size, 1);
269 pidl
"\tif ($size2 == NULL) return NT_STATUS_INVALID_PARAMETER_MIX;\n";
273 #####################################################################
274 # check that a variable we get from ParseExpr isn't a null pointer
275 # void return varient
276 sub check_null_pointer_void
($)
279 if ($size =~ /^\*/) {
280 my $size2 = substr($size, 1);
281 pidl
"\tif ($size2 == NULL) return;\n";
286 #####################################################################
287 # work out is a parse function should be declared static or not
291 if ($fn->{TYPE
} eq "TYPEDEF") {
292 if (util
::has_property
($fn, "public")) {
297 if ($fn->{TYPE
} eq "FUNCTION") {
298 if (util
::has_property
($fn, "public")) {
306 ###################################################################
307 # setup any special flags for an element or structure
311 my $flags = util
::has_property
($e, "flag");
312 if (defined $flags) {
313 pidl
"\t{ uint32_t _flags_save_$e->{TYPE} = ndr->flags;\n";
314 pidl
"\tndr_set_flags(&ndr->flags, $flags);\n";
318 ###################################################################
319 # end any special flags for an element or structure
323 my $flags = util
::has_property
($e, "flag");
324 if (defined $flags) {
325 pidl
"\tndr->flags = _flags_save_$e->{TYPE};\n\t}\n";
330 #####################################################################
331 # work out the correct alignment for a structure or union
337 for my $e (@
{$s->{ELEMENTS
}}) {
340 if (need_wire_pointer
($e)) {
343 $a = align_type
($e->{TYPE
});
346 $align = $a if ($align < $a);
352 #####################################################################
358 unless (defined($typedefs{$e})) {
359 # it must be an external type - all we can do is guess
360 # print "Warning: assuming alignment of unknown type '$e' is 4\n";
364 my $dt = $typedefs{$e}->{DATA
};
366 return $dt->{ALIGN
} if ($dt->{ALIGN
});
368 if ($dt->{TYPE
} eq "STRUCT") {
369 $dt->{ALIGN
} = struct_alignment
($dt);
370 } elsif($dt->{TYPE
} eq "UNION") {
371 $dt->{ALIGN
} = struct_alignment
($dt);
372 } elsif ($dt->{TYPE
} eq "ENUM") {
373 $dt->{ALIGN
} = align_type
(util
::enum_type_fn
(util
::get_enum
($e)));
374 } elsif ($dt->{TYPE
} eq "BITMAP") {
375 $dt->{ALIGN
} = align_type
(util
::bitmap_type_fn
(util
::get_bitmap
($e)));
378 if (not defined($dt->{ALIGN
})) {
379 die("Internal pidl error. Unable to determine alignment for data type $dt->{TYPE}!");
385 #####################################################################
386 # parse an array - push side
387 sub ParseArrayPush
($$$)
390 my $var_prefix = shift;
391 my $ndr_flags = shift;
393 my $size = ParseExpr
($e, util
::array_size
($e), $var_prefix);
395 if (defined $e->{CONFORMANT_SIZE
}) {
396 # the conformant size has already been pushed
397 } elsif (!util
::is_inline_array
($e)) {
398 # we need to emit the array size
399 pidl
"\t\tNDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, $size));\n";
402 if (my $length = util
::has_property
($e, "length_is")) {
403 $length = ParseExpr
($e, $length, $var_prefix);
404 pidl
"\t\tNDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));\n";
405 pidl
"\t\tNDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, $length));\n";
409 if (is_scalar_type
($e->{TYPE
})) {
410 pidl
"\t\tNDR_CHECK(ndr_push_array_$e->{TYPE}(ndr, $ndr_flags, $var_prefix$e->{NAME}, $size));\n";
412 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";
416 #####################################################################
418 sub ParseArrayPrint
($$)
421 my $var_prefix = shift;
422 my $size = ParseExpr
($e, util
::array_size
($e), $var_prefix);
423 my $length = util
::has_property
($e, "length_is");
425 if (defined $length) {
426 $size = ParseExpr
($e, $length, $var_prefix);
429 if (is_scalar_type
($e->{TYPE
})) {
430 pidl
"\t\tndr_print_array_$e->{TYPE}(ndr, \"$e->{NAME}\", $var_prefix$e->{NAME}, $size);\n";
432 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";
436 #####################################################################
437 # check the size_is and length_is constraints
438 sub CheckArraySizes
($$)
441 my $var_prefix = shift;
443 if (!defined $e->{CONFORMANT_SIZE
} &&
444 util
::has_property
($e, "size_is")) {
445 my $size = ParseExpr
($e, util
::array_size
($e), $var_prefix);
446 pidl
"\tif ($var_prefix$e->{NAME}) {\n";
447 check_null_pointer
($size);
448 pidl
"\t\tNDR_CHECK(ndr_check_array_size(ndr, (void*)&$var_prefix$e->{NAME}, $size));\n";
452 if (my $length = util
::has_property
($e, "length_is")) {
453 $length = ParseExpr
($e, $length, $var_prefix);
454 pidl
"\tif ($var_prefix$e->{NAME}) {\n";
455 check_null_pointer
($length);
456 pidl
"\t\tNDR_CHECK(ndr_check_array_length(ndr, (void*)&$var_prefix$e->{NAME}, $length));\n";
462 #####################################################################
463 # parse an array - pull side
464 sub ParseArrayPull
($$$)
467 my $var_prefix = shift;
468 my $ndr_flags = shift;
470 my $size = ParseExpr
($e, util
::array_size
($e), $var_prefix);
471 my $alloc_size = $size;
473 # if this is a conformant array then we use that size to allocate, and make sure
474 # we allocate enough to pull the elements
475 if (defined $e->{CONFORMANT_SIZE
}) {
476 $alloc_size = $e->{CONFORMANT_SIZE
};
477 check_null_pointer
($size);
478 pidl
"\tif ($size > $alloc_size) {\n";
479 pidl
"\t\treturn ndr_pull_error(ndr, NDR_ERR_CONFORMANT_SIZE, \"Bad conformant size %u should be %u\", $alloc_size, $size);\n";
481 } elsif (!util
::is_inline_array
($e)) {
482 if ($var_prefix =~ /^r->out/ && $size =~ /^\*r->in/) {
483 my $size2 = substr($size, 1);
484 pidl
"if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_ALLOC(ndr, $size2); }\n";
487 # non fixed arrays encode the size just before the array
488 pidl
"\t\tNDR_CHECK(ndr_pull_array_size(ndr, &$var_prefix$e->{NAME}));\n";
489 $alloc_size = "ndr_get_array_size(ndr, &$var_prefix$e->{NAME})";
492 if ((need_alloc
($e) && !util
::is_fixed_array
($e)) ||
493 ($var_prefix eq "r->in." && util
::has_property
($e, "ref"))) {
494 if (!util
::is_inline_array
($e) || $ndr_flags eq "NDR_SCALARS") {
495 pidl
"\t\tNDR_ALLOC_N(ndr, $var_prefix$e->{NAME}, $alloc_size);\n";
499 if (($var_prefix eq "r->out." && util
::has_property
($e, "ref"))) {
500 if (!util
::is_inline_array
($e) || $ndr_flags eq "NDR_SCALARS") {
501 pidl
"\tif (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {";
502 pidl
"\t\tNDR_ALLOC_N(ndr, $var_prefix$e->{NAME}, $alloc_size);\n";
507 if (my $length = util
::has_property
($e, "length_is")) {
508 pidl
"\t\tNDR_CHECK(ndr_pull_array_length(ndr, &$var_prefix$e->{NAME}));\n";
509 $size = "ndr_get_array_length(ndr, &$var_prefix$e->{NAME})";
512 check_null_pointer
($size);
513 if (is_scalar_type
($e->{TYPE
})) {
514 pidl
"\t\tNDR_CHECK(ndr_pull_array_$e->{TYPE}(ndr, $ndr_flags, $var_prefix$e->{NAME}, $size));\n";
516 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";
521 #####################################################################
522 # parse scalars in a structure element
523 sub ParseElementPushScalar
($$$)
526 my($var_prefix) = shift;
527 my($ndr_flags) = shift;
528 my $cprefix = c_push_prefix
($e);
529 my $sub_size = util
::has_property
($e, "subcontext");
533 if (my $value = util
::has_property
($e, "value")) {
534 pidl
"\t$cprefix$var_prefix$e->{NAME} = $value;\n";
537 if (util
::has_property
($e, "relative")) {
538 pidl
"\tNDR_CHECK(ndr_push_relative1(ndr, $var_prefix$e->{NAME}));\n";
539 } elsif (util
::is_inline_array
($e)) {
540 ParseArrayPush
($e, "r->", "NDR_SCALARS");
541 } elsif (need_wire_pointer
($e)) {
542 pidl
"\tNDR_CHECK(ndr_push_ptr(ndr, $var_prefix$e->{NAME}));\n";
543 } elsif (need_alloc
($e)) {
544 # no scalar component
545 } elsif (my $switch = util
::has_property
($e, "switch_is")) {
546 ParseElementPushSwitch
($e, $var_prefix, $ndr_flags, $switch);
547 } elsif (defined $sub_size) {
548 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";
550 pidl
"\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
556 #####################################################################
557 # print scalars in a structure element
558 sub ParseElementPrintScalar
($$)
561 my($var_prefix) = shift;
562 my $cprefix = c_push_prefix
($e);
564 if (util
::has_property
($e, "noprint")) {
568 if (my $value = util
::has_property
($e, "value")) {
569 pidl
"\tif (ndr->flags & LIBNDR_PRINT_SET_VALUES) {\n";
570 pidl
"\t\t$cprefix$var_prefix$e->{NAME} = $value;\n";
574 if (util
::is_fixed_array
($e)) {
575 ParseElementPrintBuffer
($e, $var_prefix);
576 } elsif ($e->{POINTERS
} || util
::array_size
($e)) {
577 pidl
"\tndr_print_ptr(ndr, \"$e->{NAME}\", $var_prefix$e->{NAME});\n";
578 pidl
"\tndr->depth++;\n";
579 ParseElementPrintBuffer
($e, $var_prefix);
580 pidl
"\tndr->depth--;\n";
581 } elsif (my $switch = util
::has_property
($e, "switch_is")) {
582 ParseElementPrintSwitch
($e, $var_prefix, $switch);
584 pidl
"\tndr_print_$e->{TYPE}(ndr, \"$e->{NAME}\", $cprefix$var_prefix$e->{NAME});\n";
588 #####################################################################
589 # parse scalars in a structure element - pull size
590 sub ParseElementPullSwitch
($$$$)
593 my($var_prefix) = shift;
594 my($ndr_flags) = shift;
596 my $switch_var = ParseExpr
($e, $switch, $var_prefix);
598 my $cprefix = c_pull_prefix
($e);
600 my $utype = $typedefs{$e->{TYPE
}};
602 check_null_pointer
($switch_var);
604 if (!defined $utype ||
605 !util
::has_property
($utype, "nodiscriminant")) {
606 my $e2 = find_sibling
($e, $switch);
607 my $type_decl = util
::map_type
($e2->{TYPE
});
608 pidl
"\tif (($ndr_flags) & NDR_SCALARS) {\n";
609 if (util
::is_enum
($e2->{TYPE
})) {
610 $type_decl = util
::enum_type_decl
($e2);
611 } elsif (util
::is_bitmap
($e2->{TYPE
})) {
612 $type_decl = util
::bitmap_type_decl
($e2);
614 pidl
"\t\t$type_decl _level;\n";
615 pidl
"\t\tNDR_CHECK(ndr_pull_$e2->{TYPE}(ndr, NDR_SCALARS, &_level));\n";
616 if ($switch_var =~ /r->in/) {
617 pidl
"\t\tif (!(ndr->flags & LIBNDR_FLAG_REF_ALLOC) && _level != $switch_var) {\n";
619 pidl
"\t\tif (_level != $switch_var) {\n";
621 pidl
"\t\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value %u in $e->{NAME}\", _level);\n";
623 if ($switch_var =~ /r->/) {
624 pidl
"else { $switch_var = _level; }\n";
629 my $sub_size = util
::has_property
($e, "subcontext");
630 if (defined $sub_size) {
631 pidl
"\tif (($ndr_flags) & NDR_SCALARS) {\n";
632 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";
635 pidl
"\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $switch_var, $cprefix$var_prefix$e->{NAME}));\n";
641 #####################################################################
642 # push switch element
643 sub ParseElementPushSwitch
($$$$)
646 my($var_prefix) = shift;
647 my($ndr_flags) = shift;
649 my $switch_var = ParseExpr
($e, $switch, $var_prefix);
650 my $cprefix = c_push_prefix
($e);
652 check_null_pointer
($switch_var);
654 my $utype = $typedefs{$e->{TYPE
}};
655 if (!defined $utype ||
656 !util
::has_property
($utype, "nodiscriminant")) {
657 my $e2 = find_sibling
($e, $switch);
658 pidl
"\tif (($ndr_flags) & NDR_SCALARS) {\n";
659 pidl
"\t\tNDR_CHECK(ndr_push_$e2->{TYPE}(ndr, NDR_SCALARS, $switch_var));\n";
663 my $sub_size = util
::has_property
($e, "subcontext");
664 if (defined $sub_size) {
665 pidl
"\tif(($ndr_flags) & NDR_SCALARS) {\n";
666 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";
669 pidl
"\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $switch_var, $cprefix$var_prefix$e->{NAME}));\n";
673 #####################################################################
674 # print scalars in a structure element
675 sub ParseElementPrintSwitch
($$$)
678 my($var_prefix) = shift;
680 my $switch_var = ParseExpr
($e, $switch, $var_prefix);
681 my $cprefix = c_push_prefix
($e);
683 check_null_pointer_void
($switch_var);
685 pidl
"\tndr_print_$e->{TYPE}(ndr, \"$e->{NAME}\", $switch_var, $cprefix$var_prefix$e->{NAME});\n";
689 #####################################################################
690 # parse scalars in a structure element - pull size
691 sub ParseElementPullScalar
($$$)
694 my($var_prefix) = shift;
695 my($ndr_flags) = shift;
696 my $cprefix = c_pull_prefix
($e);
697 my $sub_size = util
::has_property
($e, "subcontext");
701 if (util
::is_inline_array
($e)) {
702 ParseArrayPull
($e, "r->", "NDR_SCALARS");
703 } elsif (need_wire_pointer
($e)) {
704 pidl
"\tNDR_CHECK(ndr_pull_ptr(ndr, &_ptr_$e->{NAME}));\n";
705 pidl
"\tif (_ptr_$e->{NAME}) {\n";
706 pidl
"\t\tNDR_ALLOC(ndr, $var_prefix$e->{NAME});\n";
707 if (util
::has_property
($e, "relative")) {
708 pidl
"\t\tNDR_CHECK(ndr_pull_relative1(ndr, $var_prefix$e->{NAME}, _ptr_$e->{NAME}));\n";
711 pidl
"\t\t$var_prefix$e->{NAME} = NULL;\n";
713 } elsif (need_alloc
($e)) {
714 # no scalar component
715 } elsif (my $switch = util
::has_property
($e, "switch_is")) {
716 ParseElementPullSwitch
($e, $var_prefix, $ndr_flags, $switch);
717 } elsif (defined $sub_size) {
718 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";
720 pidl
"\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
722 if (my $range = util
::has_property
($e, "range")) {
723 my ($low, $high) = split(/ /, $range, 2);
724 pidl
"\tif ($var_prefix$e->{NAME} < $low || $var_prefix$e->{NAME} > $high) {\n";
725 pidl
"\t\treturn ndr_pull_error(ndr, NDR_ERR_RANGE, \"value out of range\");\n\t}\n";
731 #####################################################################
732 # parse buffers in a structure element
733 sub ParseElementPushBuffer
($$$)
736 my($var_prefix) = shift;
737 my($ndr_flags) = shift;
738 my $cprefix = c_push_prefix
($e);
739 my $sub_size = util
::has_property
($e, "subcontext");
741 if (is_pure_scalar
($e)) {
747 if (need_wire_pointer
($e)) {
748 pidl
"\tif ($var_prefix$e->{NAME}) {\n";
749 if (util
::has_property
($e, "relative")) {
750 pidl
"\t\tNDR_CHECK(ndr_push_relative2(ndr, $var_prefix$e->{NAME}));\n";
754 if (util
::is_inline_array
($e)) {
755 ParseArrayPush
($e, "r->", "NDR_BUFFERS");
756 } elsif (util
::array_size
($e)) {
757 ParseArrayPush
($e, "r->", "NDR_SCALARS|NDR_BUFFERS");
758 } elsif (my $switch = util
::has_property
($e, "switch_is")) {
759 if ($e->{POINTERS
}) {
760 ParseElementPushSwitch
($e, $var_prefix, "NDR_BUFFERS|NDR_SCALARS", $switch);
762 ParseElementPushSwitch
($e, $var_prefix, "NDR_BUFFERS", $switch);
764 } elsif (defined $sub_size) {
765 if ($e->{POINTERS
}) {
766 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";
768 } elsif ($e->{POINTERS
}) {
769 pidl
"\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, NDR_SCALARS|NDR_BUFFERS, $cprefix$var_prefix$e->{NAME}));\n";
771 pidl
"\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
774 if (need_wire_pointer
($e)) {
781 #####################################################################
782 # print buffers in a structure element
783 sub ParseElementPrintBuffer
($$)
786 my($var_prefix) = shift;
787 my $cprefix = c_push_prefix
($e);
789 if (need_wire_pointer
($e)) {
790 pidl
"\tif ($var_prefix$e->{NAME}) {\n";
793 if (util
::array_size
($e)) {
794 ParseArrayPrint
($e, $var_prefix)
795 } elsif (my $switch = util
::has_property
($e, "switch_is")) {
796 ParseElementPrintSwitch
($e, $var_prefix, $switch);
798 pidl
"\t\tndr_print_$e->{TYPE}(ndr, \"$e->{NAME}\", $cprefix$var_prefix$e->{NAME});\n";
801 if (need_wire_pointer
($e)) {
807 #####################################################################
808 # parse buffers in a structure element - pull side
809 sub ParseElementPullBuffer
($$$)
812 my($var_prefix) = shift;
813 my($ndr_flags) = shift;
814 my $cprefix = c_pull_prefix
($e);
815 my $sub_size = util
::has_property
($e, "subcontext");
817 if (is_pure_scalar
($e)) {
823 if (need_wire_pointer
($e)) {
824 pidl
"\tif ($var_prefix$e->{NAME}) {\n";
825 if (util
::has_property
($e, "relative")) {
826 pidl
"\t\tstruct ndr_pull_save _relative_save;\n";
827 pidl
"\t\tndr_pull_save(ndr, &_relative_save);\n";
828 pidl
"\t\tNDR_CHECK(ndr_pull_relative2(ndr, $var_prefix$e->{NAME}));\n";
832 if (util
::is_inline_array
($e)) {
833 ParseArrayPull
($e, "r->", "NDR_BUFFERS");
834 } elsif (util
::array_size
($e)) {
835 ParseArrayPull
($e, "r->", "NDR_SCALARS|NDR_BUFFERS");
836 } elsif (my $switch = util
::has_property
($e, "switch_is")) {
837 if ($e->{POINTERS
}) {
838 ParseElementPullSwitch
($e, $var_prefix, "NDR_SCALARS|NDR_BUFFERS", $switch);
840 ParseElementPullSwitch
($e, $var_prefix, "NDR_BUFFERS", $switch);
842 } elsif (defined $sub_size) {
843 if ($e->{POINTERS
}) {
844 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";
846 } elsif ($e->{POINTERS
}) {
847 pidl
"\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, NDR_SCALARS|NDR_BUFFERS, $cprefix$var_prefix$e->{NAME}));\n";
849 pidl
"\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
852 if (need_wire_pointer
($e)) {
853 if (util
::has_property
($e, "relative")) {
854 pidl
"\t\tndr_pull_restore(ndr, &_relative_save);\n";
862 #####################################################################
864 sub ParseStructPush
($)
868 if (! defined $struct->{ELEMENTS
}) {
872 start_flags
($struct);
874 # see if the structure contains a conformant array. If it
875 # does, then it must be the last element of the structure, and
876 # we need to push the conformant length early, as it fits on
877 # the wire before the structure (and even before the structure
879 my $e = $struct->{ELEMENTS
}[-1];
880 if (defined $e->{ARRAY_LEN
} && $e->{ARRAY_LEN
} eq "*") {
881 my $size = ParseExpr
($e, util
::array_size
($e), "r->");
882 $e->{CONFORMANT_SIZE
} = $size;
883 check_null_pointer
($size);
884 pidl
"\tNDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, $size));\n";
887 if (defined $e->{TYPE
} && $e->{TYPE
} eq "string"
888 && util
::property_matches
($e, "flag", ".*LIBNDR_FLAG_STR_CONFORMANT.*")) {
889 pidl
"\tNDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_string_array_size(ndr, r->$e->{NAME})));\n";
892 pidl
"\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
894 pidl
"\tNDR_CHECK(ndr_push_struct_start(ndr));\n";
896 my $align = struct_alignment
($struct);
897 pidl
"\tNDR_CHECK(ndr_push_align(ndr, $align));\n";
899 foreach my $e (@
{$struct->{ELEMENTS
}}) {
900 ParseElementPushScalar
($e, "r->", "NDR_SCALARS");
904 pidl
"\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n";
905 foreach my $e (@
{$struct->{ELEMENTS
}}) {
906 ParseElementPushBuffer
($e, "r->", "NDR_BUFFERS");
909 pidl
"\tndr_push_struct_end(ndr);\n";
917 #####################################################################
918 # generate a push function for an enum
922 my($type_fn) = util
::enum_type_fn
($enum);
926 pidl
"\tNDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, r));\n";
931 #####################################################################
932 # generate a pull function for an enum
936 my($type_fn) = util
::enum_type_fn
($enum);
937 my($type_v_decl) = util
::map_type
(util
::enum_type_fn
($enum));
939 pidl
"\t$type_v_decl v;\n";
941 pidl
"\tNDR_CHECK(ndr_pull_$type_fn(ndr, NDR_SCALARS, &v));\n";
947 #####################################################################
948 # generate a print function for an enum
949 sub ParseEnumPrint
($)
953 pidl
"\tconst char *val = NULL;\n\n";
957 pidl
"\tswitch (r) {\n";
958 my $els = \@
{$enum->{ELEMENTS
}};
959 foreach my $i (0 .. $#{$els}) {
962 if ($e =~ /^(.*)=/) {
965 pidl
"\t\tcase $e: val = \"$e\"; break;\n";
968 pidl
"\t}\n\n\tndr_print_enum(ndr, name, \"$enum->{TYPE}\", val, r);\n";
974 #####################################################################
975 # generate a push function for a bitmap
976 sub ParseBitmapPush
($)
979 my($type_fn) = util
::bitmap_type_fn
($bitmap);
981 start_flags
($bitmap);
983 pidl
"\tNDR_CHECK(ndr_push_$type_fn(ndr, NDR_SCALARS, r));\n";
988 #####################################################################
989 # generate a pull function for an bitmap
990 sub ParseBitmapPull
($)
993 my($type_fn) = util
::bitmap_type_fn
($bitmap);
994 my($type_decl) = util
::bitmap_type_decl
($bitmap);
996 pidl
"\t$type_decl v;\n";
997 start_flags
($bitmap);
998 pidl
"\tNDR_CHECK(ndr_pull_$type_fn(ndr, NDR_SCALARS, &v));\n";
1004 #####################################################################
1005 # generate a print function for an bitmap
1006 sub ParseBitmapPrintElement
($$)
1009 my($bitmap) = shift;
1010 my($type_decl) = util
::bitmap_type_decl
($bitmap);
1011 my($type_fn) = util
::bitmap_type_fn
($bitmap);
1012 my($name) = $bitmap->{PARENT
}->{NAME
};
1015 if ($e =~ /^(\w+) .*$/) {
1018 die "Bitmap: \"$name\" invalid Flag: \"$e\"";
1021 pidl
"\tndr_print_bitmap_flag(ndr, sizeof($type_decl), \"$flag\", $flag, r);\n";
1024 #####################################################################
1025 # generate a print function for an bitmap
1026 sub ParseBitmapPrint
($)
1028 my($bitmap) = shift;
1029 my($type_decl) = util
::bitmap_type_decl
($bitmap);
1030 my($type_fn) = util
::bitmap_type_fn
($bitmap);
1032 start_flags
($bitmap);
1034 pidl
"\tndr_print_$type_fn(ndr, name, r);\n";
1036 pidl
"\tndr->depth++;\n";
1037 foreach my $e (@
{$bitmap->{ELEMENTS
}}) {
1038 ParseBitmapPrintElement
($e, $bitmap);
1040 pidl
"\tndr->depth--;\n";
1045 #####################################################################
1046 # generate a struct print function
1047 sub ParseStructPrint
($)
1049 my($struct) = shift;
1051 if (! defined $struct->{ELEMENTS
}) {
1055 start_flags
($struct);
1057 pidl
"\tndr->depth++;\n";
1058 foreach my $e (@
{$struct->{ELEMENTS
}}) {
1059 ParseElementPrintScalar
($e, "r->");
1061 pidl
"\tndr->depth--;\n";
1066 #####################################################################
1067 # parse a struct - pull side
1068 sub ParseStructPull
($)
1070 my($struct) = shift;
1073 if (! defined $struct->{ELEMENTS
}) {
1077 # see if the structure contains a conformant array. If it
1078 # does, then it must be the last element of the structure, and
1079 # we need to pull the conformant length early, as it fits on
1080 # the wire before the structure (and even before the structure
1082 my $e = $struct->{ELEMENTS
}[-1];
1083 if (defined $e->{ARRAY_LEN
} && $e->{ARRAY_LEN
} eq "*") {
1087 if (defined $e->{TYPE
} && $e->{TYPE
} eq "string"
1088 && util
::property_matches
($e, "flag", ".*LIBNDR_FLAG_STR_CONFORMANT.*")) {
1092 if (defined $conform_e) {
1094 pidl
"\tuint32_t _conformant_size;\n";
1095 $conform_e->{CONFORMANT_SIZE
} = "_conformant_size";
1098 # declare any internal pointers we need
1099 foreach my $e (@
{$struct->{ELEMENTS
}}) {
1100 if (need_wire_pointer
($e)) {
1101 pidl
"\tuint32_t _ptr_$e->{NAME};\n";
1105 start_flags
($struct);
1107 pidl
"\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
1109 pidl
"\tNDR_CHECK(ndr_pull_struct_start(ndr));\n";
1111 if (defined $conform_e) {
1112 pidl
"\tNDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &$conform_e->{CONFORMANT_SIZE}));\n";
1115 my $align = struct_alignment
($struct);
1116 pidl
"\tNDR_CHECK(ndr_pull_align(ndr, $align));\n";
1118 foreach my $e (@
{$struct->{ELEMENTS
}}) {
1119 ParseElementPullScalar
($e, "r->", "NDR_SCALARS");
1123 pidl
"\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n";
1124 foreach my $e (@
{$struct->{ELEMENTS
}}) {
1125 ParseElementPullBuffer
($e, "r->", "NDR_BUFFERS");
1128 foreach my $e (@
{$struct->{ELEMENTS
}}) {
1129 CheckArraySizes
($e, "r->");
1132 pidl
"\tndr_pull_struct_end(ndr);\n";
1139 #####################################################################
1140 # calculate size of ndr struct
1141 sub ParseStructNdrSize
($)
1144 my $static = fn_prefix
($t);
1147 pidl
"size_t ndr_size_$t->{NAME}(const struct $t->{NAME} *r, int flags)\n";
1149 if (my $flags = util
::has_property
($t, "flag")) {
1150 pidl
"\tflags |= $flags;\n";
1152 pidl
"\treturn ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_$t->{NAME});\n";
1156 #####################################################################
1157 # calculate size of ndr struct
1158 sub ParseUnionNdrSize
($)
1161 my $static = fn_prefix
($t);
1164 pidl
"size_t ndr_size_$t->{NAME}(const union $t->{NAME} *r, int level, int flags)\n";
1166 if (my $flags = util
::has_property
($t, "flag")) {
1167 pidl
"\tflags |= $flags;\n";
1169 pidl
"\treturn ndr_size_union(r, flags, level, (ndr_push_union_fn_t)ndr_push_$t->{NAME});\n";
1173 #####################################################################
1174 # parse a union - push side
1175 sub ParseUnionPush
($)
1178 my $have_default = 0;
1182 pidl
"\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
1184 pidl
"\tNDR_CHECK(ndr_push_struct_start(ndr));\n";
1186 # my $align = union_alignment($e);
1187 # pidl "\tNDR_CHECK(ndr_push_align(ndr, $align));\n";
1189 pidl
"\tswitch (level) {\n";
1190 foreach my $el (@
{$e->{ELEMENTS
}}) {
1191 if (util
::has_property
($el, "default")) {
1192 pidl
"\tdefault:\n";
1195 pidl
"\tcase $el->{PROPERTIES}->{case}:\n";
1197 if ($el->{TYPE
} ne "EMPTY") {
1198 ParseElementPushScalar
($el, "r->", "NDR_SCALARS");
1200 pidl
"\tbreak;\n\n";
1202 if (! $have_default) {
1203 pidl
"\tdefault:\n";
1204 pidl
"\t\treturn ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n";
1208 pidl
"\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n";
1209 pidl
"\tswitch (level) {\n";
1210 foreach my $el (@
{$e->{ELEMENTS
}}) {
1211 if (util
::has_property
($el, "default")) {
1212 pidl
"\tdefault:\n";
1214 pidl
"\tcase $el->{PROPERTIES}->{case}:\n";
1216 if ($el->{TYPE
} ne "EMPTY") {
1217 ParseElementPushBuffer
($el, "r->", "NDR_BUFFERS");
1219 pidl
"\tbreak;\n\n";
1221 if (! $have_default) {
1222 pidl
"\tdefault:\n";
1223 pidl
"\t\treturn ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n";
1226 pidl
"\tndr_push_struct_end(ndr);\n";
1231 #####################################################################
1233 sub ParseUnionPrint
($)
1236 my $have_default = 0;
1240 pidl
"\tswitch (level) {\n";
1241 foreach my $el (@
{$e->{ELEMENTS
}}) {
1242 if (util
::has_property
($el, "default")) {
1244 pidl
"\tdefault:\n";
1246 pidl
"\tcase $el->{PROPERTIES}->{case}:\n";
1248 if ($el->{TYPE
} ne "EMPTY") {
1249 ParseElementPrintScalar
($el, "r->");
1251 pidl
"\tbreak;\n\n";
1253 if (! $have_default) {
1254 pidl
"\tdefault:\n\t\tndr_print_bad_level(ndr, name, level);\n";
1261 #####################################################################
1262 # parse a union - pull side
1263 sub ParseUnionPull
($)
1266 my $have_default = 0;
1270 pidl
"\tif (!(ndr_flags & NDR_SCALARS)) goto buffers;\n";
1272 pidl
"\tNDR_CHECK(ndr_pull_struct_start(ndr));\n";
1274 # my $align = union_alignment($e);
1275 # pidl "\tNDR_CHECK(ndr_pull_align(ndr, $align));\n";
1277 pidl
"\tswitch (level) {\n";
1278 foreach my $el (@
{$e->{ELEMENTS
}}) {
1279 if (util
::has_property
($el, "default")) {
1280 pidl
"\tdefault: {\n";
1283 pidl
"\tcase $el->{PROPERTIES}->{case}: {\n";
1285 if ($el->{TYPE
} ne "EMPTY") {
1286 if ($el->{POINTERS
}) {
1287 pidl
"\t\tuint32_t _ptr_$el->{NAME};\n";
1289 ParseElementPullScalar
($el, "r->", "NDR_SCALARS");
1291 pidl
"\tbreak; }\n\n";
1293 if (! $have_default) {
1294 pidl
"\tdefault:\n";
1295 pidl
"\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n";
1299 pidl
"\tif (!(ndr_flags & NDR_BUFFERS)) goto done;\n";
1300 pidl
"\tswitch (level) {\n";
1301 foreach my $el (@
{$e->{ELEMENTS
}}) {
1302 if (util
::has_property
($el, "default")) {
1303 pidl
"\tdefault:\n";
1305 pidl
"\tcase $el->{PROPERTIES}->{case}:\n";
1307 if ($el->{TYPE
} ne "EMPTY") {
1308 ParseElementPullBuffer
($el, "r->", "NDR_BUFFERS");
1310 pidl
"\tbreak;\n\n";
1312 if (! $have_default) {
1313 pidl
"\tdefault:\n";
1314 pidl
"\t\treturn ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, \"Bad switch value \%u\", level);\n";
1317 pidl
"\tndr_pull_struct_end(ndr);\n";
1323 #####################################################################
1325 sub ParseTypePush
($)
1329 ($data->{TYPE
} eq "STRUCT") &&
1330 ParseStructPush
($data);
1331 ($data->{TYPE
} eq "UNION") &&
1332 ParseUnionPush
($data);
1333 ($data->{TYPE
} eq "ENUM") &&
1334 ParseEnumPush
($data);
1335 ($data->{TYPE
} eq "BITMAP") &&
1336 ParseBitmapPush
($data);
1339 #####################################################################
1340 # generate a print function for a type
1341 sub ParseTypePrint
($)
1345 ($data->{TYPE
} eq "STRUCT") &&
1346 ParseStructPrint
($data);
1347 ($data->{TYPE
} eq "UNION") &&
1348 ParseUnionPrint
($data);
1349 ($data->{TYPE
} eq "ENUM") &&
1350 ParseEnumPrint
($data);
1351 ($data->{TYPE
} eq "BITMAP") &&
1352 ParseBitmapPrint
($data);
1355 #####################################################################
1357 sub ParseTypePull
($)
1361 ($data->{TYPE
} eq "STRUCT") &&
1362 ParseStructPull
($data);
1363 ($data->{TYPE
} eq "UNION") &&
1364 ParseUnionPull
($data);
1365 ($data->{TYPE
} eq "ENUM") &&
1366 ParseEnumPull
($data);
1367 ($data->{TYPE
} eq "BITMAP") &&
1368 ParseBitmapPull
($data);
1371 #####################################################################
1372 # parse a typedef - push side
1373 sub ParseTypedefPush
($)
1376 my $static = fn_prefix
($e);
1378 if (! needed
::is_needed
("push_$e->{NAME}")) {
1379 # print "push_$e->{NAME} not needed\n";
1383 if (defined($e->{PROPERTIES
}) && !defined($e->{DATA
}->{PROPERTIES
})) {
1384 $e->{DATA
}->{PROPERTIES
} = $e->{PROPERTIES
};
1387 if ($e->{DATA
}->{TYPE
} eq "STRUCT") {
1388 pidl
$static . "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, struct $e->{NAME} *r)";
1390 ParseTypePush
($e->{DATA
});
1391 pidl
"\treturn NT_STATUS_OK;\n";
1395 if ($e->{DATA
}->{TYPE
} eq "UNION") {
1396 pidl
$static . "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, int level, union $e->{NAME} *r)";
1398 ParseTypePush
($e->{DATA
});
1399 pidl
"\treturn NT_STATUS_OK;\n";
1403 if ($e->{DATA
}->{TYPE
} eq "ENUM") {
1404 pidl
$static . "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, enum $e->{NAME} r)";
1406 ParseTypePush
($e->{DATA
});
1407 pidl
"\treturn NT_STATUS_OK;\n";
1411 if ($e->{DATA
}->{TYPE
} eq "BITMAP") {
1412 my $type_decl = util
::bitmap_type_decl
($e->{DATA
});
1413 pidl
$static . "NTSTATUS ndr_push_$e->{NAME}(struct ndr_push *ndr, int ndr_flags, $type_decl r)";
1415 ParseTypePush
($e->{DATA
});
1416 pidl
"\treturn NT_STATUS_OK;\n";
1422 #####################################################################
1423 # parse a typedef - pull side
1424 sub ParseTypedefPull
($)
1427 my $static = fn_prefix
($e);
1429 if (defined($e->{PROPERTIES
}) && !defined($e->{DATA
}->{PROPERTIES
})) {
1430 $e->{DATA
}->{PROPERTIES
} = $e->{PROPERTIES
};
1433 if (! needed
::is_needed
("pull_$e->{NAME}")) {
1434 # print "pull_$e->{NAME} not needed\n";
1438 if ($e->{DATA
}->{TYPE
} eq "STRUCT") {
1439 pidl
$static . "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, struct $e->{NAME} *r)";
1441 ParseTypePull
($e->{DATA
});
1442 pidl
"\treturn NT_STATUS_OK;\n";
1446 if ($e->{DATA
}->{TYPE
} eq "UNION") {
1447 pidl
$static . "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, int level, union $e->{NAME} *r)";
1449 ParseTypePull
($e->{DATA
});
1450 pidl
"\treturn NT_STATUS_OK;\n";
1454 if ($e->{DATA
}->{TYPE
} eq "ENUM") {
1455 pidl
$static . "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, enum $e->{NAME} *r)";
1457 ParseTypePull
($e->{DATA
});
1458 pidl
"\treturn NT_STATUS_OK;\n";
1462 if ($e->{DATA
}->{TYPE
} eq "BITMAP") {
1463 my $type_decl = util
::bitmap_type_decl
($e->{DATA
});
1464 pidl
$static . "NTSTATUS ndr_pull_$e->{NAME}(struct ndr_pull *ndr, int ndr_flags, $type_decl *r)";
1466 ParseTypePull
($e->{DATA
});
1467 pidl
"\treturn NT_STATUS_OK;\n";
1473 #####################################################################
1474 # parse a typedef - print side
1475 sub ParseTypedefPrint
($)
1479 if (defined($e->{PROPERTIES
}) && !defined($e->{DATA
}->{PROPERTIES
})) {
1480 $e->{DATA
}->{PROPERTIES
} = $e->{PROPERTIES
};
1483 if ($e->{DATA
}->{TYPE
} eq "STRUCT") {
1484 pidl
"void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, struct $e->{NAME} *r)";
1486 pidl
"\tndr_print_struct(ndr, name, \"$e->{NAME}\");\n";
1487 ParseTypePrint
($e->{DATA
});
1491 if ($e->{DATA
}->{TYPE
} eq "UNION") {
1492 pidl
"void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, int level, union $e->{NAME} *r)";
1494 pidl
"\tndr_print_union(ndr, name, level, \"$e->{NAME}\");\n";
1495 ParseTypePrint
($e->{DATA
});
1499 if ($e->{DATA
}->{TYPE
} eq "ENUM") {
1500 pidl
"void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, enum $e->{NAME} r)";
1502 ParseTypePrint
($e->{DATA
});
1506 if ($e->{DATA
}->{TYPE
} eq "BITMAP") {
1507 my $type_decl = util
::bitmap_type_decl
($e->{DATA
});
1508 pidl
"void ndr_print_$e->{NAME}(struct ndr_print *ndr, const char *name, $type_decl r)";
1510 ParseTypePrint
($e->{DATA
});
1515 #####################################################################
1516 ## calculate the size of a structure
1517 sub ParseTypedefNdrSize
($)
1520 if (! needed
::is_needed
("ndr_size_$t->{NAME}")) {
1524 ($t->{DATA
}->{TYPE
} eq "STRUCT") &&
1525 ParseStructNdrSize
($t);
1527 ($t->{DATA
}->{TYPE
} eq "UNION") &&
1528 ParseUnionNdrSize
($t);
1531 #####################################################################
1532 # parse a function - print side
1533 sub ParseFunctionPrint
($)
1537 pidl
"void ndr_print_$fn->{NAME}(struct ndr_print *ndr, const char *name, int flags, struct $fn->{NAME} *r)";
1539 pidl
"\tndr_print_struct(ndr, name, \"$fn->{NAME}\");\n";
1540 pidl
"\tndr->depth++;\n";
1542 pidl
"\tif (flags & NDR_SET_VALUES) {\n";
1543 pidl
"\t\tndr->flags |= LIBNDR_PRINT_SET_VALUES;\n";
1546 pidl
"\tif (flags & NDR_IN) {\n";
1547 pidl
"\t\tndr_print_struct(ndr, \"in\", \"$fn->{NAME}\");\n";
1548 pidl
"\tndr->depth++;\n";
1550 foreach my $e (@
{$fn->{ELEMENTS
}}) {
1551 if (util
::has_property
($e, "in")) {
1552 ParseElementPrintScalar
($e, "r->in.");
1555 pidl
"\tndr->depth--;\n";
1558 pidl
"\tif (flags & NDR_OUT) {\n";
1559 pidl
"\t\tndr_print_struct(ndr, \"out\", \"$fn->{NAME}\");\n";
1560 pidl
"\tndr->depth++;\n";
1561 foreach my $e (@
{$fn->{ELEMENTS
}}) {
1562 if (util
::has_property
($e, "out")) {
1563 ParseElementPrintScalar
($e, "r->out.");
1566 if ($fn->{RETURN_TYPE
} && $fn->{RETURN_TYPE
} ne "void") {
1568 $cprefix = "" if (is_scalar_type
($fn->{RETURN_TYPE
})) ; # FIXME: Should really use util::c_push_prefix here
1569 pidl
"\tndr_print_$fn->{RETURN_TYPE}(ndr, \"result\", $cprefix"."r->out.result);\n";
1571 pidl
"\tndr->depth--;\n";
1574 pidl
"\tndr->depth--;\n";
1579 #####################################################################
1580 # parse a function element
1581 sub ParseFunctionElementPush
($$)
1586 if (util
::array_size
($e)) {
1587 if (need_wire_pointer
($e)) {
1588 pidl
"\tNDR_CHECK(ndr_push_ptr(ndr, r->$inout.$e->{NAME}));\n";
1589 pidl
"\tif (r->$inout.$e->{NAME}) {\n";
1590 ParseArrayPush
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1593 ParseArrayPush
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1596 ParseElementPushScalar
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1598 if ($e->{POINTERS
}) {
1599 ParseElementPushBuffer
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1604 #####################################################################
1606 sub ParseFunctionPush
($)
1609 my $static = fn_prefix
($fn);
1611 pidl
$static . "NTSTATUS ndr_push_$fn->{NAME}(struct ndr_push *ndr, int flags, struct $fn->{NAME} *r)\n{\n";
1613 pidl
"\n\tif (!(flags & NDR_IN)) goto ndr_out;\n\n";
1615 foreach my $e (@
{$fn->{ELEMENTS
}}) {
1616 if (util
::has_property
($e, "in")) {
1617 ParseFunctionElementPush
($e, "in");
1621 pidl
"\nndr_out:\n";
1622 pidl
"\tif (!(flags & NDR_OUT)) goto done;\n\n";
1624 foreach my $e (@
{$fn->{ELEMENTS
}}) {
1625 if (util
::has_property
($e, "out")) {
1626 ParseFunctionElementPush
($e, "out");
1630 if ($fn->{RETURN_TYPE
} && $fn->{RETURN_TYPE
} ne "void") {
1631 pidl
"\tNDR_CHECK(ndr_push_$fn->{RETURN_TYPE}(ndr, NDR_SCALARS, r->out.result));\n";
1635 pidl
"\n\treturn NT_STATUS_OK;\n}\n\n";
1638 #####################################################################
1639 # parse a function element
1640 sub ParseFunctionElementPull
($$)
1645 if (util
::array_size
($e)) {
1646 if (need_wire_pointer
($e)) {
1647 pidl
"\tNDR_CHECK(ndr_pull_ptr(ndr, &_ptr_$e->{NAME}));\n";
1648 pidl
"\tr->$inout.$e->{NAME} = NULL;\n";
1649 pidl
"\tif (_ptr_$e->{NAME}) {\n";
1650 } elsif ($inout eq "out" && util
::has_property
($e, "ref")) {
1651 pidl
"\tif (r->$inout.$e->{NAME}) {\n";
1655 ParseArrayPull
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1658 if ($inout eq "out" && util
::has_property
($e, "ref")) {
1659 pidl
"\tif (ndr->flags & LIBNDR_FLAG_REF_ALLOC) {\n";
1660 pidl
"\tNDR_ALLOC(ndr, r->out.$e->{NAME});\n";
1663 if ($inout eq "in" && util
::has_property
($e, "ref")) {
1664 pidl
"\tNDR_ALLOC(ndr, r->in.$e->{NAME});\n";
1667 ParseElementPullScalar
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1668 if ($e->{POINTERS
}) {
1669 ParseElementPullBuffer
($e, "r->$inout.", "NDR_SCALARS|NDR_BUFFERS");
1675 ############################################################
1676 # allocate ref variables
1677 sub AllocateRefVars
($)
1680 my $asize = util
::array_size
($e);
1682 # note that if the variable is also an "in"
1683 # variable then we copy the initial value from
1686 if (!defined $asize) {
1687 # its a simple variable
1688 pidl
"\tNDR_ALLOC(ndr, r->out.$e->{NAME});\n";
1689 if (util
::has_property
($e, "in")) {
1690 pidl
"\t*r->out.$e->{NAME} = *r->in.$e->{NAME};\n";
1692 pidl
"\tZERO_STRUCTP(r->out.$e->{NAME});\n";
1698 my $size = ParseExpr
($e, $asize, "r->out.");
1699 check_null_pointer
($size);
1700 pidl
"\tNDR_ALLOC_N(ndr, r->out.$e->{NAME}, $size);\n";
1701 if (util
::has_property
($e, "in")) {
1702 pidl
"\tmemcpy(r->out.$e->{NAME},r->in.$e->{NAME},$size * sizeof(*r->in.$e->{NAME}));\n";
1704 pidl
"\tmemset(r->out.$e->{NAME}, 0, $size * sizeof(*r->out.$e->{NAME}));\n";
1709 #####################################################################
1711 sub ParseFunctionPull
($)
1714 my $static = fn_prefix
($fn);
1716 # pull function args
1717 pidl
$static . "NTSTATUS ndr_pull_$fn->{NAME}(struct ndr_pull *ndr, int flags, struct $fn->{NAME} *r)\n{\n";
1719 # declare any internal pointers we need
1720 foreach my $e (@
{$fn->{ELEMENTS
}}) {
1721 if (need_wire_pointer
($e)) {
1722 pidl
"\tuint32_t _ptr_$e->{NAME};\n";
1726 pidl
"\n\tif (!(flags & NDR_IN)) goto ndr_out;\n\n";
1728 # auto-init the out section of a structure. I originally argued that
1729 # this was a bad idea as it hides bugs, but coping correctly
1730 # with initialisation and not wiping ref vars is turning
1731 # out to be too tricky (tridge)
1732 foreach my $e (@
{$fn->{ELEMENTS
}}) {
1733 if (util
::has_property
($e, "out")) {
1734 pidl
"\tZERO_STRUCT(r->out);\n\n";
1739 foreach my $e (@
{$fn->{ELEMENTS
}}) {
1740 if (util
::has_property
($e, "in")) {
1741 ParseFunctionElementPull
($e, "in");
1743 # we need to allocate any reference output variables, so that
1744 # a dcerpc backend can be sure they are non-null
1745 if (util
::has_property
($e, "out") && util
::has_property
($e, "ref")) {
1746 AllocateRefVars
($e);
1750 foreach my $e (@
{$fn->{ELEMENTS
}}) {
1751 if (util
::has_property
($e, "in")) {
1752 CheckArraySizes
($e, "r->in.");
1756 pidl
"\nndr_out:\n";
1757 pidl
"\tif (!(flags & NDR_OUT)) goto done;\n\n";
1759 foreach my $e (@
{$fn->{ELEMENTS
}}) {
1760 if (util
::has_property
($e, "out")) {
1761 ParseFunctionElementPull
($e, "out");
1765 foreach my $e (@
{$fn->{ELEMENTS
}}) {
1766 if (util
::has_property
($e, "out")) {
1767 CheckArraySizes
($e, "r->out.");
1771 if ($fn->{RETURN_TYPE
} && $fn->{RETURN_TYPE
} ne "void") {
1772 pidl
"\tNDR_CHECK(ndr_pull_$fn->{RETURN_TYPE}(ndr, NDR_SCALARS, &r->out.result));\n";
1776 pidl
"\n\treturn NT_STATUS_OK;\n}\n\n";
1779 #####################################################################
1780 # produce a function call table
1781 sub FunctionTable
($)
1783 my($interface) = shift;
1784 my($data) = $interface->{INHERITED_DATA
};
1786 my $uname = uc $interface->{NAME
};
1788 foreach my $d (@
{$data}) {
1789 if ($d->{TYPE
} eq "FUNCTION") { $count++; }
1792 return if ($count == 0);
1794 pidl
"static const struct dcerpc_interface_call $interface->{NAME}\_calls[] = {\n";
1795 foreach my $d (@
{$data}) {
1796 if ($d->{TYPE
} eq "FUNCTION") {
1798 pidl
"\t\t\"$d->{NAME}\",\n";
1799 pidl
"\t\tsizeof(struct $d->{NAME}),\n";
1800 pidl
"\t\t(ndr_push_flags_fn_t) ndr_push_$d->{NAME},\n";
1801 pidl
"\t\t(ndr_pull_flags_fn_t) ndr_pull_$d->{NAME},\n";
1802 pidl
"\t\t(ndr_print_function_t) ndr_print_$d->{NAME}\n";
1806 pidl
"\t{ NULL, 0, NULL, NULL, NULL }\n};\n\n";
1808 # If no endpoint is set, default to the interface name as a named pipe
1809 if (! defined $interface->{PROPERTIES
}->{endpoint
}) {
1810 $interface->{PROPERTIES
}->{endpoint
} = "\"ncacn_np:[\\\\pipe\\\\" . $interface->{NAME
} . "]\"";
1813 my @e = split / /, $interface->{PROPERTIES
}->{endpoint
};
1814 my $endpoint_count = $#e + 1;
1816 pidl
"static const char * const $interface->{NAME}\_endpoint_strings[] = {\n";
1817 foreach my $ep (@e) {
1822 pidl
"static const struct dcerpc_endpoint_list $interface->{NAME}\_endpoints = {\n";
1823 pidl
"\t$endpoint_count, $interface->{NAME}\_endpoint_strings\n";
1826 pidl
"\nconst struct dcerpc_interface_table dcerpc_table_$interface->{NAME} = {\n";
1827 pidl
"\t\"$interface->{NAME}\",\n";
1828 pidl
"\tDCERPC_$uname\_UUID,\n";
1829 pidl
"\tDCERPC_$uname\_VERSION,\n";
1830 pidl
"\tDCERPC_$uname\_HELPSTRING,\n";
1832 pidl
"\t$interface->{NAME}\_calls,\n";
1833 pidl
"\t&$interface->{NAME}\_endpoints\n";
1836 pidl
"static NTSTATUS dcerpc_ndr_$interface->{NAME}_init(void)\n";
1838 pidl
"\treturn librpc_register_interface(&dcerpc_table_$interface->{NAME});\n";
1842 #####################################################################
1843 # parse the interface definitions
1844 sub ParseInterface
($)
1846 my($interface) = shift;
1847 my($data) = $interface->{DATA
};
1850 foreach my $d (@
{$data}) {
1851 ($d->{TYPE
} eq "TYPEDEF") &&
1852 ParseTypedefPush
($d);
1853 ($d->{TYPE
} eq "FUNCTION") &&
1854 ParseFunctionPush
($d);
1858 foreach my $d (@
{$data}) {
1859 ($d->{TYPE
} eq "TYPEDEF") &&
1860 ParseTypedefPull
($d);
1861 ($d->{TYPE
} eq "FUNCTION") &&
1862 ParseFunctionPull
($d);
1866 foreach my $d (@
{$data}) {
1867 if ($d->{TYPE
} eq "TYPEDEF" &&
1868 !util
::has_property
($d, "noprint")) {
1869 ParseTypedefPrint
($d);
1871 if ($d->{TYPE
} eq "FUNCTION" &&
1872 !util
::has_property
($d, "noprint")) {
1873 ParseFunctionPrint
($d);
1878 foreach my $d (@
{$data}) {
1879 ($d->{TYPE
} eq "TYPEDEF") &&
1880 ParseTypedefNdrSize
($d);
1883 FunctionTable
($interface);
1886 sub RegistrationFunction
($$)
1889 my $filename = shift;
1891 $filename =~ /.*\/ndr_
(.*).c
/;
1893 pidl
"NTSTATUS dcerpc_$basename\_init(void)\n";
1895 pidl
"\tNTSTATUS status = NT_STATUS_OK;\n";
1896 foreach my $interface (@
{$idl}) {
1897 next if $interface->{TYPE
} ne "INTERFACE";
1899 my $data = $interface->{INHERITED_DATA
};
1901 foreach my $d (@
{$data}) {
1902 if ($d->{TYPE
} eq "FUNCTION") { $count++; }
1905 next if ($count == 0);
1907 pidl
"\tstatus = dcerpc_ndr_$interface->{NAME}_init();\n";
1908 pidl
"\tif (NT_STATUS_IS_ERR(status)) {\n";
1909 pidl
"\t\treturn status;\n";
1912 pidl
"\treturn status;\n";
1916 sub CheckPointerTypes
($$)
1919 my $default = shift;
1921 foreach my $e (@
{$s->{ELEMENTS
}}) {
1922 if ($e->{POINTERS
}) {
1923 if (not defined(pointer_type
($e))) {
1924 $e->{PROPERTIES
}->{$default} = 1;
1927 if (pointer_type
($e) eq "ptr") {
1928 print "Warning: ptr is not supported by pidl yet\n";
1934 sub LoadInterface
($)
1938 if (not util
::has_property
($x, "pointer_default")) {
1939 $x->{PROPERTIES
}->{pointer_default
} = "ptr";
1942 foreach my $d (@
{$x->{DATA
}}) {
1943 if ($d->{TYPE
} eq "DECLARE" or $d->{TYPE
} eq "TYPEDEF") {
1944 $typedefs{$d->{NAME
}} = $d;
1945 if ($d->{DATA
}->{TYPE
} eq "STRUCT" or $d->{DATA
}->{TYPE
} eq "UNION") {
1946 CheckPointerTypes
($d->{DATA
}, $x->{PROPERTIES
}->{pointer_default
});
1949 if ($d->{TYPE
} eq "FUNCTION") {
1950 CheckPointerTypes
($d, $x->{PROPERTIES
}->{pointer_default
});
1959 foreach my $x (@
{$idl}) {
1964 #####################################################################
1965 # parse a parsed IDL structure back into an IDL file
1969 my($filename) = shift;
1970 my $h_filename = $filename;
1975 if ($h_filename =~ /(.*)\.c/) {
1976 $h_filename = "$1.h";
1979 pidl
"/* parser auto-generated by pidl */\n\n";
1980 pidl
"#include \"includes.h\"\n";
1981 pidl
"#include \"$h_filename\"\n\n";
1983 foreach my $x (@
{$idl}) {
1984 if ($x->{TYPE
} eq "INTERFACE") {
1985 needed
::BuildNeeded
($x);
1990 RegistrationFunction
($idl, $filename);