1 ###################################################
2 # utility functions to support pidl
3 # Copyright tridge@samba.org 2000
4 # released under the GNU GPL
7 #####################################################################
8 # load a data structure from a file (as saved with SaveStructure)
12 my $contents = FileLoad
($f);
13 defined $contents || return undef;
14 return eval "$contents";
19 #####################################################################
20 # flatten an array of arrays into a single array
33 #####################################################################
34 # flatten an array of arrays into a single array
47 #####################################################################
48 # flatten an array of hashes into a single hash
54 for my $k (keys %{$d}) {
62 #####################################################################
63 # traverse a perl data structure removing any empty arrays or
64 # hashes and any hash elements that map to undef
69 if (ref($v) eq "ARRAY") {
70 foreach my $i (0 .. $#{$v}) {
72 if (ref($v->[$i]) eq "ARRAY" && $#{$v->[$i]}==-1) {
77 # this removes any undefined elements from the array
78 @
{$v} = grep { defined $_ } @
{$v};
79 } elsif (ref($v) eq "HASH") {
80 foreach my $x (keys %{$v}) {
82 if (!defined $v->{$x}) { delete($v->{$x}); next; }
83 if (ref($v->{$x}) eq "ARRAY" && $#{$v->{$x}}==-1) { delete($v->{$x}); next; }
89 #####################################################################
90 # return the modification time of a file
93 my($filename) = shift;
94 return (stat($filename))[9];
98 #####################################################################
99 # read a file into a string
102 my($filename) = shift;
104 open(INPUTFILE
, $filename) || return undef;
105 my($saved_delim) = $/;
107 my($data) = <INPUTFILE
>;
113 #####################################################################
114 # write a string into a file
117 my($filename) = shift;
120 open(FILE
, ">$filename") || die "can't open $filename";
125 #####################################################################
126 # return a filename with a changed extension
127 sub ChangeExtension
($$)
131 if ($fname =~ /^(.*)\.(.*?)$/) {
137 #####################################################################
138 # a dumper wrapper to prevent dependence on the Data::Dumper module
139 # unless we actually need it
142 require Data
::Dumper
;
144 return Data
::Dumper
::Dumper
($s);
147 #####################################################################
148 # save a data structure into a file
149 sub SaveStructure
($$)
151 my($filename) = shift;
153 FileSave
($filename, MyDumper
($v));
156 #####################################################################
157 # see if a pidl property list contains a give property
163 if (!defined $e->{PROPERTIES
}) {
167 return $e->{PROPERTIES
}->{$p};
171 sub is_scalar_type
($)
175 if ($type =~ /^u?int\d+/) {
178 if ($type =~ /char
|short
|long
|NTTIME
|
179 time_t
|error_status_t
|boolean32
|unsigned32
|
180 HYPER_T
|wchar_t
|DATA_BLOB
/x
) {
187 # return the NDR alignment for a type
191 my $type = $e->{TYPE
};
193 if (need_wire_pointer
($e)) {
197 return 4, if ($type eq "uint32");
198 return 4, if ($type eq "long");
199 return 2, if ($type eq "short");
200 return 1, if ($type eq "char");
201 return 1, if ($type eq "uint8");
202 return 2, if ($type eq "uint16");
203 return 4, if ($type eq "NTTIME");
204 return 4, if ($type eq "time_t");
205 return 8, if ($type eq "HYPER_T");
206 return 2, if ($type eq "wchar_t");
207 return 4, if ($type eq "DATA_BLOB");
209 # it must be an external type - all we can do is guess
213 # this is used to determine if the ndr push/pull functions will need
214 # a ndr_flags field to split by buffers/scalars
215 sub is_builtin_type
($)
219 return 1, if (is_scalar_type
($type));
224 # determine if an element needs a reference pointer on the wire
225 # in its NDR representation
226 sub need_wire_pointer
($)
229 if ($e->{POINTERS
} &&
230 !has_property
($e, "ref")) {
231 return $e->{POINTERS
};
236 # determine if an element is a pass-by-reference structure
240 if (!is_scalar_type
($e->{TYPE
}) &&
241 has_property
($e, "ref")) {
247 # determine if an element is a pure scalar. pure scalars do not
248 # have a "buffers" section in NDR
249 sub is_pure_scalar
($)
252 if (has_property
($e, "ref")) {
255 if (is_scalar_type
($e->{TYPE
}) &&
263 # determine the array size (size_is() or ARRAY_LEN)
267 my $size = has_property
($e, "size_is");
271 $size = $e->{ARRAY_LEN
};
278 # see if a variable needs to be allocated by the NDR subsystem on pull
283 if (has_property
($e, "ref")) {
287 if ($e->{POINTERS
} || array_size
($e)) {
294 # determine the C prefix used to refer to a variable when passing to a push
295 # function. This will be '*' for pointers to scalar types, '' for scalar
296 # types and normal pointers and '&' for pass-by-reference structures
301 if ($e->{TYPE
} =~ "string") {
305 if (is_scalar_type
($e->{TYPE
}) &&
309 if (!is_scalar_type
($e->{TYPE
}) &&
318 # determine the C prefix used to refer to a variable when passing to a pull
324 if (!$e->{POINTERS
} && !array_size
($e)) {
328 if ($e->{TYPE
} =~ "string") {
335 # determine if an element has a direct buffers component
336 sub has_direct_buffers
($)
339 if ($e->{POINTERS
} || array_size
($e)) {
345 # return 1 if the string is a C constant
355 # return 1 if this is a fixed array
356 sub is_fixed_array
($)
359 my $len = $e->{"ARRAY_LEN"};
360 if (defined $len && is_constant
($len)) {
366 # return 1 if this is a inline array
367 sub is_inline_array
($)
370 my $len = $e->{"ARRAY_LEN"};
371 if (is_fixed_array
($e) ||
372 defined $len && $len ne "*") {