From ece40ca87b9d278758fe822a19ebf03ee2a3a199 Mon Sep 17 00:00:00 2001 From: Gerald Combs Date: Wed, 21 Sep 2005 16:06:59 +0000 Subject: [PATCH] Add the "test" directory and man page to pidl. This should hopefully fix the current distcheck and RPM build failures. svn path=/trunk/; revision=15933 --- tools/pidl/pidl.1.xml | 607 +++++++++++++++++++++++++++++++++ tools/pidl/tests/ndr_align.pl | 144 ++++++++ tools/pidl/tests/ndr_alloc.pl | 125 +++++++ tools/pidl/tests/ndr_array.pl | 45 +++ tools/pidl/tests/ndr_refptr.pl | 516 ++++++++++++++++++++++++++++ tools/pidl/tests/ndr_simple.pl | 40 +++ tools/pidl/tests/ndr_string.pl | 57 ++++ 7 files changed, 1534 insertions(+) create mode 100644 tools/pidl/pidl.1.xml create mode 100755 tools/pidl/tests/ndr_align.pl create mode 100755 tools/pidl/tests/ndr_alloc.pl create mode 100755 tools/pidl/tests/ndr_array.pl create mode 100755 tools/pidl/tests/ndr_refptr.pl create mode 100755 tools/pidl/tests/ndr_simple.pl create mode 100755 tools/pidl/tests/ndr_string.pl diff --git a/tools/pidl/pidl.1.xml b/tools/pidl/pidl.1.xml new file mode 100644 index 0000000000..25842bc097 --- /dev/null +++ b/tools/pidl/pidl.1.xml @@ -0,0 +1,607 @@ + + + + + + pidl + 1 + + + + pidl + IDL Compiler written in Perl + + + + + pidl + --help + --outputdir OUTNAME + --parse-idl-tree + --dump-idl-tree + --dump-ndr-tree + --ndr-header[=OUTPUT] + --header[=OUTPUT] + --ejs[=OUTPUT] + --swig[=OUTPUT] + --uint-enums + --ndr-parser[=OUTPUT] + --client + --server + --dcom-proxy + --com-header + --warn-compat + --quiet + --verbose + --template + --eth-parser[=OUTPUT] + --diff + --dump-idl + idlfile + idlfile2 + ... + + + + + DESCRIPTION + + pidl is an IDL compiler written in Perl that aims to be somewhat + compatible with the midl compiler. IDL stands for + "Interface Definition Language". + + pidl can generate stubs for DCE/RPC server code, DCE/RPC + client code and ethereal dissectors for DCE/RPC traffic. + + IDL compilers like pidl take a description + of an interface as their input and use it to generate C + (though support for other languages may be added later) code that + can use these interfaces, pretty print data sent + using these interfaces, or even generate ethereal + dissectors that can parse data sent over the + wire by these interfaces. + + pidl takes IDL files in the same format as is used by midl, + converts it to a .pidl file (which contains pidl's internal representation of the interface) and can then generate whatever output you need. + .pidl files should be used for debugging purposes only. Write your + interface definitions in .idl format. + + + + The goal of pidl is to implement a IDL compiler that can be used + while developing the RPC subsystem in Samba (for + both marshalling/unmarshalling and debugging purposes). + + + + + + OPTIONS + + + + --help + + Show list of available options. + + + + --outputdir OUTNAME + Write output files to the specified directory. + Defaults to the current directory. + + + + + --parse-idl-tree + + Read internal tree structure from input files rather + then assuming they contain IDL. + + + + + --dump-idl + + Generate a new IDL file. File will be named OUTNAME.idl. + + + + + --header + + Generate a C header file for the specified interface. Filename defaults to OUTNAME.h. + + + + --ndr-header + + Generate a C header file with the prototypes for the NDR parsers. Filename defaults to ndr_OUTNAME.h. + + + + --ndr-parser + + Generate a C file containing NDR parsers. + Filename defaults to ndr_OUTNAME.c. + + + + + + --server + + Generate boilerplate for the RPC server that implements + the interface. Filename defaults to ndr_OUTNAME_s.c + + + + + --template + + Generate stubs for a RPC server that implements + the interface. Output will be written to stdout. + + + + + + --eth-parser + + Generate an Ethereal dissector (in C) for the interface. Filename + defaults to packet-dcerpc-OUTNAME.c. + + + Pidl will read additional data + from an ethereal conformance file if present. Such a file should + have the same location as the IDL file but with the extension + cnf rather then idl. See + below for details on the format of this file. + + + + + --diff + + Parse an IDL file, generate a new IDL file based + on the internal data structures and see if there are + any differences with the + original IDL file. Useful for debugging pidl. + + + + + --dump-idl-tree + + Tell pidl to dump the internal tree representation of an IDL + file the to disk. Useful + for debugging pidl. + + + + --dump-ndr-tree + + Tell pidl to dump the internal NDR information tree it generated + from the IDL file to disk. Useful for debugging pidl. + + + + + + + IDL SYNTAX + + IDL files are always preprocessed using the C preprocessor. + + Pretty much everything in an interface (the interface itself, + functions, parameters) can have attributes (or properties + whatever name you give them). Attributes + always prepend the element they apply to and are surrounded + by square brackets ([]). Multiple attributes + are separated by comma's; arguments to attributes are + specified between parentheses. + + See the section COMPATIBILITY for the list of attributes that + pidl supports. + + C-style comments can be used. + + + CONFORMANT ARRAYS + + +A conformant array is one with that ends in [*] or []. The strange +things about conformant arrays are: + + + + they can only appear as the last element of a structure + the array size appears before the structure itself on the wire. + + + + So, in this example: + + + + typedef struct { + long abc; + long count; + long foo; + [size_is(count)] long s[*]; + } Struct1; + + + +it appears like this: + + + +[size_is] [abc] [count] [foo] [s...] + + + +the first [size_is] field is the allocation size of the array, and +occurs before the array elements and even before the structure +alignment. + + + +Note that size_is() can refer to a constant, but that doesn't change +the wire representation. It does not make the array a fixed array. + + + +midl.exe would write the above array as the following C header: + + + + typedef struct { + long abc; + long count; + long foo; + long s[1]; + } Struct1; + + + +pidl takes a different approach, and writes it like this: + + + + typedef struct { + long abc; + long count; + long foo; + long *s; + } Struct1; + + + + + + VARYING ARRAYS + + +A varying array looks like this: + + + + typedef struct { + long abc; + long count; + long foo; + [size_is(count)] long *s; + } Struct1; + + + +This will look like this on the wire: + + + +[abc] [count] [foo] [PTR_s] [count] [s...] + + + + + + FIXED ARRAYS + + +A fixed array looks like this: + + + + typedef struct { + long s[10]; + } Struct1; + + + +The NDR representation looks just like 10 separate long +declarations. The array size is not encoded on the wire. + + + +pidl also supports "inline" arrays, which are not part of the IDL/NDR +standard. These are declared like this: + + + + typedef struct { + uint32 foo; + uint32 count; + uint32 bar; + long s[count]; + } Struct1; + + + +This appears like this: + + + +[foo] [count] [bar] [s...] + + + +Fixed arrays are an extension added to support some of the strange +embedded structures in security descriptors and spoolss. + + + + +This section is by no means complete. See the OpenGroup and MSDN + documentation for additional information. + + + + COMPATIBILITY WITH MIDL + + + Missing features in pidl + + The following MIDL features are not (yet) implemented in pidl + or are implemented with an incompatible interface: + + + + Asynchronous communication + Typelibs (.tlb files) + Datagram support (ncadg_*) + + + + + Supported properties (attributes is the MIDL term) + + + in, out, ref, length_is, switch_is, size_is, uuid, case, default, string, unique, ptr, pointer_default, v1_enum, object, helpstring, range, local, call_as, endpoint, switch_type, progid, coclass, iid_is. + + + + + + PIDL Specific properties + + + public + +The [public] property on a structure or union is a pidl extension that +forces the generated pull/push functions to be non-static. This allows +you to declare types that can be used between modules. If you don't +specify [public] then pull/push functions for other than top-level +functions are declared static. + + + + noprint + +The [noprint] property is a pidl extension that allows you to specify +that pidl should not generate a ndr_print_*() function for that +structure or union. This is used when you wish to define your own +print function that prints a structure in a nicer manner. A good +example is the use of [noprint] on dom_sid, which allows the +pretty-printing of SIDs. + + + + value + +The [value(expression)] property is a pidl extension that allows you +to specify the value of a field when it is put on the wire. This +allows fields that always have a well-known value to be automatically +filled in, thus making the API more programmer friendly. The +expression can be any C expression. + + + + relative + +The [relative] property can be supplied on a pointer. When it is used +it declares the pointer as a spoolss style "relative" pointer, which +means it appears on the wire as an offset within the current +encapsulating structure. This is not part of normal IDL/NDR, but it is +a very useful extension as it avoids the manual encoding of many +complex structures. + + + + subcontext(length) + + Specifies that a size of length + bytes should be read, followed by a blob of that size, + which will be parsed as NDR. + + + + flag + + Specify boolean options, mostly used for + low-level NDR options. Several options + can be specified using the | character. + Note that flags are inherited by substructures! + + + + nodiscriminant + +The [nodiscriminant] property on a union means that the usual uint16 +discriminent field at the start of the union on the wire is +omitted. This is not normally allowed in IDL/NDR, but is used for some +spoolss structures. + + + + charset(name) + + Specify that the array or string uses the specified + charset. If this attribute is specified, pidl will + take care of converting the character data from this format + to the host format. Commonly used values are UCS2, DOS and UTF8. + + + + + + + Unsupported MIDL properties + +aggregatable, appobject, async_uuid, bindable, control, cpp_quote, defaultbind, defaultcollelem, defaultvalue, defaultvtable, dispinterface, displaybind, dual, entry, first_is, helpcontext, helpfile, helpstringcontext, helpstringdll, hidden, idl_module, idl_quote, id, immediatebind, importlib, import, include, includelib, last_is, lcid, licensed, max_is, module, ms_union, no_injected_text, nonbrowsable, noncreatable, nonextensible, odl, oleautomation, optional, pragma, propget, propputref, propput, readonly, requestedit, restricted, retval, source, transmit_as, uidefault, usesgetlasterror, vararg, vi_progid, wire_marshal. + + + + + + + ETHEREAL CONFORMANCE FILES + + +Pidl needs additional data for ethereal output. This data is read from +so-called conformance files. This section describes the format of these +files. + + +Conformance files are simple text files with a single command on each line. +Empty lines and lines starting with a '#' character are ignored. +Arguments to commands are seperated by spaces. + + + +The following commands are currently supported: + + + + + + TYPE name dissector ft_type base_type mask valsstring alignment + Register new data type with specified name, what dissector function to call and what properties to give header fields for elements of this type. + + + + NOEMIT type + + Suppress emitting a dissect_type function for the specified type + + + + + PARAM_VALUE type param + + Set parameter to specify to dissector function for given type. + + + + + HF_FIELD hf title filter ft_type base_type valsstring mask description + + Generate a custom header field with specified properties. + + + + + HF_RENAME old_hf_name new_hf_name + + Force the use of new_hf_name when the parser generator was going to + use old_hf_name. + + + + This can be used in conjunction with HF_FIELD in order to make more then + one element use the same filter name. + + + + + + STRIP_PREFIX prefix + + Remove the specified prefix from all function names (if present). + + + + + PROTOCOL longname shortname filtername + + Change the short-, long- and filter-name for the current interface in + Ethereal. + + + + + FIELD_DESCRIPTION field desc + Change description for the specified header field. `field' is the hf name of the field. + + + + + IMPORT dissector code... + + Code to insert when generating the specified dissector. @HF@ and + @PARAM@ will be substituted. + + + + + + + + + EXAMPLES + + + # Generating an ethereal parser + $ ./pidl --eth-parser -- atsvc.idl + + # Generating a TDR parser + $ ./pidl --tdr-parser --tdr-header --header -- regf.idl + + + + + + VERSION + + This man page is correct for version 4.0 of the Samba suite. + + + + SEE ALSO + + Field Attributes [Remote Procedure Call], Ethereal Wiki on DCE/RPC. + + + + + AUTHOR + + pidl was written by Andrew Tridgell, Stefan Metzmacher, Tim + Potter and Jelmer Vernooij. + + This manpage was written by Jelmer Vernooij, partially based on the original pidl README by Andrew Tridgell. + + + + + diff --git a/tools/pidl/tests/ndr_align.pl b/tools/pidl/tests/ndr_align.pl new file mode 100755 index 0000000000..da994224eb --- /dev/null +++ b/tools/pidl/tests/ndr_align.pl @@ -0,0 +1,144 @@ +#!/usr/bin/perl +# NDR alignment tests +# (C) 2005 Jelmer Vernooij. Published under the GNU GPL +use strict; + +use Parse::Pidl::Test; + +my %settings = Parse::Pidl::Test::GetSettings(@ARGV); + +$settings{'IDL-Arguments'} = ['--quiet', '--parse', '--parser=ndr_test.c', '--header=ndr_test.h']; +$settings{'IncludeFiles'} = ['ndr_test.h']; +$settings{'ExtraFiles'} = ['ndr_test.c']; + +Parse::Pidl::Test::test_idl('align-uint8-uint16', \%settings, +' + typedef [public] struct { + uint8 x; + uint16 y; + } bla; +', +' + struct ndr_push *ndr = ndr_push_init(); + 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 (NT_STATUS_IS_ERR(ndr_push_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r))) + return 1; + + result_blob = ndr_push_blob(ndr); + + if (!data_blob_equal(&result_blob, &expected_blob)) + return 2; +'); + +Parse::Pidl::Test::test_idl('align-uint8-uint32', \%settings, +' + typedef [public] struct { + uint8 x; + uint32 y; + } bla; +', +' + struct ndr_push *ndr = ndr_push_init(); + 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 (NT_STATUS_IS_ERR(ndr_push_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r))) + return 1; + + result_blob = ndr_push_blob(ndr); + + if (!data_blob_equal(&result_blob, &expected_blob)) + return 2; +'); + + +Parse::Pidl::Test::test_idl('align-uint8-hyper', \%settings, +' + typedef [public] struct { + uint8 x; + hyper y; + } bla; +', +' + struct ndr_push *ndr = ndr_push_init(); + 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 = 0xbeefbeefbeefbeef; + + if (NT_STATUS_IS_ERR(ndr_push_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r))) + return 1; + + result_blob = ndr_push_blob(ndr); + + if (!data_blob_equal(&result_blob, &expected_blob)) + return 2; +'); + +Parse::Pidl::Test::test_idl('noalignflag-uint8-uint16', \%settings, +' + typedef [public] struct { + uint8 x; + uint16 y; + } bla; +', +' + struct ndr_push *ndr = ndr_push_init(); + 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 (NT_STATUS_IS_ERR(ndr_push_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r))) + return 1; + + result_blob = ndr_push_blob(ndr); + + if (!data_blob_equal(&result_blob, &expected_blob)) + return 2; +'); + +Parse::Pidl::Test::test_idl('align-blob-align2', \%settings, +' + typedef [public] struct { + uint8 x; + [flag(LIBNDR_FLAG_ALIGN2)] DATA_BLOB data; + } bla; +', +' + struct ndr_push *ndr = ndr_push_init(); + struct bla r; + uint8_t data[] = { 0x01, 0x02 }; + uint8_t expected[] = { 0x0D, 0x00, 0x01, 0x02 }; + DATA_BLOB expected_blob = { expected, 4 }; + DATA_BLOB result_blob; + + r.x = 13; + r.data.data = data; + r.data.length = 2; + + if (NT_STATUS_IS_ERR(ndr_push_bla(ndr, NDR_SCALARS|NDR_BUFFERS, &r))) + return 1; + + result_blob = ndr_push_blob(ndr); + + if (!data_blob_equal(&result_blob, &expected_blob)) + return 2; +'); diff --git a/tools/pidl/tests/ndr_alloc.pl b/tools/pidl/tests/ndr_alloc.pl new file mode 100755 index 0000000000..4f6eddbfb9 --- /dev/null +++ b/tools/pidl/tests/ndr_alloc.pl @@ -0,0 +1,125 @@ +#!/usr/bin/perl +# NDR allocation tests +# (C) 2005 Jelmer Vernooij. Published under the GNU GPL +use strict; + +use Parse::Pidl::Test; + +my %settings = Parse::Pidl::Test::GetSettings(@ARGV); +$settings{'IDL-Arguments'} = ['--quiet', '--parse', '--parser=ndr_test.c', '--header=ndr_test.h']; +$settings{'IncludeFiles'} = ['ndr_test.h']; +$settings{'ExtraFiles'} = ['ndr_test.c']; + +# Check that an outgoing scalar pointer is allocated correctly + +Parse::Pidl::Test::test_idl("alloc-scalar", \%settings, +' + 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); + struct TestAlloc r; + + if (NT_STATUS_IS_ERR(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 +Parse::Pidl::Test::test_idl("alloc-buffer", \%settings, +' + 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); + struct TestAlloc r; + + if (NT_STATUS_IS_ERR(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 +Parse::Pidl::Test::test_idl("ref-noalloc-null", \%settings, +' + [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); + struct TestAlloc r; + r.in.t = NULL; + + if (NT_STATUS_IS_OK(ndr_pull_TestAlloc(ndr, NDR_IN, &r))) + return 1; +' +); + +# Check that ref pointers aren't allocated by default +Parse::Pidl::Test::test_idl("ref-noalloc", \%settings, +' + [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); + struct TestAlloc r; + uint8_t x; + r.in.t = &x; + + if (NT_STATUS_IS_ERR(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 +Parse::Pidl::Test::test_idl("ref-alloc", \%settings, +' + [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); + struct TestAlloc r; + ndr->flags |= LIBNDR_FLAG_REF_ALLOC; + r.in.t = NULL; + + if (NT_STATUS_IS_ERR(ndr_pull_TestAlloc(ndr, NDR_IN, &r))) + return 1; + + if (r.in.t == NULL) + return 2; + + if (*r.in.t != 0x03) + return 3; +' +); diff --git a/tools/pidl/tests/ndr_array.pl b/tools/pidl/tests/ndr_array.pl new file mode 100755 index 0000000000..d486308339 --- /dev/null +++ b/tools/pidl/tests/ndr_array.pl @@ -0,0 +1,45 @@ +#!/usr/bin/perl +# Array testing +# (C) 2005 Jelmer Vernooij +# Published under the GNU General Public License +use strict; + +use Parse::Pidl::Test; + +my %settings = Parse::Pidl::Test::GetSettings(@ARGV); +$settings{'IDL-Arguments'} = ['--quiet', '--parse', '--parser=ndr_test.c', '--header=ndr_test.h']; +$settings{'IncludeFiles'} = ['ndr_test.h']; +$settings{'ExtraFiles'} = ['ndr_test.c']; + +Parse::Pidl::Test::test_idl( + # Name + 'Fixed-Array', + + # Settings + \%settings, + + # IDL + '[public] void Test([in] uint8 x[10]);', + + # C Test + ' + 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); + + if (NT_STATUS_IS_ERR(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; + } +'); diff --git a/tools/pidl/tests/ndr_refptr.pl b/tools/pidl/tests/ndr_refptr.pl new file mode 100755 index 0000000000..8344661ad3 --- /dev/null +++ b/tools/pidl/tests/ndr_refptr.pl @@ -0,0 +1,516 @@ +#!/usr/bin/perl +# Simple tests for pidl's handling of ref pointers, based +# on tridge's ref_notes.txt +# (C) 2005 Jelmer Vernooij . +# Published under the GNU General Public License. +use strict; + +use Parse::Pidl::Test; + +my %settings = Parse::Pidl::Test::GetSettings(@ARGV); +$settings{'IDL-Arguments'} = ['--quiet', '--parse', '--parser=ndr_test.c', '--header=ndr_test.h']; +$settings{'IncludeFiles'} = ['ndr_test.h']; +$settings{'ExtraFiles'} = ['ndr_test.c']; + +Parse::Pidl::Test::test_idl("noptr-push", \%settings, +' typedef struct { + uint16 x; + } xstruct; + + [public] uint16 echo_TestRef([in] xstruct foo); +', +' + struct ndr_push *ndr = ndr_push_init(); + uint16_t v = 13; + struct echo_TestRef r; + r.in.foo.x = v; + + if (NT_STATUS_IS_ERR(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; + } +'); + +Parse::Pidl::Test::test_idl("ptr-embedded-push", \%settings, +' typedef struct { + uint16 *x; + } xstruct; + + [public] uint16 echo_TestRef([in] xstruct foo); +', +' + uint16_t v = 13; + struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + r.in.foo.x = &v; + + if (NT_STATUS_IS_ERR(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; +'); + +Parse::Pidl::Test::test_idl("ptr-embedded-push-null", \%settings, +' typedef struct { + uint16 *x; + } xstruct; + + [public] uint16 echo_TestRef([in] xstruct foo); +', +' + struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + r.in.foo.x = NULL; + + if (NT_STATUS_IS_ERR(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; +'); + +Parse::Pidl::Test::test_idl("refptr-embedded-push", \%settings, +' + typedef struct { + [ref] uint16 *x; + } xstruct; + + [public] uint16 echo_TestRef([in] xstruct foo); +', +' + uint16_t v = 13; + struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + r.in.foo.x = &v; + + if (NT_STATUS_IS_ERR(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; +'); + +Parse::Pidl::Test::test_idl("refptr-embedded-push-null", \%settings, +' + typedef struct { + [ref] uint16 *x; + } xstruct; + + [public] uint16 echo_TestRef([in] xstruct foo); +', +' + struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + r.in.foo.x = NULL; + + if (NT_STATUS_IS_OK(ndr_push_echo_TestRef(ndr, NDR_IN, &r))) + return 1; + /* Windows gives [client runtime error 0x6f4] */ +'); + +Parse::Pidl::Test::test_idl("ptr-top-push", \%settings, +' + typedef struct { + uint16 x; + } xstruct; + + [public] uint16 echo_TestRef([in] xstruct *foo); +', +' + struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + struct xstruct s; + s.x = 13; + r.in.foo = &s; + + if (NT_STATUS_IS_ERR(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; +'); + +Parse::Pidl::Test::test_idl("ptr-top-push-null", \%settings, +' + typedef struct { + uint16 x; + } xstruct; + + [public] uint16 echo_TestRef([in] xstruct *foo); +', +' + struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + r.in.foo = NULL; + + if (NT_STATUS_IS_OK(ndr_push_echo_TestRef(ndr, NDR_IN, &r))) + return 1; + + /* Windows gives [client runtime error 0x6f4] */ +'); + + +Parse::Pidl::Test::test_idl("refptr-top-push", \%settings, +' + typedef struct { + uint16 x; + } xstruct; + + [public] uint16 echo_TestRef([in,ref] xstruct *foo); +', +' + struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + struct xstruct s; + s.x = 13; + r.in.foo = &s; + + if (NT_STATUS_IS_ERR(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; +'); + +Parse::Pidl::Test::test_idl("refptr-top-push-null", \%settings, +' + typedef struct { + uint16 x; + } xstruct; + + [public] uint16 echo_TestRef([in,ref] xstruct *foo); +', +' + struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + r.in.foo = NULL; + + if (NT_STATUS_IS_OK(ndr_push_echo_TestRef(ndr, NDR_IN, &r))) + return 1; + + /* Windows gives [client runtime error 0x6f4] */ +'); + + +Parse::Pidl::Test::test_idl("uniqueptr-top-push", \%settings, +' typedef struct { + uint16 x; + } xstruct; + + [public] uint16 echo_TestRef([in,unique] xstruct *foo); +', +' + struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + struct xstruct s; + s.x = 13; + r.in.foo = &s; + + if (NT_STATUS_IS_ERR(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; +'); + +Parse::Pidl::Test::test_idl("uniqueptr-top-push-null", \%settings, +' typedef struct { + uint16 x; + } xstruct; + + [public] uint16 echo_TestRef([in,unique] xstruct *foo); +', +' + struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + r.in.foo = NULL; + + if (NT_STATUS_IS_ERR(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; +'); + + +Parse::Pidl::Test::test_idl("ptr-top-out-pull", \%settings, +' + 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); + struct xstruct s; + struct echo_TestRef r; + + r.out.foo = &s; + + if (NT_STATUS_IS_ERR(ndr_pull_echo_TestRef(ndr, NDR_OUT, &r))) + return 1; + + if (!r.out.foo) + return 2; + + if (r.out.foo->x != 13) + return 3; +'); + +Parse::Pidl::Test::test_idl("ptr-top-out-pull-null", \%settings, +' + 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); + struct echo_TestRef r; + + r.out.foo = NULL; + + if (NT_STATUS_IS_OK(ndr_pull_echo_TestRef(ndr, NDR_OUT, &r))) + return 1; + + /* Windows gives [client runtime error 0x6f4] */ +'); + + +Parse::Pidl::Test::test_idl("refptr-top-out-pull", \%settings, +' + 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); + struct xstruct s; + struct echo_TestRef r; + + r.out.foo = &s; + + if (NT_STATUS_IS_ERR(ndr_pull_echo_TestRef(ndr, NDR_OUT, &r))) + return 1; + + if (!r.out.foo) + return 2; + + if (r.out.foo->x != 13) + return 3; +'); + +Parse::Pidl::Test::test_idl("refptr-top-out-pull-null", \%settings, +' + 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); + struct echo_TestRef r; + + r.out.foo = NULL; + + if (NT_STATUS_IS_OK(ndr_pull_echo_TestRef(ndr, NDR_OUT, &r))) + return 1; + + /* Windows gives [client runtime error 0x6f4] */ +'); + + +Parse::Pidl::Test::test_idl("ptr-top-push-double", \%settings, +' + [public] void echo_TestRef([in] uint16 **foo); +', +' struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + uint16_t v = 13; + uint16_t *pv = &v; + r.in.foo = &pv; + + if (NT_STATUS_IS_ERR(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; +'); + +Parse::Pidl::Test::test_idl("ptr-top-push-double-sndnull", \%settings, +' + [public] void echo_TestRef([in] uint16 **foo); +', +' struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + uint16_t *pv = NULL; + r.in.foo = &pv; + + if (NT_STATUS_IS_ERR(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; +'); + +Parse::Pidl::Test::test_idl("ptr-top-push-double-fstnull", \%settings, +' + [public] void echo_TestRef([in] uint16 **foo); +', +' struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + r.in.foo = NULL; + + if (NT_STATUS_IS_OK(ndr_push_echo_TestRef(ndr, NDR_IN, &r))) + return 1; + + /* Windows gives [client runtime error 0x6f4] */ + +'); + + +Parse::Pidl::Test::test_idl("refptr-top-push-double", \%settings, +' + [public] void echo_TestRef([in,ref] uint16 **foo); +', +' struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + uint16_t v = 13; + uint16_t *pv = &v; + r.in.foo = &pv; + + if (NT_STATUS_IS_ERR(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; +'); + +Parse::Pidl::Test::test_idl("refptr-top-push-double-sndnull", \%settings, +' + [public] void echo_TestRef([in,ref] uint16 **foo); +', +' struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + uint16_t *pv = NULL; + r.in.foo = &pv; + + if (NT_STATUS_IS_ERR(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; +'); + +Parse::Pidl::Test::test_idl("refptr-top-push-double-fstnull", \%settings, +' + [public] void echo_TestRef([in,ref] uint16 **foo); +', +' struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + r.in.foo = NULL; + + if (NT_STATUS_IS_OK(ndr_push_echo_TestRef(ndr, NDR_IN, &r))) + return 1; + + /* Windows gives [client runtime error 0x6f4] */ + +'); + +Parse::Pidl::Test::test_idl("ignore-ptr", \%settings, +' + [public] void echo_TestRef([in,ignore] uint16 *foo, [in] uint16 *bar); +', +' struct ndr_push *ndr = ndr_push_init(); + struct echo_TestRef r; + uint16_t v = 10; + r.in.foo = &v; + r.in.bar = &v; + + if (NT_STATUS_IS_OK(ndr_push_echo_TestRef(ndr, NDR_IN, &r))) + return 1; + + if (ndr->offset != 4) + return 2; +'); diff --git a/tools/pidl/tests/ndr_simple.pl b/tools/pidl/tests/ndr_simple.pl new file mode 100755 index 0000000000..7d48c9f4d7 --- /dev/null +++ b/tools/pidl/tests/ndr_simple.pl @@ -0,0 +1,40 @@ +#!/usr/bin/perl +# Some simple tests for pidl +# (C) 2005 Jelmer Vernooij +# Published under the GNU General Public License +use strict; + +use Parse::Pidl::Test; + +my %settings = Parse::Pidl::Test::GetSettings(@ARGV); +$settings{'IDL-Arguments'} = ['--quiet', '--parse', '--parser=ndr_test.c', '--header=ndr_test.h']; +$settings{'IncludeFiles'} = ['ndr_test.h']; +$settings{'ExtraFiles'} = ['ndr_test.c']; + +Parse::Pidl::Test::test_idl( + # Name + 'UInt8', + + # Settings + \%settings, + + # IDL + 'void Test();', + + # C 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); + + if (NT_STATUS_IS_ERR(ndr_pull_uint8(ndr, NDR_SCALARS, &result))) + return 1; + + if (result != 0x02) + return 2; +'); diff --git a/tools/pidl/tests/ndr_string.pl b/tools/pidl/tests/ndr_string.pl new file mode 100755 index 0000000000..ad8db912d7 --- /dev/null +++ b/tools/pidl/tests/ndr_string.pl @@ -0,0 +1,57 @@ +#!/usr/bin/perl +# String tests for pidl +# (C) 2005 Jelmer Vernooij +# Published under the GNU General Public License +use strict; + +use Parse::Pidl::Test; + +my %settings = Parse::Pidl::Test::GetSettings(@ARGV); + +$settings{'IDL-Arguments'} = ['--quiet', '--parse', '--parser=ndr_test.c', '--header=ndr_test.h']; +$settings{'IncludeFiles'} = ['ndr_test.h']; +$settings{'ExtraFiles'} = ['ndr_test.c']; + +Parse::Pidl::Test::test_idl("string-pull-empty", \%settings, +' [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 (NT_STATUS_IS_ERR(ndr_pull_TestString(ndr, NDR_IN, &r))) + return 1; + + if (r.in.data == NULL) + return 2; + + if (r.in.data[0] != 0) + return 3; +'); + +Parse::Pidl::Test::test_idl("string-ascii-pull", \%settings, +' + [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 (NT_STATUS_IS_ERR(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; +');