summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/build/pidl/eparser.pm33
-rw-r--r--source4/build/pidl/header.pm116
-rw-r--r--source4/build/pidl/idl.gram11
-rw-r--r--source4/build/pidl/parser.pm190
-rwxr-xr-xsource4/build/pidl/pidl.pl7
-rw-r--r--source4/build/pidl/util.pm60
6 files changed, 340 insertions, 77 deletions
diff --git a/source4/build/pidl/eparser.pm b/source4/build/pidl/eparser.pm
index 3cb71a6c7e..bc69d831c8 100644
--- a/source4/build/pidl/eparser.pm
+++ b/source4/build/pidl/eparser.pm
@@ -1,5 +1,5 @@
###################################################
-# Ethereal parser generator for IDL structures
+# parser generator for IDL structures
# Copyright tpot@samba.org 2001
# Copyright tridge@samba.org 2000
# released under the GNU GPL
@@ -10,21 +10,6 @@ use Data::Dumper;
my($res);
-sub is_scalar_type($)
-{
- my($type) = shift;
-
- return 1, if ($type eq "uint32");
- return 1, if ($type eq "long");
- return 1, if ($type eq "short");
- return 1, if ($type eq "char");
- return 1, if ($type eq "uint16");
- return 1, if ($type eq "hyper");
- return 1, if ($type eq "wchar_t");
-
- return 0;
-}
-
sub has_property($$)
{
my($props) = shift;
@@ -67,7 +52,7 @@ sub ParseArray($)
my($elt) = shift;
$res .= "\tfor (i = 0; i < count; i++) {\n";
- if (is_scalar_type($elt)) {
+ if (util::is_scalar_type($elt)) {
$res .= "\t\toffset = prs_$elt->{TYPE}(tvb, offset, pinfo, tree, NULL, \"$elt->{NAME});\n";
$res .= "\t}\n\n";
} else {
@@ -89,7 +74,7 @@ sub ParseElement($$)
# Arg is a policy handle
- if (has_property($elt->{PROPERTIES}, "context_handle")) {
+ if (util::has_property($elt->{PROPERTIES}, "context_handle")) {
$res .= "\toffset = prs_policy_hnd(tvb, offset, pinfo, tree);\n";
return;
}
@@ -106,7 +91,7 @@ sub ParseElement($$)
# Simple type are scalars too
- if (is_scalar_type($elt->{TYPE})) {
+ if (util::is_scalar_type($elt->{TYPE})) {
$res .= "\t\toffset = prs_$elt->{TYPE}(tvb, offset, pinfo, tree, NULL, \"$elt->{NAME}\");\n\n";
}
}
@@ -117,7 +102,7 @@ sub ParseElement($$)
# Scalars are not buffers, except if they are pointed to
- if (!is_scalar_type($elt->{TYPE}) || $elt->{POINTERS}) {
+ if (!util::is_scalar_type($elt->{TYPE}) || $elt->{POINTERS}) {
# If we have a pointer, check it
@@ -125,11 +110,11 @@ sub ParseElement($$)
$res .= "\t\tif (ptr_$elt->{NAME})\n\t";
}
- if (has_property($elt->{PROPERTIES}, "size_is")) {
+ if (util::has_property($elt->{PROPERTIES}, "size_is")) {
ParseArray($elt);
} else {
$res .= "\t\toffset = prs_$elt->{TYPE}(tvb, offset, pinfo, tree, ";
- if (is_scalar_type($elt->{TYPE})) {
+ if (util::is_scalar_type($elt->{TYPE})) {
$res .= "NULL, ";
} else {
$res .= "flags, ";
@@ -236,12 +221,12 @@ sub ParseFunctionArg($$)
my($arg) = shift;
my($io) = shift; # "in" or "out"
- if (has_property($arg->{PROPERTIES}, $io)) {
+ if (util::has_property($arg->{PROPERTIES}, $io)) {
# For some reason, pointers to elements in function definitions
# aren't parsed.
- if (defined($arg->{POINTERS}) && !is_scalar_type($arg->{TYPE})) {
+ if (defined($arg->{POINTERS}) && !util::is_scalar_type($arg->{TYPE})) {
$arg->{POINTERS} -= 1, if ($arg->{POINTERS} > 0);
delete($arg->{POINTERS}), if ($arg->{POINTERS} == 0);
}
diff --git a/source4/build/pidl/header.pm b/source4/build/pidl/header.pm
index 34707f8672..783fff2204 100644
--- a/source4/build/pidl/header.pm
+++ b/source4/build/pidl/header.pm
@@ -7,12 +7,23 @@ package IdlHeader;
use Data::Dumper;
my($res);
+my($tab_depth);
+
+sub tabs()
+{
+ for (my($i)=0; $i < $tab_depth; $i++) {
+ $res .= "\t";
+ }
+}
#####################################################################
# dump a properties list
sub DumpProperties($)
{
my($props) = shift;
+
+ return;
+
foreach my $d (@{$props}) {
if (ref($d) ne "HASH") {
$res .= "/* [$d] */ ";
@@ -29,30 +40,48 @@ sub DumpProperties($)
sub DumpElement($)
{
my($element) = shift;
+
+ if (util::has_property($element->{PROPERTIES}, "struct_len")) {
+ # a struct_len is an internal artifact - it is put on the
+ # wire but not exposed via the api, which means it does
+ # not appear in the header file
+ return;
+ }
+
+
(defined $element->{PROPERTIES}) && DumpProperties($element->{PROPERTIES});
- DumpType($element->{TYPE});
+ $res .= tabs();
+ DumpType($element->{TYPE}, "");
$res .= " ";
if ($element->{POINTERS}) {
- for (my($i)=0; $i < $element->{POINTERS}; $i++) {
- $res .= "*";
- }
+ my($n) = $element->{POINTERS};
+ if (util::is_scalar_type($element->{TYPE}) &&
+ util::has_property($element->{PROPERTIES}, "ref")) {
+ $n--;
+ }
+ for (my($i)=$n; $i > 0; $i--) {
+ $res .= "*";
+ }
}
$res .= "$element->{NAME}";
(defined $element->{ARRAY_LEN}) && ($res .= "[$element->{ARRAY_LEN}]");
+ $res .= ";\n";
}
#####################################################################
# dump a struct
-sub DumpStruct($)
+sub DumpStruct($$)
{
my($struct) = shift;
- $res .= "struct {\n";
+ my($name) = shift;
+ $res .= "struct $name {\n";
+ $tab_depth++;
if (defined $struct->{ELEMENTS}) {
foreach my $e (@{$struct->{ELEMENTS}}) {
DumpElement($e);
- $res .= ";\n";
}
}
+ $tab_depth--;
$res .= "}";
}
@@ -64,16 +93,16 @@ sub DumpUnionElement($)
my($element) = shift;
$res .= "/* [case($element->{CASE})] */ ";
DumpElement($element->{DATA});
- $res .= ";\n";
}
#####################################################################
# dump a union
-sub DumpUnion($)
+sub DumpUnion($$)
{
my($union) = shift;
+ my($name) = shift;
(defined $union->{PROPERTIES}) && DumpProperties($union->{PROPERTIES});
- $res .= "union {\n";
+ $res .= "union $name {\n";
foreach my $e (@{$union->{DATA}}) {
DumpUnionElement($e);
}
@@ -82,16 +111,23 @@ sub DumpUnion($)
#####################################################################
# dump a type
-sub DumpType($)
+sub DumpType($$)
{
my($data) = shift;
+ my($name) = shift;
if (ref($data) eq "HASH") {
($data->{TYPE} eq "STRUCT") &&
- DumpStruct($data);
+ DumpStruct($data, $name);
($data->{TYPE} eq "UNION") &&
- DumpUnion($data);
+ DumpUnion($data, $name);
+ return;
+ }
+ if ($data =~ "unistr") {
+ $res .= "const char";
+ } elsif (util::is_scalar_type($data)) {
+ $res .= "$data";
} else {
- $res .= "$data";
+ $res .= "struct $data";
}
}
@@ -100,9 +136,51 @@ sub DumpType($)
sub DumpTypedef($)
{
my($typedef) = shift;
- $res .= "typedef ";
- DumpType($typedef->{DATA});
- $res .= " $typedef->{NAME};\n\n";
+ DumpType($typedef->{DATA}, $typedef->{NAME});
+ $res .= ";\n\n";
+}
+
+#####################################################################
+# dump a function
+sub DumpFunctionInOut($$)
+{
+ my($fn) = shift;
+ my($prop) = shift;
+ foreach my $e (@{$fn->{DATA}}) {
+ if (util::has_property($e->{PROPERTIES}, $prop)) {
+ DumpElement($e);
+ }
+ }
+}
+
+
+#####################################################################
+# dump a function
+sub DumpFunction($)
+{
+ my($fn) = shift;
+ $res .= "struct $fn->{NAME} {\n";
+ $tab_depth++;
+ tabs();
+ $res .= "struct {\n";
+ $tab_depth++;
+ DumpFunctionInOut($fn, "in");
+ $tab_depth--;
+ tabs();
+ $res .= "} in;\n\n";
+ tabs();
+ $res .= "struct {\n";
+ $tab_depth++;
+ DumpFunctionInOut($fn, "out");
+ if ($fn->{RETURN_TYPE}) {
+ tabs();
+ $res .= "$fn->{RETURN_TYPE} result;\n";
+ }
+ $tab_depth--;
+ tabs();
+ $res .= "} out;\n\n";
+ $tab_depth--;
+ $res .= "};\n\n";
}
#####################################################################
@@ -114,6 +192,8 @@ sub DumpInterface($)
foreach my $d (@{$data}) {
($d->{TYPE} eq "TYPEDEF") &&
DumpTypedef($d);
+ ($d->{TYPE} eq "FUNCTION") &&
+ DumpFunction($d);
}
}
@@ -123,6 +203,8 @@ sub DumpInterface($)
sub Dump($)
{
my($idl) = shift;
+ $tab_depth = 0;
+
$res = "/* header auto-generated by pidl */\n\n";
foreach my $x (@{$idl}) {
($x->{TYPE} eq "INTERFACE") &&
diff --git a/source4/build/pidl/idl.gram b/source4/build/pidl/idl.gram
index 00b3952ba2..b700cb378e 100644
--- a/source4/build/pidl/idl.gram
+++ b/source4/build/pidl/idl.gram
@@ -33,14 +33,14 @@ typedef : 'typedef' <commit> type identifier array_len(?) ';'
"TYPE" => "TYPEDEF",
"NAME" => $item{identifier},
"DATA" => $item{type},
- "ARRAY_LEN" => $item{array_len}[0]
+ "ARRAY_LEN" => $item[5][0]
}}
| <error?>
struct: 'struct' <commit> '{' element_list1(?) '}'
{{
"TYPE" => "STRUCT",
- "ELEMENTS" => util::FlattenArray($item{element_list1})
+ "ELEMENTS" => util::FlattenArray2($item[4])
}}
| <error?>
@@ -48,7 +48,7 @@ union: property_list(s?) 'union' <commit> '{' union_element(s?) '}'
{{
"TYPE" => "UNION",
"PROPERTIES" => util::FlattenArray($item[1]),
- "DATA" => $item{union_element}
+ "DATA" => $item[5]
}}
| <error?>
@@ -70,8 +70,8 @@ base_element: property_list(s?) type pointer(s?) identifier array_len(?)
"NAME" => $item{identifier},
"TYPE" => $item{type},
"PROPERTIES" => util::FlattenArray($item[1]),
- "POINTERS" => $#{$item{pointer}}==-1?undef:$#{$item{pointer}}+1,
- "ARRAY_LEN" => $item{array_len}[0]
+ "POINTERS" => $#{$item[3]}==-1?undef:$#{$item[3]}+1,
+ "ARRAY_LEN" => $item[5][0]
}}
| <error>
@@ -97,6 +97,7 @@ property: 'unique'
| 'in'
| 'out'
| 'ref'
+ | 'struct_len'
| 'context_handle'
| 'string'
| 'byte_count_pointer' '(' expression ')' {{ "$item[1]" => "$item{expression}" }}
diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm
index 03bc5f3aff..695d943ee2 100644
--- a/source4/build/pidl/parser.pm
+++ b/source4/build/pidl/parser.pm
@@ -1,5 +1,6 @@
###################################################
-# C parser generator for IDL structures
+# Ethereal parser generator for IDL structures
+# Copyright tpot@samba.org 2001
# Copyright tridge@samba.org 2000
# released under the GNU GPL
@@ -26,35 +27,120 @@ sub ParseProperties($)
}
#####################################################################
-# parse a structure element
-sub ParseElement($)
+# parse an array - called in buffers context
+sub ParseArray($)
{
- my($element) = shift;
- (defined $element->{PROPERTIES}) && ParseProperties($element->{PROPERTIES});
- ParseType($element->{TYPE});
- $res .= " ";
- if ($element->{POINTERS}) {
- for (my($i)=0; $i < $element->{POINTERS}; $i++) {
- $res .= "*";
- }
+ my($elt) = shift;
+
+ $res .= "\tfor (i = 0; i < count; i++) {\n";
+ if (util::is_scalar_type($elt)) {
+ $res .= "\t\toffset = prs_$elt->{TYPE}(tvb, offset, pinfo, tree, NULL, \"$elt->{NAME});\n";
+ $res .= "\t}\n\n";
+ } else {
+ $res .= "\t\toffset = prs_$elt->{TYPE}(tvb, offset, pinfo, tree, \"PARSE_SCALARS\", \"$elt->{NAME}\");\n";
+ $res .= "\t}\n\n";
+
+ $res .= "\tfor (i = 0; i < count; i++) {\n";
+ $res .= "\t\toffset = prs_$elt->{TYPE}(tvb, offset, pinfo, tree, \"PARSE_BUFFERS\", \"$elt->{NAME}\");\n";
+ $res .= "\t}\n\n";
}
- $res .= "$element->{NAME}";
- (defined $element->{ARRAY_LEN}) && ($res .= "[$element->{ARRAY_LEN}]");
+}
+
+
+#####################################################################
+# parse scalars in a structure element
+sub ParseElementScalars($$)
+{
+ my($elt) = shift;
+ my($var_prefix) = shift;
+
+ if (defined $elt->{VALUE}) {
+ $res .= "\tNDR_CHECK(ndr_push_$elt->{TYPE}(ndr, $elt->{VALUE}));\n";
+ } elsif ($elt->{POINTERS} &&
+ !util::has_property($elt->{PROPERTIES}, "ref")) {
+ $res .= "\tNDR_CHECK(ndr_push_ptr(ndr, $var_prefix$elt->{NAME}));\n";
+ } else {
+ $res .= "\tNDR_CHECK(ndr_push_$elt->{TYPE}(ndr, $var_prefix$elt->{NAME}));\n";
+ }
+}
+
+#####################################################################
+# parse buffers in a structure element
+sub ParseElementBuffers($$)
+{
+ my($elt) = shift;
+ my($var_prefix) = shift;
+
+ if (util::has_property($elt->{PROPERTIES}, "ref")) {
+ return;
+ }
+
+ if (util::is_scalar_type($elt->{TYPE}) && !$elt->{POINTERS}) {
+ return;
+ }
+
+ if ($elt->{POINTERS}) {
+ $res .= "\tif ($var_prefix$elt->{NAME}) {\n\t";
+ }
+
+ if (util::has_property($elt->{PROPERTIES}, "size_is")) {
+ ParseArray($elt);
+ } else {
+ if (util::is_scalar_type($elt->{TYPE})) {
+ $res .= "\tNDR_CHECK(ndr_push_$elt->{TYPE}(ndr, *$var_prefix$elt->{NAME}));\n";
+ } else {
+ $res .= "\tNDR_CHECK(ndr_push_$elt->{TYPE}(ndr, $var_prefix$elt->{NAME}));\n";
+ }
+ }
+
+ if ($elt->{POINTERS}) {
+ $res .= "\t}\n";
+ }
}
#####################################################################
# parse a struct
sub ParseStruct($)
{
- my($struct) = shift;
- $res .= "struct {\n";
- if (defined $struct->{ELEMENTS}) {
+ my($struct) = shift;
+ my($struct_len);
+
+ if (! defined $struct->{ELEMENTS}) {
+ return;
+ }
+
+ # see if we have a structure length
foreach my $e (@{$struct->{ELEMENTS}}) {
- ParseElement($e);
- $res .= ";\n";
+ if (util::has_property($e->{PROPERTIES}, "struct_len")) {
+ $struct_len = $e;
+ $e->{VALUE} = "0";
+ }
+ }
+
+ if (defined $struct_len) {
+ $res .= "\tstruct ndr_push_save len_save1, len_save2, len_save3;\n";
+ $res .= "\tndr_push_save(ndr, &len_save1);\n";
+ }
+
+ foreach my $e (@{$struct->{ELEMENTS}}) {
+ if ($e == $struct_len) {
+ $res .= "\tNDR_CHECK(ndr_push_align_$e->{TYPE}(ndr));\n";
+ $res .= "\tndr_push_save(ndr, &len_save2);\n";
+ }
+ ParseElementScalars($e, "r->");
+ }
+
+ foreach my $e (@{$struct->{ELEMENTS}}) {
+ ParseElementBuffers($e, "r->");
+ }
+
+ if (defined $struct_len) {
+ $res .= "\tndr_push_save(ndr, &len_save3);\n";
+ $res .= "\tndr_push_restore(ndr, &len_save2);\n";
+ $struct_len->{VALUE} = "len_save3.offset - len_save1.offset";
+ ParseElementScalars($struct_len, "r->");
+ $res .= "\tndr_push_restore(ndr, &len_save3);\n";
}
- }
- $res .= "}";
}
@@ -63,9 +149,10 @@ sub ParseStruct($)
sub ParseUnionElement($)
{
my($element) = shift;
- $res .= "[case($element->{CASE})] ";
- ParseElement($element->{DATA});
- $res .= ";\n";
+
+ $res .= "\tcase $element->{DATA}->{NAME}: \n";
+ $res .= "\t\toffset = prs_$element->{DATA}->{TYPE}(tvb, offset, pinfo, tree, \"$element->{DATA}->{NAME}\");\n\t\tbreak;\n";
+
}
#####################################################################
@@ -73,12 +160,15 @@ sub ParseUnionElement($)
sub ParseUnion($)
{
my($union) = shift;
+
+ $res .= "\tswitch (level) {\n";
+
(defined $union->{PROPERTIES}) && ParseProperties($union->{PROPERTIES});
- $res .= "union {\n";
foreach my $e (@{$union->{DATA}}) {
ParseUnionElement($e);
}
- $res .= "}";
+
+ $res .= "\t}\n";
}
#####################################################################
@@ -86,6 +176,7 @@ sub ParseUnion($)
sub ParseType($)
{
my($data) = shift;
+
if (ref($data) eq "HASH") {
($data->{TYPE} eq "STRUCT") &&
ParseStruct($data);
@@ -101,17 +192,58 @@ sub ParseType($)
sub ParseTypedef($)
{
my($typedef) = shift;
- $res .= "typedef ";
+
+ $res .= "static NTSTATUS ndr_push_$typedef->{NAME}(struct ndr_push *ndr, struct $typedef->{NAME} *r)";
+ $res .= "\n{\n";
ParseType($typedef->{DATA});
- $res .= " $typedef->{NAME};\n\n";
+ $res .= "\treturn NT_STATUS_OK;\n";
+ $res .= "}\n\n";
}
#####################################################################
# parse a function
-sub ParseFunction($)
+sub ParseFunctionArg($$)
+{
+ my($arg) = shift;
+ my($io) = shift; # "in" or "out"
+
+ if (!util::has_property($arg->{PROPERTIES}, $io)) {
+ return;
+ }
+
+ ParseElementScalars($arg, "r->in.");
+ ParseElementBuffers($arg, "r->in.");
+}
+
+#####################################################################
+# parse a function
+sub ParseFunctionPush($)
{
my($function) = shift;
- $res .= "/* ignoring function $function->{NAME} */\n";
+
+ # Input function
+ $res .= "NTSTATUS ndr_push_$function->{NAME}(struct ndr_push *ndr, struct $function->{NAME} *r)\n{\n";
+
+ foreach my $arg (@{$function->{DATA}}) {
+ ParseFunctionArg($arg, "in");
+ }
+
+ $res .= "\n\treturn NT_STATUS_OK;\n}\n\n";
+}
+
+#####################################################################
+# parse a function
+sub ParseFunctionPull($)
+{
+}
+
+#####################################################################
+# parse a function
+sub ParseFunction($)
+{
+ my $i = shift;
+ ParseFunctionPush($i);
+ ParseFunctionPull($i);
}
#####################################################################
diff --git a/source4/build/pidl/pidl.pl b/source4/build/pidl/pidl.pl
index 6b32ade75a..a332671e34 100755
--- a/source4/build/pidl/pidl.pl
+++ b/source4/build/pidl/pidl.pl
@@ -7,6 +7,10 @@
# released under the GNU GPL
use strict;
+
+my($PIDLBASE) = "$ENV{HOME}/pidl";
+use lib "$ENV{HOME}/pidl";
+
use Getopt::Long;
use Data::Dumper;
use Parse::RecDescent;
@@ -35,9 +39,10 @@ sub IdlParse($)
$item[1] :
"XX_" . $item[0] . "_XX[$#item]" };
my($filename) = shift;
- my($grammer) = util::FileLoad("idl.gram");
+ my($grammer) = util::FileLoad("$PIDLBASE/idl.gram");
my($parser) = Parse::RecDescent->new($grammer);
my($saved_sep) = $/;
+
undef $/;
my($idl) = $parser->idl(`cpp $filename`);
$/ = $saved_sep;
diff --git a/source4/build/pidl/util.pm b/source4/build/pidl/util.pm
index f0e3c2a2f8..53e391eb42 100644
--- a/source4/build/pidl/util.pm
+++ b/source4/build/pidl/util.pm
@@ -6,6 +6,25 @@ package util;
use Data::Dumper;
+sub dumpit($)
+{
+ my $a = shift;
+ return Dumper $a;
+}
+
+#####################################################################
+# flatten an array of arrays into a single array
+sub FlattenArray2($)
+{
+ my $a = shift;
+ my @b;
+ for my $d (@{$a}) {
+ for my $d1 (@{$d}) {
+ push(@b, $d1);
+ }
+ }
+ return \@b;
+}
#####################################################################
# flatten an array of arrays into a single array
@@ -75,7 +94,7 @@ sub FileLoad($)
{
my($filename) = shift;
local(*INPUTFILE);
- open(INPUTFILE, $filename) || die "can't open $filename";
+ open(INPUTFILE, $filename) || die "can't load $filename";
my($saved_delim) = $/;
undef $/;
my($data) = <INPUTFILE>;
@@ -124,5 +143,44 @@ sub LoadStructure($)
return eval FileLoad(shift);
}
+#####################################################################
+# see if a pidl property list contains a give property
+sub has_property($$)
+{
+ my($props) = shift;
+ my($p) = shift;
+
+ foreach my $d (@{$props}) {
+ if (ref($d) ne "HASH") {
+ return 1, if ($d eq $p);
+ return 1, if ($d eq "in,out" && ($p eq "in" || $p eq "out"));
+ } else {
+ foreach my $k (keys %{$d}) {
+ return $d->{$k}, if ($k eq $p);
+ }
+ }
+ }
+
+ return 0;
+}
+
+
+sub is_scalar_type($)
+{
+ my($type) = shift;
+
+ return 1, if ($type eq "uint32");
+ return 1, if ($type eq "long");
+ return 1, if ($type eq "short");
+ return 1, if ($type eq "char");
+ return 1, if ($type eq "uint8");
+ return 1, if ($type eq "uint16");
+ return 1, if ($type eq "hyper");
+ return 1, if ($type eq "wchar_t");
+
+ return 0;
+}
+
1;
+