1 ###################################################
2 # Trivial Parser Generator
3 # Copyright jelmer@samba.org 2005-2007
4 # released under the GNU GPL
6 package Parse::Pidl::Samba4::TDR;
7 use Parse::Pidl qw(fatal);
8 use Parse::Pidl::Util qw(has_property ParseExpr is_constant);
9 use Parse::Pidl::Samba4 qw(is_intree choose_header);
13 @EXPORT_OK = qw(ParserType $ret $ret_hdr);
15 use vars qw($VERSION);
24 sub indent() { $tabs.="\t"; }
25 sub deindent() { $tabs = substr($tabs, 1); }
26 sub pidl($) { $ret .= $tabs.(shift)."\n"; }
27 sub pidl_hdr($) { $ret_hdr .= (shift)."\n"; }
30 return(", const char *name") if ($t eq "print");
31 return(", TALLOC_CTX *mem_ctx") if ($t eq "pull");
38 if ($p) { pidl $d; pidl_hdr "$d;"; } else { pidl "static $d"; }
44 foreach (@{$e->{ELEMENTS}}) {
45 next if (has_property($_, "charset") and
46 scalar(@{$_->{ARRAY_LEN}}) == 1);
47 return 1 if (defined($_->{ARRAY_LEN}) and
48 scalar(@{$_->{ARRAY_LEN}}) > 0);
53 sub ParserElement($$$)
59 my $mem_ctx = "mem_ctx";
61 fatal($e,"Pointers not supported in TDR") if ($e->{POINTERS} > 0);
62 fatal($e,"size_is() not supported in TDR") if (has_property($e, "size_is"));
63 fatal($e,"length_is() not supported in TDR") if (has_property($e, "length_is"));
66 $name = ", \"$e->{NAME}\"$array";
69 if (has_property($e, "flag")) {
72 pidl "uint32_t saved_flags = tdr->flags;";
73 pidl "tdr->flags |= $e->{PROPERTIES}->{flag};";
76 if (has_property($e, "charset")) {
77 fatal($e,"charset() on non-array element") unless (defined($e->{ARRAY_LEN}) and scalar(@{$e->{ARRAY_LEN}}) > 0);
79 my $len = ParseExpr(@{$e->{ARRAY_LEN}}[0], $env, $e);
80 if ($len eq "*") { $len = "-1"; }
81 $name = ", mem_ctx" if ($t eq "pull");
82 pidl "TDR_CHECK(tdr_$t\_charset(tdr$name, &v->$e->{NAME}, $len, sizeof($e->{TYPE}_t), CH_$e->{PROPERTIES}->{charset}));";
86 if (has_property($e, "switch_is")) {
87 $switch = ", " . ParseExpr($e->{PROPERTIES}->{switch_is}, $env, $e);
90 if (defined($e->{ARRAY_LEN}) and scalar(@{$e->{ARRAY_LEN}}) > 0) {
91 my $len = ParseExpr($e->{ARRAY_LEN}[0], $env, $e);
93 if ($t eq "pull" and not is_constant($len)) {
94 pidl "TDR_ALLOC(mem_ctx, v->$e->{NAME}, $len);";
95 $mem_ctx = "v->$e->{NAME}";
98 pidl "for (i = 0; i < $len; i++) {";
104 $name = ", $mem_ctx";
107 if (has_property($e, "value") && $t eq "push") {
108 pidl "v->$e->{NAME} = ".ParseExpr($e->{PROPERTIES}->{value}, $env, $e).";";
111 pidl "TDR_CHECK(tdr_$t\_$e->{TYPE}(tdr$name$switch, &v->$e->{NAME}$array));";
113 if ($array) { deindent; pidl "}"; }
115 if (has_property($e, "flag")) {
116 pidl "tdr->flags = saved_flags;";
122 sub ParserStruct($$$$)
126 fn_declare($p,"NTSTATUS tdr_$t\_$e->{NAME} (struct tdr_$t *tdr".typearg($t).", struct $e->{NAME} *v)");
128 pidl "int i;" if (ContainsArray($e));
131 pidl "tdr->print(tdr, \"\%-25s: struct $e->{NAME}\", name);";
132 pidl "tdr->level++;";
135 my %env = map { $_->{NAME} => "v->$_->{NAME}" } @{$e->{ELEMENTS}};
137 ParserElement($_, $t, \%env) foreach (@{$e->{ELEMENTS}});
140 pidl "tdr->level--;";
143 pidl "return NT_STATUS_OK;";
152 fn_declare($p,"NTSTATUS tdr_$t\_$e->{NAME}(struct tdr_$t *tdr".typearg($t).", int level, union $e->{NAME} *v)");
154 pidl "int i;" if (ContainsArray($e));
157 pidl "tdr->print(tdr, \"\%-25s: union $e->{NAME}\", name);";
158 pidl "tdr->level++;";
161 pidl "switch (level) {"; indent;
162 foreach (@{$e->{ELEMENTS}}) {
163 if (has_property($_, "case")) {
164 pidl "case " . $_->{PROPERTIES}->{case} . ":";
165 } elsif (has_property($_, "default")) {
168 indent; ParserElement($_, $t, {}); deindent;
174 pidl "tdr->level--;";
177 pidl "return NT_STATUS_OK;\n";
181 sub ParserBitmap($$$)
185 pidl "#define tdr_$t\_$e->{NAME} tdr_$t\_" . Parse::Pidl::Typelist::bitmap_type_fn($e);
191 my $bt = ($e->{PROPERTIES}->{base_type} or "uint8");
193 fn_declare($p, "NTSTATUS tdr_$t\_$e->{NAME} (struct tdr_$t *tdr".typearg($t).", enum $e->{NAME} *v)");
197 pidl "\tTDR_CHECK(tdr_$t\_$bt(tdr, mem_ctx, \&r));";
199 } elsif ($t eq "push") {
200 pidl "\tTDR_CHECK(tdr_$t\_$bt(tdr, ($bt\_t *)v));";
201 } elsif ($t eq "print") {
202 pidl "\t/* FIXME */";
204 pidl "\treturn NT_STATUS_OK;";
208 sub ParserTypedef($$$)
212 ParserType($e->{DATA},$t);
219 return if (has_property($e, "no$t"));
222 STRUCT => \&ParserStruct, UNION => \&ParserUnion,
223 ENUM => \&ParserEnum, BITMAP => \&ParserBitmap,
224 TYPEDEF => \&ParserTypedef
227 $handlers->{$e->{TYPE}}->($e, $t, has_property($e, "public"))
228 if (defined($handlers->{$e->{TYPE}}));
233 sub ParserInterface($)
237 pidl_hdr "#ifndef __TDR_$x->{NAME}_HEADER__";
238 pidl_hdr "#define __TDR_$x->{NAME}_HEADER__";
240 foreach (@{$x->{DATA}}) {
241 ParserType($_, "pull");
242 ParserType($_, "push");
243 ParserType($_, "print");
246 pidl_hdr "#endif /* __TDR_$x->{NAME}_HEADER__ */";
251 my ($idl,$hdrname,$baseheader) = @_;
252 $ret = ""; $ret_hdr = "";
253 pidl "/* autogenerated by pidl */";
255 pidl "#include \"includes.h\"";
257 pidl "#include <stdio.h>";
258 pidl "#include <stdbool.h>";
259 pidl "#include <stdlib.h>";
260 pidl "#include <stdint.h>";
261 pidl "#include <stdarg.h>";
262 pidl "#include <string.h>";
263 pidl "#include <core/nterr.h>";
265 pidl "#include \"$hdrname\"";
267 pidl_hdr "/* autogenerated by pidl */";
268 pidl_hdr "#include \"$baseheader\"";
269 pidl_hdr choose_header("tdr/tdr.h", "tdr.h");
272 foreach (@$idl) { ParserInterface($_) if ($_->{TYPE} eq "INTERFACE"); }
273 return ($ret_hdr, $ret);