mirror of
https://github.com/samba-team/samba.git
synced 2024-12-22 13:34:15 +03:00
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 1aecba7100
)
This commit is contained in:
parent
57a68c9317
commit
45db103065
@ -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
|
||||
|
@ -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";
|
||||
}
|
||||
|
@ -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}) {
|
||||
|
@ -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<MyDumper>
|
||||
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<has_property>
|
||||
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<property_matches>
|
||||
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<is_constant>
|
||||
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<make_str>
|
||||
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_uuid>
|
||||
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<ParseExpr>
|
||||
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<ParseExprExt>
|
||||
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;
|
||||
|
@ -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) = @_;
|
||||
|
||||
$data->{override} = "";
|
||||
|
||||
my $incodeblock = 0;
|
||||
my $ret;
|
||||
|
||||
open(IN,"<$f") or return undef;
|
||||
|
||||
$ret = ReadConformanceFH(*IN, $data, $f);
|
||||
|
||||
close(IN);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
sub ReadConformanceFH($$$)
|
||||
{
|
||||
my ($fh,$data,$f) = @_;
|
||||
|
||||
my $incodeblock = 0;
|
||||
|
||||
my $ln = 0;
|
||||
|
||||
foreach (<IN>) {
|
||||
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;
|
||||
|
@ -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";
|
||||
|
36
source4/pidl/tests/header.pl
Executable file
36
source4/pidl/tests/header.pl
Executable file
@ -0,0 +1,36 @@
|
||||
#!/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 => 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 <core.h>\n\n", parse_idl(""), "includes work");
|
||||
is("/* header auto-generated by pidl */\n\n#include <core.h>\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");
|
@ -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));
|
||||
|
62
source4/pidl/tests/wireshark-conf.pl
Executable file
62
source4/pidl/tests/wireshark-conf.pl
Executable file
@ -0,0 +1,62 @@
|
||||
#!/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 => 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"); } );
|
Loading…
Reference in New Issue
Block a user