Refactor build system to use waf. Waf is better at handling dependency paths which I need for IDL support
This commit is contained in:
parent
df7f98bc6f
commit
9fd10dec9c
77 changed files with 312 additions and 86 deletions
181
bin/pidl/tests/Util.pm
Normal file
181
bin/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
bin/pidl/tests/cutil.pl
Executable file
21
bin/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
bin/pidl/tests/dump.pl
Executable file
15
bin/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
bin/pidl/tests/header.pl
Executable file
108
bin/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
bin/pidl/tests/ndr.pl
Executable file
561
bin/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
bin/pidl/tests/ndr_align.pl
Executable file
143
bin/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
bin/pidl/tests/ndr_alloc.pl
Executable file
118
bin/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
bin/pidl/tests/ndr_array.pl
Executable file
37
bin/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
bin/pidl/tests/ndr_compat.pl
Executable file
21
bin/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
bin/pidl/tests/ndr_deprecations.pl
Executable file
26
bin/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
bin/pidl/tests/ndr_fullptr.pl
Executable file
44
bin/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
bin/pidl/tests/ndr_refptr.pl
Executable file
526
bin/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
bin/pidl/tests/ndr_represent.pl
Executable file
71
bin/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
bin/pidl/tests/ndr_simple.pl
Executable file
28
bin/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
bin/pidl/tests/ndr_string.pl
Executable file
192
bin/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
bin/pidl/tests/ndr_tagtype.pl
Executable file
66
bin/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
bin/pidl/tests/parse_idl.pl
Executable file
243
bin/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
bin/pidl/tests/samba-ndr.pl
Executable file
300
bin/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
bin/pidl/tests/samba3-cli.pl
Executable file
236
bin/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
bin/pidl/tests/samba3-srv.pl
Executable file
18
bin/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
bin/pidl/tests/tdr.pl
Executable file
49
bin/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
bin/pidl/tests/test_util.pl
Executable file
21
bin/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
bin/pidl/tests/typelist.pl
Executable file
93
bin/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
bin/pidl/tests/util.pl
Executable file
115
bin/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
bin/pidl/tests/wireshark-conf.pl
Executable file
205
bin/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
bin/pidl/tests/wireshark-ndr.pl
Executable file
274
bin/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