1 ###################################################
2 # create C header files for an IDL structure
3 # Copyright tridge@samba.org 2000
4 # Copyright jelmer@samba.org 2005
5 # 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}, "");
65 foreach my $l (@{$element->{LEVELS}})
67 if (($l->{TYPE} eq "POINTER")) {
68 next if ($element->{TYPE} eq "string");
70 } elsif (($l->{TYPE} eq "ARRAY")) {
71 my $pl = Ndr::GetPrevLevel($element, $l);
72 next if ($pl and $pl->{TYPE} eq "POINTER");
75 $postfix .= "[$l->{SIZE_IS}]";
79 } elsif ($l->{TYPE} eq "DATA") {
80 pidl "$prefix$element->{NAME}$postfix";
84 if (defined $element->{ARRAY_LEN}[0] && util::is_constant($element->{ARRAY_LEN}[0])) {
85 pidl "[$element->{ARRAY_LEN}[0]]";
90 #####################################################################
96 pidl "\nstruct $name {\n";
99 if (defined $struct->{ELEMENTS}) {
100 foreach my $e (@{$struct->{ELEMENTS}}) {
105 if ($el_count == 0) {
106 # some compilers can't handle empty structures
107 pidl "\tchar _empty_;\n";
113 #####################################################################
121 pidl "\nenum $name {\n";
123 foreach my $e (@{$enum->{ELEMENTS}}) {
124 unless ($first) { pidl ",\n"; }
134 #####################################################################
141 pidl "\n/* bitmap $name */\n";
143 foreach my $e (@{$bitmap->{ELEMENTS}})
151 #####################################################################
159 if (defined $union->{PROPERTIES}) {
160 HeaderProperties($union->{PROPERTIES}, {});
162 pidl "\nunion $name {\n";
164 foreach my $e (@{$union->{ELEMENTS}}) {
165 if ($e->{TYPE} ne "EMPTY") {
166 if (! defined $done{$e->{NAME}}) {
169 $done{$e->{NAME}} = 1;
176 #####################################################################
183 if (ref($data) eq "HASH") {
184 ($data->{TYPE} eq "ENUM") && HeaderEnum($data, $name);
185 ($data->{TYPE} eq "BITMAP") && HeaderBitmap($data, $name);
186 ($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name);
187 ($data->{TYPE} eq "UNION") && HeaderUnion($data, $name);
191 pidl typelist::mapType($e->{TYPE});
194 #####################################################################
198 my($typedef) = shift;
199 HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME});
200 pidl ";\n" unless ($typedef->{DATA}->{TYPE} eq "BITMAP");
203 #####################################################################
204 # prototype a typedef
205 sub HeaderTypedefProto($)
209 my $tf = NdrParser::get_typefamily($d->{DATA}{TYPE});
211 if (util::has_property($d, "gensize")) {
212 my $size_args = $tf->{SIZE_FN_ARGS}->($d);
213 pidl "size_t ndr_size_$d->{NAME}($size_args);\n";
216 return unless util::has_property($d, "public");
218 my $pull_args = $tf->{PULL_FN_ARGS}->($d);
219 my $push_args = $tf->{PUSH_FN_ARGS}->($d);
220 my $print_args = $tf->{PRINT_FN_ARGS}->($d);
221 unless (util::has_property($d, "nopush")) {
222 pidl "NTSTATUS ndr_push_$d->{NAME}($push_args);\n";
224 unless (util::has_property($d, "nopull")) {
225 pidl "NTSTATUS ndr_pull_$d->{NAME}($pull_args);\n";
227 unless (util::has_property($d, "noprint")) {
228 pidl "void ndr_print_$d->{NAME}($print_args);\n";
232 #####################################################################
237 if (!defined($const->{ARRAY_LEN}[0])) {
238 pidl "#define $const->{NAME}\t( $const->{VALUE} )\n";
240 pidl "#define $const->{NAME}\t $const->{VALUE}\n";
244 #####################################################################
246 sub HeaderFunctionInOut($$)
251 foreach my $e (@{$fn->{ELEMENTS}}) {
252 if (util::has_property($e, $prop)) {
258 #####################################################################
259 # determine if we need an "in" or "out" section
260 sub HeaderFunctionInOut_needed($$)
265 if ($prop eq "out" && $fn->{RETURN_TYPE}) {
269 foreach my $e (@{$fn->{ELEMENTS}}) {
270 if (util::has_property($e, $prop)) {
278 my %headerstructs = ();
280 #####################################################################
282 sub HeaderFunction($)
286 return if ($headerstructs{$fn->{NAME}});
288 $headerstructs{$fn->{NAME}} = 1;
290 pidl "\nstruct $fn->{NAME} {\n";
294 if (HeaderFunctionInOut_needed($fn, "in")) {
298 HeaderFunctionInOut($fn, "in");
305 if (HeaderFunctionInOut_needed($fn, "out")) {
309 HeaderFunctionInOut($fn, "out");
310 if ($fn->{RETURN_TYPE}) {
312 pidl typelist::mapType($fn->{RETURN_TYPE}) . " result;\n";
321 # sigh - some compilers don't like empty structures
323 pidl "int _dummy_element;\n";
330 #####################################################################
331 # output prototypes for a IDL function
332 sub HeaderFnProto($$)
334 my $interface = shift;
336 my $name = $fn->{NAME};
338 pidl "void ndr_print_$name(struct ndr_print *ndr, const char *name, int flags, struct $name *r);\n";
340 pidl "NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
341 pidl "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
343 return unless util::has_property($fn, "public");
345 pidl "NTSTATUS ndr_push_$name(struct ndr_push *ndr, int flags, struct $name *r);\n";
346 pidl "NTSTATUS ndr_pull_$name(struct ndr_pull *ndr, int flags, struct $name *r);\n";
351 #####################################################################
352 # parse the interface definitions
353 sub HeaderInterface($)
355 my($interface) = shift;
359 pidl "#ifndef _HEADER_NDR_$interface->{NAME}\n";
360 pidl "#define _HEADER_NDR_$interface->{NAME}\n\n";
362 if (defined $interface->{PROPERTIES}->{depends}) {
363 my @d = split / /, $interface->{PROPERTIES}->{depends};
365 pidl "#include \"librpc/gen_ndr/ndr_$i\.h\"\n";
369 if (defined $interface->{PROPERTIES}->{uuid}) {
370 my $name = uc $interface->{NAME};
371 pidl "#define DCERPC_$name\_UUID " .
372 util::make_str($interface->{PROPERTIES}->{uuid}) . "\n";
374 if(!defined $interface->{PROPERTIES}->{version}) { $interface->{PROPERTIES}->{version} = "0.0"; }
375 pidl "#define DCERPC_$name\_VERSION $interface->{PROPERTIES}->{version}\n";
377 pidl "#define DCERPC_$name\_NAME \"$interface->{NAME}\"\n";
379 if(!defined $interface->{PROPERTIES}->{helpstring}) { $interface->{PROPERTIES}->{helpstring} = "NULL"; }
380 pidl "#define DCERPC_$name\_HELPSTRING $interface->{PROPERTIES}->{helpstring}\n";
382 pidl "\nextern const struct dcerpc_interface_table dcerpc_table_$interface->{NAME};\n";
383 pidl "NTSTATUS dcerpc_server_$interface->{NAME}_init(void);\n\n";
386 foreach my $d (@{$interface->{FUNCTIONS}}) {
387 my $u_name = uc $d->{NAME};
388 pidl "#define DCERPC_$u_name (";
390 if (defined($interface->{BASE})) {
391 pidl "DCERPC_" . uc $interface->{BASE} . "_CALL_COUNT + ";
394 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 (@{$interface->{CONSTS}}) {
410 foreach my $d (@{$interface->{TYPEDEFS}}) {
412 HeaderTypedefProto($d);
415 foreach my $d (@{$interface->{FUNCTIONS}}) {
417 HeaderFnProto($interface, $d);
421 pidl "#endif /* _HEADER_NDR_$interface->{NAME} */\n";
424 #####################################################################
425 # parse a parsed IDL into a C header
432 pidl "/* header auto-generated by pidl */\n\n";
433 foreach my $x (@{$idl}) {
434 if ($x->{TYPE} eq "INTERFACE") {