line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
## XrtUtils.pm is a sub-module of Graph.pm. It has all the subroutines |
2
|
|
|
|
|
|
|
## needed for the Xrt3d part of the package. |
3
|
|
|
|
|
|
|
## |
4
|
|
|
|
|
|
|
## $Id: XrtUtils.pm,v 1.13 2006/06/07 21:09:33 emile Exp $ $Name: $ |
5
|
|
|
|
|
|
|
## |
6
|
|
|
|
|
|
|
## This software product is developed by Michael Young and David Moore, |
7
|
|
|
|
|
|
|
## and copyrighted(C) 1998 by the University of California, San Diego |
8
|
|
|
|
|
|
|
## (UCSD), with all rights reserved. UCSD administers the CAIDA grant, |
9
|
|
|
|
|
|
|
## NCR-9711092, under which part of this code was developed. |
10
|
|
|
|
|
|
|
## |
11
|
|
|
|
|
|
|
## There is no charge for this software. You can redistribute it and/or |
12
|
|
|
|
|
|
|
## modify it under the terms of the GNU General Public License, v. 2 dated |
13
|
|
|
|
|
|
|
## June 1991 which is incorporated by reference herein. This software is |
14
|
|
|
|
|
|
|
## distributed WITHOUT ANY WARRANTY, IMPLIED OR EXPRESS, OF MERCHANTABILITY |
15
|
|
|
|
|
|
|
## OR FITNESS FOR A PARTICULAR PURPOSE or that the use of it will not |
16
|
|
|
|
|
|
|
## infringe on any third party's intellectual property rights. |
17
|
|
|
|
|
|
|
## |
18
|
|
|
|
|
|
|
## You should have received a copy of the GNU GPL along with this program. |
19
|
|
|
|
|
|
|
## |
20
|
|
|
|
|
|
|
## |
21
|
|
|
|
|
|
|
## IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY |
22
|
|
|
|
|
|
|
## PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL |
23
|
|
|
|
|
|
|
## DAMAGES, INCLUDING LOST PROFITS, ARISING OUT OF THE USE OF THIS |
24
|
|
|
|
|
|
|
## SOFTWARE, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF |
25
|
|
|
|
|
|
|
## THE POSSIBILITY OF SUCH DAMAGE. |
26
|
|
|
|
|
|
|
## |
27
|
|
|
|
|
|
|
## THE SOFTWARE PROVIDED HEREIN IS ON AN "AS IS" BASIS, AND THE |
28
|
|
|
|
|
|
|
## UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, |
29
|
|
|
|
|
|
|
## SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. THE UNIVERSITY |
30
|
|
|
|
|
|
|
## OF CALIFORNIA MAKES NO REPRESENTATIONS AND EXTENDS NO WARRANTIES |
31
|
|
|
|
|
|
|
## OF ANY KIND, EITHER IMPLIED OR EXPRESS, INCLUDING, BUT NOT LIMITED |
32
|
|
|
|
|
|
|
## TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A |
33
|
|
|
|
|
|
|
## PARTICULAR PURPOSE, OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE |
34
|
|
|
|
|
|
|
## ANY PATENT, TRADEMARK OR OTHER RIGHTS. |
35
|
|
|
|
|
|
|
## |
36
|
|
|
|
|
|
|
## |
37
|
|
|
|
|
|
|
## Contact: graph-dev@caida.org |
38
|
|
|
|
|
|
|
## |
39
|
|
|
|
|
|
|
## |
40
|
|
|
|
|
|
|
package Chart::Graph::XrtUtils; |
41
|
4
|
|
|
4
|
|
21
|
use Exporter (); |
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
300
|
|
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
@ISA = qw(Exporter); |
44
|
|
|
|
|
|
|
@EXPORT = qw(); |
45
|
|
|
|
|
|
|
%EXPORT_TAGS = (UTILS => [qw(&_set_xrtpaths &_set_ldpath &_print_matrix |
46
|
|
|
|
|
|
|
&_print_array &_verify_ticks &_exec_xrt3d &_exec_xrt2d |
47
|
|
|
|
|
|
|
&_exec_netpbm &_exec_xvfb &_try_port &_convert_raster |
48
|
|
|
|
|
|
|
&_childpid_dead &_transfer_file)], |
49
|
|
|
|
|
|
|
); |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
Exporter::export_ok_tags('UTILS'); |
52
|
|
|
|
|
|
|
|
53
|
4
|
|
|
4
|
|
21
|
use Carp; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
275
|
|
54
|
4
|
|
|
4
|
|
50
|
use POSIX ":sys_wait_h"; # for waitpid() |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
1460
|
|
55
|
4
|
|
|
4
|
|
790
|
use Chart::Graph::Utils qw(:UTILS); |
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
4535
|
|
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
$cvs_Id = '$Id: XrtUtils.pm,v 1.13 2006/06/07 21:09:33 emile Exp $'; |
58
|
|
|
|
|
|
|
$cvs_Author = '$Author: emile $'; |
59
|
|
|
|
|
|
|
$cvs_Name = '$Name: $'; |
60
|
|
|
|
|
|
|
$cvs_Revision = '$Revision: 1.13 $'; |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
$VERSION = 3.2; |
63
|
|
|
|
|
|
|
|
64
|
4
|
|
|
4
|
|
24
|
use strict; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
144
|
|
65
|
4
|
|
|
4
|
|
23
|
use File::Basename; |
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
902
|
|
66
|
|
|
|
|
|
|
|
67
|
4
|
|
|
4
|
|
23
|
use vars qw($xrt2d $xrt3d); |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
10956
|
|
68
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
# |
70
|
|
|
|
|
|
|
# Subroutine: set_converterpaths() |
71
|
|
|
|
|
|
|
# |
72
|
|
|
|
|
|
|
# Description: set paths for converter programs in particular. This |
73
|
|
|
|
|
|
|
# subroutine can take one or two arguments and tests if |
74
|
|
|
|
|
|
|
# the required converter programs are indeed available |
75
|
|
|
|
|
|
|
# for the choosen method to convert a file from one |
76
|
|
|
|
|
|
|
# graphics format to another. |
77
|
|
|
|
|
|
|
# |
78
|
|
|
|
|
|
|
sub _set_converterpaths { |
79
|
0
|
|
|
0
|
|
0
|
my @converters = @_; |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
# Loop through the list of converter seeing which are available |
82
|
0
|
|
|
|
|
0
|
foreach my $converter (@converters) { |
83
|
0
|
0
|
|
|
|
0
|
if (not -x $$converter) { |
84
|
0
|
0
|
|
|
|
0
|
if (not $$converter = _get_path($$converter)) { |
85
|
0
|
|
|
|
|
0
|
return(0); |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
} |
88
|
|
|
|
|
|
|
} |
89
|
0
|
|
|
|
|
0
|
return(1); |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
# |
93
|
|
|
|
|
|
|
# Subroutine: _convert_raster($plot_file, $output_file) |
94
|
|
|
|
|
|
|
# |
95
|
|
|
|
|
|
|
# Description: A subroutine to over see the conversion process from |
96
|
|
|
|
|
|
|
# one raster graphic format to another. It will try |
97
|
|
|
|
|
|
|
# ImageMagick convert first and if that fails try Netpbm |
98
|
|
|
|
|
|
|
# utilities if they are available in that format. |
99
|
|
|
|
|
|
|
# |
100
|
|
|
|
|
|
|
sub _convert_raster { |
101
|
0
|
|
|
0
|
|
0
|
my $FORMAT = shift; |
102
|
0
|
|
|
|
|
0
|
my $plot_file = shift; |
103
|
0
|
|
|
|
|
0
|
my $output_file = shift; |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
# First try ImageMagick as it is more robust and simpler |
106
|
0
|
0
|
|
|
|
0
|
if (_set_converterpaths(\$convert)) { |
107
|
0
|
0
|
|
|
|
0
|
if (_exec_convert($convert, $FORMAT, $plot_file, $output_file)) { |
108
|
0
|
|
|
|
|
0
|
return(1); |
109
|
|
|
|
|
|
|
} else { |
110
|
0
|
|
|
|
|
0
|
carp "Attempt to use ImageMagick failed, will try Netpbm." |
111
|
|
|
|
|
|
|
} |
112
|
|
|
|
|
|
|
} else { |
113
|
0
|
|
|
|
|
0
|
carp "No ImageMagick found, will try Netpbm." |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
0
|
0
|
|
|
|
0
|
if ($FORMAT eq 'GIF') { |
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
117
|
0
|
|
|
|
|
0
|
_try_netpbm_combo($xwdtopnm, $ppmtogif, $plot_file, $output_file); |
118
|
|
|
|
|
|
|
} |
119
|
|
|
|
|
|
|
elsif ($FORMAT eq 'JPG') { |
120
|
0
|
|
|
|
|
0
|
_try_netpbm_combo($xwdtopnm, $ppmtojpg, $plot_file, $output_file); |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
elsif ($FORMAT eq 'PNG') { |
123
|
0
|
|
|
|
|
0
|
_try_netpbm_combo($xwdtopnm, $pnmtopng, $plot_file, $output_file); |
124
|
|
|
|
|
|
|
} else { |
125
|
0
|
|
|
|
|
0
|
carp "Untrapped raster image format - XrtUtils.pm internal error"; |
126
|
0
|
|
|
|
|
0
|
return(0); |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# |
131
|
|
|
|
|
|
|
# Subroutine _try_netpbm_combo($xwdtopbm, pbmtotarget, $xwd_file, $target_file) |
132
|
|
|
|
|
|
|
# |
133
|
|
|
|
|
|
|
# |
134
|
|
|
|
|
|
|
# Description: Contains the logic for testing if a combination of |
135
|
|
|
|
|
|
|
# netpbm programs can be accessed and executed to perform |
136
|
|
|
|
|
|
|
# the desired conversion. If not, it produces the |
137
|
|
|
|
|
|
|
# appropriate error messages. Basically, it saves a |
138
|
|
|
|
|
|
|
# batch of conditional statements that would otherwise be |
139
|
|
|
|
|
|
|
# repeated. |
140
|
|
|
|
|
|
|
# |
141
|
|
|
|
|
|
|
sub _try_netpbm_combo { |
142
|
0
|
|
|
0
|
|
0
|
my ($xwdtopbm, $pbmtotarget, $xwd_file, $target_file) = @_; |
143
|
|
|
|
|
|
|
|
144
|
0
|
0
|
|
|
|
0
|
if (_set_converterpaths(\$xwdtopbm, \$pbmtotarget)) { |
145
|
0
|
0
|
|
|
|
0
|
if (_exec_netpbm($xwdtopbm, $pbmtotarget, $xwd_file, $target_file)) { |
146
|
0
|
|
|
|
|
0
|
return(1); |
147
|
|
|
|
|
|
|
} else { |
148
|
0
|
|
|
|
|
0
|
carp "Failure to execute any suitable image " . |
149
|
|
|
|
|
|
|
"converters for create file: $target_file"; |
150
|
0
|
|
|
|
|
0
|
return(0); |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
} else { |
153
|
0
|
|
|
|
|
0
|
carp "Unable to find any suitable image converters to " . |
154
|
|
|
|
|
|
|
"create file: $target_file"; |
155
|
0
|
|
|
|
|
0
|
return(0); |
156
|
|
|
|
|
|
|
} |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
# |
160
|
|
|
|
|
|
|
# Subroutine: set_xrtpaths() |
161
|
|
|
|
|
|
|
# |
162
|
|
|
|
|
|
|
# Description: set paths for external programs required by xrt() |
163
|
|
|
|
|
|
|
# if they are not defined already |
164
|
|
|
|
|
|
|
# |
165
|
|
|
|
|
|
|
sub _set_xrtpaths { |
166
|
|
|
|
|
|
|
|
167
|
6
|
|
|
6
|
|
11
|
my $xrtver = shift; |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
|
171
|
6
|
50
|
|
|
|
17
|
if (defined($xrtver)) { |
172
|
6
|
100
|
|
|
|
16
|
if ($xrtver eq "xrt2d") { |
173
|
2
|
50
|
|
|
|
7
|
if (not $Chart::Graph::xrt2d = _get_path("xrt2d")) { |
174
|
2
|
|
|
|
|
8
|
return 0; |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
} |
177
|
|
|
|
|
|
|
|
178
|
4
|
50
|
|
|
|
9
|
if ($xrtver eq "xrt3d") { |
179
|
4
|
50
|
|
|
|
11
|
if (not $Chart::Graph::xrt3d = _get_path("xrt3d")) { |
180
|
4
|
|
|
|
|
19
|
return 0; |
181
|
|
|
|
|
|
|
} |
182
|
|
|
|
|
|
|
} |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
|
185
|
0
|
0
|
|
|
|
0
|
if (not defined($xwdtopnm)) { |
186
|
0
|
0
|
|
|
|
0
|
if (!($xwdtopnm = _get_path("xwdtopnm"))) { |
187
|
0
|
|
|
|
|
0
|
return 0; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
0
|
0
|
|
|
|
0
|
if (not defined($xvfb)) { |
192
|
0
|
0
|
|
|
|
0
|
if (not $xvfb = _get_path("Xvfb")) { |
193
|
0
|
|
|
|
|
0
|
return 0; |
194
|
|
|
|
|
|
|
} |
195
|
|
|
|
|
|
|
} |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
# make sure /usr/dt/lib is in the library path |
198
|
0
|
|
|
|
|
0
|
_set_ldpath("/usr/dt/lib"); |
199
|
|
|
|
|
|
|
|
200
|
0
|
|
|
|
|
0
|
return 1; |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
# |
204
|
|
|
|
|
|
|
# Subroutine: set_ldpath() |
205
|
|
|
|
|
|
|
# |
206
|
|
|
|
|
|
|
# Description: Xvfb has trouble finding libMrm, so we have to add |
207
|
|
|
|
|
|
|
# /usr/dt/lib to LD_LIBRARY_PATH |
208
|
|
|
|
|
|
|
# |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
sub _set_ldpath { |
211
|
1
|
|
|
1
|
|
3
|
my ($libpath) = @_; |
212
|
|
|
|
|
|
|
|
213
|
1
|
50
|
|
|
|
5
|
if (not defined($ENV{LD_LIBRARY_PATH})) { |
214
|
1
|
|
|
|
|
7
|
$ENV{LD_LIBRARY_PATH} = "$libpath"; |
215
|
1
|
|
|
|
|
3
|
return 1; |
216
|
|
|
|
|
|
|
} |
217
|
|
|
|
|
|
|
|
218
|
0
|
|
|
|
|
|
my @ldpath = split (/:/, $ENV{LD_LIBRARY_PATH}); |
219
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
# make sure library path isn't already defined |
221
|
0
|
|
|
|
|
|
foreach my $i(@ldpath){ |
222
|
0
|
0
|
|
|
|
|
if ($i eq $libpath) { |
223
|
0
|
|
|
|
|
|
return 1; |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
# add library path to LD_LIBRARY_PATH |
228
|
0
|
|
|
|
|
|
$ENV{LD_LIBRARY_PATH} = "$libpath:$ENV{LD_LIBRARY_PATH}"; |
229
|
0
|
|
|
|
|
|
return 1; |
230
|
|
|
|
|
|
|
} |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
# |
233
|
|
|
|
|
|
|
# Subroutine: print_matrix() |
234
|
|
|
|
|
|
|
# |
235
|
|
|
|
|
|
|
# Description: print out all the elements |
236
|
|
|
|
|
|
|
# in a X by Y matrix, row by row |
237
|
|
|
|
|
|
|
# |
238
|
|
|
|
|
|
|
|
239
|
|
|
|
|
|
|
sub _print_matrix { |
240
|
0
|
|
|
0
|
|
|
my ($handle, @matrix) = @_; |
241
|
|
|
|
|
|
|
|
242
|
0
|
|
|
|
|
|
foreach my $row (@matrix){ |
243
|
0
|
|
|
|
|
|
foreach my $i (@{$row}){ |
|
0
|
|
|
|
|
|
|
244
|
0
|
|
|
|
|
|
print $handle "$i\t"; |
245
|
|
|
|
|
|
|
} |
246
|
0
|
|
|
|
|
|
print $handle "\n"; |
247
|
|
|
|
|
|
|
} |
248
|
0
|
|
|
|
|
|
return 1; |
249
|
|
|
|
|
|
|
} |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
|
252
|
|
|
|
|
|
|
# |
253
|
|
|
|
|
|
|
# Subroutine: _transfer_file($handle, $data_filename) |
254
|
|
|
|
|
|
|
# |
255
|
|
|
|
|
|
|
# Description: open file $data_filename. Read the contents |
256
|
|
|
|
|
|
|
# and write it into the command file tab delimited. Don't |
257
|
|
|
|
|
|
|
# assume data was tab delimited to be safe. |
258
|
|
|
|
|
|
|
# |
259
|
|
|
|
|
|
|
sub _transfer_file { |
260
|
0
|
|
|
0
|
|
|
my $handle = shift; |
261
|
0
|
|
|
|
|
|
my $data_filename = shift; |
262
|
0
|
|
|
|
|
|
my $data; |
263
|
|
|
|
|
|
|
my @elements; |
264
|
|
|
|
|
|
|
|
265
|
0
|
0
|
|
|
|
|
unless(open(DATAHDL, $data_filename)) { |
266
|
0
|
|
|
|
|
|
carp "Unable to open data file: $data_filename for reading"; |
267
|
0
|
|
|
|
|
|
return(0); |
268
|
|
|
|
|
|
|
} |
269
|
0
|
|
|
|
|
|
while (defined($data = )) { |
270
|
0
|
|
|
|
|
|
chomp($data); |
271
|
0
|
|
|
|
|
|
@elements = split(/\s+/, $data); |
272
|
0
|
|
|
|
|
|
foreach my $element (@elements) { |
273
|
0
|
|
|
|
|
|
print $handle $element, "\t"; |
274
|
|
|
|
|
|
|
} |
275
|
0
|
|
|
|
|
|
print $handle "\n"; |
276
|
|
|
|
|
|
|
} |
277
|
0
|
0
|
|
|
|
|
unless(close(DATAHDL)) { |
278
|
0
|
|
|
|
|
|
carp "Unable to close data file: $data_filename after reading"; |
279
|
|
|
|
|
|
|
} |
280
|
0
|
|
|
|
|
|
return(1); |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
# |
284
|
|
|
|
|
|
|
# Subroutine: print_array() |
285
|
|
|
|
|
|
|
# |
286
|
|
|
|
|
|
|
# Description: print out each element of array, one per line |
287
|
|
|
|
|
|
|
# |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
sub _print_array { |
290
|
0
|
|
|
0
|
|
|
my ($handle, @array) = @_; |
291
|
0
|
|
|
|
|
|
my $i; |
292
|
|
|
|
|
|
|
|
293
|
0
|
|
|
|
|
|
foreach $i (@array) { |
294
|
0
|
|
|
|
|
|
print $handle "$i\n"; |
295
|
|
|
|
|
|
|
} |
296
|
0
|
|
|
|
|
|
return 1; |
297
|
|
|
|
|
|
|
} |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
# |
300
|
|
|
|
|
|
|
# Subroutine: verify_ticks(); |
301
|
|
|
|
|
|
|
# |
302
|
|
|
|
|
|
|
# Description: check that the number of tick labels is the same |
303
|
|
|
|
|
|
|
# as the number of xy rows and columns. we can only have |
304
|
|
|
|
|
|
|
# as many ticks as the number of rows or columns |
305
|
|
|
|
|
|
|
# we make this subroutine so that the calling subroutine |
306
|
|
|
|
|
|
|
# is kept cleaner. |
307
|
|
|
|
|
|
|
|
308
|
|
|
|
|
|
|
sub _verify_ticks { |
309
|
0
|
|
|
0
|
|
|
my ($cnt, $ticks_ref) = @_; |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
# if no ticks are given then just |
312
|
|
|
|
|
|
|
# give the xrt binary "1, 2,..." |
313
|
0
|
0
|
|
|
|
|
if (not defined($ticks_ref)) { |
314
|
0
|
|
|
|
|
|
my @def_ticks; |
315
|
0
|
|
|
|
|
|
for (my $i = 0; $i < $cnt; $i++) { |
316
|
0
|
|
|
|
|
|
$def_ticks[$i] = $i + 1; |
317
|
|
|
|
|
|
|
} |
318
|
0
|
|
|
|
|
|
$ticks_ref = \@def_ticks; |
319
|
|
|
|
|
|
|
} |
320
|
|
|
|
|
|
|
|
321
|
0
|
|
|
|
|
|
my $tick_cnt = @{$ticks_ref}; |
|
0
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
|
323
|
0
|
0
|
|
|
|
|
if ($cnt ne $tick_cnt){ |
324
|
0
|
|
|
|
|
|
carp "number of tick labels must equal the number of xy rows and columns"; |
325
|
0
|
|
|
|
|
|
return 0; |
326
|
|
|
|
|
|
|
} |
327
|
0
|
|
|
|
|
|
return 1; |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
|
330
|
|
|
|
|
|
|
# |
331
|
|
|
|
|
|
|
# Subroutine: exec_xrt3d() |
332
|
|
|
|
|
|
|
# |
333
|
|
|
|
|
|
|
# Description: execute the xrt3d program on the command file. |
334
|
|
|
|
|
|
|
# xrt3d generates a xwd file. |
335
|
|
|
|
|
|
|
# |
336
|
|
|
|
|
|
|
sub _exec_xrt3d { |
337
|
0
|
|
|
0
|
|
|
my ($command_file) = @_; |
338
|
0
|
|
|
|
|
|
my ($output); |
339
|
0
|
|
|
|
|
|
my ($childpid, $port); |
340
|
0
|
|
|
|
|
|
my $display_env = $ENV{DISPLAY}; |
341
|
0
|
|
|
|
|
|
my $status; |
342
|
|
|
|
|
|
|
|
343
|
0
|
0
|
|
|
|
|
if ($Chart::Graph::use_xvfb) { |
344
|
|
|
|
|
|
|
# start the virtual X server |
345
|
0
|
|
|
|
|
|
($childpid, $port) = _exec_xvfb(); |
346
|
0
|
|
|
|
|
|
$status = system("$Chart::Graph::xrt3d -display :$port.0 < $command_file"); |
347
|
|
|
|
|
|
|
} else { |
348
|
|
|
|
|
|
|
# use the local X server |
349
|
|
|
|
|
|
|
# warning: colors might be messed up |
350
|
|
|
|
|
|
|
# depending on your current setup |
351
|
0
|
|
|
|
|
|
$status = system("$Chart::Graph::xrt3d -display $display_env < $command_file"); |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
#my $status = system("$xrt -display :$port.0 < $command_file"); |
355
|
0
|
0
|
|
|
|
|
if (not _chk_status($status)) { |
356
|
0
|
|
|
|
|
|
return 0; |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
|
359
|
0
|
0
|
|
|
|
|
if ($Chart::Graph::use_xvfb) { |
360
|
0
|
|
|
|
|
|
kill('KILL', $childpid); |
361
|
|
|
|
|
|
|
} |
362
|
|
|
|
|
|
|
|
363
|
0
|
|
|
|
|
|
return 1; |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
|
366
|
|
|
|
|
|
|
# |
367
|
|
|
|
|
|
|
# Subroutine: exec_xrt2d() |
368
|
|
|
|
|
|
|
# |
369
|
|
|
|
|
|
|
# Description: execute the xrt2d program on the command file. |
370
|
|
|
|
|
|
|
# xrt2d generates a xwd file. |
371
|
|
|
|
|
|
|
# |
372
|
|
|
|
|
|
|
sub _exec_xrt2d { |
373
|
0
|
|
|
0
|
|
|
my ($command_file, $options) = @_; |
374
|
0
|
|
|
|
|
|
my ($output); |
375
|
0
|
|
|
|
|
|
my ($childpid, $port); |
376
|
0
|
|
|
|
|
|
my $display_env = $ENV{DISPLAY}; |
377
|
0
|
|
|
|
|
|
my $status; |
378
|
|
|
|
|
|
|
|
379
|
0
|
0
|
|
|
|
|
if ($Chart::Graph::use_xvfb) { |
380
|
|
|
|
|
|
|
# start the virtual X server |
381
|
0
|
|
|
|
|
|
($childpid, $port) = _exec_xvfb(); |
382
|
0
|
|
|
|
|
|
printf STDERR "\tXRT is $Chart::Graph::xrt2d\n"; |
383
|
0
|
|
|
|
|
|
my $status = system("$Chart::Graph::xrt2d -display ipn:$port.0 < $command_file $options"); |
384
|
|
|
|
|
|
|
} else { |
385
|
|
|
|
|
|
|
# use the local X server |
386
|
|
|
|
|
|
|
# warning: colors might be messed up |
387
|
|
|
|
|
|
|
# depending on your current setup |
388
|
0
|
|
|
|
|
|
$status = system("$Chart::Graph::xrt2d -display $display_env < $command_file $options"); |
389
|
|
|
|
|
|
|
} |
390
|
|
|
|
|
|
|
|
391
|
0
|
0
|
|
|
|
|
if (not _chk_status($status)) { |
392
|
0
|
|
|
|
|
|
return 0; |
393
|
|
|
|
|
|
|
} |
394
|
|
|
|
|
|
|
|
395
|
0
|
0
|
|
|
|
|
if ($Chart::Graph::use_xvfb) { |
396
|
0
|
|
|
|
|
|
kill('KILL', $childpid); |
397
|
|
|
|
|
|
|
} |
398
|
|
|
|
|
|
|
|
399
|
0
|
|
|
|
|
|
return 1; |
400
|
|
|
|
|
|
|
} |
401
|
|
|
|
|
|
|
|
402
|
|
|
|
|
|
|
# |
403
|
|
|
|
|
|
|
# Subroutine: exec_convert |
404
|
|
|
|
|
|
|
# |
405
|
|
|
|
|
|
|
# |
406
|
|
|
|
|
|
|
# Description: Use the Imagemagick 'convert' utility to convert the xwd |
407
|
|
|
|
|
|
|
# file into any one of the other common raster image |
408
|
|
|
|
|
|
|
# formats used commonly in web page production. |
409
|
|
|
|
|
|
|
# |
410
|
|
|
|
|
|
|
sub _exec_convert { |
411
|
0
|
|
|
0
|
|
|
my ($convert, $FORMAT, $xwd_file, $target_file) = @_; |
412
|
0
|
|
|
|
|
|
my ($status); |
413
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
|
415
|
0
|
0
|
|
|
|
|
if ($Chart::Graph::debug) { |
416
|
0
|
|
|
|
|
|
$status = system(join('', "$convert -verbose $xwd_file ", |
417
|
|
|
|
|
|
|
$FORMAT, ":$target_file")); |
418
|
|
|
|
|
|
|
} else { |
419
|
0
|
|
|
|
|
|
$status = system(join('', "( $convert $xwd_file ", $FORMAT, |
420
|
|
|
|
|
|
|
":$target_file; ) 2> /dev/null")); |
421
|
|
|
|
|
|
|
} |
422
|
|
|
|
|
|
|
|
423
|
0
|
0
|
|
|
|
|
if (not _chk_status($status)) { |
424
|
0
|
|
|
|
|
|
return 0; |
425
|
|
|
|
|
|
|
} |
426
|
0
|
|
|
|
|
|
return 1; |
427
|
|
|
|
|
|
|
} |
428
|
|
|
|
|
|
|
# |
429
|
|
|
|
|
|
|
# Subroutine: _exec_netpbm |
430
|
|
|
|
|
|
|
# |
431
|
|
|
|
|
|
|
# |
432
|
|
|
|
|
|
|
# Description: Convert a raster image using the older utilities now |
433
|
|
|
|
|
|
|
# collected under the name 'netpbm.' Note that not all |
434
|
|
|
|
|
|
|
# conversions are commonly included wiht all UNIX |
435
|
|
|
|
|
|
|
# distributions so that while older conversions such as |
436
|
|
|
|
|
|
|
# 'xwd' -> 'gif' are likely to work, others such as |
437
|
|
|
|
|
|
|
# conversions to 'png' may not without downloading new |
438
|
|
|
|
|
|
|
# software. |
439
|
|
|
|
|
|
|
# |
440
|
|
|
|
|
|
|
# The conversion strategy always involves a pipe from the |
441
|
|
|
|
|
|
|
# X-windows 'xwd' format to some sort 'pbm' format and |
442
|
|
|
|
|
|
|
# then from that universal format into the target format. |
443
|
|
|
|
|
|
|
# For this reason, it is more prone to machine |
444
|
|
|
|
|
|
|
# architecture issues and other errors. |
445
|
|
|
|
|
|
|
# |
446
|
|
|
|
|
|
|
sub _exec_netpbm { |
447
|
0
|
|
|
0
|
|
|
my ($xwdtopbm, $pbmtotarget, $xwd_file, $target_file) = @_; |
448
|
0
|
|
|
|
|
|
my ($status); |
449
|
|
|
|
|
|
|
|
450
|
0
|
0
|
|
|
|
|
if ($Chart::Graph::debug) { |
451
|
0
|
|
|
|
|
|
$status = system("$xwdtopbm $xwd_file | $pbmtotarget > $target_file"); |
452
|
|
|
|
|
|
|
} else { |
453
|
0
|
|
|
|
|
|
$status = system(join('', "( $xwdtopbm -quiet $xwd_file | ", |
454
|
|
|
|
|
|
|
"$pbmtotarget -quiet > $target_file; ) ", |
455
|
|
|
|
|
|
|
"2> /dev/null")); |
456
|
|
|
|
|
|
|
} |
457
|
|
|
|
|
|
|
|
458
|
0
|
0
|
|
|
|
|
if (not _chk_status($status)) { |
459
|
0
|
|
|
|
|
|
return 0; |
460
|
|
|
|
|
|
|
} |
461
|
0
|
|
|
|
|
|
return 1; |
462
|
|
|
|
|
|
|
} |
463
|
|
|
|
|
|
|
|
464
|
|
|
|
|
|
|
# |
465
|
|
|
|
|
|
|
# Subroutine: exec_xvfb() |
466
|
|
|
|
|
|
|
# |
467
|
|
|
|
|
|
|
# Description: this starts the vitualX server(X is required by xrt, so |
468
|
|
|
|
|
|
|
# we fake out xrt with Xvfb, for speed and compatability) |
469
|
|
|
|
|
|
|
# |
470
|
|
|
|
|
|
|
# |
471
|
|
|
|
|
|
|
sub _exec_xvfb { |
472
|
0
|
|
|
0
|
|
|
my $port = 99; |
473
|
0
|
|
|
|
|
|
my $childpid; |
474
|
0
|
|
|
|
|
|
my $sleep_time = 1; |
475
|
0
|
|
|
|
|
|
my $try_count = 0; |
476
|
0
|
|
|
|
|
|
my $trialnumber; |
477
|
|
|
|
|
|
|
my $childpid_status; |
478
|
|
|
|
|
|
|
|
479
|
|
|
|
|
|
|
# starting with port 100, we try to start |
480
|
|
|
|
|
|
|
# the virtual server until we find an open port |
481
|
|
|
|
|
|
|
# because of the nature of the virtual x server |
482
|
|
|
|
|
|
|
# we use, in order to know if we have found an |
483
|
|
|
|
|
|
|
# open port, we have to sleep. |
484
|
|
|
|
|
|
|
# we check the pid of the virtual x process we started |
485
|
|
|
|
|
|
|
# and see if it died or not. |
486
|
|
|
|
|
|
|
|
487
|
0
|
|
|
|
|
|
while ($childpid_status = _childpid_dead($childpid)) { |
488
|
0
|
|
|
|
|
|
$port++; |
489
|
0
|
|
|
|
|
|
$try_count++; |
490
|
0
|
0
|
|
|
|
|
if ($try_count > 10) { |
491
|
0
|
|
|
|
|
|
die "Error: Failed too many times\n"; |
492
|
|
|
|
|
|
|
} |
493
|
0
|
|
|
|
|
|
$trialnumber = _number_to_eng($try_count); |
494
|
0
|
0
|
|
|
|
|
print STDERR "*** $trialnumber try ***" unless (not $Chart::Graph::debug); |
495
|
0
|
|
|
|
|
|
$childpid = _try_port($port); |
496
|
0
|
|
|
|
|
|
sleep($sleep_time); |
497
|
|
|
|
|
|
|
} |
498
|
0
|
0
|
|
|
|
|
print STDERR " SUCCESS!!!\n" unless (not $Chart::Graph::debug); |
499
|
|
|
|
|
|
|
|
500
|
|
|
|
|
|
|
# save the childpid so we can stop the virtual server later |
501
|
|
|
|
|
|
|
# save the $port so we can tell xrt where the virtual server is. |
502
|
0
|
|
|
|
|
|
return ($childpid, $port); |
503
|
|
|
|
|
|
|
} |
504
|
|
|
|
|
|
|
# |
505
|
|
|
|
|
|
|
# Subroutine: try_port(); |
506
|
|
|
|
|
|
|
# |
507
|
|
|
|
|
|
|
# Description: will try to start Xvfb on specified port |
508
|
|
|
|
|
|
|
sub _try_port { |
509
|
|
|
|
|
|
|
|
510
|
0
|
|
|
0
|
|
|
my ($port) = @_; |
511
|
0
|
|
|
|
|
|
my ($childpid); |
512
|
|
|
|
|
|
|
|
513
|
|
|
|
|
|
|
#fork a process |
514
|
0
|
0
|
|
|
|
|
if (not defined($childpid = fork())){ |
|
|
0
|
|
|
|
|
|
515
|
|
|
|
|
|
|
# the fork failed |
516
|
0
|
|
|
|
|
|
carp "cannot fork: $!"; |
517
|
0
|
|
|
|
|
|
return 0; |
518
|
|
|
|
|
|
|
} elsif ($childpid == 0) { |
519
|
|
|
|
|
|
|
# we are in the child process |
520
|
0
|
0
|
|
|
|
|
if ($Chart::Graph::debug) { |
521
|
0
|
0
|
|
|
|
|
if (not exec "$xvfb :$port") { |
522
|
0
|
|
|
|
|
|
die "can't do $xvfb :$port: $!\n"; |
523
|
|
|
|
|
|
|
} |
524
|
|
|
|
|
|
|
} |
525
|
|
|
|
|
|
|
else { |
526
|
0
|
0
|
|
|
|
|
if (not exec "$xvfb :$port 2> /dev/null") { |
527
|
0
|
|
|
|
|
|
die "can't do $xvfb :$port 2> /dev/null: $!\n"; |
528
|
|
|
|
|
|
|
} |
529
|
|
|
|
|
|
|
} |
530
|
|
|
|
|
|
|
|
531
|
0
|
|
|
|
|
|
die "should never reach here\n"; |
532
|
|
|
|
|
|
|
|
533
|
|
|
|
|
|
|
} else { |
534
|
|
|
|
|
|
|
# we are in the parent, return the childpid |
535
|
|
|
|
|
|
|
# so we can kill it later. |
536
|
0
|
|
|
|
|
|
return $childpid; |
537
|
|
|
|
|
|
|
} |
538
|
|
|
|
|
|
|
|
539
|
|
|
|
|
|
|
} |
540
|
|
|
|
|
|
|
|
541
|
|
|
|
|
|
|
# |
542
|
|
|
|
|
|
|
# Subroutine: childpid_dead |
543
|
|
|
|
|
|
|
# |
544
|
|
|
|
|
|
|
# Description: check to see if a PID has died or not |
545
|
|
|
|
|
|
|
# |
546
|
|
|
|
|
|
|
# |
547
|
|
|
|
|
|
|
sub _childpid_dead { |
548
|
0
|
|
|
0
|
|
|
my ($childpid) = @_; |
549
|
|
|
|
|
|
|
|
550
|
0
|
0
|
|
|
|
|
if (not defined($childpid)) { |
551
|
0
|
|
|
|
|
|
return 1; |
552
|
|
|
|
|
|
|
} |
553
|
|
|
|
|
|
|
|
554
|
|
|
|
|
|
|
# WNOHANG: waitpid() will not suspend execution of |
555
|
|
|
|
|
|
|
# the calling process if status is not |
556
|
|
|
|
|
|
|
# immediately available for one of the |
557
|
|
|
|
|
|
|
# child processes specified by pid. |
558
|
0
|
|
|
|
|
|
return waitpid($childpid, &WNOHANG); |
559
|
|
|
|
|
|
|
} |
560
|
|
|
|
|
|
|
|
561
|
|
|
|
|
|
|
1; |