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 qw(fatal);
11 use Parse::Pidl::Typelist qw(mapTypeName scalar_is_reference);
12 use Parse::Pidl::Util qw(has_property is_constant);
13 use Parse::Pidl::Samba4 qw(is_intree);
15 use vars qw($VERSION);
21 sub pidl($) { $res .= shift; }
26 $res .="\t" foreach (1..$tab_depth);
30 #####################################################################
31 # parse a properties list
32 sub HeaderProperties($$)
34 my($props,$ignores) = @_;
37 foreach my $d (keys %{$props}) {
38 next if (grep(/^$d$/, @$ignores));
39 if($props->{$d} ne "1") {
40 $ret.= "$d($props->{$d}),";
47 pidl "/* [" . substr($ret, 0, -1) . "] */";
51 #####################################################################
52 # parse a structure element
58 if (has_property($element, "represent_as")) {
59 pidl mapTypeName($element->{PROPERTIES}->{represent_as})." ";
61 if (ref($element->{TYPE}) eq "HASH") {
62 HeaderType($element, $element->{TYPE}, $element->{TYPE}->{NAME});
64 HeaderType($element, $element->{TYPE}, "");
67 my $numstar = $element->{ORIGINAL}->{POINTERS};
69 $numstar-- if (scalar_is_reference($element->{TYPE}));
71 foreach (@{$element->{ORIGINAL}->{ARRAY_LEN}})
73 next if is_constant($_) and
74 not has_property($element, "charset");
77 pidl "*" foreach (1..$numstar);
79 pidl $element->{NAME};
80 foreach (@{$element->{ORIGINAL}->{ARRAY_LEN}}) {
81 next unless (is_constant($_) and
82 not has_property($element, "charset"));
87 if (defined $element->{PROPERTIES}) {
88 HeaderProperties($element->{PROPERTIES}, ["in", "out"]);
93 #####################################################################
97 my($struct,$name) = @_;
99 return if (not defined($struct->{ELEMENTS}));
103 foreach (@{$struct->{ELEMENTS}}) {
107 if ($el_count == 0) {
108 # some compilers can't handle empty structures
109 pidl tabs()."char _empty_;\n";
113 if (defined $struct->{PROPERTIES}) {
114 HeaderProperties($struct->{PROPERTIES}, []);
118 #####################################################################
122 my($enum,$name) = @_;
125 pidl "#ifndef USE_UINT_ENUMS\n";
126 pidl "enum $name {\n";
128 if (defined($enum->{ELEMENTS})) {
129 foreach my $e (@{$enum->{ELEMENTS}}) {
130 unless ($first) { pidl ",\n"; }
141 pidl "enum $name { __donnot_use_enum_$name=0x7FFFFFFF}\n";
144 if (defined($enum->{ELEMENTS})) {
145 foreach my $e (@{$enum->{ELEMENTS}}) {
149 if ($t =~ /(.*)=(.*)/) {
153 fatal($e->{ORIGINAL}, "you can't mix enum member with values and without values!")
154 unless ($without_val == 0);
159 fatal($e->{ORIGINAL}, "you can't mix enum member with values and without values!")
160 unless ($with_val == 0);
162 pidl "#define $name ( $value )\n";
168 #####################################################################
172 my($bitmap,$name) = @_;
174 return unless defined($bitmap->{ELEMENTS});
176 pidl "/* bitmap $name */\n";
177 pidl "#define $_\n" foreach (@{$bitmap->{ELEMENTS}});
181 #####################################################################
185 my($union,$name) = @_;
189 return if (not defined($union->{ELEMENTS}));
192 foreach my $e (@{$union->{ELEMENTS}}) {
193 if ($e->{TYPE} ne "EMPTY") {
194 if (! defined $done{$e->{NAME}}) {
197 $done{$e->{NAME}} = 1;
203 if (defined $union->{PROPERTIES}) {
204 HeaderProperties($union->{PROPERTIES}, []);
208 #####################################################################
212 my($e,$data,$name) = @_;
213 if (ref($data) eq "HASH") {
214 ($data->{TYPE} eq "ENUM") && HeaderEnum($data, $name);
215 ($data->{TYPE} eq "BITMAP") && HeaderBitmap($data, $name);
216 ($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name);
217 ($data->{TYPE} eq "UNION") && HeaderUnion($data, $name);
221 if (has_property($e, "charset")) {
224 pidl mapTypeName($e->{TYPE});
228 #####################################################################
232 my($typedef) = shift;
233 HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME});
236 #####################################################################
241 if (!defined($const->{ARRAY_LEN}[0])) {
242 pidl "#define $const->{NAME}\t( $const->{VALUE} )\n";
244 pidl "#define $const->{NAME}\t $const->{VALUE}\n";
248 sub ElementDirection($)
252 return "inout" if (has_property($e, "in") and has_property($e, "out"));
253 return "in" if (has_property($e, "in"));
254 return "out" if (has_property($e, "out"));
258 #####################################################################
260 sub HeaderFunctionInOut($$)
264 return unless defined($fn->{ELEMENTS});
266 foreach my $e (@{$fn->{ELEMENTS}}) {
267 HeaderElement($e) if (ElementDirection($e) eq $prop);
271 #####################################################################
272 # determine if we need an "in" or "out" section
273 sub HeaderFunctionInOut_needed($$)
277 return 1 if ($prop eq "out" && defined($fn->{RETURN_TYPE}));
279 return undef unless defined($fn->{ELEMENTS});
281 foreach my $e (@{$fn->{ELEMENTS}}) {
282 return 1 if (ElementDirection($e) eq $prop);
290 #####################################################################
292 sub HeaderFunction($)
296 return if ($headerstructs{$fn->{NAME}});
298 $headerstructs{$fn->{NAME}} = 1;
300 pidl "\nstruct $fn->{NAME} {\n";
304 if (HeaderFunctionInOut_needed($fn, "in") or
305 HeaderFunctionInOut_needed($fn, "inout")) {
306 pidl tabs()."struct {\n";
308 HeaderFunctionInOut($fn, "in");
309 HeaderFunctionInOut($fn, "inout");
311 pidl tabs()."} in;\n\n";
315 if (HeaderFunctionInOut_needed($fn, "out") or
316 HeaderFunctionInOut_needed($fn, "inout")) {
317 pidl tabs()."struct {\n";
319 HeaderFunctionInOut($fn, "out");
320 HeaderFunctionInOut($fn, "inout");
321 if (defined($fn->{RETURN_TYPE})) {
322 pidl tabs().mapTypeName($fn->{RETURN_TYPE}) . " result;\n";
325 pidl tabs()."} out;\n\n";
330 # sigh - some compilers don't like empty structures
331 pidl tabs()."int _dummy_element;\n";
344 pidl "#include \"librpc/gen_ndr/$_\.h\"\n";
351 foreach (@includes) {
352 pidl "#include $_\n";
356 #####################################################################
357 # parse the interface definitions
358 sub HeaderInterface($)
360 my($interface) = shift;
362 pidl "#ifndef _HEADER_$interface->{NAME}\n";
363 pidl "#define _HEADER_$interface->{NAME}\n\n";
365 foreach my $c (@{$interface->{CONSTS}}) {
369 foreach my $t (@{$interface->{TYPES}}) {
370 HeaderTypedef($t) if ($t->{TYPE} eq "TYPEDEF");
371 HeaderStruct($t, $t->{NAME}) if ($t->{TYPE} eq "STRUCT");
372 HeaderUnion($t, $t->{NAME}) if ($t->{TYPE} eq "UNION");
373 HeaderEnum($t, $t->{NAME}) if ($t->{TYPE} eq "ENUM");
374 HeaderBitmap($t, $t->{NAME}) if ($t->{TYPE} eq "BITMAP");
375 pidl ";\n\n" if ($t->{TYPE} eq "BITMAP" or
376 $t->{TYPE} eq "STRUCT" or
377 $t->{TYPE} eq "TYPEDEF" or
378 $t->{TYPE} eq "UNION" or
379 $t->{TYPE} eq "ENUM");
382 foreach my $fn (@{$interface->{FUNCTIONS}}) {
386 pidl "#endif /* _HEADER_$interface->{NAME} */\n";
389 #####################################################################
390 # parse a parsed IDL into a C header
398 pidl "/* header auto-generated by pidl */\n\n";
400 pidl "#include <core.h>\n";
402 pidl "#include <stdint.h>\n";
406 ($_->{TYPE} eq "INTERFACE") && HeaderInterface($_);
407 ($_->{TYPE} eq "IMPORT") && HeaderImport(@{$_->{PATHS}});
408 ($_->{TYPE} eq "INCLUDE") && HeaderInclude(@{$_->{PATHS}});