diff options
author | jmayer <jmayer@f5534014-38df-0310-8fa8-9805f1628bb7> | 2005-12-26 00:47:24 +0000 |
---|---|---|
committer | jmayer <jmayer@f5534014-38df-0310-8fa8-9805f1628bb7> | 2005-12-26 00:47:24 +0000 |
commit | a8fabc22cefbab5796d2842503490157cf9556ad (patch) | |
tree | 25260b209000c9930b09dd312bc669b40145bde2 /tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm | |
parent | f9fa74937dad7cd1f5d60f464ab0d08fd030c20c (diff) |
Update from samba tree revision 12430 to 12487
============================ Samba log start ============
------------------------------------------------------------------------
r12462 | jelmer | 2005-12-24 22:57:51 +0100 (Sat, 24 Dec 2005) | 2 lines
Hide oo magic from callers of the parser
------------------------------------------------------------------------
r12463 | jelmer | 2005-12-24 23:11:44 +0100 (Sat, 24 Dec 2005) | 2 lines
Rename 'Samba' namespace to 'Samba4'
------------------------------------------------------------------------
r12464 | jelmer | 2005-12-25 00:32:50 +0100 (Sun, 25 Dec 2005) | 4 lines
Add simple IDL parsing tests for pidl using the standard perl
testing framework (Test::Simple, distributed with perl itself).
Run these tests from 'make test'
------------------------------------------------------------------------
r12465 | jelmer | 2005-12-25 02:33:35 +0100 (Sun, 25 Dec 2005) | 3 lines
Merge Parse::Pidl::Samba4::NDR::Header into
Parse::Pidl::Samba4::NDR::Parser.
Small optimization to avoid including NDR headers multiple times
------------------------------------------------------------------------
r12470 | jelmer | 2005-12-25 04:04:13 +0100 (Sun, 25 Dec 2005) | 3 lines
Add helper module for pidl tests
Convert other pidl tests to use Test::More and run them from 'make test'
------------------------------------------------------------------------
r12480 | jelmer | 2005-12-25 15:11:59 +0100 (Sun, 25 Dec 2005) | 2 lines
Extend testsuite
------------------------------------------------------------------------
r12481 | jelmer | 2005-12-25 15:59:21 +0100 (Sun, 25 Dec 2005) | 4 lines
Move parser-specific utility functions to idl.yp, remove some unused
functions
Allow the use of non-typedef structs and unions when declaring
variables. Allow the
use of the 'signed' and 'unsigned' qualifiers for integer types
------------------------------------------------------------------------
r12482 | jelmer | 2005-12-25 15:59:39 +0100 (Sun, 25 Dec 2005) | 2 lines
Add some more tests
------------------------------------------------------------------------
r12483 | jelmer | 2005-12-25 16:19:55 +0100 (Sun, 25 Dec 2005) | 2 lines
Remove --tdr-header option (merged into --tdr-parser)
------------------------------------------------------------------------
r12484 | jelmer | 2005-12-25 18:12:52 +0100 (Sun, 25 Dec 2005) | 2 lines
Initial work on supporting non-typedeffed types
------------------------------------------------------------------------
============================ Samba log end ==============
git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@16896 f5534014-38df-0310-8fa8-9805f1628bb7
Diffstat (limited to 'tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm')
-rw-r--r-- | tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm b/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm new file mode 100644 index 0000000000..789fb7adbe --- /dev/null +++ b/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm @@ -0,0 +1,251 @@ +################################################### +# Trivial Parser Generator +# Copyright jelmer@samba.org 2005 +# released under the GNU GPL + +package Parse::Pidl::Samba4::TDR; +use Parse::Pidl::Util qw(has_property ParseExpr is_constant); + +use vars qw($VERSION); +$VERSION = '0.01'; + +use strict; + +my $ret; +my $ret_hdr; +my $tabs = ""; + +sub indent() { $tabs.="\t"; } +sub deindent() { $tabs = substr($tabs, 1); } +sub pidl($) { $ret .= $tabs.(shift)."\n"; } +sub pidl_hdr($) { $ret_hdr .= (shift)."\n"; } +sub fatal($$) { my ($e,$s) = @_; die("$e->{FILE}:$e->{LINE}: $s\n"); } +sub typearg($) { + my $t = shift; + return(", const char *name") if ($t eq "print"); + return(", TALLOC_CTX *mem_ctx") if ($t eq "pull"); + return(""); +} + +sub fn_declare($$) +{ + my ($p, $d) = @_; + if ($p) { pidl $d; pidl_hdr "$d;"; } else { pidl "static $d"; } +} + +sub ContainsArray($) +{ + my $e = shift; + foreach (@{$e->{ELEMENTS}}) { + next if (has_property($_, "charset") and + scalar(@{$_->{ARRAY_LEN}}) == 1); + return 1 if (defined($_->{ARRAY_LEN}) and + scalar(@{$_->{ARRAY_LEN}}) > 0); + } + return 0; +} + +sub ParserElement($$$) +{ + my ($e,$t,$env) = @_; + my $switch = ""; + my $array = ""; + my $name = ""; + my $mem_ctx = "mem_ctx"; + + fatal($e,"Pointers not supported in TDR") if ($e->{POINTERS} > 0); + fatal($e,"size_is() not supported in TDR") if (has_property($e, "size_is")); + fatal($e,"length_is() not supported in TDR") if (has_property($e, "length_is")); + + if ($t eq "print") { + $name = ", \"$e->{NAME}\"$array"; + } + + if (has_property($e, "flag")) { + pidl "{"; + indent; + pidl "uint32_t saved_flags = tdr->flags;"; + pidl "tdr->flags |= $e->{PROPERTIES}->{flag};"; + } + + if (has_property($e, "charset")) { + fatal($e,"charset() on non-array element") unless (defined($e->{ARRAY_LEN}) and scalar(@{$e->{ARRAY_LEN}}) > 0); + + my $len = ParseExpr(@{$e->{ARRAY_LEN}}[0], $env); + if ($len eq "*") { $len = "-1"; } + $name = ", mem_ctx" if ($t eq "pull"); + pidl "TDR_CHECK(tdr_$t\_charset(tdr$name, &v->$e->{NAME}, $len, sizeof($e->{TYPE}_t), CH_$e->{PROPERTIES}->{charset}));"; + return; + } + + if (has_property($e, "switch_is")) { + $switch = ", " . ParseExpr($e->{PROPERTIES}->{switch_is}, $env); + } + + if (defined($e->{ARRAY_LEN}) and scalar(@{$e->{ARRAY_LEN}}) > 0) { + my $len = ParseExpr($e->{ARRAY_LEN}[0], $env); + + if ($t eq "pull" and not is_constant($len)) { + pidl "TDR_ALLOC(mem_ctx, v->$e->{NAME}, $len);"; + $mem_ctx = "v->$e->{NAME}"; + } + + pidl "for (i = 0; i < $len; i++) {"; + indent; + $array = "[i]"; + } + + if ($t eq "pull") { + $name = ", $mem_ctx"; + } + + if (has_property($e, "value") && $t eq "push") { + pidl "v->$e->{NAME} = ".ParseExpr($e->{PROPERTIES}->{value}, $env).";"; + } + + pidl "TDR_CHECK(tdr_$t\_$e->{TYPE}(tdr$name$switch, &v->$e->{NAME}$array));"; + + if ($array) { deindent; pidl "}"; } + + if (has_property($e, "flag")) { + pidl "tdr->flags = saved_flags;"; + deindent; + pidl "}"; + } +} + +sub ParserStruct($$$$) +{ + my ($e,$n,$t,$p) = @_; + + fn_declare($p,,"NTSTATUS tdr_$t\_$n (struct tdr_$t *tdr".typearg($t).", struct $n *v)"); + pidl "{"; indent; + pidl "int i;" if (ContainsArray($e)); + + if ($t eq "print") { + pidl "tdr->print(tdr, \"\%-25s: struct $n\", name);"; + pidl "tdr->level++;"; + } + + my %env = map { $_->{NAME} => "v->$_->{NAME}" } @{$e->{ELEMENTS}}; + $env{"this"} = "v"; + ParserElement($_, $t, \%env) foreach (@{$e->{ELEMENTS}}); + + if ($t eq "print") { + pidl "tdr->level--;"; + } + + pidl "return NT_STATUS_OK;"; + + deindent; pidl "}"; +} + +sub ParserUnion($$$$) +{ + my ($e,$n,$t,$p) = @_; + + fn_declare($p,"NTSTATUS tdr_$t\_$n(struct tdr_$t *tdr".typearg($t).", int level, union $n *v)"); + pidl "{"; indent; + pidl "int i;" if (ContainsArray($e)); + + if ($t eq "print") { + pidl "tdr->print(tdr, \"\%-25s: union $n\", name);"; + pidl "tdr->level++;"; + } + + pidl "switch (level) {"; indent; + foreach (@{$e->{ELEMENTS}}) { + if (has_property($_, "case")) { + pidl "case " . $_->{PROPERTIES}->{case} . ":"; + } elsif (has_property($_, "default")) { + pidl "default:"; + } + indent; ParserElement($_, $t, {}); deindent; + pidl "break;"; + } + deindent; pidl "}"; + + if ($t eq "print") { + pidl "tdr->level--;"; + } + + pidl "return NT_STATUS_OK;\n"; + deindent; pidl "}"; +} + +sub ParserBitmap($$$$) +{ + my ($e,$n,$t,$p) = @_; + return if ($p); + pidl "#define tdr_$t\_$n tdr_$t\_" . Parse::Pidl::Typelist::bitmap_type_fn($e); +} + +sub ParserEnum($$$$) +{ + my ($e,$n,$t,$p) = @_; + my $bt = ($e->{PROPERTIES}->{base_type} or "uint8"); + + fn_declare($p, "NTSTATUS tdr_$t\_$n (struct tdr_$t *tdr".typearg($t).", enum $n *v)"); + pidl "{"; + if ($t eq "pull") { + pidl "\t$bt\_t r;"; + pidl "\tTDR_CHECK(tdr_$t\_$bt(tdr, mem_ctx, \&r));"; + pidl "\t*v = r;"; + } elsif ($t eq "push") { + pidl "\tTDR_CHECK(tdr_$t\_$bt(tdr, ($bt\_t *)v));"; + } elsif ($t eq "print") { + pidl "\t/* FIXME */"; + } + pidl "\treturn NT_STATUS_OK;"; + pidl "}"; +} + +sub ParserTypedef($$) +{ + my ($e,$t) = @_; + + return if (has_property($e, "no$t")); + + $e->{DATA}->{PROPERTIES} = $e->{PROPERTIES}; + + { STRUCT => \&ParserStruct, UNION => \&ParserUnion, + ENUM => \&ParserEnum, BITMAP => \&ParserBitmap + }->{$e->{DATA}->{TYPE}}->($e->{DATA}, $e->{NAME}, $t, has_property($e, "public")); + + pidl ""; +} + +sub ParserInterface($) +{ + my $x = shift; + + pidl_hdr "#ifndef __TDR_$x->{NAME}_HEADER__"; + pidl_hdr "#define __TDR_$x->{NAME}_HEADER__"; + + foreach (@{$x->{DATA}}) { + next if ($_->{TYPE} ne "TYPEDEF"); + ParserTypedef($_, "pull"); + ParserTypedef($_, "push"); + ParserTypedef($_, "print"); + } + + pidl_hdr "#endif /* __TDR_$x->{NAME}_HEADER__ */"; +} + +sub Parser($$$) +{ + my ($idl,$hdrname,$baseheader) = @_; + $ret = ""; $ret_hdr = ""; + pidl "/* autogenerated by pidl */"; + pidl "#include \"includes.h\""; + pidl "#include \"$hdrname\""; + pidl ""; + pidl_hdr "/* autogenerated by pidl */"; + pidl_hdr "#include \"$baseheader\""; + pidl_hdr ""; + + foreach (@$idl) { ParserInterface($_) if ($_->{TYPE} eq "INTERFACE"); } + return ($ret_hdr, $ret); +} + +1; |