Ilya Zakharevich on Thu, 10 Sep 1998 00:26:54 -0400 (EDT) |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Newer gnuplot support patch |
Hi, my previous gnuplot support patch did not make it into the distribution. Here is the improved version: Do touch ./src/graph/Gnuplot.h before applying this patch. This is a very primitive variant of gnuplot support, it does not allow setting terminal options and output files. Tested on OS/2 and Solaris only with libgnuplot.a of the build 340. To use the new --graphic=gnuplot configure option, you need to have libgnuplot.a in a location where PARI has a chance to find it. If gnuplot does not build a library on your architecture, just do ar cr libgnuplot.a *.o in the gnuplot build directory, and copy it to, say, /opt/local/lib. Example: plotterm("tex"); ploth(X=1,3,sin(X)); Enjoy, Ilya P.S. It will not work with gnuplot 3.5, since the C files were too intertwined to separate them by un-ar-ing only, they needed a recompile with some #defines to do it. The build 340 is much better, the interdependence of files may be broken by just extracting them from the archive. To support setting the output file name, one may need to globally rename `outfile' to `pari_outfile' in the C source, and introduce new function plotfile('str') which sets `outfile' - analoguous to the current plotterm('str'). My version of Perl interface to Gnuplot low-level plotting supports options, so it should not be hard to correct plotterm() to support options. Maybe later... (Btw, note that gnuplot has nothing to do with GNU - I corrected one place which looked like this.) --- ./Configure.orig Thu Jul 30 07:05:08 1998 +++ ./Configure Wed Sep 9 23:31:00 1998 @@ -37,6 +37,7 @@ fastread=yes config_file= optimization=full prefix=/usr/local +which_graphic_lib=none test -n "$GP_INSTALL_PREFIX" && prefix=$GP_INSTALL_PREFIX while test $# -gt 0; do case "$1" in @@ -63,6 +64,10 @@ while test $# -gt 0; do -rdll) DYNRELOC=yes;; -h|-help|-\?)error=true;; -v|-verbhelp)error=verb;; + -graphic) shift; which_graphic_lib=$1; graph_cmd=yes ;; + --graphic=*|--graphi=*|--graph=*|--grap=*|--gra=*|--gr=*|--g=*) + graph_cmd=yes + which_graphic_lib=`echo "$1" | sed -e 's/[-a-z]*=//'`;; *) echo "*** Unrecognized option $1." >&2; error=true;; esac shift @@ -77,6 +82,7 @@ Options: names can be abbreviated to one -verbhelp a longer help message -load specify a default config file (default $dflt_conf_file) --prefix=<dir> install files in <dir>/... (default $prefix) + --graphic=<gr> which graphic library to use (none X11 sunview gnuplot) Additional developer options: -g creates debugging version @@ -355,7 +361,6 @@ echo "Building for architecture: $pretty # # Looking for libraries now # -which_graphic_lib=none completionfun="gp-complete" if test "$optimization" != profiling; then # First, construct the PATHs @@ -394,7 +400,7 @@ if test "$optimization" != profiling; th # LIB: X11 pth=$x11pth lib=X11; . ./locatelib - if test -f $Xincroot/X11/Xos.h; then + if test -f $Xincroot/X11/Xos.h -a -z "$graph_cmd"; then which_graphic_lib=X11 test -n "$extralib" && echo ..."Extra Libraries are $extralib" echo ..."Found X11 header files in $Xincroot/X11"; fi @@ -404,8 +409,42 @@ if test "$optimization" != profiling; th *) pth=$dftpth ;; esac -# LIB: gnuplot (not yet supported). -# lib=gnuplot; . ./locatelib +# LIB: gnuplot + lib=gnuplot; . ./locatelib + gnuplot_libs= + case $gnuplot in + /*|[c-z]:/*) + lib=png; . ./locatelib + case $png in + /*|[c-z]:/*) + gnuplot_libs="$gnuplot_libs -lpng" + lib=z; . ./locatelib + case $z in + /*|[c-z]:/*) + gnuplot_libs="$gnuplot_libs -lz";; + esac + ;; + esac + lib=gd; . ./locatelib + case $gd in + /*|[c-z]:/*) gnuplot_libs="$gnuplot_libs -lgd";; + esac + case "$osname" in + os2) + lib=jmgraph; . ./locatelib + lib=vesa; . ./locatelib + case $jmgraph in + /*|[c-z]:/*) + case $vesa in + /*|[c-z]:/*) + gnuplot_libs="$gnuplot_libs -ljmgraph -lvesa";; + esac + ;; + esac + ;; + esac + ;; + esac # LIB: GNU ReadLine pth="$TOP/readline $pth" @@ -520,7 +559,7 @@ EOT if test -n "$readline"; then completionfun="gp-complete2"; fi case $gnuplot in - /*) addgnuplot=gnuplot;; + /*|[c-z]:/*) addgnuplot=gnuplot;; *) addgnuplot=;; esac @@ -600,6 +639,11 @@ EOT esac fi if test "$fastread" = yes -a \ + "$which_graphic_lib" = none -a -z "$graph_cmd" -a ! -z "$gnuplot"; then + which_graphic_lib=gnuplot + fi + + if test "$fastread" = yes -a \ -z "$X11" -a -z "$gnuplot" -a -z "$readline"; then echo ...none fi @@ -1080,7 +1124,7 @@ for variable in \ sizeof_long endian has_exp2\ has_getrusage has_times has_ulong has_ftime has_strftime\ has_sigrelse has_sigsetmask has_dlopen has_TIOCGWINSZ\ - gnuplot extralib X11 Xincroot which_graphic_lib \ + gnuplot extralib X11 Xincroot which_graphic_lib gnuplot_libs \ config_dir src_dir emacs_dir doc_dir \ ; do eval "echo $variable=\'"'$'"$variable\'" \>\> $dflt_conf_file --- ./config/Makefile.SH.orig Wed Sep 9 21:38:02 1998 +++ ./config/Makefile.SH Wed Sep 9 22:44:46 1998 @@ -70,6 +70,17 @@ none) PLOTLIBS= plotrunpath= ;; +gnuplot) + PLOTFILE=plotgnuplot.c + PLOTCFLAGS= + GNUPLOT_OBJS="bitmap.o term.o util.o version.o" + PLOTLIBS="$gnuplot_libs" + plotrunpath= + case "$osname" in + os2) libgnuplot=$gnuplot/gnuplot.a;; + *) libgnuplot=$gnuplot/libgnuplot.a;; + esac + ;; sunview) PLOTFILE=plotsun.c PLOTCFLAGS= @@ -165,6 +176,7 @@ INSTALL_DATA = \$(INSTALL) -m 644 PLOTFILE = $PLOTFILE PLOTCFLAGS = $PLOTCFLAGS PLOTLIBS = $PLOTLIBS +GNUPLOT_OBJS = $GNUPLOT_OBJS # Try uncommenting this line if you're using X11 and linking fails: # PLOTLIBS=-L$X11 -lX11 @@ -217,17 +229,17 @@ EOT fi cat >> $file << EOT -gp-sta: \$(OBJS) \$(OBJSGP) +gp-sta: \$(OBJS) \$(OBJSGP) \$(GNUPLOT_OBJS) \$(RM) \$@ - \$(LD) -o \$@ \$(LDFLAGS) \$(OBJS) \$(OBJSGP) \$(RUNPTH) \$(RLLIBS) \$(PLOTLIBS) \$(LIBS) + \$(LD) -o \$@ \$(LDFLAGS) \$(OBJS) \$(OBJSGP) \$(GNUPLOT_OBJS) \$(RUNPTH) \$(RLLIBS) \$(PLOTLIBS) \$(LIBS) EOT if test -z "$DYNLIBS"; then cat >> $file << EOT -gp-dyn: \$(OBJSGP) libpari.$somake +gp-dyn: \$(OBJSGP) libpari.$somake \$(GNUPLOT_OBJS) \$(RM) \$@ - \$(LD) -o \$@ \$(LDFLAGS) \$(OBJSGP) \$(RUNPTH) \$(TOPLDDYN) \$(LDDYN) \$(PLOTLIBS) \$(LIBS) + \$(LD) -o \$@ \$(LDFLAGS) \$(OBJSGP) \$(GNUPLOT_OBJS) \$(RUNPTH) \$(TOPLDDYN) \$(LDDYN) \$(PLOTLIBS) \$(LIBS) EOT else cat >> $file << EOT @@ -354,6 +366,14 @@ EOT EOT fi fi +fi + +if test -n "$GNUPLOT_OBJS"; then +cat >> $file << EOT +\$(GNUPLOT_OBJS): + ar x $libgnuplot \$(GNUPLOT_OBJS) + +EOT fi if test -n "$emacs"; then --- ./src/graph/Gnuplot.h.pre Sat Apr 11 03:15:10 1998 +++ ./src/graph/Gnuplot.h Sat Apr 11 03:47:18 1998 @@ -0,0 +1,305 @@ +/* This header should be included in one C file only! */ + +#include <stdio.h> +#include <stdlib.h> +#include <setjmp.h> + +#ifdef __cplusplus + extern "C" { +#endif + +/* CAT2: + * This macro catenates 2 tokens together. + */ +/* STRINGIFY: + * This macro surrounds its token with double quotes. + */ +#ifndef CAT2 +# if 42 == 1 +# define CAT2(a,b)a/**/b +# define CAT3(a,b,c)a/**/b/**/c +# define CAT4(a,b,c,d)a/**/b/**/c/**/d +# define CAT5(a,b,c,d,e)a/**/b/**/c/**/d/**/e +# define STRINGIFY(a)"a" + /* If you can get stringification with catify, tell me how! */ +# endif +# if 42 == 42 +# define CAT2(a,b)a ## b +# define CAT3(a,b,c)a ## b ## c +# define CAT4(a,b,c,d)a ## b ## c ## d +# define CAT5(a,b,c,d,e)a ## b ## c ## d ## e +# define StGiFy(a)# a +# define STRINGIFY(a)StGiFy(a) +# define SCAT2(a,b)StGiFy(a) StGiFy(b) +# define SCAT3(a,b,c)StGiFy(a) StGiFy(b) StGiFy(c) +# define SCAT4(a,b,c,d)StGiFy(a) StGiFy(b) StGiFy(c) StGiFy(d) +# define SCAT5(a,b,c,d,e)StGiFy(a) StGiFy(b) StGiFy(c) StGiFy(d) StGiFy(e) +# endif +# ifndef CAT2 +# include "Bletch: How does this C preprocessor catenate tokens?" +# endif +#endif /* CAT2 */ + + +#define TERM_CAN_MULTIPLOT 1 /* tested if stdout not redirected */ +#define TERM_CANNOT_MULTIPLOT 2 /* tested if stdout is redirected */ +#define TERM_BINARY 4 /* open output file with "b" */ + +#ifndef NO_JUNK_SMALL + +extern FILE *outfile; +#ifndef BITS_IN_HALFULONG /* In pari it is already defined. */ +FILE *outfile = stdout; +#endif + +extern int encoding; +int encoding = 0; +extern float xoffset; /* x origin */ +extern float yoffset; /* y origin */ +float xoffset = 0.0; /* x origin */ +float yoffset = 0.0; /* y origin */ +extern int multiplot; +int multiplot = 0; + +extern char *outstr; +#define MAX_ID_LEN 50 +/* char outstr[MAX_ID_LEN+1] = "STDOUT"; */ +char *outstr = NULL; +extern double ticscale; /* scale factor for tic marks (was (0..1])*/ +double ticscale = 1.0; /* scale factor for tic mark */ + +char *input_line = NULL; +int inline_num; /* from command.c */ + +float xsize=1.0, ysize=1.0, pointsize=1.0; /* During test! */ + +int interactive; /* from plot.c */ +char *infile_name; /* from plot.c */ +extern char default_font[]; +char default_font[MAX_ID_LEN+1] = "\0"; /* Entry added by DJL */ + +typedef int TBOOLEAN; + +enum DATA_TYPES { + INTGR, CMPLX +}; + +#if !(defined(ATARI)&&defined(__GNUC__)&&defined(_MATH_H)) && !(defined(MTOS)&&defined(__GNUC__)&&defined(_MATH_H)) /* FF's math.h has the type already */ +struct cmplx { + double real, imag; +}; +#endif + +struct value { + enum DATA_TYPES type; + union { + int int_val; + struct cmplx cmplx_val; + } v; +}; + +struct lexical_unit { /* produced by scanner */ + TBOOLEAN is_token; /* true if token, false if a value */ + struct value l_val; + int start_index; /* index of first char in token */ + int length; /* length of token in chars */ +}; + +/* char *token; */ +#define MAX_TOKENS 20 +extern struct lexical_unit *token; +struct lexical_unit tokens[MAX_TOKENS]; /* We only process options, + there should not be many */ +struct lexical_unit *token = tokens; +long c_token = 0, num_tokens = 0; +char term_options[200] = ""; + +/* Here are the only missing functions: */ + +struct value* +const_express(struct value*v) +{ + if (token[c_token].is_token) + croak("Expect a number, got a string"); + *v = token[c_token++].l_val; + return v; +} + +void* +gp_alloc(unsigned long size, char *usage) +{ + return malloc(size); +} + +void* +gp_realloc(void *old, unsigned long size, char *usage) +{ + return realloc(old,size); +} + +void +bail_to_command_line() +{ + croak("panic: gnuplot"); +} + +#endif + +/* Cannot pull the whole plot.h, too many contradictions. */ + +#ifdef __ZTC__ +typedef int (*FUNC_PTR)(...); +#else +typedef int (*FUNC_PTR)(); +#endif + +struct TERMENTRY { + char *name; +#if defined(_Windows) && !defined(WIN32) + char GPFAR description[80]; /* to make text go in FAR segment */ +#else + char *description; +#endif + unsigned int xmax,ymax,v_char,h_char,v_tic,h_tic; + FUNC_PTR options,init,reset,text,scale,graphics,move,vector,linetype, + put_text,text_angle,justify_text,point,arrow,set_font, + pointsize; + int flags; + FUNC_PTR suspend,resume,fillbox,linewidth; +}; + +#ifdef _Windows +# define termentry TERMENTRY far +#else +# define termentry TERMENTRY +#endif + +extern struct termentry *term; +struct termentry *term; + +#define RETVOID +#define RETINT , 1 + +#define F_0 void(*)() +#define F_1 void(*)(int) +#define F_1I int(*)(int) +#define F_1D void(*)(double) +#define F_1IP int(*)(char*) +#define F_2 void(*)(unsigned int,unsigned int) +#define F_2D int(*)(double,double) +#define F_3 void(*)(unsigned int,unsigned int,int) +#define F_3T void(*)(int,int,char*) +#define F_4 void(*)(int,int,int,int) +#define F_5 void(*)(int,int,int,int,int) + +#define CALL_G_METH0(method) CALL_G_METH(method,0,(),RETVOID) +#define CALL_G_METH1(method,arg1) CALL_G_METH(method,1,(arg1),RETVOID) +#define CALL_G_METH1I(method,arg1) CALL_G_METH(method,1I,(arg1),RETINT) +#define CALL_G_METH1D(method,arg1) CALL_G_METH(method,1D,(arg1),RETVOID) +#define CALL_G_METH1IP(method,arg1) CALL_G_METH(method,1IP,(arg1),RETINT) +#define CALL_G_METH2(method,arg1,arg2) \ + CALL_G_METH(method,2,((arg1),(arg2)),RETVOID) +#define CALL_G_METH2D(method,arg1,arg2) \ + CALL_G_METH(method,2D,((arg1),(arg2)),RETINT) +#define CALL_G_METH3(method,arg1,arg2,arg3) \ + CALL_G_METH(method,3,((arg1),(arg2),(arg3)),RETVOID) +#define CALL_G_METH3T(method,arg1,arg2,arg3) \ + CALL_G_METH(method,3T,((arg1),(arg2),(arg3)),RETVOID) +#define CALL_G_METH4(method,arg1,arg2,arg3,arg4) \ + CALL_G_METH(method,4,((arg1),(arg2),(arg3),(arg4)),RETVOID) +#define CALL_G_METH5(method,arg1,arg2,arg3,arg4,arg5) \ + CALL_G_METH(method,5,((arg1),(arg2),(arg3),(arg4),(arg5)),RETVOID) + +#define CALL_G_METH(method,mult,args,returnval) ( \ + (term==0) ? ( \ + croak("No terminal specified") returnval \ + ) : \ + (*(CAT2(F_,mult))term->method)args \ + ) + +#define GET_G_FLAG(mask) ( \ + (term==0) ? ( \ + croak("No terminal specified") RETINT \ + ) : \ + (term->flags & (mask))) + +#define do_init() CALL_G_METH0(init) +#define reset() CALL_G_METH0(reset) +#define text() CALL_G_METH0(text) +#define options() CALL_G_METH0(options) +#define graphics() CALL_G_METH0(graphics) +#define linetype(lt) CALL_G_METH1(linetype,lt) +#define justify_text(mode) CALL_G_METH1I(justify_text,mode) +#define text_angle(ang) CALL_G_METH1I(text_angle,ang) +#define scale(xs,ys) CALL_G_METH2D(scale,xs,ys) +#define move(x,y) CALL_G_METH2(move,x,y) +#define vector(x,y) CALL_G_METH2(vector,x,y) +#define put_text(x,y,str) CALL_G_METH3T(put_text,x,y,str) +#define point(x,y,p) CALL_G_METH3(point,x,y,p) +#define arrow(sx,sy,ex,ey,head) CALL_G_METH5(arrow,sx,sy,ex,ey,head) +#define set_font(font) CALL_G_METH1IP(set_font,font) +#define pointsize(size) CALL_G_METH1D(pointsize,size) +#define suspend() CALL_G_METH0(suspend) +#define resume() CALL_G_METH0(resume) +#define fillbox(sx,sy,ex,ey,head) CALL_G_METH5(fillbox,sx,sy,ex,ey,head) +#define linewidth(size) CALL_G_METH1D(linewidth,size) +#define can_multiplot() GET_G_FLAG(TERM_CAN_MULTIPLOT) +#define cannot_multiplot() GET_G_FLAG(TERM_CANNOT_MULTIPLOT) +#define is_binary() GET_G_FLAG(TERM_BINARY) + +#define termprop(prop) (term->prop) +#define termset(term) my_change_term(term,strlen(term)) +struct termentry * change_term(char*,int); + +#ifdef DYNAMIC_PLOTTING /* Can load plotting DLL later */ + +UNKNOWN_null() +{ + err(talker,"gnuplot-like plotting environment not loaded yet"); +} + +static FUNC_PTR change_term_p; + +struct termentry * +my_change_term(char*s,int l) +{ + if (!change_term_p) + UNKNOWN_null(); + return term = (struct termentry *)(*change_term_p)(s,l); +} + +# define change_term(p,l) my_change_term(p,l) +# define term_tbl (my_term_tbl) + +static struct termentry dummy_term_tbl[] = { + {"unknown", "Unknown terminal type - not a plotting device", + 100, 100, 1, 1, + 1, 1, UNKNOWN_null, UNKNOWN_null, UNKNOWN_null, + UNKNOWN_null, UNKNOWN_null, UNKNOWN_null, UNKNOWN_null, UNKNOWN_null, + UNKNOWN_null, UNKNOWN_null, UNKNOWN_null, + UNKNOWN_null, UNKNOWN_null, UNKNOWN_null, UNKNOWN_null, UNKNOWN_null, 0, + , UNKNOWN_null, UNKNOWN_null, UNKNOWN_null, UNKNOWN_null}, +}; +static struct termentry *my_term_tbl = dummy_term_tbl; + +/* This function should be called before any graphic code can be used... */ +set_term_funcp(FUNC_PTR change_p, struct termentry *term_p) +{ + my_term_tbl = term_p; + change_term_p = change_p; +} + +#else /* !DYNAMIC_PLOTTING */ + +extern struct termentry term_tbl[]; + +# define my_change_term change_term +# define my_term_tbl term_tbl + +#endif /* DYNAMIC_PLOTTING */ + + + +#ifdef __cplusplus + } +#endif --- ./src/graph/plotgnuplot.c.pree Sat Feb 7 11:12:06 1998 +++ ./src/graph/plotgnuplot.c Sat Apr 11 03:47:48 1998 @@ -119,20 +119,23 @@ rectdraw0(long *w, long *x, long *y, lon void PARI_get_plot() { - if (pari_plot.init) return; - term_set(DEF_TERM); + if (pari_plot.init) { + return; + } + term_set( DEF_TERM ); } + long term_set(char *s) { - if (!s) return 1; if (strlen(s) > PLOT_NAME_LEN) err(talker,"too long name for terminal"); - if (*pari_plot.name && (strcmp(pari_plot.name,s) != 0)) reset(); - + if (*pari_plot.name && (strcmp(pari_plot.name,s) != 0)) { + reset(); + } strcpy(pari_plot.name,s); - if (termset(s) <= 0) err(talker,"unknown terminal name"); - init(); /* Init terminal. */ + if (!termset( s )) err(talker,"unknown terminal name"); + do_init(); /* Init terminal. */ w_width = termprop(xmax); w_height = termprop(ymax);