1 ###################################################
2 # create C header files for an IDL structure
3 # Copyright tridge@samba.org 2000
4 # released under the GNU GPL
22 for (my($i)=0; $i < $tab_depth; $i++) {
27 #####################################################################
28 # parse a properties list
29 sub HeaderProperties($$)
37 foreach my $d (keys %{$props}) {
38 next if ($ignores->{$d});
39 if($props->{$d} ne "1") {
40 $ret.= "$d(" . $props->{$d} . "),";
47 pidl "/* [" . substr($ret, 0, -1) . "] */";
51 #####################################################################
52 # parse a structure element
57 if (defined $element->{PROPERTIES}) {
58 HeaderProperties($element->{PROPERTIES}, {"in" => 1, "out" => 1});
61 HeaderType($element, $element->{TYPE}, "");
63 if ($element->{POINTERS} && not $element->{TYPE} =~ "string") {
64 for (my($i)=$element->{POINTERS}; $i > 0; $i--) {
67 } elsif (Ndr::is_surrounding_array($element) ||
68 defined $element->{ARRAY_LEN} && !util::is_constant($element->{ARRAY_LEN})) {
69 # surrounding arrays are ugly! I choose to implement them with
70 # pointers instead of the [1] method
73 pidl "$element->{NAME}";
74 if (defined $element->{ARRAY_LEN} && util::is_constant($element->{ARRAY_LEN})) {
75 pidl "[$element->{ARRAY_LEN}]";
80 #####################################################################
86 pidl "\nstruct $name {\n";
89 if (defined $struct->{ELEMENTS}) {
90 foreach my $e (@{$struct->{ELEMENTS}}) {
96 # some compilers can't handle empty structures
97 pidl "\tchar _empty_;\n";
103 #####################################################################
110 pidl "\nenum $name {\n";
112 my $els = \@{$enum->{ELEMENTS}};
113 foreach my $i (0 .. $#{$els}-1) {
120 my $e = ${$els}[$#{$els}];
123 if ($e !~ /^(.*?)\s*$/) {
124 die "Bad enum $name\n";
131 #####################################################################
138 pidl "\n/* bitmap $name */\n";
140 my $els = \@{$bitmap->{ELEMENTS}};
141 foreach my $i (0 .. $#{$els}) {
150 #####################################################################
158 if (defined $union->{PROPERTIES}) {
159 HeaderProperties($union->{PROPERTIES}, {});
161 pidl "\nunion $name {\n";
163 foreach my $e (@{$union->{ELEMENTS}}) {
164 if ($e->{TYPE} ne "EMPTY") {
165 if (! defined $done{$e->{NAME}}) {
168 $done{$e->{NAME}} = 1;
175 #####################################################################
182 if (ref($data) eq "HASH") {
183 ($data->{TYPE} eq "ENUM") &&
184 HeaderEnum($data, $name);
185 ($data->{TYPE} eq "BITMAP") &&
186 HeaderBitmap($data, $name);
187 ($data->{TYPE} eq "STRUCT") &&
188 HeaderStruct($data, $name);
189 ($data->{TYPE} eq "UNION") &&
190 HeaderUnion($data, $name);
194 pidl typelist::mapType($e);
197 #####################################################################
201 my($typedef) = shift;
202 HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME});
203 pidl ";\n" unless ($typedef->{DATA}->{TYPE} eq "BITMAP");
206 #####################################################################
207 # prototype a typedef
208 sub HeaderTypedefProto($)
212 my $tf = NdrParser::get_typefamily($d->{DATA}{TYPE});
214 if (needed::is_needed("ndr_size_$d->{NAME}")) {
215 my $size_args = $tf->{SIZE_FN_ARGS}->($d);
216 pidl "size_t ndr_size_$d->{NAME}($size_args);\n";
219 return unless util::has_property($d, "public");
221 my $pull_args = $tf->{PULL_FN_ARGS}->($d);
222 my $push_args = $tf->{PUSH_FN_ARGS}->($d);
223 my $print_args = $tf->{PRINT_FN_ARGS}->($d);
224 unless (util::has_property($d, "nopush")) {
225 pidl "NTSTATUS ndr_push_$d->{NAME}($push_args);\n";
227 unless (util::has_property($d, "nopull")) {
228 pidl "NTSTATUS ndr_pull_$d->{NAME}($pull_args);\n";
230 unless (util::has_property($d, "noprint")) {
231 pidl "void ndr_print_$d->{NAME}($print_args);\n";
235 #####################################################################
240 if (!defined($const->{ARRAY_LEN})) {
241 pidl "#define $const->{NAME}\t( $const->{VALUE} )\n";
243 pidl "#define $const->{NAME}\t $const->{VALUE}\n";
247 #####################################################################
249 sub HeaderFunctionInOut($$)
254 foreach my $e (@{$fn->{ELEMENTS}}) {
255 if (util::has_property($e, $prop)) {
261 #####################################################################
262 # determine if we need an "in" or "out" section
263 sub HeaderFunctionInOut_needed($$)
268 if ($prop eq "out" && $fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") {
272 foreach my $e (@{$fn->{ELEMENTS}}) {
273 if (util::has_property($e, $prop)) {
281 #####################################################################
283 sub HeaderFunction($)
287 pidl "\nstruct $fn->{NAME} {\n";
291 if (HeaderFunctionInOut_needed($fn, "in")) {
295 HeaderFunctionInOut($fn, "in");
302 if (HeaderFunctionInOut_needed($fn, "out")) {
306 HeaderFunctionInOut($fn, "out");
307 if ($fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") {
309 pidl typelist::mapScalarType($fn->{RETURN_TYPE}) . " result;\n";
318 # sigh - some compilers don't like empty structures
320 pidl "int _dummy_element;\n";
327 #####################################################################
328 # output prototypes for a IDL function
329 sub HeaderFnProto($$)
331 my $interface = shift;
333 my $name = $fn->{NAME};
335 pidl "void ndr_print_$name(struct ndr_print *ndr, const char *name, int flags, struct $name *r);\n";
337 pidl "NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
338 pidl "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
343 #####################################################################
344 # parse the interface definitions
345 sub HeaderInterface($)
347 my($interface) = shift;
348 my($data) = $interface->{DATA};
352 pidl "#ifndef _HEADER_NDR_$interface->{NAME}\n";
353 pidl "#define _HEADER_NDR_$interface->{NAME}\n\n";
355 if (defined $interface->{PROPERTIES}->{depends}) {
356 my @d = split / /, $interface->{PROPERTIES}->{depends};
358 pidl "#include \"librpc/gen_ndr/ndr_$i\.h\"\n";
362 # Object interfaces use ORPC
363 if (util::has_property($interface, "object")) {
364 pidl "#include \"librpc/gen_ndr/ndr_orpc.h\"\n";
367 if (defined $interface->{PROPERTIES}->{uuid}) {
368 my $name = uc $interface->{NAME};
369 pidl "#define DCERPC_$name\_UUID " .
370 util::make_str($interface->{PROPERTIES}->{uuid}) . "\n";
372 if(!defined $interface->{PROPERTIES}->{version}) { $interface->{PROPERTIES}->{version} = "0.0"; }
373 pidl "#define DCERPC_$name\_VERSION $interface->{PROPERTIES}->{version}\n";
375 pidl "#define DCERPC_$name\_NAME \"$interface->{NAME}\"\n";
377 if(!defined $interface->{PROPERTIES}->{helpstring}) { $interface->{PROPERTIES}->{helpstring} = "NULL"; }
378 pidl "#define DCERPC_$name\_HELPSTRING $interface->{PROPERTIES}->{helpstring}\n";
380 pidl "\nextern const struct dcerpc_interface_table dcerpc_table_$interface->{NAME};\n";
381 pidl "NTSTATUS dcerpc_server_$interface->{NAME}_init(void);\n\n";
384 foreach my $d (@{$data}) {
385 if ($d->{TYPE} eq "FUNCTION") {
386 my $u_name = uc $d->{NAME};
387 pidl "#define DCERPC_$u_name (";
389 if (defined($interface->{BASE})) {
390 pidl "DCERPC_" . uc $interface->{BASE} . "_CALL_COUNT + ";
393 pidl sprintf("0x%02x", $count) . ")\n";
398 pidl "\n#define DCERPC_" . uc $interface->{NAME} . "_CALL_COUNT (";
400 if (defined($interface->{BASE})) {
401 pidl "DCERPC_" . uc $interface->{BASE} . "_CALL_COUNT + ";
406 foreach my $d (@{$data}) {
407 ($d->{TYPE} eq "CONST") &&
409 ($d->{TYPE} eq "TYPEDEF") &&
411 ($d->{TYPE} eq "TYPEDEF") &&
412 HeaderTypedefProto($d);
413 ($d->{TYPE} eq "FUNCTION") &&
415 ($d->{TYPE} eq "FUNCTION") &&
416 HeaderFnProto($interface, $d);
419 pidl "#endif /* _HEADER_NDR_$interface->{NAME} */\n";
422 #####################################################################
423 # parse a parsed IDL into a C header
429 NdrParser::Load($idl);
432 pidl "/* header auto-generated by pidl */\n\n";
433 foreach my $x (@{$idl}) {
434 if ($x->{TYPE} eq "INTERFACE") {
435 needed::BuildNeeded($x);