1 ###################################################
2 # create C header files for an IDL structure
3 # Copyright tridge@samba.org 2000
4 # released under the GNU GPL
17 for (my($i)=0; $i < $tab_depth; $i++) {
22 #####################################################################
23 # parse a properties list
24 sub HeaderProperties($)
30 foreach my $d (@{$props}) {
31 if (ref($d) ne "HASH") {
32 $res .= "/* [$d] */ ";
34 foreach my $k (keys %{$d}) {
35 $res .= "/* [$k($d->{$k})] */ ";
41 #####################################################################
42 # parse a structure element
47 (defined $element->{PROPERTIES}) && HeaderProperties($element->{PROPERTIES});
49 HeaderType($element, $element->{TYPE}, "");
51 if ($element->{POINTERS} &&
52 $element->{TYPE} ne "string") {
53 my($n) = $element->{POINTERS};
54 for (my($i)=$n; $i > 0; $i--) {
58 if (defined $element->{ARRAY_LEN} &&
59 !util::is_constant($element->{ARRAY_LEN}) &&
60 !$element->{POINTERS}) {
61 # conformant arrays are ugly! I choose to implement them with
62 # pointers instead of the [1] method
65 $res .= "$element->{NAME}";
66 if (defined $element->{ARRAY_LEN} && util::is_constant($element->{ARRAY_LEN})) {
67 $res .= "[$element->{ARRAY_LEN}]";
72 #####################################################################
78 $res .= "\nstruct $name {\n";
80 if (defined $struct->{ELEMENTS}) {
81 foreach my $e (@{$struct->{ELEMENTS}}) {
89 #####################################################################
95 $res .= "\nenum $name {\n";
97 my $els = \@{$enum->{ELEMENTS}};
98 foreach my $i (0 .. $#{$els}-1) {
105 my $e = ${$els}[$#{$els}];
108 if ($e !~ /^(.*?)\s*$/) {
109 die "Bad enum $name\n";
117 #####################################################################
125 (defined $union->{PROPERTIES}) && HeaderProperties($union->{PROPERTIES});
126 $res .= "\nunion $name {\n";
128 foreach my $e (@{$union->{DATA}}) {
129 if ($e->{TYPE} eq "UNION_ELEMENT") {
130 if (! defined $done{$e->{DATA}->{NAME}}) {
131 HeaderElement($e->{DATA});
133 $done{$e->{DATA}->{NAME}} = 1;
140 #####################################################################
147 if (ref($data) eq "HASH") {
148 ($data->{TYPE} eq "ENUM") &&
149 HeaderEnum($data, $name);
150 ($data->{TYPE} eq "STRUCT") &&
151 HeaderStruct($data, $name);
152 ($data->{TYPE} eq "UNION") &&
153 HeaderUnion($data, $name);
156 if ($data =~ "string") {
157 $res .= "const char *";
158 } elsif (util::is_scalar_type($data)) {
160 } elsif (util::has_property($e, "switch_is")) {
161 $res .= "union $data";
163 $res .= "struct $data";
167 #####################################################################
171 my($typedef) = shift;
172 HeaderType($typedef, $typedef->{DATA}, $typedef->{NAME});
176 #####################################################################
181 $res .= "#define $const->{NAME}\t( $const->{VALUE} )\n";
184 #####################################################################
186 sub HeaderFunctionInOut($$)
190 foreach my $e (@{$fn->{DATA}}) {
191 if (util::has_property($e, $prop)) {
197 #####################################################################
198 # determine if we need an "in" or "out" section
199 sub HeaderFunctionInOut_needed($$)
204 if ($prop eq "out" && $fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") {
208 foreach my $e (@{$fn->{DATA}}) {
209 if (util::has_property($e, $prop)) {
218 #####################################################################
220 sub HeaderFunction($)
223 $res .= "\nstruct $fn->{NAME} {\n";
227 if (HeaderFunctionInOut_needed($fn, "in")) {
229 $res .= "struct {\n";
231 HeaderFunctionInOut($fn, "in");
238 if (HeaderFunctionInOut_needed($fn, "out")) {
240 $res .= "struct {\n";
242 HeaderFunctionInOut($fn, "out");
243 if ($fn->{RETURN_TYPE} && $fn->{RETURN_TYPE} ne "void") {
245 $res .= "$fn->{RETURN_TYPE} result;\n";
249 $res .= "} out;\n\n";
254 # sigh - some compilers don't like empty structures
256 $res .= "int _dummy_element;\n";
263 #####################################################################
264 # parse the interface definitions
265 sub HeaderInterface($)
267 my($interface) = shift;
268 my($data) = $interface->{DATA};
272 $res .= "#ifndef _HEADER_NDR_$interface->{NAME}\n";
273 $res .= "#define _HEADER_NDR_$interface->{NAME}\n\n";
275 if (defined $if_uuid) {
276 my $name = uc $interface->{NAME};
277 $res .= "#define DCERPC_$name\_UUID \"$if_uuid\"\n";
278 $res .= "#define DCERPC_$name\_VERSION $if_version\n";
279 $res .= "#define DCERPC_$name\_NAME \"$interface->{NAME}\"\n\n";
280 $res .= "extern const struct dcerpc_interface_table dcerpc_table_$interface->{NAME};\n";
281 $res .= "void rpc_$interface->{NAME}_init(void *);\n\n";
284 foreach my $d (@{$data}) {
285 if ($d->{TYPE} eq "FUNCTION") {
286 my $u_name = uc $d->{NAME};
287 $res .= "#define DCERPC_$u_name " . sprintf("0x%02x", $count) . "\n";
294 foreach my $d (@{$data}) {
295 ($d->{TYPE} eq "CONST") &&
297 ($d->{TYPE} eq "TYPEDEF") &&
299 ($d->{TYPE} eq "FUNCTION") &&
303 $res .= "#endif /* _HEADER_NDR_$interface->{NAME} */\n";
306 #####################################################################
307 # parse the interface definitions
312 $if_uuid = $h->{PROPERTIES}->{uuid};
313 $if_version = $h->{PROPERTIES}->{version};
317 #####################################################################
318 # parse a parsed IDL into a C header
324 $res = "/* header auto-generated by pidl */\n\n";
325 foreach my $x (@{$idl}) {
326 ($x->{TYPE} eq "MODULEHEADER") &&
329 ($x->{TYPE} eq "INTERFACE") &&