Add pidl. Add preliminary work on SecIP.
Please note that the Alphatronics implementation does not follow the Vebon specification. An extra padding byte had to be added to the idl..
This commit is contained in:
parent
1972b32b60
commit
ad758df90b
67 changed files with 24048 additions and 1 deletions
181
pidl/tests/Util.pm
Normal file
181
pidl/tests/Util.pm
Normal file
|
@ -0,0 +1,181 @@
|
|||
# Some simple utility functions for pidl tests
|
||||
# Copyright (C) 2005-2006 Jelmer Vernooij
|
||||
# Published under the GNU General Public License
|
||||
|
||||
package Util;
|
||||
|
||||
require Exporter;
|
||||
@ISA = qw(Exporter);
|
||||
@EXPORT = qw(test_samba4_ndr test_warnings test_errors);
|
||||
|
||||
use strict;
|
||||
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin/../lib";
|
||||
|
||||
use Parse::Pidl::Samba4 qw(is_intree);
|
||||
|
||||
use Parse::Pidl;
|
||||
my $warnings = "";
|
||||
undef &Parse::Pidl::warning;
|
||||
*Parse::Pidl::warning = sub {
|
||||
my ($e, $l) = @_;
|
||||
if (defined($e)) {
|
||||
$warnings .= "$e->{FILE}:$e->{LINE}: $l\n";
|
||||
} else {
|
||||
$warnings .= "$l\n";
|
||||
}
|
||||
};
|
||||
|
||||
my $errors = "";
|
||||
undef &Parse::Pidl::error;
|
||||
*Parse::Pidl::error = sub {
|
||||
my ($e, $l) = @_;
|
||||
if (defined($e)) {
|
||||
$errors .= "$e->{FILE}:$e->{LINE}: $l\n";
|
||||
} else {
|
||||
$errors .= "$l\n";
|
||||
}
|
||||
};
|
||||
|
||||
use Test::More;
|
||||
use Parse::Pidl::IDL;
|
||||
use Parse::Pidl::NDR;
|
||||
use Parse::Pidl::Samba4::NDR::Parser;
|
||||
use Parse::Pidl::Samba4::Header;
|
||||
|
||||
# Generate a Samba4 parser for an IDL fragment and run it with a specified
|
||||
# piece of code to check whether the parser works as expected
|
||||
sub test_samba4_ndr
|
||||
{
|
||||
my ($name,$idl,$c,$extra) = @_;
|
||||
|
||||
$extra = "" unless defined($extra);
|
||||
|
||||
my $pidl = Parse::Pidl::IDL::parse_string("interface echo { $idl }; ", "<$name>");
|
||||
ok(defined($pidl), "($name) parse idl");
|
||||
|
||||
my $pndr = Parse::Pidl::NDR::Parse($pidl);
|
||||
ok(defined($pndr), "($name) generate NDR tree");
|
||||
|
||||
my $header = Parse::Pidl::Samba4::Header::Parse($pndr);
|
||||
ok(defined($header), "($name) generate generic header");
|
||||
|
||||
my $generator = new Parse::Pidl::Samba4::NDR::Parser();
|
||||
my ($ndrheader,$ndrparser) = $generator->Parse($pndr, undef, undef);
|
||||
ok(defined($ndrparser), "($name) generate NDR parser");
|
||||
ok(defined($ndrheader), "($name) generate NDR header");
|
||||
|
||||
SKIP: {
|
||||
|
||||
my $flags;
|
||||
if (system("pkg-config --exists ndr") == 0 and !is_intree()) {
|
||||
$flags = `pkg-config --libs --cflags ndr`;
|
||||
} else {
|
||||
skip "no samba environment available, skipping compilation", 3;
|
||||
}
|
||||
|
||||
my $main = "
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <util/data_blob.h>
|
||||
|
||||
/* header start */
|
||||
$header
|
||||
/* header end */
|
||||
|
||||
/* ndrheader start */
|
||||
$ndrheader
|
||||
/* ndrheader end */
|
||||
|
||||
/* extra start */
|
||||
$extra
|
||||
/* extra end */
|
||||
|
||||
/* ndrparser start */
|
||||
$ndrparser
|
||||
/* ndrparser end */
|
||||
|
||||
/* main start */
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
TALLOC_CTX *mem_ctx = talloc_init(NULL);
|
||||
|
||||
$c
|
||||
|
||||
talloc_free(mem_ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
/* main end */
|
||||
\n";
|
||||
|
||||
my $main_debug = "# ".join("\n# ", split("\n", $main));
|
||||
|
||||
my $test_data_prefix = $ENV{TEST_DATA_PREFIX};
|
||||
my $outfile;
|
||||
if (defined($test_data_prefix)) {
|
||||
$outfile = "$test_data_prefix/test-$name";
|
||||
} else {
|
||||
$outfile = "./test-$name";
|
||||
}
|
||||
|
||||
my $cflags = $ENV{CFLAGS};
|
||||
unless (defined($cflags)) {
|
||||
$cflags = "";
|
||||
}
|
||||
|
||||
my $ldflags = $ENV{LDFLAGS};
|
||||
unless (defined($ldflags)) {
|
||||
$ldflags = "";
|
||||
}
|
||||
|
||||
my $cc = $ENV{CC};
|
||||
unless (defined($cc)) {
|
||||
$cc = "cc";
|
||||
}
|
||||
|
||||
my $cmd = "$cc $cflags -x c - -o $outfile $flags $ldflags";
|
||||
$cmd =~ s/\n//g;
|
||||
open CC, "|$cmd";
|
||||
print CC $main;
|
||||
close CC;
|
||||
|
||||
ok(-f $outfile, "($name) compile");
|
||||
|
||||
my $ret = system($outfile, ()) >> 8;
|
||||
print "# code:\n#\n$main_debug\n" if ($ret != 0);
|
||||
print "# cmd: $cmd\n" if ($ret != 0);
|
||||
print "# return code: $ret\n" if ($ret != 0);
|
||||
|
||||
ok($ret == 0, "($name) run");
|
||||
|
||||
ok(unlink($outfile), "($name) remove");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sub test_warnings($$)
|
||||
{
|
||||
my ($exp, $code) = @_;
|
||||
|
||||
$warnings = "";
|
||||
|
||||
$code->();
|
||||
|
||||
is($warnings, $exp);
|
||||
}
|
||||
|
||||
sub test_errors($$)
|
||||
{
|
||||
my ($exp, $code) = @_;
|
||||
$errors = "";
|
||||
$code->();
|
||||
|
||||
is($errors, $exp);
|
||||
}
|
||||
|
||||
1;
|
21
pidl/tests/cutil.pl
Executable file
21
pidl/tests/cutil.pl
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 7;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl::Util qw(MyDumper);
|
||||
use Parse::Pidl::CUtil qw(get_pointer_to get_value_of);
|
||||
|
||||
is("&foo", get_pointer_to("foo"));
|
||||
is("&(&foo)", get_pointer_to(get_pointer_to("foo")));
|
||||
is("*foo", get_pointer_to("**foo"));
|
||||
is("foo", get_pointer_to("*foo"));
|
||||
|
||||
is("foo", get_value_of("&foo"));
|
||||
is("*foo", get_value_of("foo"));
|
||||
is("**foo", get_value_of("*foo"));
|
15
pidl/tests/dump.pl
Executable file
15
pidl/tests/dump.pl
Executable file
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 1;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl::Dump qw(DumpStruct);
|
||||
|
||||
is (DumpStruct({ NAME => "foo", ELEMENTS => []}),
|
||||
"struct foo {\n}");
|
||||
|
108
pidl/tests/header.pl
Executable file
108
pidl/tests/header.pl
Executable file
|
@ -0,0 +1,108 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 27;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl::Util qw(MyDumper);
|
||||
use Parse::Pidl::Samba4::Header qw(
|
||||
GenerateFunctionInEnv GenerateFunctionOutEnv GenerateStructEnv
|
||||
EnvSubstituteValue);
|
||||
use Parse::Pidl::IDL qw(parse_string);
|
||||
use Parse::Pidl::NDR;
|
||||
|
||||
sub parse_idl($)
|
||||
{
|
||||
my $text = shift;
|
||||
my $idl = Parse::Pidl::IDL::parse_string($text, "nofile");
|
||||
my $ndr = Parse::Pidl::NDR::Parse($idl);
|
||||
return Parse::Pidl::Samba4::Header::Parse($ndr);
|
||||
}
|
||||
|
||||
like(parse_idl(""), qr/\/\* header auto-generated by pidl \*\/\n/sm, "includes work");
|
||||
like(parse_idl("interface x {}"), qr/\/\* header auto-generated by pidl \*\/\n/sm, "simple empty interface doesn't cause overhead");
|
||||
like(parse_idl("interface p { typedef struct { int y; } x; };"),
|
||||
qr/.*#ifndef _HEADER_p\n#define _HEADER_p\n.+\n#endif \/\* _HEADER_p \*\/.*/ms, "ifdefs are created");
|
||||
like(parse_idl("interface p { typedef struct { int y; } x; };"),
|
||||
qr/struct x.*{.*int32_t y;.*}.*;/sm, "interface member generated properly");
|
||||
like(parse_idl("interface x { void foo (void); };"),
|
||||
qr/struct foo.*{\s+int _dummy_element;\s+};/sm, "void fn contains dummy element");
|
||||
like(parse_idl("interface x { void foo ([in] uint32 x); };"),
|
||||
qr/struct foo.*{\s+struct\s+{\s+uint32_t x;\s+} in;\s+};/sm, "fn in arg works");
|
||||
like(parse_idl("interface x { void foo ([out] uint32 x); };"),
|
||||
qr/struct foo.*{.*struct\s+{\s+uint32_t x;\s+} out;.*};/sm, "fn out arg works");
|
||||
like(parse_idl("interface x { void foo ([in,out] uint32 x); };"),
|
||||
qr/struct foo.*{.*struct\s+{\s+uint32_t x;\s+} in;\s+struct\s+{\s+uint32_t x;\s+} out;.*};/sm, "fn in,out arg works");
|
||||
like(parse_idl("interface x { void foo (uint32 x); };"), qr/struct foo.*{.*struct\s+{\s+uint32_t x;\s+} in;\s+struct\s+{\s+uint32_t x;\s+} out;.*};/sm, "fn with no props implies in,out");
|
||||
like(parse_idl("interface p { struct x { int y; }; };"),
|
||||
qr/struct x.*{.*int32_t y;.*}.*;/sm, "interface member generated properly");
|
||||
|
||||
like(parse_idl("interface p { struct x { struct y z; }; };"),
|
||||
qr/struct x.*{.*struct y z;.*}.*;/sm, "tagged type struct member");
|
||||
|
||||
like(parse_idl("interface p { struct x { union y z; }; };"),
|
||||
qr/struct x.*{.*union y z;.*}.*;/sm, "tagged type union member");
|
||||
|
||||
like(parse_idl("interface p { struct x { }; };"),
|
||||
qr/struct x.*{.*char _empty_;.*}.*;/sm, "empty struct");
|
||||
|
||||
like(parse_idl("interface p { struct x; };"),
|
||||
qr/struct x;/sm, "struct declaration");
|
||||
|
||||
like(parse_idl("interface p { typedef struct x { int p; } x; };"),
|
||||
qr/struct x.*{.*int32_t p;.*};/sm, "double struct declaration");
|
||||
|
||||
like(parse_idl("cpp_quote(\"some-foo\")"),
|
||||
qr/some-foo/sm, "cpp quote");
|
||||
|
||||
# Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work
|
||||
my $fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] };
|
||||
is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionInEnv($fn));
|
||||
|
||||
$fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] };
|
||||
is_deeply({ "foo" => "r->out.foo" }, GenerateFunctionOutEnv($fn));
|
||||
|
||||
$fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] };
|
||||
is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionInEnv($fn));
|
||||
|
||||
$fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] };
|
||||
is_deeply({ "foo" => "r->out.foo" }, GenerateFunctionOutEnv($fn));
|
||||
|
||||
$fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] };
|
||||
is_deeply({ "foo" => "r->in.foo" }, GenerateFunctionOutEnv($fn));
|
||||
|
||||
$fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] };
|
||||
is_deeply({ }, GenerateFunctionInEnv($fn));
|
||||
|
||||
$fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] };
|
||||
is_deeply({ foo => "r->foo", bar => "r->bar", this => "r" },
|
||||
GenerateStructEnv($fn, "r"));
|
||||
|
||||
$fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] };
|
||||
is_deeply({ foo => "some->complex.variable->foo",
|
||||
bar => "some->complex.variable->bar",
|
||||
this => "some->complex.variable" },
|
||||
GenerateStructEnv($fn, "some->complex.variable"));
|
||||
|
||||
$fn = { ELEMENTS => [ { NAME => "foo", PROPERTIES => { value => 3 }} ] };
|
||||
|
||||
my $env = GenerateStructEnv($fn, "r");
|
||||
EnvSubstituteValue($env, $fn);
|
||||
is_deeply($env, { foo => 3, this => "r" });
|
||||
|
||||
$fn = { ELEMENTS => [ { NAME => "foo" }, { NAME => "bar" } ] };
|
||||
$env = GenerateStructEnv($fn, "r");
|
||||
EnvSubstituteValue($env, $fn);
|
||||
is_deeply($env, { foo => 'r->foo', bar => 'r->bar', this => "r" });
|
||||
|
||||
$fn = { ELEMENTS => [ { NAME => "foo", PROPERTIES => { value => 0 }} ] };
|
||||
|
||||
$env = GenerateStructEnv($fn, "r");
|
||||
EnvSubstituteValue($env, $fn);
|
||||
is_deeply($env, { foo => 0, this => "r" });
|
||||
|
||||
|
561
pidl/tests/ndr.pl
Executable file
561
pidl/tests/ndr.pl
Executable file
|
@ -0,0 +1,561 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 47;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl::Util qw(MyDumper);
|
||||
use Parse::Pidl::NDR qw(GetElementLevelTable ParseElement align_type mapToScalar ParseType can_contain_deferred);
|
||||
|
||||
# Case 1
|
||||
|
||||
my $e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => {},
|
||||
'POINTERS' => 0,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'STRUCT' },
|
||||
'LINE' => 42 };
|
||||
|
||||
is_deeply(GetElementLevelTable($e, "unique", 0), [
|
||||
{
|
||||
'IS_DEFERRED' => 0,
|
||||
'LEVEL_INDEX' => 0,
|
||||
'DATA_TYPE' => 'uint8',
|
||||
'CONTAINS_DEFERRED' => 0,
|
||||
'TYPE' => 'DATA',
|
||||
'IS_SURROUNDING' => 0,
|
||||
}
|
||||
]);
|
||||
|
||||
my $ne = ParseElement($e, "unique", 0);
|
||||
is($ne->{ORIGINAL}, $e);
|
||||
is($ne->{NAME}, "v");
|
||||
is($ne->{ALIGN}, 1);
|
||||
is($ne->{TYPE}, "uint8");
|
||||
is_deeply($ne->{LEVELS}, [
|
||||
{
|
||||
'IS_DEFERRED' => 0,
|
||||
'LEVEL_INDEX' => 0,
|
||||
'DATA_TYPE' => 'uint8',
|
||||
'CONTAINS_DEFERRED' => 0,
|
||||
'TYPE' => 'DATA',
|
||||
'IS_SURROUNDING' => 0,
|
||||
}
|
||||
]);
|
||||
|
||||
# Case 2 : pointers
|
||||
#
|
||||
$e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => {"unique" => 1},
|
||||
'POINTERS' => 1,
|
||||
'PARENT' => { TYPE => 'STRUCT' },
|
||||
'TYPE' => 'uint8',
|
||||
'LINE' => 42 };
|
||||
|
||||
is_deeply(GetElementLevelTable($e, "unique", 0), [
|
||||
{
|
||||
LEVEL_INDEX => 0,
|
||||
IS_DEFERRED => 0,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "unique",
|
||||
POINTER_INDEX => 0,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
'IS_DEFERRED' => 1,
|
||||
'LEVEL_INDEX' => 1,
|
||||
'DATA_TYPE' => 'uint8',
|
||||
'CONTAINS_DEFERRED' => 0,
|
||||
'TYPE' => 'DATA',
|
||||
'IS_SURROUNDING' => 0,
|
||||
}
|
||||
]);
|
||||
|
||||
# Case 3 : double pointers
|
||||
#
|
||||
$e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => {"unique" => 1},
|
||||
'POINTERS' => 2,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'STRUCT' },
|
||||
'LINE' => 42 };
|
||||
|
||||
is_deeply(GetElementLevelTable($e, "unique", 0), [
|
||||
{
|
||||
LEVEL_INDEX => 0,
|
||||
IS_DEFERRED => 0,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "unique",
|
||||
POINTER_INDEX => 0,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 1,
|
||||
IS_DEFERRED => 1,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "unique",
|
||||
POINTER_INDEX => 1,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
'IS_DEFERRED' => 1,
|
||||
'LEVEL_INDEX' => 2,
|
||||
'DATA_TYPE' => 'uint8',
|
||||
'CONTAINS_DEFERRED' => 0,
|
||||
'TYPE' => 'DATA',
|
||||
'IS_SURROUNDING' => 0,
|
||||
}
|
||||
]);
|
||||
|
||||
# Case 3 : ref pointers
|
||||
#
|
||||
$e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => {"ref" => 1},
|
||||
'POINTERS' => 1,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'STRUCT' },
|
||||
'LINE' => 42 };
|
||||
|
||||
is_deeply(GetElementLevelTable($e, "unique", 0), [
|
||||
{
|
||||
LEVEL_INDEX => 0,
|
||||
IS_DEFERRED => 0,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "ref",
|
||||
POINTER_INDEX => 0,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
'IS_DEFERRED' => 1,
|
||||
'LEVEL_INDEX' => 1,
|
||||
'DATA_TYPE' => 'uint8',
|
||||
'CONTAINS_DEFERRED' => 0,
|
||||
'TYPE' => 'DATA',
|
||||
'IS_SURROUNDING' => 0,
|
||||
}
|
||||
]);
|
||||
|
||||
# Case 3 : ref pointers
|
||||
#
|
||||
$e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => {"ref" => 1},
|
||||
'POINTERS' => 3,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'STRUCT' },
|
||||
'LINE' => 42 };
|
||||
|
||||
is_deeply(GetElementLevelTable($e, "unique", 0), [
|
||||
{
|
||||
LEVEL_INDEX => 0,
|
||||
IS_DEFERRED => 0,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "ref",
|
||||
POINTER_INDEX => 0,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 1,
|
||||
IS_DEFERRED => 1,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "unique",
|
||||
POINTER_INDEX => 1,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 2,
|
||||
IS_DEFERRED => 1,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "unique",
|
||||
POINTER_INDEX => 2,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
'IS_DEFERRED' => 1,
|
||||
'LEVEL_INDEX' => 3,
|
||||
'DATA_TYPE' => 'uint8',
|
||||
'CONTAINS_DEFERRED' => 0,
|
||||
'TYPE' => 'DATA',
|
||||
'IS_SURROUNDING' => 0,
|
||||
}
|
||||
]);
|
||||
|
||||
# Case 3 : ref pointers
|
||||
#
|
||||
$e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => {"ref" => 1},
|
||||
'POINTERS' => 3,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'STRUCT' },
|
||||
'LINE' => 42 };
|
||||
|
||||
is_deeply(GetElementLevelTable($e, "ref", 0), [
|
||||
{
|
||||
LEVEL_INDEX => 0,
|
||||
IS_DEFERRED => 0,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "ref",
|
||||
POINTER_INDEX => 0,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 1,
|
||||
IS_DEFERRED => 1,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "ref",
|
||||
POINTER_INDEX => 1,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 2,
|
||||
IS_DEFERRED => 1,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "ref",
|
||||
POINTER_INDEX => 2,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
'IS_DEFERRED' => 1,
|
||||
'LEVEL_INDEX' => 3,
|
||||
'DATA_TYPE' => 'uint8',
|
||||
'CONTAINS_DEFERRED' => 0,
|
||||
'TYPE' => 'DATA',
|
||||
'IS_SURROUNDING' => 0,
|
||||
}
|
||||
]);
|
||||
|
||||
# Case 4 : top-level ref pointers
|
||||
#
|
||||
$e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => {"ref" => 1},
|
||||
'POINTERS' => 1,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'FUNCTION' },
|
||||
'LINE' => 42 };
|
||||
|
||||
is_deeply(GetElementLevelTable($e, "unique", 0), [
|
||||
{
|
||||
LEVEL_INDEX => 0,
|
||||
IS_DEFERRED => 0,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "ref",
|
||||
POINTER_INDEX => 0,
|
||||
LEVEL => 'TOP'
|
||||
},
|
||||
{
|
||||
'IS_DEFERRED' => 0,
|
||||
'LEVEL_INDEX' => 1,
|
||||
'DATA_TYPE' => 'uint8',
|
||||
'CONTAINS_DEFERRED' => 0,
|
||||
'TYPE' => 'DATA',
|
||||
'IS_SURROUNDING' => 0,
|
||||
}
|
||||
]);
|
||||
|
||||
# Case 4 : top-level ref pointers, triple with pointer_default("unique")
|
||||
#
|
||||
$e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => {"ref" => 1},
|
||||
'POINTERS' => 3,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'FUNCTION' },
|
||||
'LINE' => 42 };
|
||||
|
||||
is_deeply(GetElementLevelTable($e, "unique", 0), [
|
||||
{
|
||||
LEVEL_INDEX => 0,
|
||||
IS_DEFERRED => 0,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "ref",
|
||||
POINTER_INDEX => 0,
|
||||
LEVEL => 'TOP'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 1,
|
||||
IS_DEFERRED => 0,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "unique",
|
||||
POINTER_INDEX => 1,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 2,
|
||||
IS_DEFERRED => 1,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "unique",
|
||||
POINTER_INDEX => 2,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
'IS_DEFERRED' => 1,
|
||||
'LEVEL_INDEX' => 3,
|
||||
'DATA_TYPE' => 'uint8',
|
||||
'CONTAINS_DEFERRED' => 0,
|
||||
'TYPE' => 'DATA',
|
||||
'IS_SURROUNDING' => 0,
|
||||
}
|
||||
]);
|
||||
|
||||
# Case 4 : top-level unique pointers, triple with pointer_default("unique")
|
||||
#
|
||||
$e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => {"unique" => 1, "in" => 1},
|
||||
'POINTERS' => 3,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'FUNCTION' },
|
||||
'LINE' => 42 };
|
||||
|
||||
is_deeply(GetElementLevelTable($e, "unique", 0), [
|
||||
{
|
||||
LEVEL_INDEX => 0,
|
||||
IS_DEFERRED => 0,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "unique",
|
||||
POINTER_INDEX => 0,
|
||||
LEVEL => 'TOP'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 1,
|
||||
IS_DEFERRED => 1,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "unique",
|
||||
POINTER_INDEX => 1,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 2,
|
||||
IS_DEFERRED => 1,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "unique",
|
||||
POINTER_INDEX => 2,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
'IS_DEFERRED' => 1,
|
||||
'LEVEL_INDEX' => 3,
|
||||
'DATA_TYPE' => 'uint8',
|
||||
'CONTAINS_DEFERRED' => 0,
|
||||
'TYPE' => 'DATA',
|
||||
'IS_SURROUNDING' => 0,
|
||||
}
|
||||
]);
|
||||
|
||||
# Case 4 : top-level unique pointers, triple with pointer_default("ref")
|
||||
#
|
||||
$e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => {"unique" => 1, "in" => 1},
|
||||
'POINTERS' => 3,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'FUNCTION' },
|
||||
'LINE' => 42 };
|
||||
|
||||
is_deeply(GetElementLevelTable($e, "ref", 0), [
|
||||
{
|
||||
LEVEL_INDEX => 0,
|
||||
IS_DEFERRED => 0,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "unique",
|
||||
POINTER_INDEX => 0,
|
||||
LEVEL => 'TOP'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 1,
|
||||
IS_DEFERRED => 1,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "ref",
|
||||
POINTER_INDEX => 1,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 2,
|
||||
IS_DEFERRED => 1,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "ref",
|
||||
POINTER_INDEX => 2,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
'IS_DEFERRED' => 1,
|
||||
'LEVEL_INDEX' => 3,
|
||||
'DATA_TYPE' => 'uint8',
|
||||
'CONTAINS_DEFERRED' => 0,
|
||||
'TYPE' => 'DATA',
|
||||
'IS_SURROUNDING' => 0,
|
||||
}
|
||||
]);
|
||||
|
||||
# Case 4 : top-level ref pointers, triple with pointer_default("ref")
|
||||
#
|
||||
$e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => {"ref" => 1},
|
||||
'POINTERS' => 3,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'FUNCTION' },
|
||||
'LINE' => 42 };
|
||||
|
||||
is_deeply(GetElementLevelTable($e, "ref", 0), [
|
||||
{
|
||||
LEVEL_INDEX => 0,
|
||||
IS_DEFERRED => 0,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "ref",
|
||||
POINTER_INDEX => 0,
|
||||
LEVEL => 'TOP'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 1,
|
||||
IS_DEFERRED => 0,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "ref",
|
||||
POINTER_INDEX => 1,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
LEVEL_INDEX => 2,
|
||||
IS_DEFERRED => 1,
|
||||
TYPE => 'POINTER',
|
||||
POINTER_TYPE => "ref",
|
||||
POINTER_INDEX => 2,
|
||||
LEVEL => 'EMBEDDED'
|
||||
},
|
||||
{
|
||||
'IS_DEFERRED' => 1,
|
||||
'LEVEL_INDEX' => 3,
|
||||
'DATA_TYPE' => 'uint8',
|
||||
'CONTAINS_DEFERRED' => 0,
|
||||
'TYPE' => 'DATA',
|
||||
'IS_SURROUNDING' => 0,
|
||||
}
|
||||
]);
|
||||
|
||||
# representation_type
|
||||
$e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => { represent_as => "bar" },
|
||||
'POINTERS' => 0,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'STRUCT' },
|
||||
'LINE' => 42 };
|
||||
|
||||
$ne = ParseElement($e, undef, 0);
|
||||
is($ne->{REPRESENTATION_TYPE}, "bar");
|
||||
|
||||
# representation_type
|
||||
$e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => { },
|
||||
'POINTERS' => 0,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'STRUCT' },
|
||||
'LINE' => 42 };
|
||||
|
||||
$ne = ParseElement($e, undef, 0);
|
||||
is($ne->{REPRESENTATION_TYPE}, "uint8");
|
||||
|
||||
is(align_type("hyper"), 8);
|
||||
is(align_type("double"), 8);
|
||||
is(align_type("uint32"), 4);
|
||||
is(align_type("uint16"), 2);
|
||||
is(align_type("uint8"), 1);
|
||||
is(align_type({ TYPE => "STRUCT", "NAME" => "bla",
|
||||
ELEMENTS => [ { TYPE => "uint16" } ] }), 4);
|
||||
is(align_type({ TYPE => "STRUCT",
|
||||
ELEMENTS => [ { TYPE => "hyper" } ] }), 8);
|
||||
is(align_type({ TYPE => "TYPEDEF", DATA => {
|
||||
TYPE => "STRUCT",
|
||||
ELEMENTS => [ { TYPE => "hyper" } ] }}), 8);
|
||||
# typedef of struct without body
|
||||
is(align_type({ TYPE => "TYPEDEF", DATA => {
|
||||
TYPE => "STRUCT", ELEMENTS => undef }}), 4);
|
||||
# struct without body
|
||||
is(align_type({ TYPE => "STRUCT", ELEMENTS => undef }), 4);
|
||||
# empty struct
|
||||
is(align_type({ TYPE => "STRUCT", ELEMENTS => [] }), 1);
|
||||
is(align_type({ TYPE => "STRUCT", "NAME" => "bla",
|
||||
ELEMENTS => [ { TYPE => "uint8" } ] }), 4);
|
||||
|
||||
is(mapToScalar("someverymuchnotexistingtype"), undef);
|
||||
is(mapToScalar("uint32"), "uint32");
|
||||
is(mapToScalar({TYPE => "ENUM", PARENT => { PROPERTIES => { enum8bit => 1 } } }), "uint8");
|
||||
is(mapToScalar({TYPE => "BITMAP", PROPERTIES => { bitmap64bit => 1 } }),
|
||||
"hyper");
|
||||
is(mapToScalar({TYPE => "TYPEDEF", DATA => {TYPE => "ENUM", PARENT => { PROPERTIES => { enum8bit => 1 } } }}), "uint8");
|
||||
|
||||
my $t;
|
||||
$t = {
|
||||
TYPE => "STRUCT",
|
||||
NAME => "foo",
|
||||
SURROUNDING_ELEMENT => undef,
|
||||
ELEMENTS => undef,
|
||||
PROPERTIES => undef,
|
||||
ORIGINAL => {
|
||||
TYPE => "STRUCT",
|
||||
NAME => "foo"
|
||||
},
|
||||
ALIGN => undef
|
||||
};
|
||||
is_deeply(ParseType($t->{ORIGINAL}, "ref", 0), $t);
|
||||
|
||||
$t = {
|
||||
TYPE => "UNION",
|
||||
NAME => "foo",
|
||||
SWITCH_TYPE => "uint32",
|
||||
ELEMENTS => undef,
|
||||
PROPERTIES => undef,
|
||||
HAS_DEFAULT => 0,
|
||||
IS_MS_UNION => 0,
|
||||
ORIGINAL => {
|
||||
TYPE => "UNION",
|
||||
NAME => "foo"
|
||||
},
|
||||
ALIGN => undef
|
||||
};
|
||||
is_deeply(ParseType($t->{ORIGINAL}, "ref", 0), $t);
|
||||
|
||||
ok(not can_contain_deferred("uint32"));
|
||||
ok(can_contain_deferred("some_unknown_type"));
|
||||
ok(can_contain_deferred({ TYPE => "STRUCT",
|
||||
ELEMENTS => [ { TYPE => "uint32", POINTERS => 40 } ]}));
|
||||
ok(can_contain_deferred({ TYPE => "TYPEDEF",
|
||||
DATA => { TYPE => "STRUCT",
|
||||
ELEMENTS => [ { TYPE => "uint32", POINTERS => 40 } ]}}));
|
||||
ok(not can_contain_deferred({ TYPE => "STRUCT",
|
||||
ELEMENTS => [ { TYPE => "uint32" } ]}));
|
||||
ok(not can_contain_deferred({ TYPE => "TYPEDEF",
|
||||
DATA => { TYPE => "STRUCT",
|
||||
ELEMENTS => [ { TYPE => "uint32" } ]}}));
|
||||
ok(can_contain_deferred({ TYPE => "STRUCT",
|
||||
ELEMENTS => [ { TYPE => "someunknowntype" } ]}));
|
||||
# Make sure the elements for a enum without body aren't filled in
|
||||
ok(not defined(ParseType({TYPE => "ENUM", NAME => "foo" }, "ref", 0)->{ELEMENTS}));
|
||||
# Make sure the elements for a bitmap without body aren't filled in
|
||||
ok(not defined(ParseType({TYPE => "BITMAP", NAME => "foo" }, "ref", 0)->{ELEMENTS}));
|
||||
# Make sure the elements for a union without body aren't filled in
|
||||
ok(not defined(ParseType({TYPE => "UNION", NAME => "foo" }, "ref", 0)->{ELEMENTS}));
|
143
pidl/tests/ndr_align.pl
Executable file
143
pidl/tests/ndr_align.pl
Executable file
|
@ -0,0 +1,143 @@
|
|||
#!/usr/bin/perl
|
||||
# NDR alignment tests
|
||||
# (C) 2005 Jelmer Vernooij. Published under the GNU GPL
|
||||
use strict;
|
||||
|
||||
use Test::More tests => 5 * 8;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util qw(test_samba4_ndr);
|
||||
|
||||
test_samba4_ndr('align-uint8-uint16',
|
||||
'
|
||||
typedef [public] struct {
|
||||
uint8 x;
|
||||
uint16 y;
|
||||
} bla;
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct bla r;
|
||||
uint8_t expected[] = { 0x0D, 0x00, 0xef, 0xbe };
|
||||
DATA_BLOB expected_blob = { expected, 4 };
|
||||
DATA_BLOB result_blob;
|
||||
r.x = 13;
|
||||
r.y = 0xbeef;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r)))
|
||||
return 1;
|
||||
|
||||
result_blob = ndr_push_blob(ndr);
|
||||
|
||||
if (data_blob_cmp(&result_blob, &expected_blob) != 0)
|
||||
return 2;
|
||||
');
|
||||
|
||||
test_samba4_ndr('align-uint8-uint32',
|
||||
'
|
||||
typedef [public] struct {
|
||||
uint8 x;
|
||||
uint32 y;
|
||||
} bla;
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct bla r;
|
||||
uint8_t expected[] = { 0x0D, 0x00, 0x00, 0x00, 0xef, 0xbe, 0xef, 0xbe };
|
||||
DATA_BLOB expected_blob = { expected, 8 };
|
||||
DATA_BLOB result_blob;
|
||||
r.x = 13;
|
||||
r.y = 0xbeefbeef;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r)))
|
||||
return 1;
|
||||
|
||||
result_blob = ndr_push_blob(ndr);
|
||||
|
||||
if (data_blob_cmp(&result_blob, &expected_blob) != 0)
|
||||
return 2;
|
||||
');
|
||||
|
||||
|
||||
test_samba4_ndr('align-uint8-hyper',
|
||||
'
|
||||
typedef [public] struct {
|
||||
uint8 x;
|
||||
hyper y;
|
||||
} bla;
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct bla r;
|
||||
uint8_t expected[] = { 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xef, 0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef, 0xbe };
|
||||
DATA_BLOB expected_blob = { expected, 16 };
|
||||
DATA_BLOB result_blob;
|
||||
r.x = 13;
|
||||
r.y = 0xbeefbeefbeefbeefLLU;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r)))
|
||||
return 1;
|
||||
|
||||
result_blob = ndr_push_blob(ndr);
|
||||
|
||||
if (data_blob_cmp(&result_blob, &expected_blob) != 0)
|
||||
return 2;
|
||||
');
|
||||
|
||||
test_samba4_ndr('noalignflag-uint8-uint16',
|
||||
'
|
||||
typedef [public] struct {
|
||||
uint8 x;
|
||||
uint16 y;
|
||||
} bla;
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct bla r;
|
||||
uint8_t expected[] = { 0x0D, 0xef, 0xbe };
|
||||
DATA_BLOB expected_blob = { expected, 3 };
|
||||
DATA_BLOB result_blob;
|
||||
ndr->flags |= LIBNDR_FLAG_NOALIGN;
|
||||
|
||||
r.x = 13;
|
||||
r.y = 0xbeef;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r)))
|
||||
return 1;
|
||||
|
||||
result_blob = ndr_push_blob(ndr);
|
||||
|
||||
if (data_blob_cmp(&result_blob, &expected_blob) != 0)
|
||||
return 2;
|
||||
');
|
||||
|
||||
test_samba4_ndr('align-blob-align2',
|
||||
'
|
||||
typedef [public] struct {
|
||||
uint8 x;
|
||||
[flag(LIBNDR_FLAG_ALIGN2)] DATA_BLOB data;
|
||||
uint8 y;
|
||||
} blie;
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct blie r;
|
||||
uint8_t data[] = { 0x01, 0x02 };
|
||||
uint8_t expected[] = { 0x0D, 0x00, 0x0E };
|
||||
DATA_BLOB expected_blob = { expected, 3 };
|
||||
DATA_BLOB result_blob;
|
||||
|
||||
r.x = 13;
|
||||
r.y = 14;
|
||||
r.data.data = data;
|
||||
r.data.length = 2;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_blie(ndr, NDR_SCALARS|NDR_BUFFERS, &r)))
|
||||
return 1;
|
||||
|
||||
result_blob = ndr_push_blob(ndr);
|
||||
|
||||
if (data_blob_cmp(&result_blob, &expected_blob) != 0)
|
||||
return 2;
|
||||
');
|
118
pidl/tests/ndr_alloc.pl
Executable file
118
pidl/tests/ndr_alloc.pl
Executable file
|
@ -0,0 +1,118 @@
|
|||
#!/usr/bin/perl
|
||||
# NDR allocation tests
|
||||
# (C) 2005 Jelmer Vernooij. Published under the GNU GPL
|
||||
use strict;
|
||||
|
||||
use Test::More tests => 5 * 8;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util qw(test_samba4_ndr);
|
||||
|
||||
# Check that an outgoing scalar pointer is allocated correctly
|
||||
|
||||
test_samba4_ndr("alloc-scalar",
|
||||
'
|
||||
typedef struct {
|
||||
uint8 *x;
|
||||
} bla;
|
||||
|
||||
[public] void TestAlloc([in] bla foo);
|
||||
','
|
||||
uint8_t data[] = { 0xde, 0xad, 0xbe, 0xef, 0x03 };
|
||||
DATA_BLOB b = { data, 5 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
|
||||
struct TestAlloc r;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestAlloc(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (r.in.foo.x == NULL)
|
||||
return 2;
|
||||
|
||||
if (*r.in.foo.x != 0x03)
|
||||
return 3;
|
||||
'
|
||||
);
|
||||
|
||||
# Check that an outgoing buffer pointer is allocated correctly
|
||||
test_samba4_ndr("alloc-buffer",
|
||||
'
|
||||
typedef struct { uint8 data; } blie;
|
||||
typedef struct { blie *x; } bla;
|
||||
|
||||
[public] void TestAlloc([in] bla foo);
|
||||
','
|
||||
uint8_t data[] = { 0xde, 0xad, 0xbe, 0xef, 0x03 };
|
||||
DATA_BLOB b = { data, 5 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
|
||||
struct TestAlloc r;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestAlloc(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (r.in.foo.x == NULL)
|
||||
return 2;
|
||||
|
||||
if (r.in.foo.x->data != 0x03)
|
||||
return 3;
|
||||
'
|
||||
);
|
||||
|
||||
# Check that ref pointers aren't allocated by default
|
||||
test_samba4_ndr("ref-noalloc-null",
|
||||
'
|
||||
[public] void TestAlloc([in,ref] uint8 *t);
|
||||
','
|
||||
uint8_t data[] = { 0x03 };
|
||||
DATA_BLOB b = { data, 1 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
|
||||
struct TestAlloc r;
|
||||
r.in.t = NULL;
|
||||
|
||||
if (NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestAlloc(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
'
|
||||
);
|
||||
|
||||
# Check that ref pointers aren't allocated by default
|
||||
test_samba4_ndr("ref-noalloc",
|
||||
'
|
||||
[public] void TestAlloc([in,ref] uint8 *t);
|
||||
','
|
||||
uint8_t data[] = { 0x03 };
|
||||
DATA_BLOB b = { data, 1 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
|
||||
struct TestAlloc r;
|
||||
uint8_t x;
|
||||
r.in.t = &x;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestAlloc(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (*r.in.t != 0x03)
|
||||
return 2;
|
||||
'
|
||||
);
|
||||
|
||||
# Check that an outgoing ref pointer is allocated correctly
|
||||
test_samba4_ndr("ref-alloc",
|
||||
'
|
||||
[public] void TestAlloc([in,ref] uint8 *t);
|
||||
','
|
||||
uint8_t data[] = { 0x03 };
|
||||
DATA_BLOB b = { data, 1 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
|
||||
struct TestAlloc r;
|
||||
ndr->flags |= LIBNDR_FLAG_REF_ALLOC;
|
||||
r.in.t = NULL;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestAlloc(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (r.in.t == NULL)
|
||||
return 2;
|
||||
|
||||
if (*r.in.t != 0x03)
|
||||
return 3;
|
||||
'
|
||||
);
|
37
pidl/tests/ndr_array.pl
Executable file
37
pidl/tests/ndr_array.pl
Executable file
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/perl
|
||||
# Array testing
|
||||
# (C) 2005 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
|
||||
use Test::More tests => 8;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util qw(test_samba4_ndr);
|
||||
|
||||
test_samba4_ndr(
|
||||
'Fixed-Array',
|
||||
|
||||
'[public] void Test([in] uint8 x[10]);',
|
||||
|
||||
'
|
||||
uint8_t data[] = {1,2,3,4,5,6,7,8,9,10};
|
||||
int i;
|
||||
DATA_BLOB b;
|
||||
struct ndr_pull *ndr;
|
||||
struct Test r;
|
||||
|
||||
b.data = data;
|
||||
b.length = 10;
|
||||
ndr = ndr_pull_init_blob(&b, mem_ctx, NULL);
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_Test(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 10)
|
||||
return 2;
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
if (r.in.x[i] != i+1) return 3;
|
||||
}
|
||||
');
|
21
pidl/tests/ndr_compat.pl
Executable file
21
pidl/tests/ndr_compat.pl
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
|
||||
use Test::More tests => 2;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl;
|
||||
use Parse::Pidl::IDL;
|
||||
|
||||
sub parse_idl($)
|
||||
{
|
||||
my $idl = shift;
|
||||
my $pidl = Parse::Pidl::IDL::parse_string("interface echo { $idl }; ", "nofile");
|
||||
Parse::Pidl::NDR::Parse($pidl);
|
||||
}
|
||||
|
||||
test_warnings("", sub {parse_idl("void x();"); });
|
||||
test_warnings("nofile:0: top-level [out] pointer `x' is not a [ref] pointer\n", sub {parse_idl("void x([out,unique] int *x);"); });
|
26
pidl/tests/ndr_deprecations.pl
Executable file
26
pidl/tests/ndr_deprecations.pl
Executable file
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 1;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl::Util qw(MyDumper);
|
||||
use Parse::Pidl::NDR qw(ValidElement);
|
||||
|
||||
# Case 1
|
||||
|
||||
my $e = {
|
||||
'FILE' => 'foo.idl',
|
||||
'NAME' => 'v',
|
||||
'PROPERTIES' => {"subcontext" => 1},
|
||||
'POINTERS' => 0,
|
||||
'TYPE' => 'uint8',
|
||||
'PARENT' => { TYPE => 'STRUCT' },
|
||||
'LINE' => 42 };
|
||||
|
||||
test_warnings("foo.idl:42: subcontext() is deprecated. Use represent_as() or transmit_as() instead\n",
|
||||
sub { ValidElement($e); });
|
44
pidl/tests/ndr_fullptr.pl
Executable file
44
pidl/tests/ndr_fullptr.pl
Executable file
|
@ -0,0 +1,44 @@
|
|||
#!/usr/bin/perl
|
||||
# Simple tests for unique pointers
|
||||
# (C) 2006 Jelmer Vernooij <jelmer@samba.org>.
|
||||
# Published under the GNU General Public License.
|
||||
use strict;
|
||||
|
||||
use Test::More tests => 1 * 8;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util qw(test_samba4_ndr);
|
||||
|
||||
SKIP: {
|
||||
skip "full pointers not supported yet", 8;
|
||||
|
||||
test_samba4_ndr("fullptr-push-dup",
|
||||
'
|
||||
[public] uint16 echo_TestFull([in,ptr] uint32 *x, [in,ptr] uint32 *y);
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
uint32_t v = 13;
|
||||
struct echo_TestFull r;
|
||||
r.in.x = &v;
|
||||
r.in.y = &v;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestFull(ndr, NDR_IN, &r))) {
|
||||
fprintf(stderr, "push failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ndr->offset != 12) {
|
||||
fprintf(stderr, "Offset(%d) != 12\n", ndr->offset);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (ndr->data[0] != ndr->data[8] ||
|
||||
ndr->data[1] != ndr->data[9] ||
|
||||
ndr->data[2] != ndr->data[10] ||
|
||||
ndr->data[3] != ndr->data[11]) {
|
||||
fprintf(stderr, "Data incorrect\n");
|
||||
return 3;
|
||||
}
|
||||
');
|
||||
}
|
526
pidl/tests/ndr_refptr.pl
Executable file
526
pidl/tests/ndr_refptr.pl
Executable file
|
@ -0,0 +1,526 @@
|
|||
#!/usr/bin/perl
|
||||
# Simple tests for pidl's handling of ref pointers, based
|
||||
# on tridge's ref_notes.txt
|
||||
# (C) 2005 Jelmer Vernooij <jelmer@samba.org>.
|
||||
# Published under the GNU General Public License.
|
||||
use strict;
|
||||
|
||||
use Test::More tests => 22 * 8;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util qw(test_samba4_ndr);
|
||||
|
||||
test_samba4_ndr("noptr-push",
|
||||
' typedef struct {
|
||||
uint16 x;
|
||||
} xstruct;
|
||||
|
||||
[public] uint16 echo_TestRef([in] xstruct foo);
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
uint16_t v = 13;
|
||||
struct echo_TestRef r;
|
||||
r.in.foo.x = v;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r))) {
|
||||
fprintf(stderr, "push failed\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (ndr->offset != 2) {
|
||||
fprintf(stderr, "Offset(%d) != 2\n", ndr->offset);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (ndr->data[0] != 13 || ndr->data[1] != 0) {
|
||||
fprintf(stderr, "Data incorrect\n");
|
||||
return 3;
|
||||
}
|
||||
');
|
||||
|
||||
test_samba4_ndr("ptr-embedded-push",
|
||||
' typedef struct {
|
||||
uint16 *x;
|
||||
} xstruct;
|
||||
|
||||
[public] uint16 echo_TestRef([in] xstruct foo);
|
||||
',
|
||||
'
|
||||
uint16_t v = 13;
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
r.in.foo.x = &v;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 6)
|
||||
return 2;
|
||||
|
||||
if (ndr->data[0] == 0 && ndr->data[1] == 0 &&
|
||||
ndr->data[2] == 0 && ndr->data[3] == 0)
|
||||
return 3;
|
||||
|
||||
if (ndr->data[4] != 13 || ndr->data[5] != 0)
|
||||
return 4;
|
||||
');
|
||||
|
||||
test_samba4_ndr("ptr-embedded-push-null",
|
||||
' typedef struct {
|
||||
uint16 *x;
|
||||
} xstruct;
|
||||
|
||||
[public] uint16 echo_TestRef([in] xstruct foo);
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
r.in.foo.x = NULL;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 4)
|
||||
return 2;
|
||||
|
||||
if (ndr->data[0] != 0 || ndr->data[1] != 0 ||
|
||||
ndr->data[2] != 0 || ndr->data[3] != 0)
|
||||
return 3;
|
||||
');
|
||||
|
||||
test_samba4_ndr("refptr-embedded-push",
|
||||
'
|
||||
typedef struct {
|
||||
[ref] uint16 *x;
|
||||
} xstruct;
|
||||
|
||||
[public] uint16 echo_TestRef([in] xstruct foo);
|
||||
',
|
||||
'
|
||||
uint16_t v = 13;
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
r.in.foo.x = &v;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 6)
|
||||
return 2;
|
||||
|
||||
if (ndr->data[0] == 0 && ndr->data[1] == 0 &&
|
||||
ndr->data[2] == 0 && ndr->data[3] == 0)
|
||||
return 3;
|
||||
|
||||
if (ndr->data[4] != 13 || ndr->data[5] != 0)
|
||||
return 4;
|
||||
');
|
||||
|
||||
test_samba4_ndr("refptr-embedded-push-null",
|
||||
'
|
||||
typedef struct {
|
||||
[ref] uint16 *x;
|
||||
} xstruct;
|
||||
|
||||
[public] uint16 echo_TestRef([in] xstruct foo);
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
r.in.foo.x = NULL;
|
||||
|
||||
if (NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
/* Windows gives [client runtime error 0x6f4] */
|
||||
');
|
||||
|
||||
test_samba4_ndr("ptr-top-push",
|
||||
'
|
||||
typedef struct {
|
||||
uint16 x;
|
||||
} xstruct;
|
||||
|
||||
[public] uint16 echo_TestRef([in] xstruct *foo);
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
struct xstruct s;
|
||||
s.x = 13;
|
||||
r.in.foo = &s;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 2)
|
||||
return 2;
|
||||
|
||||
if (ndr->data[0] != 13 || ndr->data[1] != 0)
|
||||
return 3;
|
||||
');
|
||||
|
||||
test_samba4_ndr("ptr-top-push-null",
|
||||
'
|
||||
typedef struct {
|
||||
uint16 x;
|
||||
} xstruct;
|
||||
|
||||
[public] uint16 echo_TestRef([in] xstruct *foo);
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
r.in.foo = NULL;
|
||||
|
||||
if (NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
/* Windows gives [client runtime error 0x6f4] */
|
||||
');
|
||||
|
||||
|
||||
test_samba4_ndr("refptr-top-push",
|
||||
'
|
||||
typedef struct {
|
||||
uint16 x;
|
||||
} xstruct;
|
||||
|
||||
[public] uint16 echo_TestRef([in,ref] xstruct *foo);
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
struct xstruct s;
|
||||
s.x = 13;
|
||||
r.in.foo = &s;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 2)
|
||||
return 2;
|
||||
|
||||
if (ndr->data[0] != 13 || ndr->data[1] != 0)
|
||||
return 3;
|
||||
');
|
||||
|
||||
test_samba4_ndr("refptr-top-push-null",
|
||||
'
|
||||
typedef struct {
|
||||
uint16 x;
|
||||
} xstruct;
|
||||
|
||||
[public] uint16 echo_TestRef([in,ref] xstruct *foo);
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
r.in.foo = NULL;
|
||||
|
||||
if (NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
/* Windows gives [client runtime error 0x6f4] */
|
||||
');
|
||||
|
||||
|
||||
test_samba4_ndr("uniqueptr-top-push",
|
||||
' typedef struct {
|
||||
uint16 x;
|
||||
} xstruct;
|
||||
|
||||
[public] uint16 echo_TestRef([in,unique] xstruct *foo);
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
struct xstruct s;
|
||||
s.x = 13;
|
||||
r.in.foo = &s;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 6)
|
||||
return 2;
|
||||
|
||||
if (ndr->data[0] == 0 && ndr->data[1] == 0 &&
|
||||
ndr->data[2] == 0 && ndr->data[3] == 0)
|
||||
return 3;
|
||||
|
||||
if (ndr->data[4] != 13 || ndr->data[5] != 0)
|
||||
return 4;
|
||||
');
|
||||
|
||||
test_samba4_ndr("uniqueptr-top-push-null",
|
||||
' typedef struct {
|
||||
uint16 x;
|
||||
} xstruct;
|
||||
|
||||
[public] uint16 echo_TestRef([in,unique] xstruct *foo);
|
||||
',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
r.in.foo = NULL;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 4)
|
||||
return 2;
|
||||
|
||||
if (ndr->data[0] != 0 || ndr->data[1] != 0 ||
|
||||
ndr->data[2] != 0 || ndr->data[3] != 0)
|
||||
return 3;
|
||||
');
|
||||
|
||||
|
||||
test_samba4_ndr("ptr-top-out-pull",
|
||||
'
|
||||
typedef struct {
|
||||
uint16 x;
|
||||
} xstruct;
|
||||
|
||||
[public] void echo_TestRef([out] xstruct *foo);
|
||||
',
|
||||
'
|
||||
uint8_t data[] = { 0x0D, 0x00 };
|
||||
DATA_BLOB b = { data, 2 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
|
||||
struct xstruct s;
|
||||
struct echo_TestRef r;
|
||||
|
||||
r.out.foo = &s;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_echo_TestRef(ndr, NDR_OUT, &r)))
|
||||
return 1;
|
||||
|
||||
if (!r.out.foo)
|
||||
return 2;
|
||||
|
||||
if (r.out.foo->x != 13)
|
||||
return 3;
|
||||
');
|
||||
|
||||
test_samba4_ndr("ptr-top-out-pull-null",
|
||||
'
|
||||
typedef struct {
|
||||
uint16 x;
|
||||
} xstruct;
|
||||
|
||||
[public] void echo_TestRef([out] xstruct *foo);
|
||||
',
|
||||
'
|
||||
uint8_t data[] = { 0x0D, 0x00 };
|
||||
DATA_BLOB b = { data, 2 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
|
||||
r.out.foo = NULL;
|
||||
|
||||
if (NDR_ERR_CODE_IS_SUCCESS(ndr_pull_echo_TestRef(ndr, NDR_OUT, &r)))
|
||||
return 1;
|
||||
|
||||
/* Windows gives [client runtime error 0x6f4] */
|
||||
');
|
||||
|
||||
|
||||
test_samba4_ndr("refptr-top-out-pull",
|
||||
'
|
||||
typedef struct {
|
||||
uint16 x;
|
||||
} xstruct;
|
||||
|
||||
[public] void echo_TestRef([out,ref] xstruct *foo);
|
||||
',
|
||||
'
|
||||
uint8_t data[] = { 0x0D, 0x00 };
|
||||
DATA_BLOB b = { data, 2 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
|
||||
struct xstruct s;
|
||||
struct echo_TestRef r;
|
||||
|
||||
r.out.foo = &s;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_echo_TestRef(ndr, NDR_OUT, &r)))
|
||||
return 1;
|
||||
|
||||
if (!r.out.foo)
|
||||
return 2;
|
||||
|
||||
if (r.out.foo->x != 13)
|
||||
return 3;
|
||||
');
|
||||
|
||||
test_samba4_ndr("refptr-top-out-pull-null",
|
||||
'
|
||||
typedef struct {
|
||||
uint16 x;
|
||||
} xstruct;
|
||||
|
||||
[public] void echo_TestRef([out,ref] xstruct *foo);
|
||||
',
|
||||
'
|
||||
uint8_t data[] = { 0x0D, 0x00 };
|
||||
DATA_BLOB b = { data, 2 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
|
||||
r.out.foo = NULL;
|
||||
|
||||
if (NDR_ERR_CODE_IS_SUCCESS(ndr_pull_echo_TestRef(ndr, NDR_OUT, &r)))
|
||||
return 1;
|
||||
|
||||
/* Windows gives [client runtime error 0x6f4] */
|
||||
');
|
||||
|
||||
|
||||
test_samba4_ndr("ptr-top-push-double",
|
||||
'
|
||||
[public] void echo_TestRef([in] uint16 **foo);
|
||||
',
|
||||
' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
uint16_t v = 13;
|
||||
uint16_t *pv = &v;
|
||||
r.in.foo = &pv;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 6)
|
||||
return 2;
|
||||
|
||||
if (ndr->data[0] == 0 && ndr->data[1] == 0 &&
|
||||
ndr->data[2] == 0 && ndr->data[3] == 0)
|
||||
return 3;
|
||||
|
||||
if (ndr->data[4] != 0x0D || ndr->data[5] != 0x00)
|
||||
return 4;
|
||||
');
|
||||
|
||||
SKIP: {
|
||||
skip "ptr-top-push-double-sndnull is known to fail", 8;
|
||||
|
||||
test_samba4_ndr("ptr-top-push-double-sndnull",
|
||||
'
|
||||
[public] void echo_TestRef([in] uint16 **foo);
|
||||
',
|
||||
' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
uint16_t *pv = NULL;
|
||||
r.in.foo = &pv;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 4)
|
||||
return 2;
|
||||
|
||||
if (ndr->data[0] != 0 || ndr->data[1] != 0 ||
|
||||
ndr->data[2] != 0 || ndr->data[3] != 0)
|
||||
return 3;
|
||||
');
|
||||
}
|
||||
|
||||
test_samba4_ndr("ptr-top-push-double-fstnull",
|
||||
'
|
||||
[public] void echo_TestRef([in] uint16 **foo);
|
||||
',
|
||||
' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
r.in.foo = NULL;
|
||||
|
||||
if (NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
/* Windows gives [client runtime error 0x6f4] */
|
||||
|
||||
');
|
||||
|
||||
|
||||
test_samba4_ndr("refptr-top-push-double",
|
||||
'
|
||||
[public] void echo_TestRef([in,ref] uint16 **foo);
|
||||
',
|
||||
' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
uint16_t v = 13;
|
||||
uint16_t *pv = &v;
|
||||
r.in.foo = &pv;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 6)
|
||||
return 2;
|
||||
|
||||
if (ndr->data[0] == 0 && ndr->data[1] == 0 &&
|
||||
ndr->data[2] == 0 && ndr->data[3] == 0)
|
||||
return 3;
|
||||
|
||||
if (ndr->data[4] != 0x0D || ndr->data[5] != 0x00)
|
||||
return 4;
|
||||
');
|
||||
|
||||
SKIP: {
|
||||
|
||||
skip "refptr-top-push-double-sndnull is known to fail", 8;
|
||||
|
||||
test_samba4_ndr("refptr-top-push-double-sndnull",
|
||||
'
|
||||
[public] void echo_TestRef([in,ref] uint16 **foo);
|
||||
',
|
||||
' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
uint16_t *pv = NULL;
|
||||
r.in.foo = &pv;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 4)
|
||||
return 2;
|
||||
|
||||
if (ndr->data[0] != 0 || ndr->data[1] != 0 ||
|
||||
ndr->data[2] != 0 || ndr->data[3] != 0)
|
||||
return 3;
|
||||
');
|
||||
}
|
||||
|
||||
test_samba4_ndr("refptr-top-push-double-fstnull",
|
||||
'
|
||||
[public] void echo_TestRef([in,ref] uint16 **foo);
|
||||
',
|
||||
' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
r.in.foo = NULL;
|
||||
|
||||
if (NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
/* Windows gives [client runtime error 0x6f4] */
|
||||
|
||||
');
|
||||
|
||||
SKIP: {
|
||||
skip "ignore-ptrs are not supported yet", 8;
|
||||
test_samba4_ndr("ignore-ptr",
|
||||
'
|
||||
[public] void echo_TestRef([in,ignore] uint16 *foo, [in] uint16 *bar);
|
||||
',
|
||||
' struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct echo_TestRef r;
|
||||
uint16_t v = 10;
|
||||
r.in.foo = &v;
|
||||
r.in.bar = &v;
|
||||
|
||||
if (NDR_ERR_CODE_IS_SUCCESS(ndr_push_echo_TestRef(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (ndr->offset != 4)
|
||||
return 2;
|
||||
');
|
||||
}
|
71
pidl/tests/ndr_represent.pl
Executable file
71
pidl/tests/ndr_represent.pl
Executable file
|
@ -0,0 +1,71 @@
|
|||
#!/usr/bin/perl
|
||||
# NDR represent_as() / transmit_as() tests
|
||||
# (C) 2006 Jelmer Vernooij. Published under the GNU GPL
|
||||
use strict;
|
||||
|
||||
use Test::More tests => 2 * 8;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util qw(test_samba4_ndr);
|
||||
|
||||
test_samba4_ndr('represent_as-simple',
|
||||
'
|
||||
void bla([in,represent_as(uint32)] uint8 x);
|
||||
',
|
||||
'
|
||||
uint8_t expected[] = { 0x0D };
|
||||
DATA_BLOB in_blob = { expected, 1 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&in_blob, NULL, NULL);
|
||||
struct bla r;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r)))
|
||||
return 1;
|
||||
|
||||
if (r.in.x != 13)
|
||||
return 2;
|
||||
',
|
||||
'
|
||||
enum ndr_err_code ndr_uint8_to_uint32(uint8_t from, uint32_t *to)
|
||||
{
|
||||
*to = from;
|
||||
return NDR_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
enum ndr_err_code ndr_uint32_to_uint8(uint32_t from, uint8_t *to)
|
||||
{
|
||||
*to = from;
|
||||
return NDR_ERR_SUCCESS;
|
||||
}
|
||||
'
|
||||
);
|
||||
|
||||
test_samba4_ndr('transmit_as-simple',
|
||||
'
|
||||
void bla([in,transmit_as(uint32)] uint8 x);
|
||||
',
|
||||
'
|
||||
uint8_t expected[] = { 0x0D };
|
||||
DATA_BLOB in_blob = { expected, 1 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&in_blob, NULL, NULL);
|
||||
struct bla r;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r)))
|
||||
return 1;
|
||||
|
||||
if (r.in.x != 13)
|
||||
return 2;
|
||||
',
|
||||
'
|
||||
enum ndr_err_code ndr_uint8_to_uint32(uint8_t from, uint32_t *to)
|
||||
{
|
||||
*to = from;
|
||||
return NDR_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
enum ndr_err_code ndr_uint32_to_uint8(uint32_t from, uint8_t *to)
|
||||
{
|
||||
*to = from;
|
||||
return NDR_ERR_SUCCESS;
|
||||
}
|
||||
'
|
||||
);
|
28
pidl/tests/ndr_simple.pl
Executable file
28
pidl/tests/ndr_simple.pl
Executable file
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/perl
|
||||
# Some simple tests for pidl
|
||||
# (C) 2005 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
|
||||
use Test::More tests => 8;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util qw(test_samba4_ndr);
|
||||
|
||||
test_samba4_ndr("simple", "void Test(); ",
|
||||
"
|
||||
uint8_t data[] = { 0x02 };
|
||||
uint8_t result;
|
||||
DATA_BLOB b;
|
||||
struct ndr_pull *ndr;
|
||||
|
||||
b.data = data;
|
||||
b.length = 1;
|
||||
ndr = ndr_pull_init_blob(&b, mem_ctx, NULL);
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_uint8(ndr, NDR_SCALARS, &result)))
|
||||
return 1;
|
||||
|
||||
if (result != 0x02)
|
||||
return 2;
|
||||
");
|
192
pidl/tests/ndr_string.pl
Executable file
192
pidl/tests/ndr_string.pl
Executable file
|
@ -0,0 +1,192 @@
|
|||
#!/usr/bin/perl
|
||||
# String tests for pidl
|
||||
# (C) 2005 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
|
||||
use Test::More tests => 6 * 8;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util qw(test_samba4_ndr);
|
||||
|
||||
test_samba4_ndr("string-pull-empty",
|
||||
' [public] void TestString([in,flag(STR_ASCII|LIBNDR_FLAG_STR_SIZE4)] string data);',
|
||||
'
|
||||
uint8_t data[] = { 0x00, 0x00, 0x00, 0x00 };
|
||||
DATA_BLOB b = { data, 4 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL);
|
||||
struct TestString r;
|
||||
r.in.data = NULL;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestString(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (r.in.data == NULL)
|
||||
return 2;
|
||||
|
||||
if (r.in.data[0] != 0)
|
||||
return 3;
|
||||
');
|
||||
|
||||
test_samba4_ndr("string-ascii-pull",
|
||||
'
|
||||
[public] void TestString([in,flag(STR_ASCII|LIBNDR_FLAG_STR_SIZE4)] string data);
|
||||
',
|
||||
'
|
||||
uint8_t data[] = { 0x03, 0x00, 0x00, 0x00,
|
||||
\'f\', \'o\', \'o\', 0 };
|
||||
DATA_BLOB b = { data, 8 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL);
|
||||
struct TestString r;
|
||||
r.in.data = NULL;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestString(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (r.in.data == NULL)
|
||||
return 2;
|
||||
|
||||
if (strncmp(r.in.data, "foo", 3) != 0)
|
||||
return 3;
|
||||
|
||||
if (r.in.data[4] != 0)
|
||||
return 4;
|
||||
');
|
||||
|
||||
test_samba4_ndr("string-wchar-fixed-array-01",
|
||||
'
|
||||
typedef struct {
|
||||
uint32 l1;
|
||||
[string,charset(UTF16)] uint16 str[6];
|
||||
uint32 l2;
|
||||
} TestStringStruct;
|
||||
|
||||
[public] void TestString([in,ref] TestStringStruct *str);
|
||||
',
|
||||
'
|
||||
uint8_t data[] = { 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x04, 0x00, 0x00, 0x00,
|
||||
\'f\', 0x00, \'o\', 0x00,
|
||||
\'o\', 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00
|
||||
};
|
||||
DATA_BLOB b = { data, sizeof(data) };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL);
|
||||
struct TestString r;
|
||||
struct TestStringStruct str;
|
||||
r.in.str = &str;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestString(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (r.in.str == NULL)
|
||||
return 2;
|
||||
|
||||
if (r.in.str->l1 != 0x00000001)
|
||||
return 3;
|
||||
|
||||
if (strncmp(str.str, "foo", 3) != 0)
|
||||
return 4;
|
||||
|
||||
if (r.in.str->str[4] != 0)
|
||||
return 5;
|
||||
|
||||
if (r.in.str->l2 != 0x00000002)
|
||||
return 6;
|
||||
');
|
||||
|
||||
test_samba4_ndr("string-wchar-fixed-array-02",
|
||||
'
|
||||
typedef struct {
|
||||
uint32 l1;
|
||||
[string,charset(UTF16)] uint16 str[6];
|
||||
uint32 l2;
|
||||
} TestStringStruct;
|
||||
|
||||
[public] void TestString([in,ref] TestStringStruct *str);
|
||||
',
|
||||
'
|
||||
uint8_t data[] = { 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x06, 0x00, 0x00, 0x00,
|
||||
\'f\', 0x00, \'o\', 0x00,
|
||||
\'o\', 0x00, \'b\', 0x00,
|
||||
\'a\', 0x00, \'r\', 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00
|
||||
};
|
||||
DATA_BLOB b = { data, sizeof(data) };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL);
|
||||
struct TestString r;
|
||||
struct TestStringStruct str;
|
||||
r.in.str = &str;
|
||||
|
||||
/* the string terminator is wrong */
|
||||
if (NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestString(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
');
|
||||
|
||||
test_samba4_ndr("string-wchar-fixed-array-03",
|
||||
'
|
||||
typedef struct {
|
||||
uint32 l1;
|
||||
[string,charset(UTF16)] uint16 str[6];
|
||||
uint32 l2;
|
||||
} TestStringStruct;
|
||||
|
||||
[public] void TestString([in,ref] TestStringStruct *str);
|
||||
',
|
||||
'
|
||||
uint8_t data[] = { 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x07, 0x00, 0x00, 0x00,
|
||||
\'f\', 0x00, \'o\', 0x00,
|
||||
\'o\', 0x00, \'b\', 0x00,
|
||||
\'a\', 0x00, \'r\', 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x02, 0x00, 0x00, 0x00
|
||||
};
|
||||
DATA_BLOB b = { data, sizeof(data) };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL);
|
||||
struct TestString r;
|
||||
struct TestStringStruct str;
|
||||
r.in.str = &str;
|
||||
|
||||
/* the length 0x07 is to large */
|
||||
if (NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestString(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
');
|
||||
|
||||
SKIP: {
|
||||
skip "doesn't seem to work yet", 8;
|
||||
|
||||
test_samba4_ndr("string-out",
|
||||
'
|
||||
[public] void TestString([out,string,charset(UNIX)] uint8 **data);
|
||||
',
|
||||
'
|
||||
uint8_t data[] = { 0x03, 0x00, 0x00, 0x00,
|
||||
\'f\', \'o\', \'o\', 0 };
|
||||
DATA_BLOB b = { data, 8 };
|
||||
struct ndr_pull *ndr = ndr_pull_init_blob(&b, NULL);
|
||||
struct TestString r;
|
||||
char *str = NULL;
|
||||
r.out.data = &str;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_pull_TestString(ndr, NDR_IN, &r)))
|
||||
return 1;
|
||||
|
||||
if (r.out.data == NULL)
|
||||
return 2;
|
||||
|
||||
if (*r.out.data == NULL)
|
||||
return 3;
|
||||
|
||||
if (strncmp(r.out.data, "foo", 3) != 0)
|
||||
return 4;
|
||||
|
||||
if (r.out.data[4] != 0)
|
||||
return 5;
|
||||
');
|
||||
}
|
66
pidl/tests/ndr_tagtype.pl
Executable file
66
pidl/tests/ndr_tagtype.pl
Executable file
|
@ -0,0 +1,66 @@
|
|||
#!/usr/bin/perl
|
||||
# Support for tagged types
|
||||
# (C) 2005 Jelmer Vernooij. Published under the GNU GPL
|
||||
use strict;
|
||||
|
||||
use Test::More tests => 3 * 8;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util qw(test_samba4_ndr);
|
||||
|
||||
test_samba4_ndr('struct-notypedef', '[public] struct bla { uint8 x; }; ',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct bla r;
|
||||
uint8_t expected[] = { 0x0D };
|
||||
DATA_BLOB expected_blob = { expected, 1 };
|
||||
DATA_BLOB result_blob;
|
||||
r.x = 13;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_STRUCT_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r)))
|
||||
return 1;
|
||||
|
||||
result_blob = ndr_push_blob(ndr);
|
||||
|
||||
if (data_blob_cmp(&result_blob, &expected_blob) != 0)
|
||||
return 2;
|
||||
');
|
||||
|
||||
test_samba4_ndr('struct-notypedef-used', '[public] struct bla { uint8 x; };
|
||||
[public] void myfn([in] struct bla r); ',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct myfn fn;
|
||||
uint8_t expected[] = { 0x0D };
|
||||
DATA_BLOB expected_blob = { expected, 1 };
|
||||
DATA_BLOB result_blob;
|
||||
fn.in.r.x = 13;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_myfn(ndr, NDR_IN, &fn)))
|
||||
return 1;
|
||||
|
||||
result_blob = ndr_push_blob(ndr);
|
||||
|
||||
if (data_blob_cmp(&result_blob, &expected_blob) != 0)
|
||||
return 2;
|
||||
');
|
||||
|
||||
|
||||
test_samba4_ndr('struct-notypedef-embedded', 'struct bla { uint8 x; };
|
||||
[public] struct myst { struct bla r; }; ',
|
||||
'
|
||||
struct ndr_push *ndr = ndr_push_init_ctx(NULL, NULL);
|
||||
struct myst st;
|
||||
uint8_t expected[] = { 0x0D };
|
||||
DATA_BLOB expected_blob = { expected, 1 };
|
||||
DATA_BLOB result_blob;
|
||||
st.r.x = 13;
|
||||
|
||||
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_push_STRUCT_myst(ndr, NDR_IN, &st)))
|
||||
return 1;
|
||||
|
||||
result_blob = ndr_push_blob(ndr);
|
||||
|
||||
if (data_blob_cmp(&result_blob, &expected_blob) != 0)
|
||||
return 2;
|
||||
');
|
243
pidl/tests/parse_idl.pl
Executable file
243
pidl/tests/parse_idl.pl
Executable file
|
@ -0,0 +1,243 @@
|
|||
#!/usr/bin/perl
|
||||
# Some simple tests for pidls parsing routines
|
||||
# (C) 2005 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
|
||||
use Test::More tests => 65 * 2 + 7;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util qw(test_errors);
|
||||
use Parse::Pidl::IDL;
|
||||
use Parse::Pidl::NDR;
|
||||
|
||||
sub testok($$)
|
||||
{
|
||||
my ($name, $data) = @_;
|
||||
|
||||
test_errors("", sub {
|
||||
my $pidl = Parse::Pidl::IDL::parse_string($data, "<$name>");
|
||||
ok (defined($pidl), $name);
|
||||
});
|
||||
}
|
||||
|
||||
sub testfail($$$)
|
||||
{
|
||||
my ($name, $data, $error) = @_;
|
||||
|
||||
test_errors($error, sub {
|
||||
my $pidl = Parse::Pidl::IDL::parse_string($data, "<$name>");
|
||||
|
||||
ok ((not defined $pidl), $name);
|
||||
});
|
||||
}
|
||||
|
||||
testfail "unknowntag", "bla test {};",
|
||||
"<unknowntag>:0: Syntax error near 'bla'\n";
|
||||
testok "test1", "interface test { void Test(); }; ";
|
||||
testok "voidtest", "interface test { int Testx(void); }; ";
|
||||
testfail "voidtest", "interface test { Test(); }; ",
|
||||
"<voidtest>:0: Syntax error near '('\n";
|
||||
testok "argtest", "interface test { int Test(int a, long b, uint32 c); }; ";
|
||||
testok "array1", "interface test { int Test(int a[]); };";
|
||||
testok "array2", "interface test { int Test(int a[2]); };";
|
||||
testok "array3", "interface test { int Test(int a[b]); };";
|
||||
testfail "array4", "interface test { int Test(int[] a); };",
|
||||
"<array4>:0: Syntax error near '['\n";
|
||||
testok "ptr1", "interface test { int Test(int *a); };";
|
||||
testok "ptr2", "interface test { int Test(int **a); };";
|
||||
testok "ptr3", "interface test { int Test(int ***a); };";
|
||||
testfail "empty1", "interface test { };", "<empty1>:0: Syntax error near '}'\n";
|
||||
testfail "empty2", "", "";
|
||||
testok "attr1", "[uuid(\"myuuid\"),attr] interface test { int Test(int ***a); };";
|
||||
testok "attr2", "interface test { [public] int Test(); };";
|
||||
testok "attr3", "[attr1] [attr2] interface test { [public] int Test(); };";
|
||||
testok "multfn", "interface test { int test1(); int test2(); };";
|
||||
testok "multif", "interface test { int test1(); }; interface test2 { int test2(); };";
|
||||
testok "tdstruct1", "interface test { typedef struct { } foo; };";
|
||||
testok "tdstruct2", "interface test { typedef struct { int a; } foo; };";
|
||||
testok "tdstruct3", "interface test { typedef struct { int a; int b; } foo; };";
|
||||
testfail "tdstruct4", "interface test { typedef struct { int a, int b; } foo; };",
|
||||
"<tdstruct4>:0: Syntax error near ','\n";
|
||||
testok "struct1", "interface test { struct x { }; };";
|
||||
testok "struct2", "interface test { struct x { int a; }; };";
|
||||
testok "struct3", "interface test { struct x { int a; int b; }; };";
|
||||
testfail "struct4", "interface test { struct x { int a, int b; }; };",
|
||||
"<struct4>:0: Syntax error near ','\n";
|
||||
testfail "struct5", "interface test { struct { int a; } x; };",
|
||||
"<struct5>:0: Syntax error near 'x'\n";
|
||||
testok "tdunion1", "interface test { typedef union { } a; };";
|
||||
testok "tdunion2", "interface test { typedef union { int a; } a; };";
|
||||
testok "union1", "interface test { union a { }; };";
|
||||
testok "union2", "interface test { union x { int a; }; };";
|
||||
testfail "union3", "interface test { union { int a; } x; };",
|
||||
"<union3>:0: Syntax error near 'x'\n";
|
||||
testok "typedef1", "interface test { typedef int a; };";
|
||||
testfail "typedef2", "interface test { typedef x; };",
|
||||
"<typedef2>:0: Syntax error near ';'\n";
|
||||
testok "tdenum1", "interface test { typedef enum { A=1, B=2, C} a; };";
|
||||
testok "enum1", "interface test { enum a { A=1, B=2, C}; };";
|
||||
testfail "enum2", "interface test { enum { A=1, B=2, C} a; };",
|
||||
"<enum2>:0: Syntax error near 'a'\n";
|
||||
testok "nested1", "interface test { struct x { struct { int a; } z; }; };";
|
||||
testok "nested2", "interface test { struct x { struct y { int a; } z; }; };";
|
||||
testok "bitmap1", "interface test { bitmap x { a=1 }; };";
|
||||
testok "unsigned", "interface test { struct x { unsigned short y; }; };";
|
||||
testok "struct-property", "interface test { [public] struct x { short y; }; };";
|
||||
testok "signed", "interface test { struct x { signed short y; }; };";
|
||||
testok "declarg", "interface test { void test(struct { int x; } a); };";
|
||||
testok "structarg", "interface test { void test(struct a b); };";
|
||||
testfail "structargmissing", "interface test { void test(struct a); };",
|
||||
"<structargmissing>:0: Syntax error near ')'\n";
|
||||
testok "structqual", "interface test { struct x { struct y z; }; };";
|
||||
testok "unionqual", "interface test { struct x { union y z; }; };";
|
||||
testok "enumqual", "interface test { struct x { enum y z; }; };";
|
||||
testok "bitmapqual", "interface test { struct x { bitmap y z; }; };";
|
||||
testok "emptystructdecl", "interface test { struct x; };";
|
||||
testok "emptyenumdecl", "interface test { enum x; };";
|
||||
testok "emptytdstructdecl", "interface test { typedef struct x y; };";
|
||||
testok "import", "import \"foo.idl\";";
|
||||
testok "include", "include \"foo.h\";";
|
||||
testfail "import-noquotes", "import foo.idl;",
|
||||
"<import-noquotes>:0: Syntax error near 'foo'\n";
|
||||
testfail "include-noquotes", "include foo.idl;",
|
||||
"<include-noquotes>:0: Syntax error near 'foo'\n";
|
||||
testok "importlib", "importlib \"foo.idl\";";
|
||||
testfail "import-nosemicolon", "import \"foo.idl\"",
|
||||
"<import-nosemicolon>:0: Syntax error near 'foo.idl'\n";
|
||||
testok "import-multiple", "import \"foo.idl\", \"bar.idl\";";
|
||||
testok "include-multiple", "include \"foo.idl\", \"bar.idl\";";
|
||||
testok "empty-struct", "interface test { struct foo { }; }";
|
||||
testok "typedef-double", "interface test { typedef struct foo { } foo; }";
|
||||
testok "cpp-quote", "cpp_quote(\"bla\")";
|
||||
|
||||
my $x = Parse::Pidl::IDL::parse_string("interface foo { struct x {}; }", "<foo>");
|
||||
|
||||
is_deeply($x, [ {
|
||||
'TYPE' => 'INTERFACE',
|
||||
'NAME' => 'foo',
|
||||
'DATA' => [ {
|
||||
'TYPE' => 'STRUCT',
|
||||
'NAME' => 'x',
|
||||
'ELEMENTS' => [],
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
} ],
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
}]);
|
||||
|
||||
$x = Parse::Pidl::IDL::parse_string("interface foo { struct x; }", "<foo>");
|
||||
is_deeply($x, [ {
|
||||
'TYPE' => 'INTERFACE',
|
||||
'NAME' => 'foo',
|
||||
'DATA' => [ {
|
||||
'TYPE' => 'STRUCT',
|
||||
'NAME' => 'x',
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
} ],
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
}]);
|
||||
|
||||
$x = Parse::Pidl::IDL::parse_string("cpp_quote(\"foobar\")", "<quote>");
|
||||
is_deeply($x, [ {
|
||||
'TYPE' => 'CPP_QUOTE',
|
||||
'DATA' => '"foobar"',
|
||||
'FILE' => '<quote>',
|
||||
'LINE' => 0
|
||||
}]);
|
||||
|
||||
# A typedef of a struct without body
|
||||
$x = Parse::Pidl::IDL::parse_string("interface foo { typedef struct x y; }", "<foo>");
|
||||
|
||||
is_deeply($x, [ {
|
||||
'TYPE' => 'INTERFACE',
|
||||
'NAME' => 'foo',
|
||||
'DATA' => [ {
|
||||
'TYPE' => 'TYPEDEF',
|
||||
'NAME' => 'y',
|
||||
'POINTERS' => 0,
|
||||
'DATA' => {
|
||||
'TYPE' => 'STRUCT',
|
||||
'NAME' => 'x',
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0,
|
||||
},
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0,
|
||||
} ],
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
}]);
|
||||
|
||||
# A typedef of a struct with empty body
|
||||
$x = Parse::Pidl::IDL::parse_string("interface foo { typedef struct {} y; }", "<foo>");
|
||||
|
||||
is_deeply($x, [ {
|
||||
'TYPE' => 'INTERFACE',
|
||||
'NAME' => 'foo',
|
||||
'DATA' => [ {
|
||||
'TYPE' => 'TYPEDEF',
|
||||
'NAME' => 'y',
|
||||
'POINTERS' => 0,
|
||||
'DATA' => {
|
||||
'TYPE' => 'STRUCT',
|
||||
'ELEMENTS' => [],
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
},
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
} ],
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
}]);
|
||||
|
||||
# A typedef of a bitmap with no body
|
||||
$x = Parse::Pidl::IDL::parse_string("interface foo { typedef bitmap x y; }", "<foo>");
|
||||
|
||||
is_deeply($x, [ {
|
||||
'TYPE' => 'INTERFACE',
|
||||
'NAME' => 'foo',
|
||||
'DATA' => [ {
|
||||
'TYPE' => 'TYPEDEF',
|
||||
'NAME' => 'y',
|
||||
'POINTERS' => 0,
|
||||
'DATA' => {
|
||||
'TYPE' => 'BITMAP',
|
||||
'NAME' => 'x',
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
},
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
} ],
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
}]);
|
||||
|
||||
|
||||
# A typedef of a union with no body
|
||||
$x = Parse::Pidl::IDL::parse_string("interface foo { typedef union x y; }", "<foo>");
|
||||
|
||||
is_deeply($x, [ {
|
||||
'TYPE' => 'INTERFACE',
|
||||
'NAME' => 'foo',
|
||||
'DATA' => [ {
|
||||
'TYPE' => 'TYPEDEF',
|
||||
'NAME' => 'y',
|
||||
'POINTERS' => 0,
|
||||
'DATA' => {
|
||||
'TYPE' => 'UNION',
|
||||
'NAME' => 'x',
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
},
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
} ],
|
||||
'FILE' => '<foo>',
|
||||
'LINE' => 0
|
||||
}]);
|
300
pidl/tests/samba-ndr.pl
Executable file
300
pidl/tests/samba-ndr.pl
Executable file
|
@ -0,0 +1,300 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 31;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use strict;
|
||||
use Parse::Pidl::Util qw(MyDumper);
|
||||
use Parse::Pidl::Samba4::NDR::Parser qw(check_null_pointer
|
||||
NeededFunction NeededElement NeededType
|
||||
NeededInterface TypeFunctionName ParseElementPrint);
|
||||
|
||||
my $output;
|
||||
sub print_fn($) { my $x = shift; $output.=$x; }
|
||||
|
||||
# Test case 1: Simple unique pointer dereference
|
||||
|
||||
$output = "";
|
||||
my $fn = check_null_pointer({
|
||||
PARENT => {
|
||||
ELEMENTS => [
|
||||
{
|
||||
NAME => "bla",
|
||||
LEVELS => [
|
||||
{ TYPE => "POINTER",
|
||||
POINTER_INDEX => 0,
|
||||
POINTER_TYPE => "unique" },
|
||||
{ TYPE => "DATA" }
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
}, { bla => "r->in.bla" }, \&print_fn, "return;");
|
||||
|
||||
|
||||
test_warnings("", sub { $fn->("r->in.bla"); });
|
||||
|
||||
is($output, "if (r->in.bla == NULL) return;");
|
||||
|
||||
# Test case 2: Simple ref pointer dereference
|
||||
|
||||
$output = "";
|
||||
$fn = check_null_pointer({
|
||||
PARENT => {
|
||||
ELEMENTS => [
|
||||
{
|
||||
NAME => "bla",
|
||||
LEVELS => [
|
||||
{ TYPE => "POINTER",
|
||||
POINTER_INDEX => 0,
|
||||
POINTER_TYPE => "ref" },
|
||||
{ TYPE => "DATA" }
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
}, { bla => "r->in.bla" }, \&print_fn, undef);
|
||||
|
||||
test_warnings("", sub { $fn->("r->in.bla"); });
|
||||
|
||||
is($output, "");
|
||||
|
||||
# Test case 3: Illegal dereference
|
||||
|
||||
$output = "";
|
||||
$fn = check_null_pointer({
|
||||
FILE => "nofile",
|
||||
LINE => 1,
|
||||
PARENT => {
|
||||
ELEMENTS => [
|
||||
{
|
||||
NAME => "bla",
|
||||
LEVELS => [
|
||||
{ TYPE => "DATA" }
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
}, { bla => "r->in.bla" }, \&print_fn, undef);
|
||||
|
||||
test_warnings("nofile:1: too much dereferences for `bla'\n",
|
||||
sub { $fn->("r->in.bla"); });
|
||||
|
||||
is($output, "");
|
||||
|
||||
# Test case 4: Double pointer dereference
|
||||
|
||||
$output = "";
|
||||
$fn = check_null_pointer({
|
||||
PARENT => {
|
||||
ELEMENTS => [
|
||||
{
|
||||
NAME => "bla",
|
||||
LEVELS => [
|
||||
{ TYPE => "POINTER",
|
||||
POINTER_INDEX => 0,
|
||||
POINTER_TYPE => "unique" },
|
||||
{ TYPE => "POINTER",
|
||||
POINTER_INDEX => 1,
|
||||
POINTER_TYPE => "unique" },
|
||||
{ TYPE => "DATA" }
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
}, { bla => "r->in.bla" }, \&print_fn, "return;");
|
||||
|
||||
test_warnings("",
|
||||
sub { $fn->("*r->in.bla"); });
|
||||
|
||||
is($output, "if (*r->in.bla == NULL) return;");
|
||||
|
||||
# Test case 5: Unknown variable
|
||||
|
||||
$output = "";
|
||||
$fn = check_null_pointer({
|
||||
FILE => "nofile",
|
||||
LINE => 2,
|
||||
PARENT => {
|
||||
ELEMENTS => [
|
||||
{
|
||||
NAME => "bla",
|
||||
LEVELS => [
|
||||
{ TYPE => "DATA" }
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
||||
}, { }, \&print_fn, "return;");
|
||||
|
||||
test_warnings("nofile:2: unknown dereferenced expression `r->in.bla'\n",
|
||||
sub { $fn->("r->in.bla"); });
|
||||
|
||||
is($output, "if (r->in.bla == NULL) return;");
|
||||
|
||||
my $needed = {};
|
||||
NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "pull", $needed);
|
||||
is_deeply($needed, { ndr_pull_foo => 1 });
|
||||
|
||||
# old settings should be kept
|
||||
$needed = { ndr_pull_foo => 0 };
|
||||
NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "pull", $needed);
|
||||
is_deeply($needed, { ndr_pull_foo => 0 });
|
||||
|
||||
# print/pull/push are independent of each other
|
||||
$needed = { ndr_pull_foo => 0 };
|
||||
NeededElement({ TYPE => "foo", REPRESENTATION_TYPE => "foo" }, "print", $needed);
|
||||
is_deeply($needed, { ndr_pull_foo => 0, ndr_print_foo => 1 });
|
||||
|
||||
$needed = { };
|
||||
NeededFunction({ NAME => "foo", ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] }, $needed);
|
||||
is_deeply($needed, { ndr_pull_foo => 1, ndr_print_foo => 1, ndr_push_foo => 1,
|
||||
ndr_pull_bar => 1, ndr_print_bar => 1, ndr_push_bar => 1});
|
||||
|
||||
# push/pull/print are always set for functions
|
||||
$needed = { ndr_pull_foo => 0 };
|
||||
NeededFunction({ NAME => "foo", ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] }, $needed);
|
||||
is_deeply($needed, { ndr_pull_foo => 1, ndr_print_foo => 1, ndr_push_foo => 1,
|
||||
ndr_pull_bar => 1, ndr_push_bar => 1, ndr_print_bar => 1});
|
||||
|
||||
# public structs are always needed
|
||||
$needed = {};
|
||||
NeededType({ NAME => "bla", TYPE => "TYPEDEF",
|
||||
DATA => { TYPE => "STRUCT", ELEMENTS => [] } },
|
||||
$needed, "pull");
|
||||
is_deeply($needed, { });
|
||||
|
||||
$needed = {};
|
||||
NeededInterface({ TYPES => [ { PROPERTIES => { public => 1 }, NAME => "bla",
|
||||
TYPE => "TYPEDEF",
|
||||
DATA => { TYPE => "STRUCT", ELEMENTS => [] } } ] },
|
||||
$needed);
|
||||
is_deeply($needed, { ndr_pull_bla => 1, ndr_push_bla => 1, ndr_print_bla => 1 });
|
||||
|
||||
# make sure types for elements are set too
|
||||
$needed = {};
|
||||
NeededInterface({ TYPES => [ { PROPERTIES => { public => 1 }, NAME => "bla",
|
||||
TYPE => "TYPEDEF",
|
||||
DATA => { TYPE => "STRUCT",
|
||||
ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] } } ] },
|
||||
$needed);
|
||||
is_deeply($needed, { ndr_pull_bla => 1, ndr_pull_bar => 1, ndr_push_bla => 1, ndr_push_bar => 1,
|
||||
ndr_print_bla => 1, ndr_print_bar => 1});
|
||||
|
||||
$needed = {};
|
||||
NeededInterface({ TYPES => [ { PROPERTIES => { gensize => 1}, NAME => "bla",
|
||||
TYPE => "TYPEDEF",
|
||||
DATA => { TYPE => "STRUCT",
|
||||
ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] } } ] },
|
||||
$needed);
|
||||
is_deeply($needed, { ndr_size_bla => 1 });
|
||||
|
||||
# make sure types for elements are set too
|
||||
$needed = { ndr_pull_bla => 1 };
|
||||
NeededType({ NAME => "bla",
|
||||
TYPE => "TYPEDEF",
|
||||
DATA => { TYPE => "STRUCT",
|
||||
ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "bar" } ] } },
|
||||
$needed, "pull");
|
||||
is_deeply($needed, { ndr_pull_bla => 1, ndr_pull_bar => 1 });
|
||||
|
||||
$needed = {};
|
||||
NeededInterface({ TYPES => [ { PROPERTIES => { public => 1},
|
||||
NAME => "bla",
|
||||
TYPE => "TYPEDEF",
|
||||
DATA => { TYPE => "STRUCT",
|
||||
ELEMENTS => [ { TYPE => "bar", REPRESENTATION_TYPE => "rep" } ] } } ] }, $needed);
|
||||
is_deeply($needed, { ndr_pull_bla => 1, ndr_push_bla => 1, ndr_print_bla => 1,
|
||||
ndr_print_rep => 1,
|
||||
ndr_pull_bar => 1, ndr_push_bar => 1,
|
||||
ndr_bar_to_rep => 1, ndr_rep_to_bar => 1});
|
||||
|
||||
my $generator = new Parse::Pidl::Samba4::NDR::Parser();
|
||||
$generator->ParseStructPush({
|
||||
NAME => "mystruct",
|
||||
TYPE => "STRUCT",
|
||||
PROPERTIES => {},
|
||||
ALIGN => 4,
|
||||
ELEMENTS => [ ]}, "ndr", "x");
|
||||
is($generator->{res}, "NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
|
||||
if (ndr_flags & NDR_SCALARS) {
|
||||
NDR_CHECK(ndr_push_align(ndr, 4));
|
||||
NDR_CHECK(ndr_push_trailer_align(ndr, 4));
|
||||
}
|
||||
if (ndr_flags & NDR_BUFFERS) {
|
||||
}
|
||||
");
|
||||
|
||||
$generator = new Parse::Pidl::Samba4::NDR::Parser();
|
||||
my $e = {
|
||||
NAME => "el1",
|
||||
TYPE => "mytype",
|
||||
REPRESENTATION_TYPE => "mytype",
|
||||
PROPERTIES => {},
|
||||
LEVELS => [
|
||||
{ LEVEL_INDEX => 0, TYPE => "DATA", DATA_TYPE => "mytype" }
|
||||
] };
|
||||
$generator->ParseStructPush({
|
||||
NAME => "mystruct",
|
||||
TYPE => "STRUCT",
|
||||
PROPERTIES => {},
|
||||
ALIGN => 4,
|
||||
SURROUNDING_ELEMENT => $e,
|
||||
ELEMENTS => [ $e ]}, "ndr", "x");
|
||||
is($generator->{res}, "NDR_PUSH_CHECK_FLAGS(ndr, ndr_flags);
|
||||
if (ndr_flags & NDR_SCALARS) {
|
||||
NDR_CHECK(ndr_push_uint3264(ndr, NDR_SCALARS, ndr_string_array_size(ndr, x->el1)));
|
||||
NDR_CHECK(ndr_push_align(ndr, 4));
|
||||
NDR_CHECK(ndr_push_mytype(ndr, NDR_SCALARS, &x->el1));
|
||||
NDR_CHECK(ndr_push_trailer_align(ndr, 4));
|
||||
}
|
||||
if (ndr_flags & NDR_BUFFERS) {
|
||||
}
|
||||
");
|
||||
|
||||
is(TypeFunctionName("ndr_pull", "uint32"), "ndr_pull_uint32");
|
||||
is(TypeFunctionName("ndr_pull", {TYPE => "ENUM", NAME => "bar"}), "ndr_pull_ENUM_bar");
|
||||
is(TypeFunctionName("ndr_pull", {TYPE => "TYPEDEF", NAME => "bar", DATA => undef}), "ndr_pull_bar");
|
||||
is(TypeFunctionName("ndr_push", {TYPE => "STRUCT", NAME => "bar"}), "ndr_push_STRUCT_bar");
|
||||
|
||||
# check noprint works
|
||||
$generator = new Parse::Pidl::Samba4::NDR::Parser();
|
||||
$generator->ParseElementPrint({ NAME => "x", TYPE => "rt", REPRESENTATION_TYPE => "rt",
|
||||
PROPERTIES => { noprint => 1},
|
||||
LEVELS => [ { TYPE => "DATA", DATA_TYPE => "rt"} ]},
|
||||
"ndr", "var", { "x" => "r->foobar" } );
|
||||
is($generator->{res}, "");
|
||||
|
||||
$generator = new Parse::Pidl::Samba4::NDR::Parser();
|
||||
$generator->ParseElementPrint({ NAME => "x", TYPE => "rt", REPRESENTATION_TYPE => "rt",
|
||||
PROPERTIES => {},
|
||||
LEVELS => [ { TYPE => "DATA", DATA_TYPE => "rt" }]},
|
||||
"ndr", "var", { "x" => "r->foobar" } );
|
||||
is($generator->{res}, "ndr_print_rt(ndr, \"x\", &var);\n");
|
||||
|
||||
# make sure that a print function for an element with value() set works
|
||||
$generator = new Parse::Pidl::Samba4::NDR::Parser();
|
||||
$generator->ParseElementPrint({ NAME => "x", TYPE => "uint32", REPRESENTATION_TYPE => "uint32",
|
||||
PROPERTIES => { value => "23" },
|
||||
LEVELS => [ { TYPE => "DATA", DATA_TYPE => "uint32"} ]},
|
||||
"ndr", "var", { "x" => "r->foobar" } );
|
||||
is($generator->{res}, "ndr_print_uint32(ndr, \"x\", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?23:var);\n");
|
||||
|
||||
$generator = new Parse::Pidl::Samba4::NDR::Parser();
|
||||
$generator->AuthServiceStruct("bridge", "\"rot13\",\"onetimepad\"");
|
||||
is($generator->{res}, "static const char * const bridge_authservice_strings[] = {
|
||||
\"rot13\",
|
||||
\"onetimepad\",
|
||||
};
|
||||
|
||||
static const struct ndr_interface_string_array bridge_authservices = {
|
||||
.count = 2,
|
||||
.names = bridge_authservice_strings
|
||||
};
|
||||
|
||||
");
|
236
pidl/tests/samba3-cli.pl
Executable file
236
pidl/tests/samba3-cli.pl
Executable file
|
@ -0,0 +1,236 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 8;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl::Util qw(MyDumper);
|
||||
use Parse::Pidl::Samba3::ClientNDR qw(ParseFunction);
|
||||
use Parse::Pidl::Samba4::Header qw(GenerateFunctionInEnv GenerateFunctionOutEnv);
|
||||
|
||||
# Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work
|
||||
my $fn = { ELEMENTS => [ { DIRECTION => ["in"], NAME => "foo" } ] };
|
||||
is_deeply({ "foo" => "r.in.foo" }, GenerateFunctionInEnv($fn, "r."));
|
||||
is_deeply({ "foo" => "r.in.foo" }, GenerateFunctionOutEnv($fn, "r."));
|
||||
|
||||
$fn = { ELEMENTS => [ { DIRECTION => ["out", "in"], NAME => "foo" } ] };
|
||||
is_deeply({ "foo" => "r.in.foo" }, GenerateFunctionInEnv($fn, "r."));
|
||||
is_deeply({ "foo" => "r.out.foo" }, GenerateFunctionOutEnv($fn, "r."));
|
||||
|
||||
$fn = { ELEMENTS => [ { DIRECTION => ["out"], NAME => "foo" } ] };
|
||||
is_deeply({ }, GenerateFunctionInEnv($fn, "r."));
|
||||
is_deeply({ "foo" => "r.out.foo" }, GenerateFunctionOutEnv($fn, "r."));
|
||||
|
||||
my $x = new Parse::Pidl::Samba3::ClientNDR();
|
||||
|
||||
$fn = { NAME => "bar", ELEMENTS => [ ] };
|
||||
$x->ParseFunction("foo", $fn);
|
||||
is($x->{res},
|
||||
"struct rpccli_bar_state {
|
||||
TALLOC_CTX *out_mem_ctx;
|
||||
};
|
||||
|
||||
static void rpccli_bar_done(struct tevent_req *subreq);
|
||||
|
||||
struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct rpc_pipe_client *cli)
|
||||
{
|
||||
struct tevent_req *req;
|
||||
struct rpccli_bar_state *state;
|
||||
struct tevent_req *subreq;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct rpccli_bar_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
state->out_mem_ctx = NULL;
|
||||
|
||||
subreq = dcerpc_bar_send(state,
|
||||
ev,
|
||||
cli->binding_handle);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
tevent_req_set_callback(subreq, rpccli_bar_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void rpccli_bar_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct rpccli_bar_state *state = tevent_req_data(
|
||||
req, struct rpccli_bar_state);
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
if (state->out_mem_ctx) {
|
||||
mem_ctx = state->out_mem_ctx;
|
||||
} else {
|
||||
mem_ctx = state;
|
||||
}
|
||||
|
||||
status = dcerpc_bar_recv(subreq,
|
||||
mem_ctx);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
tevent_req_nterror(req, status);
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
NTSTATUS rpccli_bar_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
struct rpccli_bar_state *state = tevent_req_data(
|
||||
req, struct rpccli_bar_state);
|
||||
NTSTATUS status;
|
||||
|
||||
if (tevent_req_is_nterror(req, &status)) {
|
||||
tevent_req_received(req);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Steal possible out parameters to the callers context */
|
||||
talloc_steal(mem_ctx, state->out_mem_ctx);
|
||||
|
||||
tevent_req_received(req);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS rpccli_bar(struct rpc_pipe_client *cli,
|
||||
TALLOC_CTX *mem_ctx)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
status = dcerpc_bar(cli->binding_handle,
|
||||
mem_ctx);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Return result */
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
");
|
||||
|
||||
$x = new Parse::Pidl::Samba3::ClientNDR();
|
||||
|
||||
$fn = { NAME => "bar", ELEMENTS => [ ], RETURN_TYPE => "WERROR" };
|
||||
$x->ParseFunction("foo", $fn);
|
||||
is($x->{res},
|
||||
"struct rpccli_bar_state {
|
||||
TALLOC_CTX *out_mem_ctx;
|
||||
WERROR result;
|
||||
};
|
||||
|
||||
static void rpccli_bar_done(struct tevent_req *subreq);
|
||||
|
||||
struct tevent_req *rpccli_bar_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct rpc_pipe_client *cli)
|
||||
{
|
||||
struct tevent_req *req;
|
||||
struct rpccli_bar_state *state;
|
||||
struct tevent_req *subreq;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct rpccli_bar_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
state->out_mem_ctx = NULL;
|
||||
|
||||
subreq = dcerpc_bar_send(state,
|
||||
ev,
|
||||
cli->binding_handle);
|
||||
if (tevent_req_nomem(subreq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
tevent_req_set_callback(subreq, rpccli_bar_done, req);
|
||||
return req;
|
||||
}
|
||||
|
||||
static void rpccli_bar_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct tevent_req *req = tevent_req_callback_data(
|
||||
subreq, struct tevent_req);
|
||||
struct rpccli_bar_state *state = tevent_req_data(
|
||||
req, struct rpccli_bar_state);
|
||||
NTSTATUS status;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
if (state->out_mem_ctx) {
|
||||
mem_ctx = state->out_mem_ctx;
|
||||
} else {
|
||||
mem_ctx = state;
|
||||
}
|
||||
|
||||
status = dcerpc_bar_recv(subreq,
|
||||
mem_ctx,
|
||||
&state->result);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
tevent_req_nterror(req, status);
|
||||
return;
|
||||
}
|
||||
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
NTSTATUS rpccli_bar_recv(struct tevent_req *req,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
WERROR *result)
|
||||
{
|
||||
struct rpccli_bar_state *state = tevent_req_data(
|
||||
req, struct rpccli_bar_state);
|
||||
NTSTATUS status;
|
||||
|
||||
if (tevent_req_is_nterror(req, &status)) {
|
||||
tevent_req_received(req);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Steal possible out parameters to the callers context */
|
||||
talloc_steal(mem_ctx, state->out_mem_ctx);
|
||||
|
||||
/* Return result */
|
||||
*result = state->result;
|
||||
|
||||
tevent_req_received(req);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
NTSTATUS rpccli_bar(struct rpc_pipe_client *cli,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
WERROR *werror)
|
||||
{
|
||||
WERROR result;
|
||||
NTSTATUS status;
|
||||
|
||||
status = dcerpc_bar(cli->binding_handle,
|
||||
mem_ctx,
|
||||
&result);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Return result */
|
||||
if (werror) {
|
||||
*werror = result;
|
||||
}
|
||||
|
||||
return werror_to_ntstatus(result);
|
||||
}
|
||||
|
||||
");
|
||||
|
18
pidl/tests/samba3-srv.pl
Executable file
18
pidl/tests/samba3-srv.pl
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2008 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 1;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl::Util qw(MyDumper has_property);
|
||||
use Parse::Pidl::Samba3::ServerNDR qw(DeclLevel);
|
||||
|
||||
my $l = { TYPE => "DATA", DATA_TYPE => "uint32" };
|
||||
my $e = { FILE => "foo", LINE => 0, PROPERTIES => { }, TYPE => "uint32",
|
||||
LEVELS => [ $l ] };
|
||||
|
||||
is("uint32_t", DeclLevel($e, 0));
|
49
pidl/tests/tdr.pl
Executable file
49
pidl/tests/tdr.pl
Executable file
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 6;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl::Samba4::TDR qw(ParserType);
|
||||
|
||||
my $tdr = new Parse::Pidl::Samba4::TDR();
|
||||
|
||||
$tdr->ParserType({TYPE => "STRUCT", NAME => "foo", PROPERTIES => {public => 1}}, "pull");
|
||||
is($tdr->{ret}, "NTSTATUS tdr_pull_foo (struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, struct foo *v)
|
||||
{
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
");
|
||||
is($tdr->{ret_hdr}, "NTSTATUS tdr_pull_foo (struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, struct foo *v);\n");
|
||||
|
||||
|
||||
$tdr = new Parse::Pidl::Samba4::TDR();
|
||||
$tdr->ParserType({TYPE => "UNION", NAME => "bar", PROPERTIES => {public => 1}}, "pull");
|
||||
is($tdr->{ret}, "NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, int level, union bar *v)
|
||||
{
|
||||
switch (level) {
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
|
||||
}
|
||||
|
||||
");
|
||||
is($tdr->{ret_hdr}, "NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, int level, union bar *v);\n");
|
||||
|
||||
$tdr = new Parse::Pidl::Samba4::TDR();
|
||||
$tdr->ParserType({TYPE => "UNION", NAME => "bar", PROPERTIES => {}}, "pull");
|
||||
is($tdr->{ret}, "static NTSTATUS tdr_pull_bar(struct tdr_pull *tdr, TALLOC_CTX *mem_ctx, int level, union bar *v)
|
||||
{
|
||||
switch (level) {
|
||||
}
|
||||
return NT_STATUS_OK;
|
||||
|
||||
}
|
||||
|
||||
");
|
||||
is($tdr->{ret_hdr}, "");
|
21
pidl/tests/test_util.pl
Executable file
21
pidl/tests/test_util.pl
Executable file
|
@ -0,0 +1,21 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
|
||||
use Test::More tests => 6;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util qw(test_warnings test_errors);
|
||||
use Parse::Pidl qw(warning error);
|
||||
|
||||
test_warnings("", sub {});
|
||||
|
||||
test_warnings("x:1: msg\n", sub { warning({FILE => "x", LINE => 1}, "msg"); });
|
||||
test_warnings("", sub {});
|
||||
|
||||
test_errors("", sub {});
|
||||
|
||||
test_errors("x:1: msg\n", sub { error({FILE => "x", LINE => 1}, "msg"); });
|
||||
test_errors("", sub {});
|
||||
|
93
pidl/tests/typelist.pl
Executable file
93
pidl/tests/typelist.pl
Executable file
|
@ -0,0 +1,93 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 56;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl::Typelist qw(hasType typeHasBody getType mapTypeName expandAlias
|
||||
mapScalarType addType typeIs is_scalar scalar_is_reference
|
||||
enum_type_fn bitmap_type_fn mapType);
|
||||
|
||||
is("foo", expandAlias("foo"));
|
||||
is("uint32", expandAlias("DWORD"));
|
||||
is("int32", expandAlias("int"));
|
||||
is("", expandAlias(""));
|
||||
is("int32", expandAlias("int32"));
|
||||
|
||||
is("uint32_t", mapScalarType("uint32"));
|
||||
is("void", mapScalarType("void"));
|
||||
is("uint64_t", mapScalarType("hyper"));
|
||||
is("double", mapScalarType("double"));
|
||||
|
||||
my $x = { TYPE => "ENUM", NAME => "foo", EXTRADATA => 1 };
|
||||
addType($x);
|
||||
is_deeply($x, getType("foo"));
|
||||
is(undef, getType("bloebla"));
|
||||
is_deeply(getType({ TYPE => "STRUCT" }), { TYPE => "STRUCT" });
|
||||
is_deeply(getType({ TYPE => "ENUM", NAME => "foo" }), $x);
|
||||
is_deeply(getType("uint16"), {
|
||||
NAME => "uint16",
|
||||
BASEFILE => "<builtin>",
|
||||
TYPE => "TYPEDEF",
|
||||
DATA => { NAME => "uint16", TYPE => "SCALAR" }});
|
||||
|
||||
is_deeply(getType("double"), {
|
||||
NAME => "double",
|
||||
BASEFILE => "<builtin>",
|
||||
TYPE => "TYPEDEF",
|
||||
DATA => { NAME => "double", TYPE => "SCALAR" }});
|
||||
|
||||
is(0, typeIs("someUnknownType", "ENUM"));
|
||||
is(0, typeIs("foo", "ENUM"));
|
||||
addType({NAME => "mytypedef", TYPE => "TYPEDEF", DATA => { TYPE => "ENUM" }});
|
||||
is(1, typeIs("mytypedef", "ENUM"));
|
||||
is(0, typeIs("mytypedef", "BITMAP"));
|
||||
is(1, typeIs({ TYPE => "ENUM"}, "ENUM"));
|
||||
is(0, typeIs({ TYPE => "BITMAP"}, "ENUM"));
|
||||
is(1, typeIs("uint32", "SCALAR"));
|
||||
is(0, typeIs("uint32", "ENUM"));
|
||||
|
||||
is(1, hasType("foo"));
|
||||
is(0, hasType("nonexistant"));
|
||||
is(0, hasType({TYPE => "ENUM", NAME => "someUnknownType"}));
|
||||
is(1, hasType({TYPE => "ENUM", NAME => "foo"}));
|
||||
is(1, hasType({TYPE => "ENUM"}));
|
||||
is(1, hasType({TYPE => "STRUCT"}));
|
||||
|
||||
is(1, is_scalar("uint32"));
|
||||
is(0, is_scalar("nonexistant"));
|
||||
is(1, is_scalar({TYPE => "ENUM"}));
|
||||
is(0, is_scalar({TYPE => "STRUCT"}));
|
||||
is(1, is_scalar({TYPE => "TYPEDEF", DATA => {TYPE => "ENUM" }}));
|
||||
is(1, is_scalar("mytypedef"));
|
||||
|
||||
is(1, scalar_is_reference("string"));
|
||||
is(0, scalar_is_reference("uint32"));
|
||||
is(0, scalar_is_reference({TYPE => "STRUCT", NAME => "echo_foobar"}));
|
||||
|
||||
is("uint8", enum_type_fn({TYPE => "ENUM", PARENT=>{PROPERTIES => {enum8bit => 1}}}));
|
||||
is("uint32", enum_type_fn({TYPE => "ENUM", PARENT=>{PROPERTIES => {v1_enum => 1}}}));
|
||||
is("uint1632", enum_type_fn({TYPE => "ENUM", PARENT=>{PROPERTIES => {}}}));
|
||||
|
||||
is("uint8", bitmap_type_fn({TYPE => "BITMAP", PROPERTIES => {bitmap8bit => 1}}));
|
||||
is("uint16", bitmap_type_fn({TYPE => "BITMAP", PROPERTIES => {bitmap16bit => 1}}));
|
||||
is("hyper", bitmap_type_fn({TYPE => "BITMAP", PROPERTIES => {bitmap64bit => 1}}));
|
||||
is("uint32", bitmap_type_fn({TYPE => "BITMAP", PROPERTIES => {}}));
|
||||
|
||||
is("enum foo", mapType({TYPE => "ENUM"}, "foo"));
|
||||
is("union foo", mapType({TYPE => "UNION"}, "foo"));
|
||||
is("struct foo", mapType({TYPE => "STRUCT"}, "foo"));
|
||||
is("uint8_t", mapType({TYPE => "BITMAP", PROPERTIES => {bitmap8bit => 1}}, "foo"));
|
||||
is("uint8_t", mapType({TYPE => "SCALAR"}, "uint8"));
|
||||
is("uint32_t", mapType({TYPE => "TYPEDEF", DATA => {TYPE => "SCALAR"}}, "uint32"));
|
||||
|
||||
is("void", mapTypeName(undef));
|
||||
is("uint32_t", mapTypeName("uint32"));
|
||||
is("int32_t", mapTypeName("int"));
|
||||
|
||||
ok(not typeHasBody({TYPE => "TYPEDEF", DATA => { TYPE => "STRUCT" }}));
|
||||
ok(typeHasBody({TYPE => "TYPEDEF", DATA => { TYPE => "STRUCT", ELEMENTS => [] }}));
|
115
pidl/tests/util.pl
Executable file
115
pidl/tests/util.pl
Executable file
|
@ -0,0 +1,115 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 72;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl qw(error);
|
||||
use Parse::Pidl::Util;
|
||||
|
||||
# has_property()
|
||||
is(undef, has_property({}, "foo"));
|
||||
is(undef, has_property({PROPERTIES => {}}, "foo"));
|
||||
is("data", has_property({PROPERTIES => {foo => "data"}}, "foo"));
|
||||
is(undef, has_property({PROPERTIES => {foo => undef}}, "foo"));
|
||||
|
||||
# is_constant()
|
||||
ok(is_constant("2"));
|
||||
ok(is_constant("256"));
|
||||
ok(is_constant("0x400"));
|
||||
ok(is_constant("0x4BC"));
|
||||
ok(not is_constant("0x4BGC"));
|
||||
ok(not is_constant("str"));
|
||||
ok(not is_constant("2 * expr"));
|
||||
|
||||
# make_str()
|
||||
is("\"bla\"", make_str("bla"));
|
||||
is("\"bla\"", make_str("\"bla\""));
|
||||
is("\"\"bla\"\"", make_str("\"\"bla\"\""));
|
||||
is("\"bla\"\"", make_str("bla\""));
|
||||
is("\"foo\"bar\"", make_str("foo\"bar"));
|
||||
|
||||
is("bla", unmake_str("\"bla\""));
|
||||
is("\"bla\"", unmake_str("\"\"bla\"\""));
|
||||
|
||||
# print_uuid()
|
||||
is(undef, print_uuid("invalid"));
|
||||
is("{0x12345778,0x1234,0xabcd,{0xef,0x00},{0x01,0x23,0x45,0x67,0x89,0xac}}",
|
||||
print_uuid("12345778-1234-abcd-ef00-0123456789ac"));
|
||||
is("{0x12345778,0x1234,0xabcd,{0xef,0x00},{0x01,0x23,0x45,0x67,0x89,0xac}}",
|
||||
print_uuid("\"12345778-1234-abcd-ef00-0123456789ac\""));
|
||||
|
||||
# property_matches()
|
||||
# missing property
|
||||
ok(not property_matches({PROPERTIES => {}}, "x", "data"));
|
||||
# data not matching
|
||||
ok(not property_matches({PROPERTIES => {x => "bar"}}, "x", "data"));
|
||||
# data matching exactly
|
||||
ok(property_matches({PROPERTIES => {x => "data"}}, "x", "data"));
|
||||
# regex matching
|
||||
ok(property_matches({PROPERTIES => {x => "data"}}, "x", "^([dat]+)\$"));
|
||||
|
||||
# ParseExpr()
|
||||
is(undef, ParseExpr("", {}, undef));
|
||||
is("a", ParseExpr("a", {"b" => "2"}, undef));
|
||||
is("2", ParseExpr("a", {"a" => "2"}, undef));
|
||||
is("2 * 2", ParseExpr("a*a", {"a" => "2"}, undef));
|
||||
is("r->length + r->length",
|
||||
ParseExpr("length+length", {"length" => "r->length"}, undef));
|
||||
is("2 / 2 * (r->length)",
|
||||
ParseExpr("constant/constant*(len)", {"constant" => "2",
|
||||
"len" => "r->length"}, undef));
|
||||
is("2 + 2 - r->length",
|
||||
ParseExpr("constant+constant-len", {"constant" => "2",
|
||||
"len" => "r->length"}, undef));
|
||||
is("*r->length", ParseExpr("*len", { "len" => "r->length"}, undef));
|
||||
is("**r->length", ParseExpr("**len", { "len" => "r->length"}, undef));
|
||||
is("r->length & 2", ParseExpr("len&2", { "len" => "r->length"}, undef));
|
||||
is("&r->length", ParseExpr("&len", { "len" => "r->length"}, undef));
|
||||
is("calc()", ParseExpr("calc()", { "foo" => "2"}, undef));
|
||||
is("calc(2 * 2)", ParseExpr("calc(foo * 2)", { "foo" => "2"}, undef));
|
||||
is("strlen(\"data\")", ParseExpr("strlen(foo)", { "foo" => "\"data\""}, undef));
|
||||
is("strlen(\"data\", 4)", ParseExpr("strlen(foo, 4)", { "foo" => "\"data\""}, undef));
|
||||
is("foo / bar", ParseExpr("foo / bar", { "bla" => "\"data\""}, undef));
|
||||
is("r->length % 2", ParseExpr("len%2", { "len" => "r->length"}, undef));
|
||||
is("r->length == 2", ParseExpr("len==2", { "len" => "r->length"}, undef));
|
||||
is("r->length != 2", ParseExpr("len!=2", { "len" => "r->length"}, undef));
|
||||
is("pr->length", ParseExpr("pr->length", { "p" => "r"}, undef));
|
||||
is("r->length", ParseExpr("p->length", { "p" => "r"}, undef));
|
||||
is("_foo / bla32", ParseExpr("_foo / bla32", { "bla" => "\"data\""}, undef));
|
||||
is("foo.bar.blah", ParseExpr("foo.blah", { "foo" => "foo.bar"}, undef));
|
||||
is("\"bla\"", ParseExpr("\"bla\"", {}, undef));
|
||||
is("1 << 2", ParseExpr("1 << 2", {}, undef));
|
||||
is("1 >> 2", ParseExpr("1 >> 2", {}, undef));
|
||||
is("0x200", ParseExpr("0x200", {}, undef));
|
||||
is("2?3:0", ParseExpr("2?3:0", {}, undef));
|
||||
is("~0", ParseExpr("~0", {}, undef));
|
||||
is("b->a->a", ParseExpr("a->a->a", {"a" => "b"}, undef));
|
||||
is("b.a.a", ParseExpr("a.a.a", {"a" => "b"}, undef));
|
||||
|
||||
test_errors("nofile:0: Parse error in `~' near `~'\n", sub {
|
||||
is(undef, ParseExpr("~", {}, {FILE => "nofile", LINE => 0})); });
|
||||
|
||||
test_errors("nofile:0: Got pointer, expected integer\n", sub {
|
||||
is(undef, ParseExprExt("foo", {}, {FILE => "nofile", LINE => 0},
|
||||
undef, sub { my $x = shift;
|
||||
error({FILE => "nofile", LINE => 0},
|
||||
"Got pointer, expected integer");
|
||||
return undef; }))});
|
||||
|
||||
is("b.a.a", ParseExpr("b.a.a", {"a" => "b"}, undef));
|
||||
is("((rr_type) == NBT_QTYPE_NETBIOS)", ParseExpr("((rr_type)==NBT_QTYPE_NETBIOS)", {}, undef));
|
||||
is("talloc_check_name", ParseExpr("talloc_check_name", {}, undef));
|
||||
is("talloc_check_name()", ParseExpr("talloc_check_name()", {}, undef));
|
||||
is("talloc_check_name(ndr)", ParseExpr("talloc_check_name(ndr)", {}, undef));
|
||||
is("talloc_check_name(ndr, 1)", ParseExpr("talloc_check_name(ndr,1)", {}, undef));
|
||||
is("talloc_check_name(ndr, \"struct ndr_push\")", ParseExpr("talloc_check_name(ndr,\"struct ndr_push\")", {}, undef));
|
||||
is("((rr_type) == NBT_QTYPE_NETBIOS) && talloc_check_name(ndr, \"struct ndr_push\")", ParseExpr("((rr_type)==NBT_QTYPE_NETBIOS)&&talloc_check_name(ndr,\"struct ndr_push\")", {}, undef));
|
||||
is("(rdata).data.length", ParseExpr("(rdata).data.length", {}, undef));
|
||||
is("((rdata).data.length == 2)", ParseExpr("((rdata).data.length==2)", {}, undef));
|
||||
is("((rdata).data.length == 2)?0:rr_type", ParseExpr("((rdata).data.length==2)?0:rr_type", {}, undef));
|
||||
is("((((rr_type) == NBT_QTYPE_NETBIOS) && talloc_check_name(ndr, \"struct ndr_push\") && ((rdata).data.length == 2))?0:rr_type)", ParseExpr("((((rr_type)==NBT_QTYPE_NETBIOS)&&talloc_check_name(ndr,\"struct ndr_push\")&&((rdata).data.length==2))?0:rr_type)", {}, undef));
|
205
pidl/tests/wireshark-conf.pl
Executable file
205
pidl/tests/wireshark-conf.pl
Executable file
|
@ -0,0 +1,205 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
# test parsing wireshark conformance files
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 49;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl::Util qw(MyDumper);
|
||||
use Parse::Pidl::Wireshark::Conformance qw(ReadConformanceFH valid_ft_type valid_base_type);
|
||||
|
||||
sub parse_conf($)
|
||||
{
|
||||
my $str = shift;
|
||||
open(TMP, "+>", undef) or die("unable to open temp file");
|
||||
print TMP $str;
|
||||
seek(TMP, 0, 0);
|
||||
my $data = {};
|
||||
ReadConformanceFH(*TMP, $data, "nofile") or return undef;
|
||||
close(TMP);
|
||||
return $data;
|
||||
}
|
||||
|
||||
ok(parse_conf("\n"), undef);
|
||||
ok(parse_conf(" \n"), undef);
|
||||
ok(parse_conf("CODE START\nCODE END\n"));
|
||||
test_warnings("nofile:1: Expecting CODE END\n", sub { is(parse_conf("CODE START\n"), undef); });
|
||||
ok(parse_conf("#foobar\n"), undef);
|
||||
test_warnings("nofile:1: Unknown command `foobar'\n",
|
||||
sub { ok(parse_conf("foobar\n"), undef); });
|
||||
|
||||
test_warnings("nofile:1: incomplete HF_RENAME command\n",
|
||||
sub { parse_conf("HF_RENAME\n"); });
|
||||
|
||||
is_deeply(parse_conf("HF_RENAME foo bar\n")->{hf_renames}->{foo},
|
||||
{ OLDNAME => "foo", NEWNAME => "bar", POS => {FILE => "nofile", LINE => 1}, USED => 0});
|
||||
|
||||
is_deeply(parse_conf("NOEMIT\n"), { "noemit_dissector" => 1 });
|
||||
is_deeply(parse_conf("NOEMIT foo\n"), { "noemit" => { "foo" => 1 } });
|
||||
|
||||
test_warnings("nofile:1: incomplete MANUAL command\n",
|
||||
sub { parse_conf("MANUAL\n"); } );
|
||||
|
||||
is_deeply(parse_conf("MANUAL foo\n"), { manual => {foo => 1}});
|
||||
|
||||
test_errors("nofile:1: incomplete INCLUDE command\n",
|
||||
sub { parse_conf("INCLUDE\n"); } );
|
||||
|
||||
test_warnings("nofile:1: incomplete FIELD_DESCRIPTION command\n",
|
||||
sub { parse_conf("FIELD_DESCRIPTION foo\n"); });
|
||||
|
||||
is_deeply(parse_conf("FIELD_DESCRIPTION foo \"my description\"\n"),
|
||||
{ fielddescription => { foo => { DESCRIPTION => "\"my description\"", POS => { FILE => "nofile", LINE => 1}, USED => 0 }}});
|
||||
|
||||
is_deeply(parse_conf("FIELD_DESCRIPTION foo my description\n"),
|
||||
{ fielddescription => { foo => { DESCRIPTION => "my", POS => { FILE => "nofile", LINE => 1}, USED => 0 }}});
|
||||
|
||||
is_deeply(parse_conf("CODE START\ndata\nCODE END\n"), { override => "data\n" });
|
||||
is_deeply(parse_conf("CODE START\ndata\nmore data\nCODE END\n"), { override => "data\nmore data\n" });
|
||||
test_warnings("nofile:1: Unknown command `CODE'\n",
|
||||
sub { parse_conf("CODE END\n"); } );
|
||||
|
||||
is_deeply(parse_conf("TYPE winreg_String dissect_myminregstring(); FT_STRING BASE_DEC 0 0 2\n"), { types => { winreg_String => {
|
||||
NAME => "winreg_String",
|
||||
POS => { FILE => "nofile", LINE => 1 },
|
||||
USED => 0,
|
||||
DISSECTOR_NAME => "dissect_myminregstring();",
|
||||
FT_TYPE => "FT_STRING",
|
||||
BASE_TYPE => "BASE_DEC",
|
||||
MASK => 0,
|
||||
VALSSTRING => 0,
|
||||
ALIGNMENT => 2}}});
|
||||
|
||||
ok(valid_ft_type("FT_UINT32"));
|
||||
ok(not valid_ft_type("BLA"));
|
||||
ok(not valid_ft_type("ft_uint32"));
|
||||
ok(valid_ft_type("FT_BLA"));
|
||||
|
||||
ok(valid_base_type("BASE_DEC"));
|
||||
ok(valid_base_type("BASE_HEX"));
|
||||
ok(not valid_base_type("base_dec"));
|
||||
ok(not valid_base_type("BLA"));
|
||||
ok(not valid_base_type("BASEDEC"));
|
||||
|
||||
test_errors("nofile:1: incomplete TYPE command\n",
|
||||
sub { parse_conf("TYPE mytype dissector\n"); });
|
||||
|
||||
test_warnings("nofile:1: dissector name does not contain `dissect'\n",
|
||||
sub { parse_conf("TYPE winreg_String myminregstring; FT_STRING BASE_DEC 0 0 2\n"); });
|
||||
|
||||
test_warnings("nofile:1: invalid FT_TYPE `BLA'\n",
|
||||
sub { parse_conf("TYPE winreg_String dissect_myminregstring; BLA BASE_DEC 0 0 2\n"); });
|
||||
|
||||
test_warnings("nofile:1: invalid BASE_TYPE `BLOE'\n",
|
||||
sub { parse_conf("TYPE winreg_String dissect_myminregstring; FT_UINT32 BLOE 0 0 2\n"); });
|
||||
|
||||
is_deeply(parse_conf("TFS hf_bla \"True string\" \"False String\"\n"),
|
||||
{ tfs => { hf_bla => {
|
||||
TRUE_STRING => "\"True string\"",
|
||||
FALSE_STRING => "\"False String\"" } } });
|
||||
|
||||
test_errors("nofile:1: incomplete TFS command\n",
|
||||
sub { parse_conf("TFS hf_bla \"Trues\""); } );
|
||||
|
||||
test_errors("nofile:1: incomplete PARAM_VALUE command\n",
|
||||
sub { parse_conf("PARAM_VALUE\n"); });
|
||||
|
||||
is_deeply(parse_conf("PARAM_VALUE Life 42\n"),
|
||||
{ dissectorparams => {
|
||||
Life => {
|
||||
DISSECTOR => "Life",
|
||||
POS => { FILE => "nofile", LINE => 1 },
|
||||
PARAM => 42,
|
||||
USED => 0
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
is_deeply(parse_conf("STRIP_PREFIX bla_\n"),
|
||||
{ strip_prefixes => [ "bla_" ] });
|
||||
|
||||
is_deeply(parse_conf("STRIP_PREFIX bla_\nSTRIP_PREFIX bloe\n"),
|
||||
{ strip_prefixes => [ "bla_", "bloe" ] });
|
||||
|
||||
is_deeply(parse_conf("PROTOCOL atsvc \"Scheduling jobs on remote machines\" \"at\" \"atsvc\"\n"),
|
||||
{ protocols => {
|
||||
atsvc => {
|
||||
LONGNAME => "\"Scheduling jobs on remote machines\"",
|
||||
SHORTNAME => "\"at\"",
|
||||
FILTERNAME => "\"atsvc\""
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
is_deeply(parse_conf("IMPORT bla\n"), {
|
||||
imports => {
|
||||
bla => {
|
||||
NAME => "bla",
|
||||
DATA => "",
|
||||
USED => 0,
|
||||
POS => { FILE => "nofile", LINE => 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
is_deeply(parse_conf("IMPORT bla fn1 fn2 fn3\n"), {
|
||||
imports => {
|
||||
bla => {
|
||||
NAME => "bla",
|
||||
DATA => "fn1 fn2 fn3",
|
||||
USED => 0,
|
||||
POS => { FILE => "nofile", LINE => 1 }
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
test_errors("nofile:1: no dissectorname specified\n",
|
||||
sub { parse_conf("IMPORT\n"); } );
|
||||
|
||||
test_errors("nofile:1: incomplete HF_FIELD command\n",
|
||||
sub { parse_conf("HF_FIELD hf_idx\n"); });
|
||||
|
||||
test_errors("nofile:1: incomplete ETT_FIELD command\n",
|
||||
sub { parse_conf("ETT_FIELD\n"); });
|
||||
|
||||
is_deeply(parse_conf("TYPE winreg_String dissect_myminregstring(); FT_STRING BASE_DEC 0 0 0 2\n"), {
|
||||
types => {
|
||||
winreg_String => {
|
||||
NAME => "winreg_String",
|
||||
POS => { FILE => "nofile", LINE => 1 },
|
||||
USED => 0,
|
||||
DISSECTOR_NAME => "dissect_myminregstring();",
|
||||
FT_TYPE => "FT_STRING",
|
||||
BASE_TYPE => "BASE_DEC",
|
||||
MASK => 0,
|
||||
VALSSTRING => 0,
|
||||
ALIGNMENT => 0
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
is_deeply(parse_conf("TYPE winreg_String \"offset = dissect_myminregstring(\@HF\@);\" FT_STRING BASE_DEC 0 0 0 2\n"), {
|
||||
types => {
|
||||
winreg_String => {
|
||||
NAME => "winreg_String",
|
||||
POS => { FILE => "nofile", LINE => 1 },
|
||||
USED => 0,
|
||||
DISSECTOR_NAME => "offset = dissect_myminregstring(\@HF\@);",
|
||||
FT_TYPE => "FT_STRING",
|
||||
BASE_TYPE => "BASE_DEC",
|
||||
MASK => 0,
|
||||
VALSSTRING => 0,
|
||||
ALIGNMENT => 0
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
274
pidl/tests/wireshark-ndr.pl
Executable file
274
pidl/tests/wireshark-ndr.pl
Executable file
|
@ -0,0 +1,274 @@
|
|||
#!/usr/bin/perl
|
||||
# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
||||
# Published under the GNU General Public License
|
||||
# test parsing wireshark conformance files
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::More tests => 40;
|
||||
use FindBin qw($RealBin);
|
||||
use lib "$RealBin";
|
||||
use Util;
|
||||
use Parse::Pidl::Util qw(MyDumper);
|
||||
use strict;
|
||||
use Parse::Pidl::Wireshark::NDR qw(field2name %res PrintIdl StripPrefixes RegisterInterfaceHandoff register_hf_field ProcessImport ProcessInclude find_type DumpEttList DumpEttDeclaration DumpHfList DumpHfDeclaration DumpFunctionTable register_type register_ett);
|
||||
|
||||
is("Access Mask", field2name("access_mask"));
|
||||
is("Accessmask", field2name("AccessMask"));
|
||||
|
||||
my $x = new Parse::Pidl::Wireshark::NDR();
|
||||
$x->PrintIdl("foo\nbar\n");
|
||||
is("/* IDL: foo */
|
||||
/* IDL: bar */
|
||||
|
||||
", $x->{res}->{code});
|
||||
|
||||
is("bla_foo", StripPrefixes("bla_foo", []));
|
||||
is("foo", StripPrefixes("bla_foo", ["bla"]));
|
||||
is("foo_bla", StripPrefixes("foo_bla", ["bla"]));
|
||||
|
||||
$x = new Parse::Pidl::Wireshark::NDR();
|
||||
$x->RegisterInterfaceHandoff({});
|
||||
is($x->{res}->{code}, "");
|
||||
ok(not defined($x->{hf_used}->{hf_bla_opnum}));
|
||||
|
||||
$x = new Parse::Pidl::Wireshark::NDR();
|
||||
$x->{res}->{code} = "";
|
||||
$x->RegisterInterfaceHandoff({UUID => "uuid", NAME => "bla"});
|
||||
is($x->{res}->{code}, 'void proto_reg_handoff_dcerpc_bla(void)
|
||||
{
|
||||
dcerpc_init_uuid(proto_dcerpc_bla, ett_dcerpc_bla,
|
||||
&uuid_dcerpc_bla, ver_dcerpc_bla,
|
||||
bla_dissectors, hf_bla_opnum);
|
||||
}
|
||||
');
|
||||
is($x->{hf_used}->{hf_bla_opnum}, 1);
|
||||
|
||||
$x->{conformance} = {};
|
||||
is("hf_bla_idx",
|
||||
$x->register_hf_field("hf_bla_idx", "bla", "my.filter", "FT_UINT32", "BASE_HEX", "NULL", 0xF, undef));
|
||||
is_deeply($x->{conformance}, {
|
||||
header_fields => {
|
||||
"hf_bla_idx" => {
|
||||
INDEX => "hf_bla_idx",
|
||||
NAME => "bla",
|
||||
FILTER => "my.filter",
|
||||
BASE_TYPE => "BASE_HEX",
|
||||
FT_TYPE => "FT_UINT32",
|
||||
VALSSTRING => "NULL",
|
||||
BLURB => undef,
|
||||
MASK => 0xF
|
||||
}
|
||||
},
|
||||
hf_renames => {},
|
||||
fielddescription => {}
|
||||
});
|
||||
|
||||
$x->{conformance} = { fielddescription => { hf_bla_idx => { DESCRIPTION => "Some Description" }}};
|
||||
is("hf_bla_idx",
|
||||
$x->register_hf_field("hf_bla_idx", "bla", "my.filter", "FT_UINT32", "BASE_HEX", "NULL", 0xF, undef));
|
||||
is_deeply($x->{conformance}, {
|
||||
fielddescription => {
|
||||
hf_bla_idx => {
|
||||
DESCRIPTION => "Some Description",
|
||||
USED => 1
|
||||
}
|
||||
},
|
||||
header_fields => {
|
||||
"hf_bla_idx" => {
|
||||
INDEX => "hf_bla_idx",
|
||||
NAME => "bla",
|
||||
FILTER => "my.filter",
|
||||
BASE_TYPE => "BASE_HEX",
|
||||
FT_TYPE => "FT_UINT32",
|
||||
VALSSTRING => "NULL",
|
||||
BLURB => "Some Description",
|
||||
MASK => 0xF
|
||||
}
|
||||
},
|
||||
hf_renames => {},
|
||||
});
|
||||
|
||||
$x->{conformance} = { fielddescription => { hf_bla_idx => { DESCRIPTION => "Some Description" }}};
|
||||
is("hf_bla_idx",
|
||||
$x->register_hf_field("hf_bla_idx", "bla", "my.filter", "FT_UINT32", "BASE_HEX", "NULL", 0xF,
|
||||
"Actual Description"));
|
||||
is_deeply($x->{conformance}, {
|
||||
fielddescription => {
|
||||
hf_bla_idx => { DESCRIPTION => "Some Description" }
|
||||
},
|
||||
header_fields => {
|
||||
"hf_bla_idx" => {
|
||||
INDEX => "hf_bla_idx",
|
||||
NAME => "bla",
|
||||
FILTER => "my.filter",
|
||||
BASE_TYPE => "BASE_HEX",
|
||||
FT_TYPE => "FT_UINT32",
|
||||
VALSSTRING => "NULL",
|
||||
BLURB => "Actual Description",
|
||||
MASK => 0xF
|
||||
}
|
||||
},
|
||||
hf_renames => {},
|
||||
});
|
||||
|
||||
|
||||
|
||||
$x->{conformance} = { hf_renames => { "hf_bla_idx" => { NEWNAME => "hf_bloe_idx" } } };
|
||||
$x->register_hf_field("hf_bla_idx", "bla", "my.filter", "FT_UINT32", "BASE_HEX", "NULL", 0xF, undef);
|
||||
is_deeply($x->{conformance}, {
|
||||
hf_renames => { hf_bla_idx => { USED => 1, NEWNAME => "hf_bloe_idx" } } });
|
||||
|
||||
$x->{hf_used} = { hf_bla => 1 };
|
||||
test_warnings("", sub {
|
||||
$x->CheckUsed({ header_fields => { foo => { INDEX => "hf_bla" }}})});
|
||||
|
||||
$x->{hf_used} = { };
|
||||
test_warnings("hf field `hf_bla' not used\n", sub {
|
||||
$x->CheckUsed({ header_fields => { foo => { INDEX => "hf_bla" }}})});
|
||||
|
||||
test_warnings("hf field `hf_id' not used\n",
|
||||
sub { $x->CheckUsed({
|
||||
hf_renames => {
|
||||
hf_id => {
|
||||
OLDNAME => "hf_id",
|
||||
NEWNAME => "hf_newid",
|
||||
USED => 0
|
||||
}
|
||||
}
|
||||
}); } );
|
||||
|
||||
test_warnings("dissector param never used\n",
|
||||
sub { $x->CheckUsed({
|
||||
dissectorparams => {
|
||||
dissect_foo => {
|
||||
PARAM => 42,
|
||||
USED => 0
|
||||
}
|
||||
}
|
||||
}); } );
|
||||
|
||||
test_warnings("description never used\n",
|
||||
sub { $x->CheckUsed({
|
||||
fielddescription => {
|
||||
hf_bla => {
|
||||
USED => 0
|
||||
}
|
||||
}
|
||||
}); } );
|
||||
|
||||
test_warnings("import never used\n",
|
||||
sub { $x->CheckUsed({
|
||||
imports => {
|
||||
bla => {
|
||||
USED => 0
|
||||
}
|
||||
}
|
||||
}); } );
|
||||
|
||||
test_warnings("nofile:1: type never used\n",
|
||||
sub { $x->CheckUsed({
|
||||
types => {
|
||||
bla => {
|
||||
USED => 0,
|
||||
POS => { FILE => "nofile", LINE => 1 }
|
||||
}
|
||||
}
|
||||
}); } );
|
||||
|
||||
test_warnings("True/False description never used\n",
|
||||
sub { $x->CheckUsed({
|
||||
tfs => {
|
||||
hf_bloe => {
|
||||
USED => 0
|
||||
}
|
||||
}
|
||||
}); } );
|
||||
|
||||
$x = new Parse::Pidl::Wireshark::NDR();
|
||||
$x->ProcessImport("security", "bla");
|
||||
is($x->{res}->{hdr}, "#include \"packet-dcerpc-bla.h\"\n\n");
|
||||
|
||||
$x = new Parse::Pidl::Wireshark::NDR();
|
||||
$x->ProcessImport("\"bla.idl\"", "\"foo.idl\"");
|
||||
is($x->{res}->{hdr}, "#include \"packet-dcerpc-bla.h\"\n" .
|
||||
"#include \"packet-dcerpc-foo.h\"\n\n");
|
||||
|
||||
$x = new Parse::Pidl::Wireshark::NDR();
|
||||
$x->ProcessInclude("foo.h", "bla.h", "bar.h");
|
||||
is($x->{res}->{hdr}, "#include \"foo.h\"\n" .
|
||||
"#include \"bla.h\"\n" .
|
||||
"#include \"bar.h\"\n\n");
|
||||
|
||||
$x->{conformance} = {types => { bla => "brainslug" } };
|
||||
is("brainslug", $x->find_type("bla"));
|
||||
|
||||
is(DumpEttList(["ett_t1", "ett_bla"]),
|
||||
"\tstatic gint *ett[] = {\n" .
|
||||
"\t\t&ett_t1,\n" .
|
||||
"\t\t&ett_bla,\n" .
|
||||
"\t};\n");
|
||||
|
||||
is(DumpEttList(), "\tstatic gint *ett[] = {\n\t};\n");
|
||||
is(DumpEttList(["bla"]), "\tstatic gint *ett[] = {\n\t\t&bla,\n\t};\n");
|
||||
|
||||
is(DumpEttDeclaration(["void", "zoid"]),
|
||||
"\n/* Ett declarations */\n" .
|
||||
"static gint void = -1;\n" .
|
||||
"static gint zoid = -1;\n" .
|
||||
"\n");
|
||||
|
||||
is(DumpEttDeclaration(), "\n/* Ett declarations */\n\n");
|
||||
|
||||
$x->{conformance} = {
|
||||
header_fields => {
|
||||
hf_bla => { INDEX => "hf_bla", NAME => "Bla", FILTER => "bla.field", FT_TYPE => "FT_UINT32", BASE_TYPE => "BASE_DEC", VALSSTRING => "NULL", MASK => 0xFF, BLURB => "NULL" }
|
||||
}
|
||||
};
|
||||
|
||||
is($x->DumpHfList(), "\tstatic hf_register_info hf[] = {
|
||||
{ &hf_bla,
|
||||
{ \"Bla\", \"bla.field\", FT_UINT32, BASE_DEC, NULL, 255, \"NULL\", HFILL }},
|
||||
};
|
||||
");
|
||||
|
||||
is($x->DumpHfDeclaration(), "
|
||||
/* Header field declarations */
|
||||
static gint hf_bla = -1;
|
||||
|
||||
");
|
||||
|
||||
is(DumpFunctionTable({
|
||||
NAME => "someif",
|
||||
FUNCTIONS => [ { NAME => "fn1", OPNUM => 3 }, { NAME => "someif_fn2", OPNUM => 2 } ] }),
|
||||
'static dcerpc_sub_dissector someif_dissectors[] = {
|
||||
{ 3, "fn1",
|
||||
someif_dissect_fn1_request, someif_dissect_fn1_response},
|
||||
{ 2, "fn2",
|
||||
someif_dissect_fn2_request, someif_dissect_fn2_response},
|
||||
{ 0, NULL, NULL, NULL }
|
||||
};
|
||||
');
|
||||
|
||||
$x->{conformance} = {};
|
||||
$x->register_type("bla_type", "dissect_bla", "FT_UINT32", "BASE_HEX", 0xFF, "NULL", 4);
|
||||
is_deeply($x->{conformance}, {
|
||||
types => {
|
||||
bla_type => {
|
||||
NAME => "bla_type",
|
||||
DISSECTOR_NAME => "dissect_bla",
|
||||
FT_TYPE => "FT_UINT32",
|
||||
BASE_TYPE => "BASE_HEX",
|
||||
MASK => 255,
|
||||
VALSSTRING => "NULL",
|
||||
ALIGNMENT => 4
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$x->{ett} = [];
|
||||
$x->register_ett("name");
|
||||
is_deeply($x->{ett}, ["name"]);
|
||||
$x->register_ett("leela");
|
||||
is_deeply($x->{ett}, ["name", "leela"]);
|
Loading…
Add table
Add a link
Reference in a new issue