1#!/usr/bin/perl 2# Some simple tests for pidls parsing routines 3# (C) 2005 Jelmer Vernooij <jelmer@samba.org> 4# Published under the GNU General Public License 5use strict; 6 7use Test::More tests => 65 * 2 + 7; 8use FindBin qw($RealBin); 9use lib "$RealBin"; 10use Util qw(test_errors); 11use Parse::Pidl::IDL; 12use Parse::Pidl::NDR; 13 14sub testok($$) 15{ 16 my ($name, $data) = @_; 17 18 test_errors("", sub { 19 my $pidl = Parse::Pidl::IDL::parse_string($data, "<$name>"); 20 ok (defined($pidl), $name); 21 }); 22} 23 24sub testfail($$$) 25{ 26 my ($name, $data, $error) = @_; 27 28 test_errors($error, sub { 29 my $pidl = Parse::Pidl::IDL::parse_string($data, "<$name>"); 30 31 ok ((not defined $pidl), $name); 32 }); 33} 34 35testfail "unknowntag", "bla test {};", 36 "<unknowntag>:0: Syntax error near 'bla'\n"; 37testok "test1", "interface test { void Test(); }; "; 38testok "voidtest", "interface test { int Testx(void); }; "; 39testfail "voidtest", "interface test { Test(); }; ", 40 "<voidtest>:0: Syntax error near '('\n"; 41testok "argtest", "interface test { int Test(int a, long b, uint32 c); }; "; 42testok "array1", "interface test { int Test(int a[]); };"; 43testok "array2", "interface test { int Test(int a[2]); };"; 44testok "array3", "interface test { int Test(int a[b]); };"; 45testfail "array4", "interface test { int Test(int[] a); };", 46 "<array4>:0: Syntax error near '['\n"; 47testok "ptr1", "interface test { int Test(int *a); };"; 48testok "ptr2", "interface test { int Test(int **a); };"; 49testok "ptr3", "interface test { int Test(int ***a); };"; 50testfail "empty1", "interface test { };", "<empty1>:0: Syntax error near '}'\n"; 51testfail "empty2", "", ""; 52testok "attr1", "[uuid(\"myuuid\"),attr] interface test { int Test(int ***a); };"; 53testok "attr2", "interface test { [public] int Test(); };"; 54testok "attr3", "[attr1] [attr2] interface test { [public] int Test(); };"; 55testok "multfn", "interface test { int test1(); int test2(); };"; 56testok "multif", "interface test { int test1(); }; interface test2 { int test2(); };"; 57testok "tdstruct1", "interface test { typedef struct { } foo; };"; 58testok "tdstruct2", "interface test { typedef struct { int a; } foo; };"; 59testok "tdstruct3", "interface test { typedef struct { int a; int b; } foo; };"; 60testfail "tdstruct4", "interface test { typedef struct { int a, int b; } foo; };", 61 "<tdstruct4>:0: Syntax error near ','\n"; 62testok "struct1", "interface test { struct x { }; };"; 63testok "struct2", "interface test { struct x { int a; }; };"; 64testok "struct3", "interface test { struct x { int a; int b; }; };"; 65testfail "struct4", "interface test { struct x { int a, int b; }; };", 66 "<struct4>:0: Syntax error near ','\n"; 67testfail "struct5", "interface test { struct { int a; } x; };", 68 "<struct5>:0: Syntax error near 'x'\n"; 69testok "tdunion1", "interface test { typedef union { } a; };"; 70testok "tdunion2", "interface test { typedef union { int a; } a; };"; 71testok "union1", "interface test { union a { }; };"; 72testok "union2", "interface test { union x { int a; }; };"; 73testfail "union3", "interface test { union { int a; } x; };", 74 "<union3>:0: Syntax error near 'x'\n"; 75testok "typedef1", "interface test { typedef int a; };"; 76testfail "typedef2", "interface test { typedef x; };", 77 "<typedef2>:0: Syntax error near ';'\n"; 78testok "tdenum1", "interface test { typedef enum { A=1, B=2, C} a; };"; 79testok "enum1", "interface test { enum a { A=1, B=2, C}; };"; 80testfail "enum2", "interface test { enum { A=1, B=2, C} a; };", 81 "<enum2>:0: Syntax error near 'a'\n"; 82testok "nested1", "interface test { struct x { struct { int a; } z; }; };"; 83testok "nested2", "interface test { struct x { struct y { int a; } z; }; };"; 84testok "bitmap1", "interface test { bitmap x { a=1 }; };"; 85testok "unsigned", "interface test { struct x { unsigned short y; }; };"; 86testok "struct-property", "interface test { [public] struct x { short y; }; };"; 87testok "signed", "interface test { struct x { signed short y; }; };"; 88testok "declarg", "interface test { void test(struct { int x; } a); };"; 89testok "structarg", "interface test { void test(struct a b); };"; 90testfail "structargmissing", "interface test { void test(struct a); };", 91 "<structargmissing>:0: Syntax error near ')'\n"; 92testok "structqual", "interface test { struct x { struct y z; }; };"; 93testok "unionqual", "interface test { struct x { union y z; }; };"; 94testok "enumqual", "interface test { struct x { enum y z; }; };"; 95testok "bitmapqual", "interface test { struct x { bitmap y z; }; };"; 96testok "emptystructdecl", "interface test { struct x; };"; 97testok "emptyenumdecl", "interface test { enum x; };"; 98testok "emptytdstructdecl", "interface test { typedef struct x y; };"; 99testok "import", "import \"foo.idl\";"; 100testok "include", "include \"foo.h\";"; 101testfail "import-noquotes", "import foo.idl;", 102 "<import-noquotes>:0: Syntax error near 'foo'\n"; 103testfail "include-noquotes", "include foo.idl;", 104 "<include-noquotes>:0: Syntax error near 'foo'\n"; 105testok "importlib", "importlib \"foo.idl\";"; 106testfail "import-nosemicolon", "import \"foo.idl\"", 107 "<import-nosemicolon>:0: Syntax error near 'foo.idl'\n"; 108testok "import-multiple", "import \"foo.idl\", \"bar.idl\";"; 109testok "include-multiple", "include \"foo.idl\", \"bar.idl\";"; 110testok "empty-struct", "interface test { struct foo { }; }"; 111testok "typedef-double", "interface test { typedef struct foo { } foo; }"; 112testok "cpp-quote", "cpp_quote(\"bla\")"; 113 114my $x = Parse::Pidl::IDL::parse_string("interface foo { struct x {}; }", "<foo>"); 115 116is_deeply($x, [ { 117 'TYPE' => 'INTERFACE', 118 'NAME' => 'foo', 119 'DATA' => [ { 120 'TYPE' => 'STRUCT', 121 'NAME' => 'x', 122 'ELEMENTS' => [], 123 'FILE' => '<foo>', 124 'LINE' => 0 125 } ], 126 'FILE' => '<foo>', 127 'LINE' => 0 128}]); 129 130$x = Parse::Pidl::IDL::parse_string("interface foo { struct x; }", "<foo>"); 131is_deeply($x, [ { 132 'TYPE' => 'INTERFACE', 133 'NAME' => 'foo', 134 'DATA' => [ { 135 'TYPE' => 'STRUCT', 136 'NAME' => 'x', 137 'FILE' => '<foo>', 138 'LINE' => 0 139 } ], 140 'FILE' => '<foo>', 141 'LINE' => 0 142}]); 143 144$x = Parse::Pidl::IDL::parse_string("cpp_quote(\"foobar\")", "<quote>"); 145is_deeply($x, [ { 146 'TYPE' => 'CPP_QUOTE', 147 'DATA' => '"foobar"', 148 'FILE' => '<quote>', 149 'LINE' => 0 150}]); 151 152# A typedef of a struct without body 153$x = Parse::Pidl::IDL::parse_string("interface foo { typedef struct x y; }", "<foo>"); 154 155is_deeply($x, [ { 156 'TYPE' => 'INTERFACE', 157 'NAME' => 'foo', 158 'DATA' => [ { 159 'TYPE' => 'TYPEDEF', 160 'NAME' => 'y', 161 'POINTERS' => 0, 162 'DATA' => { 163 'TYPE' => 'STRUCT', 164 'NAME' => 'x', 165 'FILE' => '<foo>', 166 'LINE' => 0, 167 }, 168 'FILE' => '<foo>', 169 'LINE' => 0, 170 } ], 171 'FILE' => '<foo>', 172 'LINE' => 0 173}]); 174 175# A typedef of a struct with empty body 176$x = Parse::Pidl::IDL::parse_string("interface foo { typedef struct {} y; }", "<foo>"); 177 178is_deeply($x, [ { 179 'TYPE' => 'INTERFACE', 180 'NAME' => 'foo', 181 'DATA' => [ { 182 'TYPE' => 'TYPEDEF', 183 'NAME' => 'y', 184 'POINTERS' => 0, 185 'DATA' => { 186 'TYPE' => 'STRUCT', 187 'ELEMENTS' => [], 188 'FILE' => '<foo>', 189 'LINE' => 0 190 }, 191 'FILE' => '<foo>', 192 'LINE' => 0 193 } ], 194 'FILE' => '<foo>', 195 'LINE' => 0 196}]); 197 198# A typedef of a bitmap with no body 199$x = Parse::Pidl::IDL::parse_string("interface foo { typedef bitmap x y; }", "<foo>"); 200 201is_deeply($x, [ { 202 'TYPE' => 'INTERFACE', 203 'NAME' => 'foo', 204 'DATA' => [ { 205 'TYPE' => 'TYPEDEF', 206 'NAME' => 'y', 207 'POINTERS' => 0, 208 'DATA' => { 209 'TYPE' => 'BITMAP', 210 'NAME' => 'x', 211 'FILE' => '<foo>', 212 'LINE' => 0 213 }, 214 'FILE' => '<foo>', 215 'LINE' => 0 216 } ], 217 'FILE' => '<foo>', 218 'LINE' => 0 219}]); 220 221 222# A typedef of a union with no body 223$x = Parse::Pidl::IDL::parse_string("interface foo { typedef union x y; }", "<foo>"); 224 225is_deeply($x, [ { 226 'TYPE' => 'INTERFACE', 227 'NAME' => 'foo', 228 'DATA' => [ { 229 'TYPE' => 'TYPEDEF', 230 'NAME' => 'y', 231 'POINTERS' => 0, 232 'DATA' => { 233 'TYPE' => 'UNION', 234 'NAME' => 'x', 235 'FILE' => '<foo>', 236 'LINE' => 0 237 }, 238 'FILE' => '<foo>', 239 'LINE' => 0 240 } ], 241 'FILE' => '<foo>', 242 'LINE' => 0 243}]); 244