1 ###################################################
2 # utility functions to support pidl
3 # Copyright tridge@samba.org 2000
4 # released under the GNU GPL
9 #####################################################################
10 # load a data structure from a file (as saved with SaveStructure)
14 my $contents = FileLoad($f);
15 defined $contents || return undef;
16 return eval "$contents";
21 #####################################################################
22 # flatten an array of arrays into a single array
35 #####################################################################
36 # flatten an array of arrays into a single array
49 #####################################################################
50 # flatten an array of hashes into a single hash
56 for my $k (keys %{$d}) {
64 #####################################################################
65 # traverse a perl data structure removing any empty arrays or
66 # hashes and any hash elements that map to undef
71 if (ref($v) eq "ARRAY") {
72 foreach my $i (0 .. $#{$v}) {
74 if (ref($v->[$i]) eq "ARRAY" && $#{$v->[$i]}==-1) {
79 # this removes any undefined elements from the array
80 @{$v} = grep { defined $_ } @{$v};
81 } elsif (ref($v) eq "HASH") {
82 foreach my $x (keys %{$v}) {
84 if (!defined $v->{$x}) { delete($v->{$x}); next; }
85 if (ref($v->{$x}) eq "ARRAY" && $#{$v->{$x}}==-1) { delete($v->{$x}); next; }
91 #####################################################################
92 # return the modification time of a file
95 my($filename) = shift;
96 return (stat($filename))[9];
100 #####################################################################
101 # read a file into a string
104 my($filename) = shift;
106 open(INPUTFILE, $filename) || return undef;
107 my($saved_delim) = $/;
109 my($data) = <INPUTFILE>;
115 #####################################################################
116 # write a string into a file
119 my($filename) = shift;
122 open(FILE, ">$filename") || die "can't open $filename";
127 #####################################################################
128 # return a filename with a changed extension
129 sub ChangeExtension($$)
133 if ($fname =~ /^(.*)\.(.*?)$/) {
139 #####################################################################
140 # a dumper wrapper to prevent dependence on the Data::Dumper module
141 # unless we actually need it
144 require Data::Dumper;
146 return Data::Dumper::Dumper($s);
149 #####################################################################
150 # save a data structure into a file
151 sub SaveStructure($$)
153 my($filename) = shift;
155 FileSave($filename, MyDumper($v));
158 #####################################################################
159 # find an interface in an array of interfaces
160 sub get_interface($$)
166 if($_->{NAME} eq $n) { return $_; }
172 #####################################################################
173 # see if a pidl property list contains a give property
179 if (!defined $e->{PROPERTIES}) {
183 return $e->{PROPERTIES}->{$p};
186 #####################################################################
187 # see if a pidl property matches a value
188 sub property_matches($$$)
194 if (!defined has_property($e, $p)) {
198 if ($e->{PROPERTIES}->{$p} =~ /$v/) {
210 $enum_list{$name} = 1;
216 return defined $enum_list{$name}
219 sub is_scalar_type($)
223 if ($type =~ /^u?int\d+/) {
226 if ($type =~ /char|short|long|NTTIME|NTTIME_1sec|
227 time_t|error_status_t|boolean32|unsigned32|
228 HYPER_T|wchar_t|DATA_BLOB|WERROR/x) {
232 if (is_enum($type)) {
239 # return the NDR alignment for a type
243 my $type = $e->{TYPE};
245 if (need_wire_pointer($e)) {
249 return 4, if ($type eq "uint32");
250 return 4, if ($type eq "long");
251 return 2, if ($type eq "short");
252 return 1, if ($type eq "char");
253 return 1, if ($type eq "uint8");
254 return 2, if ($type eq "uint16");
255 return 4, if ($type eq "NTTIME");
256 return 4, if ($type eq "NTTIME_1sec");
257 return 4, if ($type eq "time_t");
258 return 8, if ($type eq "HYPER_T");
259 return 2, if ($type eq "wchar_t");
260 return 4, if ($type eq "DATA_BLOB");
261 return 4, if ($type eq "int32");
263 # it must be an external type - all we can do is guess
267 # this is used to determine if the ndr push/pull functions will need
268 # a ndr_flags field to split by buffers/scalars
269 sub is_builtin_type($)
273 return 1, if (is_scalar_type($type));
278 # determine if an element needs a reference pointer on the wire
279 # in its NDR representation
280 sub need_wire_pointer($)
283 if ($e->{POINTERS} &&
284 !has_property($e, "ref")) {
285 return $e->{POINTERS};
290 # determine if an element is a pass-by-reference structure
294 if (!is_scalar_type($e->{TYPE}) &&
295 has_property($e, "ref")) {
301 # determine if an element is a pure scalar. pure scalars do not
302 # have a "buffers" section in NDR
303 sub is_pure_scalar($)
306 if (has_property($e, "ref")) {
309 if (is_scalar_type($e->{TYPE}) &&
317 # determine the array size (size_is() or ARRAY_LEN)
321 my $size = has_property($e, "size_is");
325 $size = $e->{ARRAY_LEN};
332 # see if a variable needs to be allocated by the NDR subsystem on pull
337 if (has_property($e, "ref")) {
341 if ($e->{POINTERS} || array_size($e)) {
348 # determine the C prefix used to refer to a variable when passing to a push
349 # function. This will be '*' for pointers to scalar types, '' for scalar
350 # types and normal pointers and '&' for pass-by-reference structures
355 if ($e->{TYPE} =~ "string") {
359 if (is_scalar_type($e->{TYPE}) &&
363 if (!is_scalar_type($e->{TYPE}) &&
372 # determine the C prefix used to refer to a variable when passing to a pull
378 if (!$e->{POINTERS} && !array_size($e)) {
382 if ($e->{TYPE} =~ "string") {
389 # determine if an element has a direct buffers component
390 sub has_direct_buffers($)
393 if ($e->{POINTERS} || array_size($e)) {
399 # return 1 if the string is a C constant
403 if (defined $s && $s =~ /^\d/) {
409 # return 1 if this is a fixed array
410 sub is_fixed_array($)
413 my $len = $e->{"ARRAY_LEN"};
414 if (defined $len && is_constant($len)) {
420 # return 1 if this is a inline array
421 sub is_inline_array($)
424 my $len = $e->{"ARRAY_LEN"};
425 if (is_fixed_array($e) ||
426 defined $len && $len ne "*") {
432 # return a "" quoted string, unless already quoted
436 if (substr($str, 0, 1) eq "\"") {
439 return "\"" . $str . "\"";