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::Samba::Header;
10 use Parse::Pidl::Typelist qw(mapType);
11 use Parse::Pidl::Util qw(has_property is_constant);
12 use Parse::Pidl::NDR qw(GetNextLevel GetPrevLevel);
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 HeaderType($element, $element->{TYPE}, "");
59 my $numstar = $element->{POINTERS};
60 foreach (@{$element->{ARRAY_LEN}})
62 next if is_constant($_) and
63 not has_property($element, "charset");
66 $numstar-- if Parse::Pidl::Typelist::scalar_is_reference($element->{TYPE});
67 pidl "*" foreach (1..$numstar);
68 pidl $element->{NAME};
69 foreach (@{$element->{ARRAY_LEN}}) {
70 next unless (is_constant($_) and
71 not has_property($element, "charset"));
76 if (defined $element->{PROPERTIES}) {
77 HeaderProperties($element->{PROPERTIES}, ["in", "out"]);
82 #####################################################################
86 my($struct,$name) = @_;
87 pidl "struct $name {\n";
90 if (defined $struct->{ELEMENTS}) {
91 foreach my $e (@{$struct->{ELEMENTS}}) {
97 # some compilers can't handle empty structures
98 pidl tabs()."char _empty_;\n";
102 if (defined $struct->{PROPERTIES}) {
103 HeaderProperties($struct->{PROPERTIES}, []);
107 #####################################################################
111 my($enum,$name) = @_;
114 if (not Parse::Pidl::Util::useUintEnums()) {
115 pidl "enum $name {\n";
117 foreach my $e (@{$enum->{ELEMENTS}}) {
118 unless ($first) { pidl ",\n"; }
128 pidl "enum $name { __donnot_use_enum_$name=0x7FFFFFFF};\n";
131 foreach my $e (@{$enum->{ELEMENTS}}) {
135 if ($t =~ /(.*)=(.*)/) {
139 die ("you can't mix enum member with values and without values when using --uint-enums!")
140 unless ($without_val == 0);
145 die ("you can't mix enum member with values and without values when using --uint-enums!")
146 unless ($with_val == 0);
148 pidl "#define $name ( $value )\n";
154 #####################################################################
158 my($bitmap,$name) = @_;
160 pidl "/* bitmap $name */\n";
161 pidl "#define $_\n" foreach (@{$bitmap->{ELEMENTS}});
165 #####################################################################
169 my($union,$name) = @_;
172 pidl "union $name {\n";
174 foreach my $e (@{$union->{ELEMENTS}}) {
175 if ($e->{TYPE} ne "EMPTY") {
176 if (! defined $done{$e->{NAME}}) {
179 $done{$e->{NAME}} = 1;
185 if (defined $union->{PROPERTIES}) {
186 HeaderProperties($union->{PROPERTIES}, []);
190 #####################################################################
194 my($e,$data,$name) = @_;
195 if (ref($data) eq "HASH") {
196 ($data->{TYPE} eq "ENUM") && HeaderEnum($data, $name);
197 ($data->{TYPE} eq "BITMAP") && HeaderBitmap($data, $name);
198 ($data->{TYPE} eq "STRUCT") && HeaderStruct($data, $name);
199 ($data->{TYPE} eq "UNION") && HeaderUnion($data, $name);
203 if (has_property($e, "charset")) {
206 pidl mapType($e->{TYPE});
210 #####################################################################
214 my($typedef) = shift;
215 HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME});
216 pidl ";\n\n" unless ($typedef->{DATA}->{TYPE} eq "BITMAP");
219 #####################################################################
224 if (!defined($const->{ARRAY_LEN}[0])) {
225 pidl "#define $const->{NAME}\t( $const->{VALUE} )\n";
227 pidl "#define $const->{NAME}\t $const->{VALUE}\n";
231 #####################################################################
233 sub HeaderFunctionInOut($$)
237 foreach my $e (@{$fn->{ELEMENTS}}) {
238 if (has_property($e, $prop)) {
244 #####################################################################
245 # determine if we need an "in" or "out" section
246 sub HeaderFunctionInOut_needed($$)
250 return 1 if ($prop eq "out" && $fn->{RETURN_TYPE} ne "void");
252 foreach (@{$fn->{ELEMENTS}}) {
253 return 1 if (has_property($_, $prop));
259 my %headerstructs = ();
261 #####################################################################
263 sub HeaderFunction($)
267 return if ($headerstructs{$fn->{NAME}});
269 $headerstructs{$fn->{NAME}} = 1;
271 pidl "\nstruct $fn->{NAME} {\n";
275 if (HeaderFunctionInOut_needed($fn, "in")) {
276 pidl tabs()."struct {\n";
278 HeaderFunctionInOut($fn, "in");
280 pidl tabs()."} in;\n\n";
284 if (HeaderFunctionInOut_needed($fn, "out")) {
285 pidl tabs()."struct {\n";
287 HeaderFunctionInOut($fn, "out");
288 if ($fn->{RETURN_TYPE} ne "void") {
289 pidl tabs().mapType($fn->{RETURN_TYPE}) . " result;\n";
292 pidl tabs()."} out;\n\n";
297 # sigh - some compilers don't like empty structures
298 pidl tabs()."int _dummy_element;\n";
305 #####################################################################
306 # parse the interface definitions
307 sub HeaderInterface($)
309 my($interface) = shift;
313 pidl "#ifndef _HEADER_$interface->{NAME}\n";
314 pidl "#define _HEADER_$interface->{NAME}\n\n";
316 if (defined $interface->{PROPERTIES}->{depends}) {
317 my @d = split / /, $interface->{PROPERTIES}->{depends};
319 pidl "#include \"librpc/gen_ndr/$i\.h\"\n";
323 foreach my $d (@{$interface->{DATA}}) {
324 next if ($d->{TYPE} ne "CONST");
328 foreach my $d (@{$interface->{DATA}}) {
329 next if ($d->{TYPE} ne "TYPEDEF");
333 foreach my $d (@{$interface->{DATA}}) {
334 next if ($d->{TYPE} ne "FUNCTION");
338 pidl "#endif /* _HEADER_$interface->{NAME} */\n";
341 #####################################################################
342 # parse a parsed IDL into a C header
349 pidl "/* header auto-generated by pidl */\n\n";
350 foreach my $x (@{$idl}) {
351 ($x->{TYPE} eq "INTERFACE") && HeaderInterface($x);