aboutsummaryrefslogtreecommitdiffstats
path: root/tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm
diff options
context:
space:
mode:
authorjmayer <jmayer@f5534014-38df-0310-8fa8-9805f1628bb7>2005-12-26 00:47:24 +0000
committerjmayer <jmayer@f5534014-38df-0310-8fa8-9805f1628bb7>2005-12-26 00:47:24 +0000
commita8fabc22cefbab5796d2842503490157cf9556ad (patch)
tree25260b209000c9930b09dd312bc669b40145bde2 /tools/pidl/lib/Parse/Pidl/Samba4/TDR.pm
parentf9fa74937dad7cd1f5d60f464ab0d08fd030c20c (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.pm251
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;