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($$)
31 my($props,$ignores) = @_;
34 foreach my $d (keys %{$props}) {
35 next if (grep(/^$d$/, @$ignores));
36 if($props->{$d} ne "1") {
37 $ret.= "$d($props->{$d}),";
44 pidl "/* [" . substr($ret, 0, -1) . "] */";
48 #####################################################################
49 # parse a structure element
55 HeaderType($element, $element->{TYPE}, "");
59 foreach my $l (@{$element->{LEVELS}})
61 if (($l->{TYPE} eq "POINTER")) {
62 my $nl = Ndr::GetNextLevel($element, $l);
63 $nl = Ndr::GetNextLevel($element, $nl) if ($nl->{TYPE} eq "SUBCONTEXT");
64 next if ($nl->{TYPE} eq "DATA" and typelist::scalar_is_reference($nl->{DATA_TYPE}));
66 } elsif ($l->{TYPE} eq "ARRAY") {
67 my $pl = Ndr::GetPrevLevel($element, $l);
68 next if ($pl and $pl->{TYPE} eq "POINTER");
71 $postfix .= "[$l->{SIZE_IS}]";
75 } elsif ($l->{TYPE} eq "DATA") {
76 pidl "$prefix$element->{NAME}$postfix";
80 if (defined $element->{ARRAY_LEN}[0] && util::is_constant($element->{ARRAY_LEN}[0])) {
81 pidl "[$element->{ARRAY_LEN}[0]]";
84 if (defined $element->{PROPERTIES}) {
85 HeaderProperties($element->{PROPERTIES}, ["in", "out"]);
90 #####################################################################
94 my($struct,$name) = @_;
95 pidl "\nstruct $name {\n";
98 if (defined $struct->{ELEMENTS}) {
99 foreach my $e (@{$struct->{ELEMENTS}}) {
104 if ($el_count == 0) {
105 # some compilers can't handle empty structures
106 pidl "\tchar _empty_;\n";
110 if (defined $struct->{PROPERTIES}) {
111 HeaderProperties($struct->{PROPERTIES}, []);
115 #####################################################################
119 my($enum,$name) = @_;
122 if (not util::useUintEnums()) {
123 pidl "\nenum $name {\n";
125 foreach my $e (@{$enum->{ELEMENTS}}) {
126 unless ($first) { pidl ",\n"; }
136 pidl "\nenum $name { __donnot_use_enum_$name=0x7FFFFFFF};\n";
139 foreach my $e (@{$enum->{ELEMENTS}}) {
143 if ($t =~ /(.*)=(.*)/) {
147 die ("you can't mix enum member with values and without values when using --uint-enums!")
148 unless ($without_val == 0);
153 die ("you can't mix enum member with values and without values when using --uint-enums!")
154 unless ($with_val == 0);
156 pidl "#define $name ( $value )\n";
162 #####################################################################
166 my($bitmap,$name) = @_;
168 pidl "\n/* bitmap $name */\n";
170 foreach my $e (@{$bitmap->{ELEMENTS}})
178 #####################################################################
182 my($union,$name) = @_;
185 pidl "\nunion $name {\n";
187 foreach my $e (@{$union->{ELEMENTS}}) {
188 if ($e->{TYPE} ne "EMPTY") {
189 if (! defined $done{$e->{NAME}}) {
192 $done{$e->{NAME}} = 1;
198 if (defined $union->{PROPERTIES}) {
199 HeaderProperties($union->{PROPERTIES}, []);
203 #####################################################################
207 my($e,$data,$name) = @_;
208 if (ref($data) eq "HASH") {
209 ($data->{TYPE} eq "ENUM") && HeaderEnum($data, $name);
210 ($data->{TYPE} eq "BITMAP") && HeaderBitmap($data, $name);
211 ($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name);
212 ($data->{TYPE} eq "UNION") && HeaderUnion($data, $name);
216 pidl typelist::mapType($e->{TYPE});
219 #####################################################################
223 my($typedef) = shift;
224 HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME});
225 pidl ";\n" unless ($typedef->{DATA}->{TYPE} eq "BITMAP");
228 #####################################################################
229 # prototype a typedef
230 sub HeaderTypedefProto($)
234 my $tf = NdrParser::get_typefamily($d->{DATA}{TYPE});
236 if (util::has_property($d, "gensize")) {
237 my $size_args = $tf->{SIZE_FN_ARGS}->($d);
238 pidl "size_t ndr_size_$d->{NAME}($size_args);\n";
241 return unless util::has_property($d, "public");
243 my $pull_args = $tf->{PULL_FN_ARGS}->($d);
244 my $push_args = $tf->{PUSH_FN_ARGS}->($d);
245 my $print_args = $tf->{PRINT_FN_ARGS}->($d);
246 unless (util::has_property($d, "nopush")) {
247 pidl "NTSTATUS ndr_push_$d->{NAME}($push_args);\n";
249 unless (util::has_property($d, "nopull")) {
250 pidl "NTSTATUS ndr_pull_$d->{NAME}($pull_args);\n";
252 unless (util::has_property($d, "noprint")) {
253 pidl "void ndr_print_$d->{NAME}($print_args);\n";
257 #####################################################################
262 if (!defined($const->{ARRAY_LEN}[0])) {
263 pidl "#define $const->{NAME}\t( $const->{VALUE} )\n";
265 pidl "#define $const->{NAME}\t $const->{VALUE}\n";
269 #####################################################################
271 sub HeaderFunctionInOut($$)
275 foreach my $e (@{$fn->{ELEMENTS}}) {
276 if (util::has_property($e, $prop)) {
282 #####################################################################
283 # determine if we need an "in" or "out" section
284 sub HeaderFunctionInOut_needed($$)
288 if ($prop eq "out" && $fn->{RETURN_TYPE}) {
292 foreach my $e (@{$fn->{ELEMENTS}}) {
293 if (util::has_property($e, $prop)) {
301 my %headerstructs = ();
303 #####################################################################
305 sub HeaderFunction($)
309 return if ($headerstructs{$fn->{NAME}});
311 $headerstructs{$fn->{NAME}} = 1;
313 pidl "\nstruct $fn->{NAME} {\n";
317 if (HeaderFunctionInOut_needed($fn, "in")) {
321 HeaderFunctionInOut($fn, "in");
328 if (HeaderFunctionInOut_needed($fn, "out")) {
332 HeaderFunctionInOut($fn, "out");
333 if ($fn->{RETURN_TYPE}) {
335 pidl typelist::mapType($fn->{RETURN_TYPE}) . " result;\n";
344 # sigh - some compilers don't like empty structures
346 pidl "int _dummy_element;\n";
353 #####################################################################
354 # output prototypes for a IDL function
355 sub HeaderFnProto($$)
357 my ($interface,$fn) = @_;
358 my $name = $fn->{NAME};
360 pidl "void ndr_print_$name(struct ndr_print *ndr, const char *name, int flags, struct $name *r);\n";
362 if (defined($fn->{OPNUM})) {
363 pidl "NTSTATUS dcerpc_$name(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
364 pidl "struct rpc_request *dcerpc_$name\_send(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct $name *r);\n";
367 return unless util::has_property($fn, "public");
369 pidl "NTSTATUS ndr_push_$name(struct ndr_push *ndr, int flags, struct $name *r);\n";
370 pidl "NTSTATUS ndr_pull_$name(struct ndr_pull *ndr, int flags, struct $name *r);\n";
375 #####################################################################
376 # parse the interface definitions
377 sub HeaderInterface($)
379 my($interface) = shift;
383 pidl "#ifndef _HEADER_NDR_$interface->{NAME}\n";
384 pidl "#define _HEADER_NDR_$interface->{NAME}\n\n";
386 if (defined $interface->{PROPERTIES}->{depends}) {
387 my @d = split / /, $interface->{PROPERTIES}->{depends};
389 pidl "#include \"librpc/gen_ndr/ndr_$i\.h\"\n";
393 if (defined $interface->{PROPERTIES}->{uuid}) {
394 my $name = uc $interface->{NAME};
395 pidl "#define DCERPC_$name\_UUID " .
396 util::make_str($interface->{PROPERTIES}->{uuid}) . "\n";
398 if(!defined $interface->{PROPERTIES}->{version}) { $interface->{PROPERTIES}->{version} = "0.0"; }
399 pidl "#define DCERPC_$name\_VERSION $interface->{PROPERTIES}->{version}\n";
401 pidl "#define DCERPC_$name\_NAME \"$interface->{NAME}\"\n";
403 if(!defined $interface->{PROPERTIES}->{helpstring}) { $interface->{PROPERTIES}->{helpstring} = "NULL"; }
404 pidl "#define DCERPC_$name\_HELPSTRING $interface->{PROPERTIES}->{helpstring}\n";
406 pidl "\nextern const struct dcerpc_interface_table dcerpc_table_$interface->{NAME};\n";
407 pidl "NTSTATUS dcerpc_server_$interface->{NAME}_init(void);\n\n";
410 foreach my $d (@{$interface->{FUNCTIONS}}) {
411 next if not defined($d->{OPNUM});
412 my $u_name = uc $d->{NAME};
413 pidl "#define DCERPC_$u_name (";
415 if (defined($interface->{BASE})) {
416 pidl "DCERPC_" . uc $interface->{BASE} . "_CALL_COUNT + ";
419 if ($d->{OPNUM} != $count) {
420 die ("Function ".$d->{NAME}." has: wrong opnum [".$d->{OPNUM}."] should be [".$count."]");
423 pidl sprintf("0x%02x", $count) . ")\n";
427 pidl "\n#define DCERPC_" . uc $interface->{NAME} . "_CALL_COUNT (";
429 if (defined($interface->{BASE})) {
430 pidl "DCERPC_" . uc $interface->{BASE} . "_CALL_COUNT + ";
435 foreach my $d (@{$interface->{CONSTS}}) {
439 foreach my $d (@{$interface->{TYPEDEFS}}) {
441 HeaderTypedefProto($d);
444 foreach my $d (@{$interface->{FUNCTIONS}}) {
446 HeaderFnProto($interface, $d);
449 pidl "#endif /* _HEADER_NDR_$interface->{NAME} */\n";
452 #####################################################################
453 # parse a parsed IDL into a C header
460 pidl "/* header auto-generated by pidl */\n\n";
461 foreach my $x (@{$idl}) {
462 ($x->{TYPE} eq "INTERFACE") && HeaderInterface($x);