mirror of
https://github.com/samba-team/samba.git
synced 2025-01-11 05:18:09 +03:00
r597: Start generating parser code - only supports uint16, uint32 and policy
handle types.
This commit is contained in:
parent
defaf0d817
commit
1e02ccd94e
@ -7,264 +7,93 @@
|
||||
package IdlEParser;
|
||||
|
||||
use strict;
|
||||
use dump;
|
||||
use Data::Dumper;
|
||||
|
||||
my($res);
|
||||
|
||||
sub has_property($$)
|
||||
sub ParamSimpleNdrType($)
|
||||
{
|
||||
my($props) = shift;
|
||||
my($p) = shift;
|
||||
my($res);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
$res .= "\toffset = dissect_ndr_$p->{TYPE}(tvb, offset, pinfo, tree, drep, hf_$p->{NAME}, NULL);\n";
|
||||
|
||||
return 0;
|
||||
return $res;
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a properties list
|
||||
sub ParseProperties($)
|
||||
sub ParamPolicyHandle($)
|
||||
{
|
||||
my($props) = shift;
|
||||
foreach my $d (@{$props}) {
|
||||
if (ref($d) ne "HASH") {
|
||||
$res .= "[$d] ";
|
||||
} else {
|
||||
foreach my $k (keys %{$d}) {
|
||||
$res .= "[$k($d->{$k})] ";
|
||||
}
|
||||
}
|
||||
}
|
||||
my($p) = shift;
|
||||
my($res);
|
||||
|
||||
$res .= "\toffset = dissect_nt_policy_handle(tvb, offset, pinfo, tree, drep, hf_policy_hnd, NULL, NULL, FALSE, FALSE);\n";
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse an array - called in buffers context
|
||||
sub ParseArray($)
|
||||
{
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a structure element
|
||||
sub ParseElement($$)
|
||||
{
|
||||
my($elt) = shift;
|
||||
my($flags) = shift;
|
||||
|
||||
# Arg is a policy handle
|
||||
|
||||
if (util::has_property($elt, "context_handle")) {
|
||||
$res .= "\toffset = prs_policy_hnd(tvb, offset, pinfo, tree);\n";
|
||||
return;
|
||||
}
|
||||
|
||||
# Parse type
|
||||
|
||||
if ($flags =~ /scalars/) {
|
||||
|
||||
# Pointers are scalars
|
||||
|
||||
if ($elt->{POINTERS}) {
|
||||
$res .= "\t\toffset = prs_ptr(tvb, offset, pinfo, tree, &ptr_$elt->{NAME}, \"$elt->{NAME}\");\n";
|
||||
} else {
|
||||
|
||||
# Simple type are scalars too
|
||||
|
||||
if (util::is_scalar_type($elt->{TYPE})) {
|
||||
$res .= "\t\toffset = prs_$elt->{TYPE}(tvb, offset, pinfo, tree, NULL, \"$elt->{NAME}\");\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($flags =~ /buffers/) {
|
||||
|
||||
# Scalars are not buffers, except if they are pointed to
|
||||
|
||||
if (!util::is_scalar_type($elt->{TYPE}) || $elt->{POINTERS}) {
|
||||
|
||||
# If we have a pointer, check it
|
||||
|
||||
if ($elt->{POINTERS}) {
|
||||
$res .= "\t\tif (ptr_$elt->{NAME})\n\t";
|
||||
}
|
||||
|
||||
if (util::has_property($elt, "size_is")) {
|
||||
ParseArray($elt);
|
||||
} else {
|
||||
$res .= "\t\toffset = prs_$elt->{TYPE}(tvb, offset, pinfo, tree, ";
|
||||
if (util::is_scalar_type($elt->{TYPE})) {
|
||||
$res .= "NULL, ";
|
||||
} else {
|
||||
$res .= "flags, ";
|
||||
}
|
||||
$res .= "\"$elt->{NAME}\");\n\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a struct
|
||||
sub ParseStruct($)
|
||||
{
|
||||
my($struct) = shift;
|
||||
|
||||
if (defined $struct->{ELEMENTS}) {
|
||||
|
||||
# Parse scalars
|
||||
|
||||
$res .= "\tif (flags & PARSE_SCALARS) {\n";
|
||||
|
||||
foreach my $e (@{$struct->{ELEMENTS}}) {
|
||||
ParseElement($e, "scalars");
|
||||
}
|
||||
|
||||
$res .= "\t}\n\n";
|
||||
|
||||
# Parse buffers
|
||||
|
||||
$res .= "\tif (flags & PARSE_BUFFERS) {\n";
|
||||
|
||||
foreach my $e (@{$struct->{ELEMENTS}}) {
|
||||
ParseElement($e, "buffers");
|
||||
}
|
||||
|
||||
$res .= "\t}\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#####################################################################
|
||||
# parse a union element
|
||||
sub ParseUnionElement($)
|
||||
{
|
||||
my($element) = shift;
|
||||
|
||||
$res .= "\tcase $element->{DATA}->{NAME}: \n";
|
||||
$res .= "\t\toffset = prs_$element->{DATA}->{TYPE}(tvb, offset, pinfo, tree, \"$element->{DATA}->{NAME}\");\n\t\tbreak;\n";
|
||||
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a union
|
||||
sub ParseUnion($)
|
||||
{
|
||||
my($union) = shift;
|
||||
|
||||
$res .= "\tswitch (level) {\n";
|
||||
|
||||
(defined $union->{PROPERTIES}) && ParseProperties($union->{PROPERTIES});
|
||||
foreach my $e (@{$union->{DATA}}) {
|
||||
ParseUnionElement($e);
|
||||
}
|
||||
|
||||
$res .= "\t}\n";
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a type
|
||||
sub ParseType($)
|
||||
{
|
||||
my($data) = shift;
|
||||
|
||||
if (ref($data) eq "HASH") {
|
||||
($data->{TYPE} eq "STRUCT") &&
|
||||
ParseStruct($data);
|
||||
($data->{TYPE} eq "UNION") &&
|
||||
ParseUnion($data);
|
||||
} else {
|
||||
$res .= "$data";
|
||||
}
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
# parse a typedef
|
||||
sub ParseTypedef($)
|
||||
{
|
||||
my($typedef) = shift;
|
||||
|
||||
$res .= "static int prs_$typedef->{NAME}(tvbuff_t *tvb, int offset,\
|
||||
\tpacket_info *pinfo, proto_tree *tree, int flags, char *name)\n{\n";
|
||||
ParseType($typedef->{DATA});
|
||||
$res .= "\treturn offset;\n";
|
||||
$res .= "}\n\n";
|
||||
}
|
||||
my %param_handlers = (
|
||||
'uint16' => \&ParamSimpleNdrType,
|
||||
'uint32' => \&ParamSimpleNdrType,
|
||||
'policy_handle' => \&ParamPolicyHandle,
|
||||
);
|
||||
|
||||
#####################################################################
|
||||
# parse a function
|
||||
sub ParseFunctionArg($$)
|
||||
sub ParseParameter($)
|
||||
{
|
||||
my($arg) = shift;
|
||||
my($io) = shift; # "in" or "out"
|
||||
my($p) = shift;
|
||||
my($res);
|
||||
|
||||
if (util::has_property($arg, $io)) {
|
||||
|
||||
# For some reason, pointers to elements in function definitions
|
||||
# aren't parsed.
|
||||
|
||||
if (defined($arg->{POINTERS}) && !util::is_scalar_type($arg->{TYPE})) {
|
||||
$arg->{POINTERS} -= 1, if ($arg->{POINTERS} > 0);
|
||||
delete($arg->{POINTERS}), if ($arg->{POINTERS} == 0);
|
||||
}
|
||||
|
||||
ParseElement($arg, "scalars|buffers");
|
||||
if (defined($param_handlers{$p->{TYPE}})) {
|
||||
$res .= &{$param_handlers{$p->{TYPE}}}($p);
|
||||
return $res;
|
||||
}
|
||||
|
||||
$res .= "\t/* Unhandled IDL type '$p->{TYPE}' in $p->{PARENT}->{NAME} */\n";
|
||||
|
||||
return $res;
|
||||
# exit(1);
|
||||
}
|
||||
|
||||
|
||||
#####################################################################
|
||||
# parse a function
|
||||
sub ParseFunction($)
|
||||
{
|
||||
my($function) = shift;
|
||||
my($f) = shift;
|
||||
my($res);
|
||||
|
||||
# Input function
|
||||
$res .= "/*\n\n";
|
||||
$res .= IdlDump::DumpFunction($f);
|
||||
$res .= "*/\n\n";
|
||||
|
||||
$res .= "static int $function->{NAME}_q(tvbuff_t *tvb, int offset,\
|
||||
\tpacket_info *pinfo, proto_tree *tree, char *drep)\n{\n";
|
||||
# Request function
|
||||
|
||||
foreach my $arg (@{$function->{DATA}}) {
|
||||
ParseFunctionArg($arg, "in");
|
||||
}
|
||||
|
||||
$res .= "\n\treturn offset;\n}\n\n";
|
||||
|
||||
# Output function
|
||||
$res .= "static int\n";
|
||||
$res .= "$f->{NAME}_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep)\n";
|
||||
$res .= "{\n";
|
||||
|
||||
$res .= "static int $function->{NAME}_r(tvbuff_t *tvb, int offset,\
|
||||
\tpacket_info *pinfo, proto_tree *tree, char *drep)\n{\n";
|
||||
|
||||
foreach my $arg (@{$function->{DATA}}) {
|
||||
ParseFunctionArg($arg, "out");
|
||||
my($d);
|
||||
foreach $d (@{$f->{DATA}}) {
|
||||
$res .= ParseParameter($d), if defined($d->{PROPERTIES}{in});
|
||||
}
|
||||
|
||||
$res .= "\n\toffset = prs_ntstatus(tvb, offset, pinfo, tree);\n";
|
||||
$res .= "\treturn offset;\n";
|
||||
$res .= "}\n\n";
|
||||
|
||||
$res .= "\n\treturn offset;\n}\n\n";
|
||||
# Response function
|
||||
|
||||
$res .= "static int\n";
|
||||
$res .= "$f->{NAME}_resp(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, guint8 *drep)\n";
|
||||
$res .= "{\n";
|
||||
|
||||
foreach $d (@{$f->{DATA}}) {
|
||||
$res .= ParseParameter($d), if defined($d->{PROPERTIES}{out});
|
||||
}
|
||||
|
||||
|
||||
$res .= "\treturn offset;\n";
|
||||
$res .= "}\n\n";
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
#####################################################################
|
||||
@ -273,12 +102,13 @@ sub ParseInterface($)
|
||||
{
|
||||
my($interface) = shift;
|
||||
my($data) = $interface->{DATA};
|
||||
my($res) = "";
|
||||
|
||||
foreach my $d (@{$data}) {
|
||||
($d->{TYPE} eq "TYPEDEF") &&
|
||||
ParseTypedef($d);
|
||||
($d->{TYPE} eq "FUNCTION") &&
|
||||
ParseFunction($d);
|
||||
$res .= ParseFunction($d), if $d->{TYPE} eq "FUNCTION";
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
||||
@ -287,11 +117,13 @@ sub ParseInterface($)
|
||||
sub Parse($)
|
||||
{
|
||||
my($idl) = shift;
|
||||
my($res);
|
||||
|
||||
$res = "/* parser auto-generated by pidl */\n\n";
|
||||
foreach my $x (@{$idl}) {
|
||||
($x->{TYPE} eq "INTERFACE") &&
|
||||
ParseInterface($x);
|
||||
foreach my $d (@{$idl}) {
|
||||
$res .= ParseInterface($d), if $d->{TYPE} eq "INTERFACE";
|
||||
}
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user