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(mapType);
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 mapType($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 mapType($e->{TYPE});
216 #####################################################################
220 my($typedef) = shift;
221 HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME});
222 pidl ";\n\n" unless ($typedef->{DATA}->{TYPE} eq "BITMAP" or
223 $typedef->{DATA}->{TYPE} eq "ENUM");
226 #####################################################################
231 if (!defined($const->{ARRAY_LEN}[0])) {
232 pidl "#define $const->{NAME}\t( $const->{VALUE} )\n";
234 pidl "#define $const->{NAME}\t $const->{VALUE}\n";
238 sub ElementDirection($)
242 return "inout" if (has_property($e, "in") and has_property($e, "out"));
243 return "in" if (has_property($e, "in"));
244 return "out" if (has_property($e, "out"));
248 #####################################################################
250 sub HeaderFunctionInOut($$)
254 foreach (@{$fn->{ELEMENTS}}) {
255 HeaderElement($_) if (ElementDirection($_) eq $prop);
259 #####################################################################
260 # determine if we need an "in" or "out" section
261 sub HeaderFunctionInOut_needed($$)
265 return 1 if ($prop eq "out" && $fn->{RETURN_TYPE} ne "void");
267 foreach (@{$fn->{ELEMENTS}}) {
268 return 1 if (ElementDirection($_) eq $prop);
276 #####################################################################
278 sub HeaderFunction($)
282 return if ($headerstructs{$fn->{NAME}});
284 $headerstructs{$fn->{NAME}} = 1;
286 pidl "\nstruct $fn->{NAME} {\n";
290 if (HeaderFunctionInOut_needed($fn, "in") or
291 HeaderFunctionInOut_needed($fn, "inout")) {
292 pidl tabs()."struct {\n";
294 HeaderFunctionInOut($fn, "in");
295 HeaderFunctionInOut($fn, "inout");
297 pidl tabs()."} in;\n\n";
301 if (HeaderFunctionInOut_needed($fn, "out") or
302 HeaderFunctionInOut_needed($fn, "inout")) {
303 pidl tabs()."struct {\n";
305 HeaderFunctionInOut($fn, "out");
306 HeaderFunctionInOut($fn, "inout");
307 if ($fn->{RETURN_TYPE} ne "void") {
308 pidl tabs().mapType($fn->{RETURN_TYPE}) . " result;\n";
311 pidl tabs()."} out;\n\n";
316 # sigh - some compilers don't like empty structures
317 pidl tabs()."int _dummy_element;\n";
330 pidl "#include \"librpc/gen_ndr/$_\.h\"\n";
337 foreach (@includes) {
338 pidl "#include $_\n";
342 #####################################################################
343 # parse the interface definitions
344 sub HeaderInterface($)
346 my($interface) = shift;
348 pidl "#ifndef _HEADER_$interface->{NAME}\n";
349 pidl "#define _HEADER_$interface->{NAME}\n\n";
351 foreach my $d (@{$interface->{DATA}}) {
352 next if ($d->{TYPE} ne "CONST");
356 foreach my $d (@{$interface->{DATA}}) {
357 next if ($d->{TYPE} ne "TYPEDEF");
361 foreach my $d (@{$interface->{DATA}}) {
362 next if ($d->{TYPE} ne "FUNCTION");
367 pidl "#endif /* _HEADER_$interface->{NAME} */\n";
370 #####################################################################
371 # parse a parsed IDL into a C header
379 pidl "/* header auto-generated by pidl */\n\n";
381 pidl "#include <core.h>\n\n";
385 ($_->{TYPE} eq "INTERFACE") && HeaderInterface($_);
386 ($_->{TYPE} eq "IMPORT") && HeaderImport(@{$_->{PATHS}});
387 ($_->{TYPE} eq "INCLUDE") && HeaderInclude(@{$_->{PATHS}});