1#!/usr/bin/perl
2# (C) 2007 Jelmer Vernooij <jelmer@samba.org>
3# Published under the GNU General Public License
4use strict;
5use warnings;
6
7use Test::More tests => 72;
8use FindBin qw($RealBin);
9use lib "$RealBin";
10use Util;
11use Parse::Pidl qw(error);
12use Parse::Pidl::Util;
13
14# has_property()
15is(undef, has_property({}, "foo"));
16is(undef, has_property({PROPERTIES => {}}, "foo"));
17is("data", has_property({PROPERTIES => {foo => "data"}}, "foo"));
18is(undef, has_property({PROPERTIES => {foo => undef}}, "foo"));
19
20# is_constant()
21ok(is_constant("2"));
22ok(is_constant("256"));
23ok(is_constant("0x400"));
24ok(is_constant("0x4BC"));
25ok(not is_constant("0x4BGC"));
26ok(not is_constant("str"));
27ok(not is_constant("2 * expr"));
28
29# make_str()
30is("\"bla\"", make_str("bla"));
31is("\"bla\"", make_str("\"bla\""));
32is("\"\"bla\"\"", make_str("\"\"bla\"\""));
33is("\"bla\"\"", make_str("bla\""));
34is("\"foo\"bar\"", make_str("foo\"bar"));
35
36is("bla", unmake_str("\"bla\""));
37is("\"bla\"", unmake_str("\"\"bla\"\""));
38
39# print_uuid()
40is(undef, print_uuid("invalid"));
41is("{0x12345778,0x1234,0xabcd,{0xef,0x00},{0x01,0x23,0x45,0x67,0x89,0xac}}",
42   print_uuid("12345778-1234-abcd-ef00-0123456789ac"));
43is("{0x12345778,0x1234,0xabcd,{0xef,0x00},{0x01,0x23,0x45,0x67,0x89,0xac}}",
44   print_uuid("\"12345778-1234-abcd-ef00-0123456789ac\""));
45
46# property_matches()
47# missing property
48ok(not property_matches({PROPERTIES => {}}, "x", "data"));
49# data not matching
50ok(not property_matches({PROPERTIES => {x => "bar"}}, "x", "data"));
51# data matching exactly
52ok(property_matches({PROPERTIES => {x => "data"}}, "x", "data"));
53# regex matching
54ok(property_matches({PROPERTIES => {x => "data"}}, "x", "^([dat]+)\$"));
55
56# ParseExpr()
57is(undef, ParseExpr("", {}, undef));
58is("a", ParseExpr("a", {"b" => "2"}, undef));
59is("2", ParseExpr("a", {"a" => "2"}, undef));
60is("2 * 2", ParseExpr("a*a", {"a" => "2"}, undef));
61is("r->length + r->length",
62   ParseExpr("length+length", {"length" => "r->length"}, undef));
63is("2 / 2 * (r->length)",
64	ParseExpr("constant/constant*(len)", {"constant" => "2",
65			                              "len" => "r->length"}, undef));
66is("2 + 2 - r->length",
67	ParseExpr("constant+constant-len", {"constant" => "2",
68			                              "len" => "r->length"}, undef));
69is("*r->length", ParseExpr("*len", { "len" => "r->length"}, undef));
70is("**r->length", ParseExpr("**len", { "len" => "r->length"}, undef));
71is("r->length & 2", ParseExpr("len&2", { "len" => "r->length"}, undef));
72is("&r->length", ParseExpr("&len", { "len" => "r->length"}, undef));
73is("calc()", ParseExpr("calc()", { "foo" => "2"}, undef));
74is("calc(2 * 2)", ParseExpr("calc(foo * 2)", { "foo" => "2"}, undef));
75is("strlen(\"data\")", ParseExpr("strlen(foo)", { "foo" => "\"data\""}, undef));
76is("strlen(\"data\", 4)", ParseExpr("strlen(foo, 4)", { "foo" => "\"data\""}, undef));
77is("foo / bar", ParseExpr("foo / bar", { "bla" => "\"data\""}, undef));
78is("r->length % 2", ParseExpr("len%2", { "len" => "r->length"}, undef));
79is("r->length == 2", ParseExpr("len==2", { "len" => "r->length"}, undef));
80is("r->length != 2", ParseExpr("len!=2", { "len" => "r->length"}, undef));
81is("pr->length", ParseExpr("pr->length", { "p" => "r"}, undef));
82is("r->length", ParseExpr("p->length", { "p" => "r"}, undef));
83is("_foo / bla32", ParseExpr("_foo / bla32", { "bla" => "\"data\""}, undef));
84is("foo.bar.blah", ParseExpr("foo.blah", { "foo" => "foo.bar"}, undef));
85is("\"bla\"", ParseExpr("\"bla\"", {}, undef));
86is("1 << 2", ParseExpr("1 << 2", {}, undef));
87is("1 >> 2", ParseExpr("1 >> 2", {}, undef));
88is("0x200", ParseExpr("0x200", {}, undef));
89is("2?3:0", ParseExpr("2?3:0", {}, undef));
90is("~0", ParseExpr("~0", {}, undef));
91is("b->a->a", ParseExpr("a->a->a", {"a" => "b"}, undef));
92is("b.a.a", ParseExpr("a.a.a", {"a" => "b"}, undef));
93
94test_errors("nofile:0: Parse error in `~' near `~'\n", sub {
95	is(undef, ParseExpr("~", {}, {FILE => "nofile", LINE => 0})); });
96
97test_errors("nofile:0: Got pointer, expected integer\n", sub {
98		is(undef, ParseExprExt("foo", {}, {FILE => "nofile", LINE => 0},
99				         undef, sub { my $x = shift;
100							 error({FILE => "nofile", LINE => 0},
101									 "Got pointer, expected integer");
102							 return undef; }))});
103
104is("b.a.a", ParseExpr("b.a.a", {"a" => "b"}, undef));
105is("((rr_type) == NBT_QTYPE_NETBIOS)", ParseExpr("((rr_type)==NBT_QTYPE_NETBIOS)", {}, undef));
106is("talloc_check_name", ParseExpr("talloc_check_name", {}, undef));
107is("talloc_check_name()", ParseExpr("talloc_check_name()", {}, undef));
108is("talloc_check_name(ndr)", ParseExpr("talloc_check_name(ndr)", {}, undef));
109is("talloc_check_name(ndr, 1)", ParseExpr("talloc_check_name(ndr,1)", {}, undef));
110is("talloc_check_name(ndr, \"struct ndr_push\")", ParseExpr("talloc_check_name(ndr,\"struct ndr_push\")", {}, undef));
111is("((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));
112is("(rdata).data.length", ParseExpr("(rdata).data.length", {}, undef));
113is("((rdata).data.length == 2)", ParseExpr("((rdata).data.length==2)", {}, undef));
114is("((rdata).data.length == 2)?0:rr_type", ParseExpr("((rdata).data.length==2)?0:rr_type", {}, undef));
115is("((((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));
116