Ilya Zakharevich on Mon, 7 Jun 1999 02:43:08 -0400 (EDT) |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
[PATCH 2.0.15] Newer gnuplot plotting |
This more or less finishes (again? ;-) support for gnuplot terminals as output for the graphic. a) Strings were put too low in gnuplot terminal; b) Allow setting of the output file sizes, as in plotterm("gif=300,200"); c) Allow querying of possible output terminals, via plotterm("?"). d) Update to newer Gnuplot-interface-layer (Gnuplot.h). This allows compilation on Linux (stdout was bad as an initializer), corrects bugs in processing of terminal options. Enjoy, Ilya diff -pru pari-2.0.15.beta.old/src/graph/Gnuplot.h pari-2.0.15.beta/src/graph/Gnuplot.h --- pari-2.0.15.beta.old/src/graph/Gnuplot.h Thu May 20 09:02:46 1999 +++ pari-2.0.15.beta/src/graph/Gnuplot.h Mon Jun 7 01:54:42 1999 @@ -49,10 +49,20 @@ /* Compatibility with the old gnuplot: */ extern FILE *outfile; -FILE *outfile = stdout; +FILE *outfile = NULL; extern FILE *gpoutfile; -FILE *gpoutfile = stdout; +FILE *gpoutfile = NULL; + +static outfile_set; +static void +set_gpoutfile(void) +{ + outfile = stdout; + gpoutfile = stdout; +} + +#define SET_OUTFILE (outfile_set++ ? 1 : set_gpoutfile(), 1) extern int encoding; int encoding = 0; @@ -226,9 +236,14 @@ struct termentry *term; ) : \ (term->flags & (mask))) -#define do_init() CALL_G_METH0(init) -#define reset() CALL_G_METH0(reset) -#define text() CALL_G_METH0(text) +#ifdef DONT_POLLUTE_INIT +# define gptable_init() CALL_G_METH0(init) +#else +# define init() CALL_G_METH0(init) +# define gptable_init init +#endif +#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) @@ -252,28 +267,127 @@ struct termentry *term; #define termprop(prop) (term->prop) #define termset(term) my_change_term(term,strlen(term)) + struct termentry * change_term(char*,int); +#define TTABLE_STARTPLOT 0 +#define TTABLE_ENDPLOT 1 +#define TTABLE_STARTMPLOT 2 +#define TTABLE_ENDMPLOT 3 +#define TTABLE_INIT 4 +#define TTABLE_LIST 5 +#define TTABLE_COUNT 6 + +typedef void (*TSET_FP)(char *s); +typedef void (*TST_END_FP)(void); +typedef void (*SET_SIZES_t)(double x, double y); +typedef double (*GET_SIZES_t)(int flag); + +struct t_ftable { + int loaded; + FUNC_PTR change_term_p; + TSET_FP term_set_outputp; + SET_SIZES_t set_sizesp; + GET_SIZES_t get_sizesp; + TST_END_FP term_funcs[TTABLE_COUNT]; +}; + #ifdef DYNAMIC_PLOTTING /* Can load plotting DLL later */ UNKNOWN_null() { - err(talker,"gnuplot-like plotting environment not loaded yet"); + croak("gnuplot-like plotting environment not loaded yet"); +} + +static void myterm_table_not_loaded_v(void); +static void myterm_table_not_loaded(char*); +static int myterm_table_not_loaded_u(); +static void myterm_table_not_loaded_vdd(double x, double y); +static double myterm_table_not_loaded_di(int flag); + +#if 0 +static int ftable_warned; +static void +tmp_my_term_init +{ + if (!warned++) + warn("This runtime link with gnuplot-shim does not implement midlevel start/end functions"); + shim_myinit(); +} +#endif + +static struct t_ftable my_term_ftable = +{ + 0, &myterm_table_not_loaded_u, &myterm_table_not_loaded, + &myterm_table_not_loaded_vdd, + &myterm_table_not_loaded_di, + {&myterm_table_not_loaded_v, &myterm_table_not_loaded_v, + &myterm_table_not_loaded_v, &myterm_table_not_loaded_v, + &myterm_table_not_loaded_v, &myterm_table_not_loaded_v} +}; + +static struct t_ftable *my_term_ftablep = &my_term_ftable; + +static void +myterm_table_not_loaded_v(void) +{ + if (!my_term_ftablep->loaded) { + UNKNOWN_null(); + return; + } + croak("This runtime link with gnuplot-shim does not implement midlevel start/end functions"); +} + +static void +myterm_table_not_loaded(char *s) +{ + myterm_table_not_loaded_v(); +} + +static void +myterm_table_not_loaded_vdd(double x, double y) +{ + myterm_table_not_loaded_v(); +} + +static double +myterm_table_not_loaded_di(int flag) +{ + myterm_table_not_loaded_v(); +} + +static int +myterm_table_not_loaded_u() +{ + myterm_table_not_loaded_v(); + return 0; } -static FUNC_PTR change_term_p; +# define change_term (*my_term_ftablep->change_term_p) +# define term_set_output (*my_term_ftablep->term_set_outputp) +# define term_start_plot (*my_term_ftablep->term_funcs[TTABLE_STARTPLOT]) +# define term_end_plot (*my_term_ftablep->term_funcs[TTABLE_ENDPLOT]) +# define term_start_multiplot (*my_term_ftablep->term_funcs[TTABLE_STARTMPLOT]) +# define term_end_multiplot (*my_term_ftablep->term_funcs[TTABLE_ENDMPLOT]) +# define term_init (*my_term_ftablep->term_funcs[TTABLE_INIT]) +# define list_terms (*my_term_ftablep->term_funcs[TTABLE_LIST]) +# define plotsizes_scale (*my_term_ftablep->set_sizesp) +# define plotsizes_scale_get (*my_term_ftablep->get_sizesp) + +# define scaled_xmax() ((int)termprop(xmax)*plotsizes_scale_get(0)) +# define scaled_ymax() ((int)termprop(ymax)*plotsizes_scale_get(1)) + +#define USE_FUNCTION_FROM_TABLE -struct termentry * +static struct termentry * my_change_term(char*s,int l) { - if (!change_term_p) + SET_OUTFILE; + if (!my_term_ftablep->change_term_p) UNKNOWN_null(); - return term = (struct termentry *)(*change_term_p)(s,l); + return term = (struct termentry *)(*my_term_ftablep->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, @@ -283,45 +397,94 @@ static struct termentry dummy_term_tbl[] 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; -# define term_set_output (*term_set_outputp) -static void -myterm_set_output(char *s) +#define set_term_funcp(change_p, term_p) set_term_funcp2((change_p), 0) +/* #define set_term_funcp3(change_p, term_p, tchange) \ + set_term_funcp2((change_p), (tchange)) */ + +/* This function should be called before any graphic code can be used... */ +void +set_term_funcp2(FUNC_PTR change_p, TSET_FP tchange) { - croak("Change terminal not implemented yet with dynamic gnuplot"); + SET_OUTFILE; + my_term_ftable.change_term_p = change_p; + my_term_ftable.loaded = 1; + if (tchange) { + my_term_ftable.term_set_outputp = tchange; + } } -typedef void (*TSET_FP)(char *s); -TSET_FP term_set_outputp = &myterm_set_output; +/* Used from Math::Pari */ +void +set_term_funcp3(FUNC_PTR change_p, void *term_p, TSET_FP tchange) +{ + set_term_funcp2(change_p, tchange); +} -/* This function should be called before any graphic code can be used... */ -set_term_funcp(FUNC_PTR change_p, struct termentry *term_p) +void +set_term_ftable(struct t_ftable *p) { - my_term_tbl = term_p; - change_term_p = change_p; - /* XXXX Need to set term_set_outputp as well */ + SET_OUTFILE; + my_term_ftablep = p; } -/* This function should be called before any graphic code can be used... */ -set_term_funcp3(FUNC_PTR change_p, struct termentry *term_p, TSET_FP tchange) +#else /* !DYNAMIC_PLOTTING */ + +extern struct termentry term_tbl[]; + +# define my_change_term change_term +# define my_term_tbl term_tbl + +extern void term_set_output(char *s); +extern void term_start_plot(void); +extern void term_end_plot(void); +extern void term_start_multiplot(void); +extern void term_end_multiplot(void); +extern void term_init(void); +extern void list_terms(void); + +static void +plotsizes_scale(double x, double y) { xsize=x; ysize=y; } + +static double +plotsizes_get(int flag) { return (flag ? ysize : xsize); } + +struct t_ftable my_term_ftable = +{ + 1, (FUNC_PTR)&change_term, &term_set_output, + &plotsizes_scale, &plotsizes_get, + {&term_start_plot, &term_end_plot, + &term_start_multiplot, &term_end_multiplot, &term_init, &list_terms} +}; + +struct t_ftable *get_term_ftable() { SET_OUTFILE; return &my_term_ftable; } +void set_term_ftable() { SET_OUTFILE; } + + +void +set_term_funcp3(FUNC_PTR change_p, void *term_p, TSET_FP tchange) { - my_term_tbl = term_p; - change_term_p = change_p; + SET_OUTFILE; + my_term_ftable.change_term_p = change_p; + my_term_ftable.loaded = 1; if (tchange) { - term_set_outputp = tchange; + my_term_ftable.term_set_outputp = tchange; } - /* XXXX Need to set term_set_outputp as well */ } -#else /* !DYNAMIC_PLOTTING */ +#define scaled_xmax() ((int)termprop(xmax)*xsize) +#define scaled_ymax() ((int)termprop(ymax)*ysize) -extern struct termentry term_tbl[]; +#endif /* !DYNAMIC_PLOTTING */ + +#define int_get_term_ftable() ((IV)get_term_ftable()) +#define int_set_term_ftable(a) (v_set_term_ftable((void*)a)) -# define my_change_term change_term -# define my_term_tbl term_tbl +void +v_set_term_ftable(void *a) { set_term_ftable((struct t_ftable*)a); } -#endif /* DYNAMIC_PLOTTING */ +void +setup_gpshim(void) { SET_OUTFILE; } #ifdef SET_OPTIONS_FROM_STRING /* This sets the tokens for the options */ @@ -339,6 +502,11 @@ set_tokens_string(char *start) if (!*s) return; tstart = s; + if (*s == ',') { + s++; + is_integer = is_real = 0; + goto process; + } is_integer = is_real = ((*s) != 0); if (*s == '+' || *s == '-') s++; @@ -350,19 +518,24 @@ set_tokens_string(char *start) is_real = 0; else if (is_integer == 1 && !(s[1] <= '9' && s[1] >= '0')) is_real = 0; - } else if (*s != 'e' || *s == 'E') { + } else if (*s == 'e' || *s == 'E') { if (has_exp) is_real = 0; has_exp = 1; if (s[1] == '+' || s[1] == '-') s++; - } else + } else if (*s == ',' && (is_integer || is_real)) + break; + else is_real = 0; is_integer = 0; } else if (is_integer) is_integer++; s++; } + process: + token[num_tokens].start_index = tstart - input_line; + token[num_tokens].length = s - tstart; if (is_integer) { token[num_tokens].is_token = 0; token[num_tokens].l_val.type = INTGR; @@ -374,8 +547,6 @@ set_tokens_string(char *start) token[num_tokens].l_val.v.cmplx_val.imag = 0; } else { token[num_tokens].is_token = 1; - token[num_tokens].start_index = tstart - input_line; - token[num_tokens].length = s - tstart; } num_tokens++; } @@ -389,8 +560,12 @@ set_tokens_string(char *start) void set_options_from(char *s) { + char *o = input_line; + + input_line = s; /* for error reports */ set_tokens_string(s); options(); + input_line = o; c_token = num_tokens = 0; } #endif diff -pru pari-2.0.15.beta.old/src/graph/plotgnuplot.c pari-2.0.15.beta/src/graph/plotgnuplot.c --- pari-2.0.15.beta.old/src/graph/plotgnuplot.c Mon Jun 7 02:27:33 1999 +++ pari-2.0.15.beta/src/graph/plotgnuplot.c Mon Jun 7 01:55:16 1999 @@ -14,6 +14,7 @@ #define croak(str) err(talker,str) #define SET_OPTIONS_FROM_STRING #define GNUPLOT_OUTLINE_STDOUT +#define DONT_POLLUTE_INIT #include "Gnuplot.h" #ifdef __EMX__ @@ -34,7 +35,11 @@ rectdraw0(long *w, long *x, long *y, lon PARI_get_plot(0); +#if 0 graphics(); /* Switch on terminal. */ +#else + term_start_plot(); /* Switch on terminal. */ +#endif linetype(line_type); /* X does not work otherwise. */ setpointsize(pointsize); for(i=0;i<lw;i++) @@ -100,7 +105,9 @@ rectdraw0(long *w, long *x, long *y, lon if (RoSTx(p1)+x0 < 0 || RoSTx(p1)+x0+RoSTl(p1)-1 >= w_width || RoSTy(p1) + y0 < 0 || RoSTy(p1) + y0 >= w_height) { } else { - put_text(RoSTx(p1)+x0, w_height - 1 - RoSTy(p1) - y0, RoSTs(p1)); + put_text(RoSTx(p1)+x0, + w_height - 1 - RoSTy(p1) - y0 + (f_height - 1)/2, + RoSTs(p1)); } break; case ROt_PTT: @@ -118,7 +125,11 @@ rectdraw0(long *w, long *x, long *y, lon p1=RoNext(p1); } } +#if 0 text(); /* Reset terminal */ +#else + term_end_plot(); /* Reset terminal. */ +#endif } void @@ -127,6 +138,7 @@ PARI_get_plot(long fatal) if (pari_plot.init) { return; } + setup_gpshim(); term_set( DEF_TERM ); } @@ -134,12 +146,17 @@ PARI_get_plot(long fatal) long term_set(char *s) { - char *t; + char *t, *size = NULL; + double x, y; if (*s == 0) s = pari_plot.name; t = s; - while (*t && !(*t == ' ' || *t == '\t' || *s == '\t')) + if (t[1] == '\0' && t[0] == '?') { + list_terms(); + return 1; + } + while (*t && !(*t == ' ' || *t == '\t' || *t == '\n' || *t == '=')) t++; if ((t-s) > PLOT_NAME_LEN) err(talker,"too long name \"%s\"for terminal", s); @@ -149,17 +166,39 @@ term_set(char *s) reset(); strncpy(pari_plot.name,s,t-s); pari_plot.name[t-s] = '\0'; + if (!termset( pari_plot.name )) err(talker,"error setting terminal \"%s\"", pari_plot.name); + if (*t == '=') { + size = ++t; + x = atof(size); + while (*t && !(*t == ' ' || *t == '\t' || *t == '\n' || *t == ',')) + t++; + if (*t != ',') + err(talker, "Terminal size directive without ','"); + y = atof(++t); + while (*t && !(*t == ' ' || *t == '\t' || *t == '\n')) + t++; + plotsizes_scale(x*(1 + 1e-6)/termprop(xmax), + y*(1 + 1e-6)/termprop(ymax)); /* Later - truncated! */ + } else { + plotsizes_scale(1,1); + } + /* *Needed*, say, by gif output: */ set_options_from(t); - do_init(); /* Init terminal. */ +#if 0 + gptable_init(); /* Init terminal. */ +#else + term_init(); +#endif + setpointsize(pointsize); - w_width = termprop(xmax); - w_height = termprop(ymax); + w_width = scaled_xmax(); + w_height = scaled_ymax(); f_height = termprop(v_char); f_width = termprop(h_char); h_unit = termprop(h_tic); @@ -173,6 +212,7 @@ long plot_outfile_set(char *s) { int normal = (strcmp(s,"-") == 0); + setup_gpshim(); /* Delegate all the hard work to term_set_output() */ if (normal)