| line | stmt | bran | path | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  |  | =head1 NAME | 
| 2 |  |  |  |  |  |  |  |  | 
| 3 |  |  |  |  |  |  |  | Alien::Gnuplot - Find and verify functionality of the gnuplot executable. | 
| 4 |  |  |  |  |  |  |  |  | 
| 5 |  |  |  |  |  |  |  | =head1 SYNOPSIS | 
| 6 |  |  |  |  |  |  |  |  | 
| 7 |  |  |  |  |  |  |  | package MyGnuplotter; | 
| 8 |  |  |  |  |  |  |  |  | 
| 9 |  |  |  |  |  |  |  | use strict; | 
| 10 |  |  |  |  |  |  |  |  | 
| 11 |  |  |  |  |  |  |  | use Alien::Gnuplot; | 
| 12 |  |  |  |  |  |  |  |  | 
| 13 |  |  |  |  |  |  |  | $gnuplot = $Alien::Gnuplot::executable; | 
| 14 |  |  |  |  |  |  |  |  | 
| 15 |  |  |  |  |  |  |  | `$gnuplot < /tmp/plotfile`; | 
| 16 |  |  |  |  |  |  |  |  | 
| 17 |  |  |  |  |  |  |  | 1; | 
| 18 |  |  |  |  |  |  |  |  | 
| 19 |  |  |  |  |  |  |  | =head1 DESCRIPTION | 
| 20 |  |  |  |  |  |  |  |  | 
| 21 |  |  |  |  |  |  |  | Alien::Gnuplot verifies existence and sanity of the gnuplot external | 
| 22 |  |  |  |  |  |  |  | application.  It only declares one access method, | 
| 23 |  |  |  |  |  |  |  | C, which does the actual work and is | 
| 24 |  |  |  |  |  |  |  | called automatically at load time.  Alien::Gnuplot doesn't have any | 
| 25 |  |  |  |  |  |  |  | actual plotting methods - making use of gnuplot, once it is found and | 
| 26 |  |  |  |  |  |  |  | verified, is up to you or your client module. | 
| 27 |  |  |  |  |  |  |  |  | 
| 28 |  |  |  |  |  |  |  | Using Alien::Gnuplot checks for existence of the executable, verifies | 
| 29 |  |  |  |  |  |  |  | that it runs properly, and sets several global variables to describe | 
| 30 |  |  |  |  |  |  |  | the properties of the gnuplot it found: | 
| 31 |  |  |  |  |  |  |  |  | 
| 32 |  |  |  |  |  |  |  | =over 3 | 
| 33 |  |  |  |  |  |  |  |  | 
| 34 |  |  |  |  |  |  |  | =item * C<$Alien::Gnuplot::executable> | 
| 35 |  |  |  |  |  |  |  |  | 
| 36 |  |  |  |  |  |  |  | gets the path to the gnuplot executable. | 
| 37 |  |  |  |  |  |  |  |  | 
| 38 |  |  |  |  |  |  |  | =item * C<$Alien::Gnuplot::version> | 
| 39 |  |  |  |  |  |  |  |  | 
| 40 |  |  |  |  |  |  |  | gets the self-reported version number of the executable. | 
| 41 |  |  |  |  |  |  |  |  | 
| 42 |  |  |  |  |  |  |  | =item * C<$Alien::Gnuplot::pl> | 
| 43 |  |  |  |  |  |  |  |  | 
| 44 |  |  |  |  |  |  |  | gets the self-reported patch level. | 
| 45 |  |  |  |  |  |  |  |  | 
| 46 |  |  |  |  |  |  |  | =item * C<@Alien::Gnuplot::terms> | 
| 47 |  |  |  |  |  |  |  |  | 
| 48 |  |  |  |  |  |  |  | gets a list of the names of all supported terminal devices. | 
| 49 |  |  |  |  |  |  |  |  | 
| 50 |  |  |  |  |  |  |  | =item * C<%Alien::Gnuplot::terms> | 
| 51 |  |  |  |  |  |  |  |  | 
| 52 |  |  |  |  |  |  |  | gets a key for each supported terminal device; values are the 1-line | 
| 53 |  |  |  |  |  |  |  | description from gnuplot.  This is useful for testing whether a | 
| 54 |  |  |  |  |  |  |  | particular terminal is supported. | 
| 55 |  |  |  |  |  |  |  |  | 
| 56 |  |  |  |  |  |  |  | =item * C<@Alien::Gnuplot::colors> | 
| 57 |  |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  |  | gets a list of the names of all named colors recognized by this gnuplot. | 
| 59 |  |  |  |  |  |  |  |  | 
| 60 |  |  |  |  |  |  |  | =item * C<%Alien::Gnuplot::colors> | 
| 61 |  |  |  |  |  |  |  |  | 
| 62 |  |  |  |  |  |  |  | gets a key for each named color; values are the C<#RRGGBB> form of the color. | 
| 63 |  |  |  |  |  |  |  | This is useful for decoding colors, or for checking whether a particular color | 
| 64 |  |  |  |  |  |  |  | name is recognized.  All the color names are lowercase alphanumeric. | 
| 65 |  |  |  |  |  |  |  |  | 
| 66 |  |  |  |  |  |  |  | =back | 
| 67 |  |  |  |  |  |  |  |  | 
| 68 |  |  |  |  |  |  |  | You can point Alien::Gnuplot to a particular path for gnuplot, by | 
| 69 |  |  |  |  |  |  |  | setting the environment variable GNUPLOT_BINARY to the path.  Otherwise | 
| 70 |  |  |  |  |  |  |  | your path will be searched (using File::Spec) for the executable file. | 
| 71 |  |  |  |  |  |  |  |  | 
| 72 |  |  |  |  |  |  |  | If there is no executable application in your path or in the location | 
| 73 |  |  |  |  |  |  |  | pointed to by GNUPLOT_BINARY, then the module throws an exception. | 
| 74 |  |  |  |  |  |  |  | You can also verify that it has not completed successfully, by | 
| 75 |  |  |  |  |  |  |  | examining $Alien::Gnuplot::version, which is undefined in case of | 
| 76 |  |  |  |  |  |  |  | failure and contains the gnuplot version string on success. | 
| 77 |  |  |  |  |  |  |  |  | 
| 78 |  |  |  |  |  |  |  | If you think the global state of the gnuplot executable may have | 
| 79 |  |  |  |  |  |  |  | changed, you can either reload the module or explicitly call | 
| 80 |  |  |  |  |  |  |  | C to force a fresh inspection of | 
| 81 |  |  |  |  |  |  |  | the executable. | 
| 82 |  |  |  |  |  |  |  |  | 
| 83 |  |  |  |  |  |  |  | =head1 INSTALLATION STRATEGY | 
| 84 |  |  |  |  |  |  |  |  | 
| 85 |  |  |  |  |  |  |  | When you install Alien::Gnuplot, it checks that gnuplot itself is | 
| 86 |  |  |  |  |  |  |  | installed as well.  If it is not, then Alien::Gnuplot attempts to | 
| 87 |  |  |  |  |  |  |  | use one of several common package managers to install gnuplot for you. | 
| 88 |  |  |  |  |  |  |  | If it can't find one of those, if dies (and refuses to install), printing | 
| 89 |  |  |  |  |  |  |  | a friendly message about how to get gnuplot before throwing an error. | 
| 90 |  |  |  |  |  |  |  |  | 
| 91 |  |  |  |  |  |  |  | In principle, gnuplot could be automagically downloaded and built, | 
| 92 |  |  |  |  |  |  |  | but it is distributed via Sourceforge -- which obfuscates interior | 
| 93 |  |  |  |  |  |  |  | links, making such tools surprisingly difficult to write. | 
| 94 |  |  |  |  |  |  |  |  | 
| 95 |  |  |  |  |  |  |  | =head1 CROSS-PLATFORM BEHAVIOR | 
| 96 |  |  |  |  |  |  |  |  | 
| 97 |  |  |  |  |  |  |  | On POSIX systems, including Linux and MacOS, Alien::Gnuplot uses | 
| 98 |  |  |  |  |  |  |  | fork/exec to invoke the gnuplot executable and asynchronously monitor | 
| 99 |  |  |  |  |  |  |  | it for hangs.  Microsoft Windows process control is more difficult, so | 
| 100 |  |  |  |  |  |  |  | if $^O contains "MSWin32", a simpler system call is used, that is | 
| 101 |  |  |  |  |  |  |  | riskier -- it involves waiting for the unknown executable to complete. | 
| 102 |  |  |  |  |  |  |  |  | 
| 103 |  |  |  |  |  |  |  | =head1 REPOSITORIES | 
| 104 |  |  |  |  |  |  |  |  | 
| 105 |  |  |  |  |  |  |  | Gnuplot's main home page is at L. | 
| 106 |  |  |  |  |  |  |  |  | 
| 107 |  |  |  |  |  |  |  | Alien::Gnuplot development is at L. | 
| 108 |  |  |  |  |  |  |  |  | 
| 109 |  |  |  |  |  |  |  | A major client module for Alien::Gnuplot is PDL::Graphics::Gnuplot, which | 
| 110 |  |  |  |  |  |  |  | can be found at L. | 
| 111 |  |  |  |  |  |  |  | PDL is at L. | 
| 112 |  |  |  |  |  |  |  |  | 
| 113 |  |  |  |  |  |  |  | =head1 AUTHOR | 
| 114 |  |  |  |  |  |  |  |  | 
| 115 |  |  |  |  |  |  |  | Craig DeForest | 
| 116 |  |  |  |  |  |  |  |  | 
| 117 |  |  |  |  |  |  |  | (with special thanks to Chris Marshall, Juergen Mueck, and | 
| 118 |  |  |  |  |  |  |  | Sisyphus for testing and debugging on the Microsoft platform) | 
| 119 |  |  |  |  |  |  |  |  | 
| 120 |  |  |  |  |  |  |  | =head1 COPYRIGHT AND LICENSE | 
| 121 |  |  |  |  |  |  |  |  | 
| 122 |  |  |  |  |  |  |  | Copyright (C) 2013 Craig DeForest | 
| 123 |  |  |  |  |  |  |  |  | 
| 124 |  |  |  |  |  |  |  | This library is free software; you can redistribute it and/or modify | 
| 125 |  |  |  |  |  |  |  | it under the same terms as Perl itself. | 
| 126 |  |  |  |  |  |  |  |  | 
| 127 |  |  |  |  |  |  |  | =cut | 
| 128 |  |  |  |  |  |  |  |  | 
| 129 |  |  |  |  |  |  |  | package Alien::Gnuplot; | 
| 130 |  |  |  |  |  |  |  |  | 
| 131 | 3 |  |  |  | 3 |  | 1526 | use strict; | 
|  | 3 |  |  |  |  |  | 17 |  | 
|  | 3 |  |  |  |  |  | 153 |  | 
| 132 |  |  |  |  |  |  |  | our $DEBUG = 0; # set to 1 for some debugging output | 
| 133 |  |  |  |  |  |  |  |  | 
| 134 | 3 |  |  |  | 3 |  | 1324 | use parent qw( Alien::Base ); | 
|  | 3 |  |  |  |  |  | 1298 |  | 
|  | 3 |  |  |  |  |  | 21 |  | 
| 135 |  |  |  |  |  |  |  |  | 
| 136 | 3 |  |  |  | 3 |  | 155635 | use File::Spec; | 
|  | 3 |  |  |  |  |  | 10 |  | 
|  | 3 |  |  |  |  |  | 71 |  | 
| 137 | 3 |  |  |  | 3 |  | 16 | use File::Temp qw/tempfile/; | 
|  | 3 |  |  |  |  |  | 4 |  | 
|  | 3 |  |  |  |  |  | 139 |  | 
| 138 | 3 |  |  |  | 3 |  | 1537 | use File::Which; | 
|  | 3 |  |  |  |  |  | 2973 |  | 
|  | 3 |  |  |  |  |  | 194 |  | 
| 139 | 3 |  |  |  | 3 |  | 22 | use Time::HiRes qw/usleep/; | 
|  | 3 |  |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  |  | 23 |  | 
| 140 | 3 |  |  |  | 3 |  | 1859 | use POSIX ":sys_wait_h"; | 
|  | 3 |  |  |  |  |  | 19228 |  | 
|  | 3 |  |  |  |  |  | 18 |  | 
| 141 | 3 |  |  |  | 3 |  | 4635 | use Fcntl qw/SEEK_SET/; | 
|  | 3 |  |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  |  | 125 |  | 
| 142 | 3 |  |  |  | 3 |  | 2744 | use Env qw( @PATH ); | 
|  | 3 |  |  |  |  |  | 7968 |  | 
|  | 3 |  |  |  |  |  | 17 |  | 
| 143 |  |  |  |  |  |  |  |  | 
| 144 |  |  |  |  |  |  |  | # VERSION here is for CPAN to parse -- it is the version of the module itself.  But we | 
| 145 |  |  |  |  |  |  |  | # overload the system VERSION to compare a required version against gnuplot itself, rather | 
| 146 |  |  |  |  |  |  |  | # than against the module version. | 
| 147 |  |  |  |  |  |  |  |  | 
| 148 |  |  |  |  |  |  |  | our $VERSION = '1.042'; | 
| 149 |  |  |  |  |  |  |  |  | 
| 150 |  |  |  |  |  |  |  | # On install, try to make sure at least this version is present. | 
| 151 |  |  |  |  |  |  |  | our $GNUPLOT_RECOMMENDED_VERSION = '4.6'; | 
| 152 |  |  |  |  |  |  |  |  | 
| 153 |  |  |  |  |  |  |  | our $executable;  # Holds the path to the found gnuplot | 
| 154 |  |  |  |  |  |  |  | our $version;     # Holds the found version number | 
| 155 |  |  |  |  |  |  |  | our $pl;          # Holds the found patchlevel | 
| 156 |  |  |  |  |  |  |  | our @terms; | 
| 157 |  |  |  |  |  |  |  | our %terms; | 
| 158 |  |  |  |  |  |  |  | our @colors; | 
| 159 |  |  |  |  |  |  |  | our %colors; | 
| 160 |  |  |  |  |  |  |  |  | 
| 161 |  |  |  |  |  |  |  | sub VERSION { | 
| 162 | 2 |  |  |  | 2 | 0 | 719 | my $module =shift; | 
| 163 | 2 |  |  |  |  |  | 5 | my $req_v = shift; | 
| 164 |  |  |  |  |  |  |  | # Need this line when using | 
| 165 |  |  |  |  |  |  |  | # | 
| 166 |  |  |  |  |  |  |  | #   use Alien::Gnuplot 4.4; | 
| 167 |  |  |  |  |  |  |  | # | 
| 168 |  |  |  |  |  |  |  | # to check Gnuplot version. | 
| 169 | 2 | 50 |  |  |  |  | 6 | $module->load_gnuplot unless $version; # already have version | 
| 170 | 2 | 100 |  |  |  |  | 11 | unless($req_v <= $version) { | 
| 171 | 1 |  |  |  |  |  | 11 | die qq{ | 
| 172 |  |  |  |  |  |  |  |  | 
| 173 |  |  |  |  |  |  |  | Alien::Gnuplot: Found gnuplot version $version, but you requested $req_v. | 
| 174 |  |  |  |  |  |  |  | You should upgrade gnuplot, either by reinstalling Alien::Gnuplot or | 
| 175 |  |  |  |  |  |  |  | getting it yourself from L. | 
| 176 |  |  |  |  |  |  |  |  | 
| 177 |  |  |  |  |  |  |  | }; | 
| 178 |  |  |  |  |  |  |  | } | 
| 179 |  |  |  |  |  |  |  | } | 
| 180 |  |  |  |  |  |  |  |  | 
| 181 |  |  |  |  |  |  |  | sub exe { | 
| 182 |  |  |  |  |  |  |  | ############################## | 
| 183 |  |  |  |  |  |  |  | # Search the path for the executable | 
| 184 |  |  |  |  |  |  |  | # | 
| 185 | 4 |  |  |  | 4 | 0 | 9 | my ($class) = @_; | 
| 186 | 4 |  |  | 50 |  |  | 15 | $class ||= __PACKAGE__; | 
| 187 |  |  |  |  |  |  |  |  | 
| 188 | 4 |  |  |  |  |  | 8 | my $exec_path; | 
| 189 |  |  |  |  |  |  |  | # GNUPLOT_BINARY overrides at runtime | 
| 190 | 4 | 100 |  |  |  |  | 24 | if($ENV{'GNUPLOT_BINARY'}) { | 
| 191 | 1 |  |  |  |  |  | 5 | $exec_path = $ENV{'GNUPLOT_BINARY'}; | 
| 192 |  |  |  |  |  |  |  | } else { | 
| 193 | 3 |  |  |  |  |  | 24 | local $ENV{PATH} = $ENV{PATH}; | 
| 194 | 3 |  |  |  |  |  | 28 | unshift @PATH, $class->bin_dir; | 
| 195 | 3 |  |  |  |  |  | 1400 | $exec_path = which("gnuplot"); | 
| 196 |  |  |  |  |  |  |  | } | 
| 197 |  |  |  |  |  |  |  |  | 
| 198 | 4 |  |  |  |  |  | 425 | return $exec_path; | 
| 199 |  |  |  |  |  |  |  | } | 
| 200 |  |  |  |  |  |  |  |  | 
| 201 |  |  |  |  |  |  |  | sub load_gnuplot { | 
| 202 | 4 |  |  |  | 4 | 0 | 198 | my ($class) = @_; | 
| 203 | 4 |  |  | 50 |  |  | 46 | $class ||= __PACKAGE__; | 
| 204 |  |  |  |  |  |  |  |  | 
| 205 | 4 |  |  |  |  |  | 15 | my $exec_path = $class->exe; | 
| 206 | 4 |  |  |  |  |  | 18 | $class->check_gnuplot($exec_path); | 
| 207 |  |  |  |  |  |  |  | } | 
| 208 |  |  |  |  |  |  |  |  | 
| 209 |  |  |  |  |  |  |  | sub check_gnuplot { | 
| 210 | 4 |  |  |  | 4 | 0 | 9 | my $exec_path = pop @_; | 
| 211 |  |  |  |  |  |  |  |  | 
| 212 | 4 | 100 |  |  |  |  | 118 | unless(-x $exec_path) { | 
| 213 | 1 |  |  |  |  |  | 15 | die q{ | 
| 214 |  |  |  |  |  |  |  | Alien::Gnuplot: no executable gnuplot found!  If you have gnuplot, | 
| 215 |  |  |  |  |  |  |  | you can put its exact location in your GNUPLOT_BINARY environment | 
| 216 |  |  |  |  |  |  |  | variable or make sure your PATH contains it.  If you do not have | 
| 217 |  |  |  |  |  |  |  | gnuplot, you can reinstall Alien::Gnuplot (and its installation | 
| 218 |  |  |  |  |  |  |  | script will try to install gnuplot) or get it yourself from L. | 
| 219 |  |  |  |  |  |  |  | }; | 
| 220 |  |  |  |  |  |  |  | } | 
| 221 |  |  |  |  |  |  |  |  | 
| 222 |  |  |  |  |  |  |  | ############################## | 
| 223 |  |  |  |  |  |  |  | # Execute the executable to make sure it's really gnuplot, and parse | 
| 224 |  |  |  |  |  |  |  | # out its reported version.  This is complicated by gnuplot's shenanigans | 
| 225 |  |  |  |  |  |  |  | # with STDOUT and STDERR, so we fork and redirect everything to a file. | 
| 226 |  |  |  |  |  |  |  | # The parent process gives the daughter 2 seconds to report progress, then | 
| 227 |  |  |  |  |  |  |  | # kills it dead. | 
| 228 | 3 |  |  |  |  |  | 15 | my($pid); | 
| 229 | 3 |  |  |  |  |  | 18 | my ($undef, $file) = tempfile(); | 
| 230 |  |  |  |  |  |  |  |  | 
| 231 |  |  |  |  |  |  |  | # Create command file | 
| 232 | 3 |  |  |  |  |  | 2138 | open FOO, ">${file}_gzinta"; | 
| 233 | 3 |  |  |  |  |  | 62 | print FOO "show version\nset terminal\n\n\n\n\n\n\n\n\n\nprint \"CcColors\"\nshow colornames\n\n\n\n\n\n\n\nprint \"FfFinished\"\nexit\n"; | 
| 234 | 3 |  |  |  |  |  | 171 | close FOO; | 
| 235 |  |  |  |  |  |  |  |  | 
| 236 | 3 | 50 |  |  |  |  | 23 | if($^O =~ /MSWin32/i) { | 
| 237 |  |  |  |  |  |  |  |  | 
| 238 | 0 | 0 |  |  |  |  | 0 | if( $exec_path =~ m/([\"\*\?\<\>\|])/ ) { | 
| 239 | 0 |  |  |  |  |  | 0 | die "Alien::Gnuplot: Invalid character '$1' in path to gnuplot -- I give up" ; | 
| 240 |  |  |  |  |  |  |  | } | 
| 241 |  |  |  |  |  |  |  |  | 
| 242 |  |  |  |  |  |  |  | # Microsoft Windows sucks at IPC (and many other things), so | 
| 243 |  |  |  |  |  |  |  | # use "system" instead of civilized fork/exec. | 
| 244 |  |  |  |  |  |  |  | # This leaves us vulnerable to gnuplot itself hanging, but | 
| 245 |  |  |  |  |  |  |  | # sidesteps the problem of waitpid hanging on Strawberry Perl. | 
| 246 | 0 |  |  |  |  |  | 0 | open FOO, ">&STDOUT"; | 
| 247 | 0 |  |  |  |  |  | 0 | open BAR, ">&STDERR"; | 
| 248 | 0 |  |  |  |  |  | 0 | open STDOUT,">$file"; | 
| 249 | 0 |  |  |  |  |  | 0 | open STDERR,">$file"; | 
| 250 | 0 |  |  |  |  |  | 0 | system(qq{"$exec_path" < ${file}_gzinta}); | 
| 251 | 0 |  |  |  |  |  | 0 | open STDOUT,">&FOO"; | 
| 252 | 0 |  |  |  |  |  | 0 | open STDERR,">&BAR"; | 
| 253 | 0 |  |  |  |  |  | 0 | close FOO; | 
| 254 | 0 |  |  |  |  |  | 0 | close BAR; | 
| 255 |  |  |  |  |  |  |  | } else { | 
| 256 | 3 |  |  |  |  |  | 2598 | $pid = fork(); | 
| 257 | 3 | 50 |  |  |  |  | 457 | if(defined($pid)) { | 
| 258 | 3 | 50 |  |  |  |  | 132 | if(!$pid) { | 
| 259 |  |  |  |  |  |  |  | # daughter | 
| 260 | 0 |  |  |  |  |  | 0 | open BAR, ">&STDERR"; # preserve stderr | 
| 261 | 0 |  |  |  |  |  | 0 | eval { | 
| 262 | 0 |  |  |  |  |  | 0 | open STDOUT, ">$file"; | 
| 263 | 0 |  |  |  |  |  | 0 | open STDERR, ">&STDOUT"; | 
| 264 | 0 |  |  |  |  |  | 0 | open STDIN, "<${file}_gzinta"; | 
| 265 | 0 |  |  |  |  |  | 0 | seek STDIN, 0, SEEK_SET; | 
| 266 | 3 |  |  |  | 3 |  | 2145 | no warnings; | 
|  | 3 |  |  |  |  |  | 10 |  | 
|  | 3 |  |  |  |  |  | 2601 |  | 
| 267 | 0 |  |  |  |  |  | 0 | exec($exec_path); | 
| 268 | 0 |  |  |  |  |  | 0 | print BAR "Execution of $exec_path failed!\n"; | 
| 269 | 0 |  |  |  |  |  | 0 | exit(1); | 
| 270 |  |  |  |  |  |  |  | }; | 
| 271 | 0 |  |  |  |  |  | 0 | print STDERR "Alien::Gnuplot: Unknown problems spawning '$exec_path' to probe gnuplot.\n"; | 
| 272 | 0 |  |  |  |  |  | 0 | exit(2); # there was a problem! | 
| 273 |  |  |  |  |  |  |  | } else { | 
| 274 |  |  |  |  |  |  |  | # parent | 
| 275 |  |  |  |  |  |  |  | # Assume we're more POSIX-compliant... | 
| 276 | 3 | 50 |  |  |  |  | 114 | if($DEBUG) { print "waiting for pid $pid (up to 20 iterations of 100ms)"; flush STDOUT; } | 
|  | 0 |  |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  |  | 0 |  | 
| 277 | 3 |  |  |  |  |  | 111 | for (1..20) { | 
| 278 | 12 | 50 |  |  |  |  | 192 | if($DEBUG) { print "."; flush STDOUT; } | 
|  | 0 |  |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  |  | 0 |  | 
| 279 | 12 | 100 |  |  |  |  | 306 | if(waitpid($pid,WNOHANG)) { | 
| 280 | 3 |  |  |  |  |  | 38 | $pid=0; | 
| 281 | 3 |  |  |  |  |  | 17 | last; | 
| 282 |  |  |  |  |  |  |  | } | 
| 283 | 9 |  |  |  |  |  | 901509 | usleep(1e5); | 
| 284 |  |  |  |  |  |  |  | } | 
| 285 | 3 | 50 |  |  |  |  | 69 | if($DEBUG) { print "\n"; flush STDOUT; } | 
|  | 0 |  |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  |  | 0 |  | 
| 286 |  |  |  |  |  |  |  |  | 
| 287 | 3 | 50 |  |  |  |  | 34 | if($pid) { | 
| 288 | 0 | 0 |  |  |  |  | 0 | if( $DEBUG) { print "gnuplot didn't complete.  Killing it dead...\n"; flush STDOUT; } | 
|  | 0 |  |  |  |  |  | 0 |  | 
|  | 0 |  |  |  |  |  | 0 |  | 
| 289 | 0 |  |  |  |  |  | 0 | kill 9,$pid;   # zap | 
| 290 | 0 |  |  |  |  |  | 0 | waitpid($pid,0); # reap | 
| 291 |  |  |  |  |  |  |  | } | 
| 292 |  |  |  |  |  |  |  | } #end of parent case | 
| 293 |  |  |  |  |  |  |  | } else { | 
| 294 |  |  |  |  |  |  |  | # fork returned undef - error. | 
| 295 | 0 |  |  |  |  |  | 0 | die "Alien::Gnuplot: Couldn't fork to test gnuplot! ($@)\n"; | 
| 296 |  |  |  |  |  |  |  | } | 
| 297 |  |  |  |  |  |  |  | } | 
| 298 |  |  |  |  |  |  |  |  | 
| 299 |  |  |  |  |  |  |  | ############################## | 
| 300 |  |  |  |  |  |  |  | # Read what gnuplot had to say, and clean up our mess... | 
| 301 | 3 |  |  |  |  |  | 296 | open FOO, "<$file"; | 
| 302 | 3 |  |  |  |  |  | 570 | my @lines = ; | 
| 303 | 3 |  |  |  |  |  | 72 | close FOO; | 
| 304 | 3 |  |  |  |  |  | 204 | unlink $file; | 
| 305 | 3 |  |  |  |  |  | 235 | unlink $file."_gzinta"; | 
| 306 |  |  |  |  |  |  |  |  | 
| 307 |  |  |  |  |  |  |  | ############################## | 
| 308 |  |  |  |  |  |  |  | # Whew.  Now parse out the 'GNUPLOT' and version number... | 
| 309 | 3 |  |  |  |  |  | 41 | my $lines = join("", map { chomp $_; $_} @lines); | 
|  | 465 |  |  |  |  |  | 619 |  | 
|  | 465 |  |  |  |  |  | 756 |  | 
| 310 | 3 | 50 |  |  |  |  | 152 | $lines =~ s/\s+G N U P L O T\s*//  or  die qq{ | 
| 311 |  |  |  |  |  |  |  | Alien::Gnuplot: the executable '$exec_path' appears not to be gnuplot, | 
| 312 |  |  |  |  |  |  |  | or perhaps there was a problem running it.  You can remove it or set | 
| 313 |  |  |  |  |  |  |  | your GNUPLOT_BINARY variable to an actual gnuplot. | 
| 314 |  |  |  |  |  |  |  | }; | 
| 315 |  |  |  |  |  |  |  |  | 
| 316 | 3 | 50 |  |  |  |  | 72 | $lines =~ m/Version (\d+\.\d+) (patchlevel (\d+))?/ or die qq{ | 
| 317 |  |  |  |  |  |  |  | Alien::Gnuplot: the executable file $exec_path claims to be gnuplot, but | 
| 318 |  |  |  |  |  |  |  | I could not parse a version number from its output.  Sorry, I give up. | 
| 319 |  |  |  |  |  |  |  |  | 
| 320 |  |  |  |  |  |  |  | }; | 
| 321 |  |  |  |  |  |  |  |  | 
| 322 | 3 |  |  |  |  |  | 56 | $version = $1; | 
| 323 | 3 |  |  |  |  |  | 33 | $pl = $3; | 
| 324 | 3 |  |  |  |  |  | 26 | $executable = $exec_path; | 
| 325 |  |  |  |  |  |  |  |  | 
| 326 |  |  |  |  |  |  |  | ############################## | 
| 327 |  |  |  |  |  |  |  | # Parse out available terminals and put them into the | 
| 328 |  |  |  |  |  |  |  | # global list and hash. | 
| 329 | 3 |  |  |  |  |  | 12 | @terms = (); | 
| 330 | 3 |  |  |  |  |  | 8 | %terms = (); | 
| 331 | 3 |  |  |  |  |  | 44 | my $reading_terms = 0; | 
| 332 | 3 |  |  |  |  |  | 24 | for my $line(@lines) { | 
| 333 | 123 | 100 |  |  |  |  | 276 | last if($line =~ m/CcColors/); | 
| 334 | 120 | 100 |  |  |  |  | 185 | if(!$reading_terms) { | 
| 335 | 42 | 100 |  |  |  |  | 97 | if($line =~ m/^Available terminal types\:/) { | 
| 336 | 3 |  |  |  |  |  | 11 | $reading_terms = 1; | 
| 337 |  |  |  |  |  |  |  | } | 
| 338 |  |  |  |  |  |  |  | } else { | 
| 339 | 78 |  |  |  |  |  | 128 | $line =~ s/^Press return for more\:\s*//; | 
| 340 | 78 | 50 |  |  |  |  | 242 | $line =~ m/^\s*(\w+)\s(.*[^\s])\s*$/ || next; | 
| 341 | 78 |  |  |  |  |  | 207 | push(@terms, $1); | 
| 342 | 78 |  |  |  |  |  | 311 | $terms{$1} = $2; | 
| 343 |  |  |  |  |  |  |  | } | 
| 344 |  |  |  |  |  |  |  | } | 
| 345 |  |  |  |  |  |  |  |  | 
| 346 |  |  |  |  |  |  |  | ############################## | 
| 347 |  |  |  |  |  |  |  | # Parse out available colors and put them into that global list and hash. | 
| 348 | 3 |  |  |  |  |  | 8 | @colors = (); | 
| 349 | 3 |  |  |  |  |  | 7 | %colors = (); | 
| 350 |  |  |  |  |  |  |  |  | 
| 351 | 3 |  |  |  |  |  | 9 | for my $line(@lines) { | 
| 352 | 465 | 100 |  |  |  |  | 910 | last if($line =~ m/FfFinished/); | 
| 353 | 462 | 100 |  |  |  |  | 1250 | next unless( $line =~ m/\s+([\w\-0-9]+)\s+(\#......)/); | 
| 354 | 333 |  |  |  |  |  | 1110 | $colors{$1} = $2; | 
| 355 |  |  |  |  |  |  |  | } | 
| 356 | 3 |  |  |  |  |  | 955 | @colors = sort keys %colors; | 
| 357 |  |  |  |  |  |  |  | } | 
| 358 |  |  |  |  |  |  |  |  | 
| 359 |  |  |  |  |  |  |  | sub import { | 
| 360 | 3 |  |  |  | 3 |  | 28 | my $pkg = shift; | 
| 361 | 3 |  |  |  |  |  | 30 | $pkg->SUPER::import(@_); | 
| 362 | 3 |  |  |  |  |  | 59123 | $pkg->load_gnuplot(); | 
| 363 |  |  |  |  |  |  |  | }; | 
| 364 |  |  |  |  |  |  |  |  | 
| 365 |  |  |  |  |  |  |  |  | 
| 366 |  |  |  |  |  |  |  | 1; | 
| 367 |  |  |  |  |  |  |  |  |