1 ###################################################
2 # create C header files for an IDL structure
3 # Copyright tridge@samba.org 2000
4 # released under the GNU GPL
21 for (my($i)=0; $i < $tab_depth; $i++) {
26 #####################################################################
27 # parse a properties list
28 sub HeaderProperties
($$)
36 foreach my $d (keys %{$props}) {
37 next if ($ignores->{$d});
38 if($props->{$d} ne "1") {
39 $ret.= "$d(" . $props->{$d} . "),";
46 pidl
"/* [" . substr($ret, 0, -1) . "] */";
50 #####################################################################
51 # parse a structure element
56 if (defined $element->{PROPERTIES
}) {
57 HeaderProperties
($element->{PROPERTIES
}, {"in" => 1, "out" => 1});
60 HeaderType
($element, $element->{TYPE
}, "");
62 if ($element->{POINTERS
} &&
63 $element->{TYPE
} ne "string") {
64 my($n) = $element->{POINTERS
};
65 for (my($i)=$n; $i > 0; $i--) {
69 if (defined $element->{ARRAY_LEN
} &&
70 !util
::is_constant
($element->{ARRAY_LEN
}) &&
71 !$element->{POINTERS
}) {
72 # conformant arrays are ugly! I choose to implement them with
73 # pointers instead of the [1] method
76 pidl
"$element->{NAME}";
77 if (defined $element->{ARRAY_LEN
} && util
::is_constant
($element->{ARRAY_LEN
})) {
78 pidl
"[$element->{ARRAY_LEN}]";
83 #####################################################################
89 pidl
"\nstruct $name {\n";
92 if (defined $struct->{ELEMENTS
}) {
93 foreach my $e (@
{$struct->{ELEMENTS
}}) {
99 # some compilers can't handle empty structures
100 pidl
"\tchar _empty_;\n";
106 #####################################################################
113 pidl
"\nenum $name {\n";
115 my $els = \@
{$enum->{ELEMENTS
}};
116 foreach my $i (0 .. $#{$els}-1) {
123 my $e = ${$els}[$#{$els}];
126 if ($e !~ /^(.*?)\s*$/) {
127 die "Bad enum $name\n";
134 #####################################################################
141 pidl
"\n/* bitmap $name */\n";
143 my $els = \@
{$bitmap->{ELEMENTS
}};
144 foreach my $i (0 .. $#{$els}) {
153 #####################################################################
161 if (defined $union->{PROPERTIES
}) {
162 HeaderProperties
($union->{PROPERTIES
}, {});
164 pidl
"\nunion $name {\n";
166 foreach my $e (@
{$union->{ELEMENTS
}}) {
167 if ($e->{TYPE
} ne "EMPTY") {
168 if (! defined $done{$e->{NAME
}}) {
171 $done{$e->{NAME
}} = 1;
178 #####################################################################
185 if (ref($data) eq "HASH") {
186 ($data->{TYPE
} eq "ENUM") &&
187 HeaderEnum
($data, $name);
188 ($data->{TYPE
} eq "BITMAP") &&
189 HeaderBitmap
($data, $name);
190 ($data->{TYPE
} eq "STRUCT") &&
191 HeaderStruct
($data, $name);
192 ($data->{TYPE
} eq "UNION") &&
193 HeaderUnion
($data, $name);
198 if (my $t = NdrParser
::get_typedef
($e->{TYPE
})) {
202 if ($data =~ "string") {
204 } elsif (not defined($dt->{TYPE
})) {
207 if ($dt->{TYPE
} eq "ENUM") {
209 } elsif ($dt->{TYPE
} eq "BITMAP") {
210 pidl util
::bitmap_type_decl
($dt);
211 } elsif ($dt->{TYPE
} eq "SCALAR") {
212 pidl util
::map_type
($data);
213 } elsif ($dt->{TYPE
} eq "UNION") {
215 } elsif ($dt->{TYPE
} eq "STRUCT") {
218 print "Unknown data type type $dt->{TYPE}\n";
223 #####################################################################
227 my($typedef) = shift;
228 HeaderType
($typedef, $typedef->{DATA
}, $typedef->{NAME
});
229 pidl
";\n" unless ($typedef->{DATA
}->{TYPE
} eq "BITMAP");
232 #####################################################################
233 # prototype a typedef
234 sub HeaderTypedefProto
($)
238 if (needed
::is_needed
("ndr_size_$d->{NAME}")) {
239 if ($d->{DATA
}{TYPE
} eq "STRUCT") {
240 pidl
"size_t ndr_size_$d->{NAME}(const struct $d->{NAME} *r, int flags);\n";
242 if ($d->{DATA
}{TYPE
} eq "UNION") {
243 pidl
"size_t ndr_size_$d->{NAME}(const union $d->{NAME} *r, uint32_t level, int flags);\n";
247 return unless util
::has_property
($d, "public");
249 my $tf = NdrParser
::get_typefamily
($d->{DATA
}{TYPE
});
251 my $pull_args = $tf->{PULL_FN_ARGS
}->($d);
252 my $push_args = $tf->{PUSH_FN_ARGS
}->($d);
253 my $print_args = $tf->{PRINT_FN_ARGS
}->($d);
254 pidl
"NTSTATUS ndr_push_$d->{NAME}($push_args);\n";
255 pidl
"NTSTATUS ndr_pull_$d->{NAME}($pull_args);\n";
256 if (!util
::has_property
($d, "noprint")) {
257 pidl
"void ndr_print_$d->{NAME}($print_args);\n";
261 #####################################################################
266 if (!defined($const->{ARRAY_LEN
})) {
267 pidl
"#define $const->{NAME}\t( $const->{VALUE} )\n";
269 pidl
"#define $const->{NAME}\t $const->{VALUE}\n";
273 #####################################################################
275 sub HeaderFunctionInOut
($$)
280 foreach my $e (@
{$fn->{ELEMENTS
}}) {
281 if (util
::has_property
($e, $prop)) {
287 #####################################################################
288 # determine if we need an "in" or "out" section
289 sub HeaderFunctionInOut_needed
($$)
294 if ($prop eq "out" && $fn->{RETURN_TYPE
} && $fn->{RETURN_TYPE
} ne "void") {
298 foreach my $e (@
{$fn->{ELEMENTS
}}) {
299 if (util
::has_property
($e, $prop)) {
308 #####################################################################
310 sub HeaderFunction
($)
314 pidl
"\nstruct $fn->{NAME} {\n";
318 if (HeaderFunctionInOut_needed
($fn, "in")) {
322 HeaderFunctionInOut
($fn, "in");
329 if (HeaderFunctionInOut_needed
($fn, "out")) {
333 HeaderFunctionInOut
($fn, "out");
334 if ($fn->{RETURN_TYPE
} && $fn->{RETURN_TYPE
} ne "void") {
336 pidl util
::map_type
($fn->{RETURN_TYPE
}) . " result;\n";
345 # sigh - some compilers don't like empty structures
347 pidl
"int _dummy_element;\n";
354 #####################################################################
355 # output prototypes for a IDL function
356 sub HeaderFnProto
($$)
358 my $interface = shift;
360 my $name = $fn->{NAME
};
362 pidl
"void ndr_print_$name(struct ndr_print *ndr, const char *name, int flags, struct $name *r);\n";
364 if (util
::has_property
($interface, "object")) {
365 pidl
"NTSTATUS dcom_$interface->{NAME}_$name (struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $name *r);\n";
367 pidl
"NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
368 pidl
"struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
374 #####################################################################
375 # generate vtable structure for DCOM interface
378 my $interface = shift;
379 pidl
"struct dcom_$interface->{NAME}_vtable {\n";
380 if (defined($interface->{BASE
})) {
381 pidl
"\tstruct dcom_$interface->{BASE}\_vtable base;\n";
384 my $data = $interface->{DATA
};
385 foreach my $d (@
{$data}) {
386 pidl
"\tNTSTATUS (*$d->{NAME}) (struct dcom_interface_p *d, TALLOC_CTX *mem_ctx, struct $d->{NAME} *r);\n" if ($d->{TYPE
} eq "FUNCTION");
392 #####################################################################
393 # parse the interface definitions
394 sub HeaderInterface
($)
396 my($interface) = shift;
397 my($data) = $interface->{DATA
};
401 pidl
"#ifndef _HEADER_NDR_$interface->{NAME}\n";
402 pidl
"#define _HEADER_NDR_$interface->{NAME}\n\n";
404 if (defined $interface->{PROPERTIES
}->{depends
}) {
405 my @d = split / /, $interface->{PROPERTIES
}->{depends
};
407 pidl
"#include \"librpc/gen_ndr/ndr_$i\.h\"\n";
411 if (defined $interface->{PROPERTIES
}->{uuid
}) {
412 my $name = uc $interface->{NAME
};
413 pidl
"#define DCERPC_$name\_UUID " .
414 util
::make_str
($interface->{PROPERTIES
}->{uuid
}) . "\n";
416 if(!defined $interface->{PROPERTIES
}->{version
}) { $interface->{PROPERTIES
}->{version
} = "0.0"; }
417 pidl
"#define DCERPC_$name\_VERSION $interface->{PROPERTIES}->{version}\n";
419 pidl
"#define DCERPC_$name\_NAME \"$interface->{NAME}\"\n";
421 if(!defined $interface->{PROPERTIES
}->{helpstring
}) { $interface->{PROPERTIES
}->{helpstring
} = "NULL"; }
422 pidl
"#define DCERPC_$name\_HELPSTRING $interface->{PROPERTIES}->{helpstring}\n";
424 pidl
"\nextern const struct dcerpc_interface_table dcerpc_table_$interface->{NAME};\n";
425 pidl
"NTSTATUS dcerpc_server_$interface->{NAME}_init(void);\n\n";
428 foreach my $d (@
{$data}) {
429 if ($d->{TYPE
} eq "FUNCTION") {
430 my $u_name = uc $d->{NAME
};
431 pidl
"#define DCERPC_$u_name (";
433 if (defined($interface->{BASE
})) {
434 pidl
"DCERPC_" . uc $interface->{BASE
} . "_CALL_COUNT + ";
437 pidl
sprintf("0x%02x", $count) . ")\n";
442 pidl
"\n#define DCERPC_" . uc $interface->{NAME
} . "_CALL_COUNT (";
444 if (defined($interface->{BASE
})) {
445 pidl
"DCERPC_" . uc $interface->{BASE
} . "_CALL_COUNT + ";
450 foreach my $d (@
{$data}) {
451 ($d->{TYPE
} eq "CONST") &&
453 ($d->{TYPE
} eq "TYPEDEF") &&
455 ($d->{TYPE
} eq "TYPEDEF") &&
456 HeaderTypedefProto
($d);
457 ($d->{TYPE
} eq "FUNCTION") &&
459 ($d->{TYPE
} eq "FUNCTION") &&
460 HeaderFnProto
($interface, $d);
463 (util
::has_property
($interface, "object")) &&
464 HeaderVTable
($interface);
466 pidl
"#endif /* _HEADER_NDR_$interface->{NAME} */\n";
469 #####################################################################
470 # parse a parsed IDL into a C header
476 NdrParser
::Load
($idl);
479 pidl
"/* header auto-generated by pidl */\n\n";
480 foreach my $x (@
{$idl}) {
481 if ($x->{TYPE
} eq "INTERFACE") {
482 needed
::BuildNeeded
($x);