summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2003-11-10 11:33:21 +0000
committerAndrew Tridgell <tridge@samba.org>2003-11-10 11:33:21 +0000
commitdb7012397ff2295f64821703035607085a7344d8 (patch)
tree27b1962350216defded0c53ed69f82d28d72e27c /source4
parente69987090fa1368dcb3d4025ae45e30bca4333c9 (diff)
downloadsamba-db7012397ff2295f64821703035607085a7344d8.tar.gz
samba-db7012397ff2295f64821703035607085a7344d8.tar.bz2
samba-db7012397ff2295f64821703035607085a7344d8.zip
much cleaner handling of the different types of variables
(This used to be commit 4df59bcff56a00e413fbde1a40ffebcb16763d3c)
Diffstat (limited to 'source4')
-rw-r--r--source4/build/pidl/header.pm9
-rw-r--r--source4/build/pidl/idl.gram1
-rw-r--r--source4/build/pidl/parser.pm120
-rw-r--r--source4/build/pidl/util.pm105
4 files changed, 150 insertions, 85 deletions
diff --git a/source4/build/pidl/header.pm b/source4/build/pidl/header.pm
index 5068bdd1b3..561a16a1e2 100644
--- a/source4/build/pidl/header.pm
+++ b/source4/build/pidl/header.pm
@@ -59,8 +59,15 @@ sub DumpElement($)
$res .= "*";
}
}
+ if (defined $element->{ARRAY_LEN} &&
+ $element->{ARRAY_LEN} eq "*") {
+ $res .= "*";
+ }
$res .= "$element->{NAME}";
- (defined $element->{ARRAY_LEN}) && ($res .= "[$element->{ARRAY_LEN}]");
+ if (defined $element->{ARRAY_LEN} &&
+ $element->{ARRAY_LEN} ne "*") {
+ $res .= "[$element->{ARRAY_LEN}]";
+ }
$res .= ";\n";
}
diff --git a/source4/build/pidl/idl.gram b/source4/build/pidl/idl.gram
index a5e89aadf4..c3723a14af 100644
--- a/source4/build/pidl/idl.gram
+++ b/source4/build/pidl/idl.gram
@@ -132,5 +132,6 @@ type :
text: /[\w\s.?-]*/
constant: /-?\d+/
+ | '*'
cpp_prefix: '#' /.*/
diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm
index 7c691c61bc..32fa66f416 100644
--- a/source4/build/pidl/parser.pm
+++ b/source4/build/pidl/parser.pm
@@ -32,7 +32,7 @@ sub find_size_var($)
{
my($e) = shift;
my($fn) = $e->{PARENT};
- my($size) = util::has_property($e, "size_is");
+ my($size) = util::array_size($e);
if ($fn->{TYPE} ne "FUNCTION") {
return "r->$size";
@@ -75,7 +75,7 @@ sub ParseArrayPull($$)
my $var_prefix = shift;
my $size = find_size_var($e);
- if (!util::has_property($e, "ref")) {
+ if (util::need_alloc($e)) {
$res .= "\t\tNDR_ALLOC_N_SIZE(ndr, $var_prefix$e->{NAME}, $size, sizeof($var_prefix$e->{NAME}\[0]));\n";
}
if (util::is_scalar_type($e->{TYPE})) {
@@ -93,26 +93,16 @@ sub ParseElementPushScalar($$$)
my($e) = shift;
my($var_prefix) = shift;
my($ndr_flags) = shift;
+ my $cprefix = util::c_push_prefix($e);
if (defined $e->{VALUE}) {
$res .= "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $e->{VALUE}));\n";
- } elsif ($e->{POINTERS} &&
- !util::has_property($e, "ref")) {
+ } elsif (util::need_wire_pointer($e)) {
$res .= "\tNDR_CHECK(ndr_push_ptr(ndr, $var_prefix$e->{NAME}));\n";
} elsif (util::is_builtin_type($e->{TYPE})) {
- if (util::is_scalar_type($e->{TYPE}) &&
- util::has_property($e, "ref")) {
- $res .= "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, *$var_prefix$e->{NAME}));\n";
- } else {
- $res .= "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $var_prefix$e->{NAME}));\n";
- }
+ $res .= "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n";
} else {
- if (util::is_scalar_type($e->{TYPE}) ||
- $e->{POINTERS}) {
- $res .= "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $var_prefix$e->{NAME}));\n";
- } else {
- $res .= "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, &$var_prefix$e->{NAME}));\n";
- }
+ $res .= "\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
}
}
@@ -123,34 +113,23 @@ sub ParseElementPullScalar($$$)
my($e) = shift;
my($var_prefix) = shift;
my($ndr_flags) = shift;
+ my $cprefix = util::c_pull_prefix($e);
if (defined $e->{VALUE}) {
$res .= "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $e->{VALUE}));\n";
- } elsif ($e->{POINTERS} &&
- !util::has_property($e, "ref")) {
+ } elsif (util::need_wire_pointer($e)) {
$res .= "\tNDR_CHECK(ndr_pull_uint32(ndr, &_ptr_$e->{NAME}));\n";
$res .= "\tif (_ptr_$e->{NAME}) {\n";
$res .= "\t\tNDR_ALLOC(ndr, $var_prefix$e->{NAME});\n";
$res .= "\t} else {\n";
$res .= "\t\t$var_prefix$e->{NAME} = NULL;\n";
$res .= "\t}\n";
- } elsif (!util::is_scalar_type($e->{TYPE}) &&
- util::has_property($e, "ref")) {
- if (util::is_builtin_type($e->{TYPE})) {
- $res .= "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $var_prefix$e->{NAME}));\n";
- } else {
- $res .= "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $var_prefix$e->{NAME}));\n";
- }
+ } elsif (util::need_alloc($e)) {
+ # no scalar component
+ } elsif (util::is_builtin_type($e->{TYPE})) {
+ $res .= "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n";
} else {
- if (util::is_builtin_type($e->{TYPE})) {
- if (!util::has_property($e, "ref")) {
- $res .= "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, &$var_prefix$e->{NAME}));\n";
- } else {
- $res .= "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $var_prefix$e->{NAME}));\n";
- }
- } else {
- $res .= "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, &$var_prefix$e->{NAME}));\n";
- }
+ $res .= "\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
}
}
@@ -160,34 +139,25 @@ sub ParseElementPushBuffer($$)
{
my($e) = shift;
my($var_prefix) = shift;
+ my $cprefix = util::c_push_prefix($e);
- if (util::has_property($e, "ref")) {
- return;
- }
-
- if (util::is_scalar_type($e->{TYPE}) && !$e->{POINTERS}) {
+ if (util::is_pure_scalar($e)) {
return;
}
- if ($e->{POINTERS}) {
+ if (util::need_wire_pointer($e)) {
$res .= "\tif ($var_prefix$e->{NAME}) {\n";
}
- if (util::has_property($e, "size_is")) {
+ if (util::array_size($e)) {
ParseArrayPush($e, "r->");
+ } elsif (util::is_builtin_type($e->{TYPE})) {
+ $res .= "\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n";
} else {
- if (util::is_scalar_type($e->{TYPE})) {
- $res .= "\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, *$var_prefix$e->{NAME}));\n";
- } elsif (!$e->{POINTERS}) {
- $res .= "\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, ndr_flags, &$var_prefix$e->{NAME}));\n";
- } elsif (util::is_builtin_type($e->{TYPE})) {
- $res .= "\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, $var_prefix$e->{NAME}));\n";
- } else {
- $res .= "\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, ndr_flags, $var_prefix$e->{NAME}));\n";
- }
+ $res .= "\t\tNDR_CHECK(ndr_push_$e->{TYPE}(ndr, ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
}
- if ($e->{POINTERS}) {
+ if (util::need_wire_pointer($e)) {
$res .= "\t}\n";
}
}
@@ -200,37 +170,25 @@ sub ParseElementPullBuffer($$$)
my($e) = shift;
my($var_prefix) = shift;
my($ndr_flags) = shift;
+ my $cprefix = util::c_pull_prefix($e);
- if (util::has_property($e, "ref")) {
+ if (util::is_pure_scalar($e)) {
return;
}
- if (util::is_scalar_type($e->{TYPE}) && !$e->{POINTERS}) {
- return;
- }
-
- if ($e->{POINTERS}) {
+ if (util::need_wire_pointer($e)) {
$res .= "\tif ($var_prefix$e->{NAME}) {\n";
}
- if (util::has_property($e, "size_is")) {
+ if (util::array_size($e)) {
ParseArrayPull($e, "r->");
+ } elsif (util::is_builtin_type($e->{TYPE})) {
+ $res .= "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $cprefix$var_prefix$e->{NAME}));\n";
} else {
- if (!$e->{POINTERS} ||
- $e->{TYPE} =~ "unistr.*") {
- if (util::is_builtin_type($e->{TYPE})) {
- $res .= "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, &$var_prefix$e->{NAME}));\n";
- } else {
- $res .= "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, &$var_prefix$e->{NAME}));\n";
- }
- } elsif (util::is_builtin_type($e->{TYPE})) {
- $res .= "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $var_prefix$e->{NAME}));\n";
- } else {
- $res .= "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $var_prefix$e->{NAME}));\n";
- }
+ $res .= "\t\tNDR_CHECK(ndr_pull_$e->{TYPE}(ndr, $ndr_flags, $cprefix$var_prefix$e->{NAME}));\n";
}
- if ($e->{POINTERS}) {
+ if (util::need_wire_pointer($e)) {
$res .= "\t}\n";
}
}
@@ -301,8 +259,7 @@ sub ParseStructPull($)
# declare any internal pointers we need
foreach my $e (@{$struct->{ELEMENTS}}) {
$e->{PARENT} = $struct;
- if ($e->{POINTERS} &&
- !util::has_property($e, "ref")) {
+ if (util::need_wire_pointer($e)) {
$res .= "\tuint32 _ptr_$e->{NAME};\n";
}
}
@@ -440,7 +397,7 @@ sub ParseFunctionPush($)
foreach my $e (@{$function->{DATA}}) {
if (util::has_property($e, "in")) {
$e->{PARENT} = $function;
- if (util::has_property($e, "size_is")) {
+ if (util::array_size($e)) {
$res .= "\tif (r->in.$e->{NAME}) {\n";
if (!util::is_scalar_type($e->{TYPE})) {
$res .= "\t\tint ndr_flags = NDR_SCALARS|NDR_BUFFERS;\n";
@@ -468,18 +425,17 @@ sub ParseFunctionPull($)
# declare any internal pointers we need
foreach my $e (@{$fn->{DATA}}) {
- if (util::has_property($e, "out") &&
- $e->{POINTERS} &&
- !util::is_scalar_type($e->{TYPE}) &&
- !util::has_property($e, "ref")) {
- $res .= "\tuint32 _ptr_$e->{NAME};\n";
+ if (util::has_property($e, "out")) {
+ if (util::need_wire_pointer($e)) {
+ $res .= "\tuint32 _ptr_$e->{NAME};\n";
+ }
}
}
foreach my $e (@{$fn->{DATA}}) {
if (util::has_property($e, "out")) {
$e->{PARENT} = $fn;
- if (util::has_property($e, "size_is")) {
+ if (util::array_size($e)) {
$res .= "\tif (r->out.$e->{NAME}) {\n";
if (!util::is_scalar_type($e->{TYPE})) {
$res .= "\t\tint ndr_flags = NDR_SCALARS|NDR_BUFFERS;\n";
@@ -487,10 +443,6 @@ sub ParseFunctionPull($)
ParseArrayPull($e, "r->out.");
$res .= "\t}\n";
} else {
- if ($e->{POINTERS} &&
- !util::has_property($e, "ref")) {
- $res .= "\tNDR_ALLOC(ndr, r->out.$e->{NAME});\n";
- }
ParseElementPullScalar($e, "r->out.", "NDR_SCALARS|NDR_BUFFERS");
ParseElementPullBuffer($e, "r->out.", "NDR_SCALARS|NDR_BUFFERS");
}
diff --git a/source4/build/pidl/util.pm b/source4/build/pidl/util.pm
index a724052e2f..5bf8ac4d9a 100644
--- a/source4/build/pidl/util.pm
+++ b/source4/build/pidl/util.pm
@@ -186,6 +186,8 @@ sub is_scalar_type($)
return 0;
}
+# this is used to determine if the ndr push/pull functions will need
+# a ndr_flags field to split by buffers/scalars
sub is_builtin_type($)
{
my($type) = shift;
@@ -200,6 +202,109 @@ sub is_builtin_type($)
return 0;
}
+# determine if an element needs a reference pointer on the wire
+# in its NDR representation
+sub need_wire_pointer($)
+{
+ my $e = shift;
+ if ($e->{POINTERS} &&
+ !has_property($e, "ref")) {
+ return $e->{POINTERS};
+ }
+ return undef;
+}
+
+
+# determine if an element is a pass-by-reference structure
+sub is_ref_struct($)
+{
+ my $e = shift;
+ if (!is_scalar_type($e->{TYPE}) &&
+ has_property($e, "ref")) {
+ return 1;
+ }
+ return 0;
+}
+
+# determine if an element is a pure scalar. pure scalars do not
+# have a "buffers" section in NDR
+sub is_pure_scalar($)
+{
+ my $e = shift;
+ if (has_property($e, "ref")) {
+ return 1;
+ }
+ if (is_scalar_type($e->{TYPE}) && !$e->{POINTERS}) {
+ return 1;
+ }
+ return 0;
+}
+
+# determine the array size (size_is() or ARRAY_LEN)
+sub array_size($)
+{
+ my $e = shift;
+ my $size = has_property($e, "size_is");
+ if ($size) {
+ return $size;
+ }
+ $size = $e->{ARRAY_LEN};
+ if ($size) {
+ return $size;
+ }
+ return undef;
+}
+
+# see if a variable needs to be allocated by the NDR subsystem on pull
+sub need_alloc($)
+{
+ my $e = shift;
+
+ if (has_property($e, "ref")) {
+ return 0;
+ }
+
+ if ($e->{POINTERS} || array_size($e)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+# determine the C prefix used to refer to a variable when passing to a push
+# function. This will be '*' for pointers to scalar types, '' for scalar
+# types and normal pointers and '&' for pass-by-reference structures
+sub c_push_prefix($)
+{
+ my $e = shift;
+ if (is_scalar_type($e->{TYPE}) &&
+ $e->{POINTERS}) {
+ return "*";
+ }
+ if (!is_scalar_type($e->{TYPE}) &&
+ !$e->{POINTERS} &&
+ !array_size($e)) {
+ return "&";
+ }
+ return "";
+}
+
+# determine the C prefix used to refer to a variable when passing to a pull
+# return '&' or ''
+sub c_pull_prefix($)
+{
+ my $e = shift;
+
+ if (!$e->{POINTERS} && !array_size($e)) {
+ return "&";
+ }
+
+ if ($e->{TYPE} =~ "unistr.*") {
+ return "&";
+ }
+
+ return "";
+}
1;