From 45db1030651e69896fdb9e78aa2e2495a7ce7ff5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 8 Feb 2007 23:54:31 +0000 Subject: r21253: Merge some pidl fixes: * Add tests for wireshark dissector generator * Add tests for the header code * Some cleanups * Fix handling of elements without [in] or [out] (This used to be commit 1aecba7100685ed291ea13b0ae47fb0cf9e6a6c8) --- source4/pidl/TODO | 7 ++ source4/pidl/lib/Parse/Pidl/Samba4/Header.pm | 31 ++++++--- source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm | 46 ++++++------- source4/pidl/lib/Parse/Pidl/Util.pm | 75 +++++++++++++++++----- .../pidl/lib/Parse/Pidl/Wireshark/Conformance.pm | 48 +++++++++++--- source4/pidl/lib/Parse/Pidl/Wireshark/NDR.pm | 6 +- source4/pidl/tests/header.pl | 36 +++++++++++ source4/pidl/tests/samba-ndr.pl | 23 ++++++- source4/pidl/tests/wireshark-conf.pl | 62 ++++++++++++++++++ 9 files changed, 276 insertions(+), 58 deletions(-) create mode 100755 source4/pidl/tests/header.pl create mode 100755 source4/pidl/tests/wireshark-conf.pl (limited to 'source4/pidl') diff --git a/source4/pidl/TODO b/source4/pidl/TODO index 7cf6a4209a..4e344e3c37 100644 --- a/source4/pidl/TODO +++ b/source4/pidl/TODO @@ -21,3 +21,10 @@ - mem_ctx in the interface rather than as struct ndr member. - real typelibs + +- fix [in,out] handling and allocation for samba3: + - add inout + - make NULL to mean "allocate me" + - remove NDR_AUTO_REF_ALLOC flag + +- automatic test generator based on IDL pointer types diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm b/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm index 96f695d1cd..2b5b9c9e01 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/Header.pm @@ -9,7 +9,6 @@ package Parse::Pidl::Samba4::Header; use strict; use Parse::Pidl::Typelist qw(mapType); use Parse::Pidl::Util qw(has_property is_constant); -use Parse::Pidl::NDR qw(GetNextLevel GetPrevLevel); use Parse::Pidl::Samba4 qw(is_intree); use vars qw($VERSION); @@ -236,15 +235,25 @@ sub HeaderConst($) } } +sub ElementDirection($) +{ + my ($e) = @_; + + return "inout" if (has_property($e, "in") and has_property($e, "out")); + return "in" if (has_property($e, "in")); + return "out" if (has_property($e, "out")); + return "inout"; +} + ##################################################################### # parse a function sub HeaderFunctionInOut($$) { my($fn,$prop) = @_; - foreach (@{$fn->{ELEMENTS}}) { - HeaderElement($_) if (has_property($_, $prop)); - } + foreach (@{$fn->{ELEMENTS}}) { + HeaderElement($_) if (ElementDirection($_) eq $prop); + } } ##################################################################### @@ -255,8 +264,8 @@ sub HeaderFunctionInOut_needed($$) return 1 if ($prop eq "out" && $fn->{RETURN_TYPE} ne "void"); - foreach (@{$fn->{ELEMENTS}}) { - return 1 if (has_property($_, $prop)); + foreach (@{$fn->{ELEMENTS}}) { + return 1 if (ElementDirection($_) eq $prop); } return undef; @@ -278,19 +287,23 @@ sub HeaderFunction($) $tab_depth++; my $needed = 0; - if (HeaderFunctionInOut_needed($fn, "in")) { + if (HeaderFunctionInOut_needed($fn, "in") or + HeaderFunctionInOut_needed($fn, "inout")) { pidl tabs()."struct {\n"; $tab_depth++; HeaderFunctionInOut($fn, "in"); + HeaderFunctionInOut($fn, "inout"); $tab_depth--; pidl tabs()."} in;\n\n"; $needed++; } - if (HeaderFunctionInOut_needed($fn, "out")) { + if (HeaderFunctionInOut_needed($fn, "out") or + HeaderFunctionInOut_needed($fn, "inout")) { pidl tabs()."struct {\n"; $tab_depth++; HeaderFunctionInOut($fn, "out"); + HeaderFunctionInOut($fn, "inout"); if ($fn->{RETURN_TYPE} ne "void") { pidl tabs().mapType($fn->{RETURN_TYPE}) . " result;\n"; } @@ -299,7 +312,7 @@ sub HeaderFunction($) $needed++; } - if (! $needed) { + if (!$needed) { # sigh - some compilers don't like empty structures pidl tabs()."int _dummy_element;\n"; } diff --git a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm index 1e199ba62b..3b1bc726ff 100644 --- a/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm +++ b/source4/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm @@ -10,7 +10,7 @@ package Parse::Pidl::Samba4::NDR::Parser; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(is_charset_array); -@EXPORT_OK = qw(check_null_pointer); +@EXPORT_OK = qw(check_null_pointer GenerateFunctionInEnv GenerateFunctionOutEnv); use strict; use Parse::Pidl::Typelist qw(hasType getType mapType); @@ -451,7 +451,9 @@ sub ParseArrayPullHeader($$$$$) if ($l->{IS_VARYING} and not $l->{IS_ZERO_TERMINATED}) { defer "if ($var_name) {"; defer_indent; - my $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL}, check_null_pointer($e, $env, \&defer, "return NT_STATUS_INVALID_PARAMETER_MIX;"), check_fully_dereferenced($e, $env)); + my $length = ParseExprExt($l->{LENGTH_IS}, $env, $e->{ORIGINAL}, + check_null_pointer($e, $env, \&defer, "return NT_STATUS_INVALID_PARAMETER_MIX;"), + check_fully_dereferenced($e, $env)); defer "NDR_CHECK(ndr_check_array_length(ndr, (void*)" . get_pointer_to($var_name) . ", $length));"; defer_deindent; defer "}" @@ -689,12 +691,12 @@ sub ParseElementPushLevel ##################################################################### # parse scalars in a structure element -sub ParseElementPush($$$$$$) +sub ParseElementPush($$$$$) { - my ($e,$ndr,$var_prefix,$env,$primitives,$deferred) = @_; + my ($e,$ndr,$env,$primitives,$deferred) = @_; my $subndr = undef; - my $var_name = $var_prefix.$e->{NAME}; + my $var_name = $env->{$e->{NAME}}; return unless $primitives or ($deferred and ContainsDeferred($e, $e->{LEVELS}[0])); @@ -1096,11 +1098,11 @@ sub ParseElementPullLevel ##################################################################### # parse scalars in a structure element - pull size -sub ParseElementPull($$$$$$) +sub ParseElementPull($$$$$) { - my($e,$ndr,$var_prefix,$env,$primitives,$deferred) = @_; + my($e,$ndr,$env,$primitives,$deferred) = @_; - my $var_name = $var_prefix.$e->{NAME}; + my $var_name = $env->{$e->{NAME}}; my $represent_name; my $transmit_name; @@ -1247,7 +1249,7 @@ sub ParseStructPush($$) } foreach my $e (@{$struct->{ELEMENTS}}) { - ParseElementPush($e, "ndr", "r->", $env, 1, 0); + ParseElementPush($e, "ndr", $env, 1, 0); } deindent; @@ -1261,7 +1263,7 @@ sub ParseStructPush($$) pidl "NDR_CHECK(ndr_push_setup_relative_base_offset2(ndr, r));"; } foreach my $e (@{$struct->{ELEMENTS}}) { - ParseElementPush($e, "ndr", "r->", $env, 0, 1); + ParseElementPush($e, "ndr", $env, 0, 1); } deindent; @@ -1547,7 +1549,7 @@ sub ParseStructPull($$) } foreach my $e (@{$struct->{ELEMENTS}}) { - ParseElementPull($e, "ndr", "r->", $env, 1, 0); + ParseElementPull($e, "ndr", $env, 1, 0); } add_deferred(); @@ -1562,7 +1564,7 @@ sub ParseStructPull($$) pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset2(ndr, r));"; } foreach my $e (@{$struct->{ELEMENTS}}) { - ParseElementPull($e, "ndr", "r->", $env, 0, 1); + ParseElementPull($e, "ndr", $env, 0, 1); } add_deferred(); @@ -1662,7 +1664,7 @@ sub ParseUnionPush($$) pidl "NDR_CHECK(ndr_push_setup_relative_base_offset1(ndr, r, ndr->offset));"; } DeclareArrayVariables($el); - ParseElementPush($el, "ndr", "r->", {}, 1, 0); + ParseElementPush($el, "ndr", {$el->{NAME} => "r->$el->{NAME}"}, 1, 0); deindent; } pidl "break;"; @@ -1689,7 +1691,7 @@ sub ParseUnionPush($$) pidl "$el->{CASE}:"; if ($el->{TYPE} ne "EMPTY") { indent; - ParseElementPush($el, "ndr", "r->", {}, 0, 1); + ParseElementPush($el, "ndr", {$el->{NAME} => "r->$el->{NAME}"}, 0, 1); deindent; } pidl "break;"; @@ -1810,7 +1812,7 @@ sub ParseUnionPull($$) # and store it based on the toplevel struct/union pidl "NDR_CHECK(ndr_pull_setup_relative_base_offset1(ndr, r, ndr->offset));"; } - ParseElementPull($el, "ndr", "r->", {}, 1, 0); + ParseElementPull($el, "ndr", {$el->{NAME} => "r->$el->{NAME}"}, 1, 0); deindent; } pidl "break; }"; @@ -1837,7 +1839,7 @@ sub ParseUnionPull($$) pidl "$el->{CASE}:"; if ($el->{TYPE} ne "EMPTY") { indent; - ParseElementPull($el, "ndr", "r->", {}, 0, 1); + ParseElementPull($el, "ndr", {$el->{NAME} => "r->$el->{NAME}"}, 0, 1); deindent; } pidl "break;"; @@ -1993,7 +1995,7 @@ sub ParseFunctionPrint($) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - ParseElementPrint($e, "r->in.$e->{NAME}", $env); + ParseElementPrint($e, $env->{$e->{NAME}}, $env); } } pidl "ndr->depth--;"; @@ -2008,7 +2010,7 @@ sub ParseFunctionPrint($) $env = GenerateFunctionOutEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/out/,@{$e->{DIRECTION}})) { - ParseElementPrint($e, "r->out.$e->{NAME}", $env); + ParseElementPrint($e, $env->{$e->{NAME}}, $env); } } if ($fn->{RETURN_TYPE}) { @@ -2050,7 +2052,7 @@ sub ParseFunctionPush($) foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/in/,@{$e->{DIRECTION}})) { - ParseElementPush($e, "ndr", "r->in.", $env, 1, 1); + ParseElementPush($e, "ndr", $env, 1, 1); } } @@ -2063,7 +2065,7 @@ sub ParseFunctionPush($) $env = GenerateFunctionOutEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { if (grep(/out/,@{$e->{DIRECTION}})) { - ParseElementPush($e, "ndr", "r->out.", $env, 1, 1); + ParseElementPush($e, "ndr", $env, 1, 1); } } @@ -2147,7 +2149,7 @@ sub ParseFunctionPull($) foreach my $e (@{$fn->{ELEMENTS}}) { next unless (grep(/in/, @{$e->{DIRECTION}})); - ParseElementPull($e, "ndr", "r->in.", $env, 1, 1); + ParseElementPull($e, "ndr", $env, 1, 1); } # allocate the "simple" out ref variables. FIXME: Shouldn't this have it's @@ -2194,7 +2196,7 @@ sub ParseFunctionPull($) $env = GenerateFunctionOutEnv($fn); foreach my $e (@{$fn->{ELEMENTS}}) { next unless grep(/out/, @{$e->{DIRECTION}}); - ParseElementPull($e, "ndr", "r->out.", $env, 1, 1); + ParseElementPull($e, "ndr", $env, 1, 1); } if ($fn->{RETURN_TYPE}) { diff --git a/source4/pidl/lib/Parse/Pidl/Util.pm b/source4/pidl/lib/Parse/Pidl/Util.pm index 00185fbef7..8716094abd 100644 --- a/source4/pidl/lib/Parse/Pidl/Util.pm +++ b/source4/pidl/lib/Parse/Pidl/Util.pm @@ -15,9 +15,31 @@ use strict; use Parse::Pidl::Expr; use Parse::Pidl qw(error); -##################################################################### -# a dumper wrapper to prevent dependence on the Data::Dumper module -# unless we actually need it +=head1 NAME + +Parse::Pidl::Util - Generic utility functions for pidl + +=head1 SYNOPSIS + +use Parse::Pidl::Util; + +=head1 DESCRIPTION + +Simple module that contains a couple of trivial helper functions +used throughout the various pidl modules. + +=head1 FUNCTIONS + +=over 4 + +=cut + +=item B +a dumper wrapper to prevent dependence on the Data::Dumper module +unless we actually need it + +=cut + sub MyDumper($) { require Data::Dumper; @@ -25,8 +47,10 @@ sub MyDumper($) return Data::Dumper::Dumper($s); } -##################################################################### -# see if a pidl property list contains a given property +=item B +see if a pidl property list contains a given property + +=cut sub has_property($$) { my($e, $p) = @_; @@ -36,8 +60,10 @@ sub has_property($$) return $e->{PROPERTIES}->{$p}; } -##################################################################### -# see if a pidl property matches a value +=item B +see if a pidl property matches a value + +=cut sub property_matches($$$) { my($e,$p,$v) = @_; @@ -53,16 +79,22 @@ sub property_matches($$$) return undef; } -# return 1 if the string is a C constant +=item B +return 1 if the string is a C constant + +=cut sub is_constant($) { my $s = shift; - return 1 if (defined $s && $s =~ /^\d+$/); - return 1 if (defined $s && $s =~ /^0x[0-9A-Fa-f]+$/); + return 1 if ($s =~ /^\d+$/); + return 1 if ($s =~ /^0x[0-9A-Fa-f]+$/); return 0; } -# return a "" quoted string, unless already quoted +=item B +return a "" quoted string, unless already quoted + +=cut sub make_str($) { my $str = shift; @@ -72,6 +104,10 @@ sub make_str($) return "\"$str\""; } +=item B +Print C representation of a UUID. + +=cut sub print_uuid($) { my ($uuid) = @_; @@ -87,12 +123,14 @@ sub print_uuid($) "{".join(',', map {"0x$_"} @node)."}}"; } +=item B +Interpret an IDL expression, substituting particular variables. + +=cut sub ParseExpr($$$) { my($expr, $varlist, $e) = @_; - die("Undefined value in ParseExpr") if not defined($expr); - my $x = new Parse::Pidl::Expr(); return $x->Run($expr, sub { my $x = shift; error($e, $x); }, @@ -104,12 +142,15 @@ sub ParseExpr($$$) undef, undef); } +=item B +Interpret an IDL expression, substituting particular variables. Can call +callbacks when pointers are being dereferenced or variables are being used. + +=cut sub ParseExprExt($$$$$) { my($expr, $varlist, $e, $deref, $use) = @_; - die("Undefined value in ParseExpr") if not defined($expr); - my $x = new Parse::Pidl::Expr(); return $x->Run($expr, sub { my $x = shift; error($e, $x); }, @@ -121,4 +162,8 @@ sub ParseExprExt($$$$$) $deref, $use); } +=back + +=cut + 1; diff --git a/source4/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm b/source4/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm index 4ad60319a6..9798c7c552 100644 --- a/source4/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm +++ b/source4/pidl/lib/Parse/Pidl/Wireshark/Conformance.pm @@ -96,7 +96,7 @@ use vars qw($VERSION); $VERSION = '0.01'; @ISA = qw(Exporter); -@EXPORT_OK = qw(ReadConformance); +@EXPORT_OK = qw(ReadConformance ReadConformanceFH); use strict; @@ -157,7 +157,7 @@ sub handle_hf_rename($$$$) my ($pos,$data,$old,$new) = @_; unless(defined($new)) { - error($pos, "incomplete HF_RENAME command"); + warning($pos, "incomplete HF_RENAME command"); return; } @@ -253,6 +253,11 @@ sub handle_manual($$$) { my ($pos,$data,$fn) = @_; + unless(defined($fn)) { + warning($pos, "incomplete MANUAL command"); + return; + } + $data->{manual}->{$fn} = 1; } @@ -271,6 +276,11 @@ sub handle_fielddescription($$$$) { my ($pos,$data,$field,$desc) = @_; + unless(defined($desc)) { + warning($pos, "incomplete FIELD_DESCRIPTION command"); + return; + } + $data->{fielddescription}->{$field} = { DESCRIPTION => $desc, POS => $pos, @@ -314,16 +324,26 @@ my %field_handlers = ( sub ReadConformance($$) { my ($f,$data) = @_; + my $ret; - $data->{override} = ""; + open(IN,"<$f") or return undef; - my $incodeblock = 0; + $ret = ReadConformanceFH(*IN, $data, $f); - open(IN,"<$f") or return undef; + close(IN); + + return $ret; +} + +sub ReadConformanceFH($$$) +{ + my ($fh,$data,$f) = @_; + + my $incodeblock = 0; my $ln = 0; - foreach () { + foreach (<$fh>) { $ln++; next if (/^#.*$/); next if (/^$/); @@ -337,7 +357,11 @@ sub ReadConformance($$) $incodeblock = 0; next; } elsif ($incodeblock) { - $data->{override}.="$_\n"; + if (exists $data->{override}) { + $data->{override}.="$_\n"; + } else { + $data->{override} = "$_\n"; + } next; } @@ -349,6 +373,8 @@ sub ReadConformance($$) my $pos = { FILE => $f, LINE => $ln }; + next unless(defined($cmd)); + if (not defined($field_handlers{$cmd})) { warning($pos, "Unknown command `$cmd'"); next; @@ -357,7 +383,13 @@ sub ReadConformance($$) $field_handlers{$cmd}($pos, $data, @fields); } - close(IN); + if ($incodeblock) { + warning({ FILE => $f, LINE => $ln }, + "Expecting CODE END"); + return undef; + } + + return 1; } 1; diff --git a/source4/pidl/lib/Parse/Pidl/Wireshark/NDR.pm b/source4/pidl/lib/Parse/Pidl/Wireshark/NDR.pm index 9415c16652..646f5fdabc 100644 --- a/source4/pidl/lib/Parse/Pidl/Wireshark/NDR.pm +++ b/source4/pidl/lib/Parse/Pidl/Wireshark/NDR.pm @@ -2,7 +2,7 @@ # Samba4 NDR parser generator for IDL structures # Copyright tridge@samba.org 2000-2003 # Copyright tpot@samba.org 2001,2005 -# Copyright jelmer@samba.org 2004-2005 +# Copyright jelmer@samba.org 2004-2007 # Portions based on idl2eth.c by Ronnie Sahlberg # released under the GNU GPL @@ -918,7 +918,9 @@ sub Parse($$$$) $parser.=$res{ett}; $parser.=$res{hf}; $parser.=$res{def}; - $parser.=$conformance->{override}; + if (exists ($conformance->{override})) { + $parser.=$conformance->{override}; + } $parser.=$res{code}; my $header = "/* autogenerated by pidl */\n\n"; diff --git a/source4/pidl/tests/header.pl b/source4/pidl/tests/header.pl new file mode 100755 index 0000000000..e7cd913916 --- /dev/null +++ b/source4/pidl/tests/header.pl @@ -0,0 +1,36 @@ +#!/usr/bin/perl +# (C) 2007 Jelmer Vernooij +# Published under the GNU General Public License +use strict; +use warnings; + +use Test::More tests => 9; +use FindBin qw($RealBin); +use lib "$RealBin"; +use Util; +use Parse::Pidl::Util qw(MyDumper); +use Parse::Pidl::Samba4::Header; +use Parse::Pidl::IDL qw(parse_string); + +sub parse_idl($) +{ + my $text = shift; + my $idl = Parse::Pidl::IDL::parse_string($text, "nofile"); + return Parse::Pidl::Samba4::Header::Parse($idl); +} + +is("/* header auto-generated by pidl */\n\n#include \n\n", parse_idl(""), "includes work"); +is("/* header auto-generated by pidl */\n\n#include \n\n", parse_idl("interface x {}"), "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"); diff --git a/source4/pidl/tests/samba-ndr.pl b/source4/pidl/tests/samba-ndr.pl index a3e94bd8b5..a6d74beea9 100755 --- a/source4/pidl/tests/samba-ndr.pl +++ b/source4/pidl/tests/samba-ndr.pl @@ -4,12 +4,12 @@ use strict; use warnings; -use Test::More tests => 10; +use Test::More tests => 16; use FindBin qw($RealBin); use lib "$RealBin"; use Util; use Parse::Pidl::Util qw(MyDumper); -use Parse::Pidl::Samba4::NDR::Parser qw(check_null_pointer); +use Parse::Pidl::Samba4::NDR::Parser qw(check_null_pointer GenerateFunctionInEnv GenerateFunctionOutEnv); my $output; sub print_fn($) { my $x = shift; $output.=$x; } @@ -133,3 +133,22 @@ test_warnings("nofile:2: unknown dereferenced expression `r->in.bla'\n", sub { $fn->("r->in.bla"); }); is($output, "if (r->in.bla == NULL) return;"); + +# Make sure GenerateFunctionInEnv and GenerateFunctionOutEnv work +$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)); diff --git a/source4/pidl/tests/wireshark-conf.pl b/source4/pidl/tests/wireshark-conf.pl new file mode 100755 index 0000000000..8601a91ed9 --- /dev/null +++ b/source4/pidl/tests/wireshark-conf.pl @@ -0,0 +1,62 @@ +#!/usr/bin/perl +# (C) 2007 Jelmer Vernooij +# Published under the GNU General Public License +# test parsing wireshark conformance files +use strict; +use warnings; + +use Test::More tests => 20; +use FindBin qw($RealBin); +use lib "$RealBin"; +use Util; +use Parse::Pidl::Util qw(MyDumper); +use Parse::Pidl::Wireshark::Conformance qw(ReadConformanceFH); + +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_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"); } ); -- cgit