Alien-Gnuplot

 view release on metacpan or  search on metacpan

lib/Alien/Gnuplot.pm  view on Meta::CPAN

variable or make sure your PATH contains it.  If you do not have
gnuplot, you can reinstall Alien::Gnuplot (and its installation 
script will try to install gnuplot) or get it yourself from L<https://gnuplot.sourceforge.net/>.
};
    }
    
##############################
# Execute the executable to make sure it's really gnuplot, and parse
# out its reported version.  This is complicated by gnuplot's shenanigans
# with STDOUT and STDERR, so we fork and redirect everything to a file.
# The parent process gives the daughter 2 seconds to report progress, then
# kills it dead.
    my($pid);
    my ($undef, $file) = tempfile();

    # Create command file
    open FOO, ">${file}_gzinta";
    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";
    close FOO;

    if($^O =~ /MSWin32/i) {

	if( $exec_path =~ m/([\"\*\?\<\>\|])/ ) {
	    die "Alien::Gnuplot: Invalid character '$1' in path to gnuplot -- I give up" ;
	}
	
	# Microsoft Windows sucks at IPC (and many other things), so
	# use "system" instead of civilized fork/exec.
	# This leaves us vulnerable to gnuplot itself hanging, but 
	# sidesteps the problem of waitpid hanging on Strawberry Perl.
	open FOO, ">&STDOUT";
	open BAR, ">&STDERR";
	open STDOUT,">$file";
	open STDERR,">$file";
	system(qq{"$exec_path" < ${file}_gzinta});
	open STDOUT,">&FOO";
	open STDERR,">&BAR";
	close FOO;
	close BAR;
    } else {
	$pid = fork();
	if(defined($pid)) {
	    if(!$pid) {
		# daughter
		open BAR, ">&STDERR"; # preserve stderr
		eval { 
		    open STDOUT, ">$file";
		    open STDERR, ">&STDOUT";
		    open STDIN, "<${file}_gzinta";
		    seek STDIN, 0, SEEK_SET;
		    no warnings; 
		    exec($exec_path);
		    print BAR "Execution of $exec_path failed!\n";
		    exit(1);
		}; 
		print STDERR "Alien::Gnuplot: Unknown problems spawning '$exec_path' to probe gnuplot.\n";
		exit(2); # there was a problem!
	    } else {
		# parent
		# Assume we're more POSIX-compliant...
		if($DEBUG) { print "waiting for pid $pid (up to 20 iterations of 100ms)"; flush STDOUT; }
		for (1..20) {
		    if($DEBUG) { print "."; flush STDOUT; }
		    if(waitpid($pid,WNOHANG)) {
			$pid=0;
			last;
		    }
		    usleep(1e5);
		}
		if($DEBUG) { print "\n"; flush STDOUT; }
		
		if($pid) {
		    if( $DEBUG) { print "gnuplot didn't complete.  Killing it dead...\n"; flush STDOUT; }
		    kill 9,$pid;   # zap
		    waitpid($pid,0); # reap
		}
	    } #end of parent case
	} else {
	    # fork returned undef - error.
	    die "Alien::Gnuplot: Couldn't fork to test gnuplot! ($@)\n";
	}
    }
    
##############################
# Read what gnuplot had to say, and clean up our mess...
    open FOO, "<$file";
    my @lines = <FOO>;
    close FOO;
    unlink $file;
    unlink $file."_gzinta";
    
##############################
# Whew.  Now parse out the 'GNUPLOT' and version number...
    my $lines = join("", map { chomp $_; $_} @lines);
    $lines =~ s/\s+G N U P L O T\s*//  or  die qq{
Alien::Gnuplot: the executable '$exec_path' appears not to be gnuplot,
or perhaps there was a problem running it.  You can remove it or set
your GNUPLOT_BINARY variable to an actual gnuplot.

Raw output from Gnuplot:
$lines
};
    
    $lines =~ m/Version (\d+\.\d+) (patchlevel (\d+))?/ or die qq{
Alien::Gnuplot: the executable file $exec_path claims to be gnuplot, but 
I could not parse a version number from its output.  Sorry, I give up.

Raw output from Gnuplot:
$lines
};
    
    $version = $1;
    $pl = $3;
    $executable = $exec_path;
    
##############################
# Parse out available terminals and put them into the 
# global list and hash.
    @terms = ();
    %terms = ();
    my $reading_terms = 0;



( run in 4.100 seconds using v1.01-cache-2.11-cpan-96521ef73a4 )