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
7 package Parse::Pidl::Samba4::Header;
10 use Parse::Pidl::Typelist qw(mapTypeName);
11 use Parse::Pidl::Util qw(has_property is_constant);
12 use Parse::Pidl::Samba4 qw(is_intree);
14 use vars qw($VERSION);
20 sub pidl($) { $res .= shift; }
25 $res .="\t" foreach (1..$tab_depth);
29 #####################################################################
30 # parse a properties list
31 sub HeaderProperties($$)
33 my($props,$ignores) = @_;
36 foreach my $d (keys %{$props}) {
37 next if (grep(/^$d$/, @$ignores));
38 if($props->{$d} ne "1") {
39 $ret.= "$d($props->{$d}),";
46 pidl "/* [" . substr($ret, 0, -1) . "] */";
50 #####################################################################
51 # parse a structure element
57 if (has_property($element, "represent_as")) {
58 pidl mapTypeName($element->{PROPERTIES}->{represent_as})." ";
60 HeaderType($element, $element->{TYPE}, "");
62 my $numstar = $element->{POINTERS};
64 $numstar-- if Parse::Pidl::Typelist::scalar_is_reference($element->{TYPE});
66 foreach (@{$element->{ARRAY_LEN}})
68 next if is_constant($_) and
69 not has_property($element, "charset");
72 pidl "*" foreach (1..$numstar);
74 pidl $element->{NAME};
75 foreach (@{$element->{ARRAY_LEN}}) {
76 next unless (is_constant($_) and
77 not has_property($element, "charset"));
82 if (defined $element->{PROPERTIES}) {
83 HeaderProperties($element->{PROPERTIES}, ["in", "out"]);
88 #####################################################################
92 my($struct,$name) = @_;
93 pidl "struct $name {\n";
96 if (defined $struct->{ELEMENTS}) {
97 foreach (@{$struct->{ELEMENTS}}) {
102 if ($el_count == 0) {
103 # some compilers can't handle empty structures
104 pidl tabs()."char _empty_;\n";
108 if (defined $struct->{PROPERTIES}) {
109 HeaderProperties($struct->{PROPERTIES}, []);
113 #####################################################################
117 my($enum,$name) = @_;
120 pidl "#ifndef USE_UINT_ENUMS\n";
121 pidl "enum $name {\n";
123 foreach my $e (@{$enum->{ELEMENTS}}) {
124 unless ($first) { pidl ",\n"; }
134 pidl "enum $name { __donnot_use_enum_$name=0x7FFFFFFF};\n";
137 foreach my $e (@{$enum->{ELEMENTS}}) {
141 if ($t =~ /(.*)=(.*)/) {
145 die ("you can't mix enum member with values and without values when using --uint-enums!")
146 unless ($without_val == 0);
151 die ("you can't mix enum member with values and without values when using --uint-enums!")
152 unless ($with_val == 0);
154 pidl "#define $name ( $value )\n";
160 #####################################################################
164 my($bitmap,$name) = @_;
166 pidl "/* bitmap $name */\n";
167 pidl "#define $_\n" foreach (@{$bitmap->{ELEMENTS}});
171 #####################################################################
175 my($union,$name) = @_;
178 pidl "union $name {\n";
180 foreach my $e (@{$union->{ELEMENTS}}) {
181 if ($e->{TYPE} ne "EMPTY") {
182 if (! defined $done{$e->{NAME}}) {
185 $done{$e->{NAME}} = 1;
191 if (defined $union->{PROPERTIES}) {
192 HeaderProperties($union->{PROPERTIES}, []);
196 #####################################################################
200 my($e,$data,$name) = @_;
201 if (ref($data) eq "HASH") {
202 ($data->{TYPE} eq "ENUM") && HeaderEnum($data, $name);
203 ($data->{TYPE} eq "BITMAP") && HeaderBitmap($data, $name);
204 ($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name);
205 ($data->{TYPE} eq "UNION") && HeaderUnion($data, $name);
209 if (has_property($e, "charset")) {
212 pidl mapTypeName($e->{TYPE});
216 #####################################################################
220 my($typedef) = shift;
221 HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME});
224 #####################################################################
229 if (!defined($const->{ARRAY_LEN}[0])) {
230 pidl "#define $const->{NAME}\t( $const->{VALUE} )\n";
232 pidl "#define $const->{NAME}\t $const->{VALUE}\n";
236 sub ElementDirection($)
240 return "inout" if (has_property($e, "in") and has_property($e, "out"));
241 return "in" if (has_property($e, "in"));
242 return "out" if (has_property($e, "out"));
246 #####################################################################
248 sub HeaderFunctionInOut($$)
252 foreach (@{$fn->{ELEMENTS}}) {
253 HeaderElement($_) if (ElementDirection($_) eq $prop);
257 #####################################################################
258 # determine if we need an "in" or "out" section
259 sub HeaderFunctionInOut_needed($$)
263 return 1 if ($prop eq "out" && $fn->{RETURN_TYPE} ne "void");
265 foreach (@{$fn->{ELEMENTS}}) {
266 return 1 if (ElementDirection($_) eq $prop);
274 #####################################################################
276 sub HeaderFunction($)
280 return if ($headerstructs{$fn->{NAME}});
282 $headerstructs{$fn->{NAME}} = 1;
284 pidl "\nstruct $fn->{NAME} {\n";
288 if (HeaderFunctionInOut_needed($fn, "in") or
289 HeaderFunctionInOut_needed($fn, "inout")) {
290 pidl tabs()."struct {\n";
292 HeaderFunctionInOut($fn, "in");
293 HeaderFunctionInOut($fn, "inout");
295 pidl tabs()."} in;\n\n";
299 if (HeaderFunctionInOut_needed($fn, "out") or
300 HeaderFunctionInOut_needed($fn, "inout")) {
301 pidl tabs()."struct {\n";
303 HeaderFunctionInOut($fn, "out");
304 HeaderFunctionInOut($fn, "inout");
305 if ($fn->{RETURN_TYPE} ne "void") {
306 pidl tabs().mapTypeName($fn->{RETURN_TYPE}) . " result;\n";
309 pidl tabs()."} out;\n\n";
314 # sigh - some compilers don't like empty structures
315 pidl tabs()."int _dummy_element;\n";
328 pidl "#include \"librpc/gen_ndr/$_\.h\"\n";
335 foreach (@includes) {
336 pidl "#include $_\n";
340 #####################################################################
341 # parse the interface definitions
342 sub HeaderInterface($)
344 my($interface) = shift;
346 pidl "#ifndef _HEADER_$interface->{NAME}\n";
347 pidl "#define _HEADER_$interface->{NAME}\n\n";
349 foreach my $d (@{$interface->{DATA}}) {
350 next if ($d->{TYPE} ne "CONST");
354 foreach my $d (@{$interface->{DATA}}) {
355 HeaderTypedef($d) if ($d->{TYPE} eq "TYPEDEF");
356 HeaderStruct($d, $d->{NAME}) if ($d->{TYPE} eq "STRUCT");
357 HeaderUnion($d, $d->{NAME}) if ($d->{TYPE} eq "UNION");
358 HeaderEnum($d, $d->{NAME}) if ($d->{TYPE} eq "ENUM");
359 HeaderBitmap($d, $d->{NAME}) if ($d->{TYPE} eq "BITMAP");
363 foreach my $d (@{$interface->{DATA}}) {
364 next if ($d->{TYPE} ne "FUNCTION");
369 pidl "#endif /* _HEADER_$interface->{NAME} */\n";
372 #####################################################################
373 # parse a parsed IDL into a C header
381 pidl "/* header auto-generated by pidl */\n\n";
383 pidl "#include <core.h>\n";
385 pidl "#include <stdint.h>\n";
389 ($_->{TYPE} eq "INTERFACE") && HeaderInterface($_);
390 ($_->{TYPE} eq "IMPORT") && HeaderImport(@{$_->{PATHS}});
391 ($_->{TYPE} eq "INCLUDE") && HeaderInclude(@{$_->{PATHS}});