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 "*") {