#ifndef lint
static char *RCSid() { return RCSid("$Id: save.c,v 1.11.2.6 2000/10/31 14:48:19 joze Exp $"); }
#endif
/* GNUPLOT - save.c */
/*[
* Copyright 1986 - 1993, 1998 Thomas Williams, Colin Kelley
*
* Permission to use, copy, and distribute this software and its
* documentation for any purpose with or without fee is hereby granted,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation.
*
* Permission to modify the software is granted, but not the right to
* distribute the complete modified source code. Modifications are to
* be distributed as patches to the released version. Permission to
* distribute binaries produced by compiling modified sources is granted,
* provided you
* 1. distribute the corresponding source modifications from the
* released version in the form of a patch file along with the binaries,
* 2. add special version identification to distinguish your version
* in addition to the base release version number,
* 3. provide your name and address as the primary contact for the
* support of your modified version, and
* 4. retain our contact information in regard to use of the base
* software.
* Permission to distribute the released version of the source code along
* with corresponding source modifications in the form of a patch file is
* granted with same provisions 2 through 4 for binary distributions.
*
* This software is provided "as is" without express or implied warranty
* to the extent permitted by applicable law.
]*/
#include "save.h"
#include "command.h"
#include "eval.h"
#include "fit.h"
#include "gp_time.h"
#include "hidden3d.h"
#include "setshow.h"
#include "util.h"
/* HBB 990825 FIXME: how come these strings are only used for
* _displaying_ encodings (-->no use in set.c) ? */
const char *encoding_names[] = {
"default", "iso_8859_1", "cp437", "cp850", NULL };
static void save_functions__sub __PROTO((FILE *));
static void save_variables__sub __PROTO((FILE *));
static void save_tics __PROTO((FILE *, int, int, struct ticdef *, TBOOLEAN, const char *));
static void save_position __PROTO((FILE *, struct position *));
static void save_range __PROTO((FILE *, int, double, double, TBOOLEAN, const char *));
static void save_set_all __PROTO((FILE *));
#define SAVE_NUM_OR_TIME(fp, x, axis) \
do{if (datatype[axis]==TIME) { \
char s[80]; char *p; \
putc('"', fp); \
gstrftime(s,80,timefmt,(double)(x)); \
for(p=s; *p; ++p) {\
if ( *p == '\t' ) fputs("\\t",fp);\
else if (*p == '\n') fputs("\\n",fp); \
else if ( *p > 126 || *p < 32 ) fprintf(fp,"\\%03o",*p);\
else putc(*p, fp);\
}\
putc('"', fp);\
} else {\
fprintf(fp,"%#g",x);\
}} while(0)
/*
* functions corresponding to the arguments of the GNUPLOT `save` command
*/
void
save_functions(fp)
FILE *fp;
{
if (fp) {
show_version(fp); /* I _love_ information written */
save_functions__sub(fp); /* at the top and the end of an */
fputs("# EOF\n", fp); /* human readable ASCII file. */
if (stdout != fp)
(void) fclose(fp); /* (JFi) */
} else
os_error(c_token, "Cannot open save file");
}
void
save_variables(fp)
FILE *fp;
{
if (fp) {
show_version(fp);
save_variables__sub(fp);
fputs("# EOF\n", fp);
if (stdout != fp)
(void) fclose(fp); /* (JFi) */
} else
os_error(c_token, "Cannot open save file");
}
void
save_set(fp)
FILE *fp;
{
if (fp) {
show_version(fp);
save_set_all(fp);
fputs("# EOF\n", fp);
if (stdout != fp)
(void) fclose(fp); /* (JFi) */
} else
os_error(c_token, "Cannot open save file");
}
void
save_all(fp)
FILE *fp;
{
if (fp) {
show_version(fp);
save_set_all(fp);
save_functions__sub(fp);
save_variables__sub(fp);
fprintf(fp, "%s\n", replot_line);
if (wri_to_fil_last_fit_cmd(NULL)) {
fputs("## ", fp);
wri_to_fil_last_fit_cmd(fp);
putc('\n', fp);
}
fputs("# EOF\n", fp);
if (stdout != fp)
(void) fclose(fp); /* (JFi) */
} else
os_error(c_token, "Cannot open save file");
}
/*
* auxiliary functions
*/
static void
save_functions__sub(fp)
FILE *fp;
{
register struct udft_entry *udf = first_udf;
while (udf) {
if (udf->definition) {
fprintf(fp, "%s\n", udf->definition);
}
udf = udf->next_udf;
}
}
static void
save_variables__sub(fp)
FILE *fp;
{
/* always skip pi */
register struct udvt_entry *udv = first_udv->next_udv;
while (udv) {
if (!udv->udv_undef) {
fprintf(fp, "%s = ", udv->udv_name);
disp_value(fp, &(udv->udv_value));
(void) putc('\n', fp);
}
udv = udv->next_udv;
}
}
/* HBB 19990823: new function 'save term'. This will be mainly useful
* for the typical 'set term post ... plot ... set term
* sequence. It's the only 'save' function that will write the
* current term setting to a file uncommentedly. */
void
save_term(fp)
FILE *fp;
{
if (fp) {
show_version(fp);
/* A possible gotcha: the default initialization often doesn't set
* term_options, but a 'set term ' without options doesn't
* reset the options to startup defaults. This may have to be
* changed on a per-terminal driver basis... */
if (term)
fprintf(fp, "set terminal %s %s\n", term->name, term_options);
else
fputs("set terminal unknown\n", fp);
/* output will still be written in commented form. Otherwise, the
* risk of overwriting files is just too high */
if (outstr)
fprintf(fp, "# set output '%s'\n", outstr);
else
fputs("# set output\n", fp);
fputs("# EOF\n", fp);
if (stdout != fp)
(void) fclose(fp); /* (JFi) */
} else
os_error(c_token, "Cannot open save file");
}
static void
save_set_all(fp)
FILE *fp;
{
struct text_label *this_label;
struct arrow_def *this_arrow;
struct linestyle_def *this_linestyle;
/* opinions are split as to whether we save term and outfile
* as a compromise, we output them as comments !
*/
if (term)
fprintf(fp, "# set terminal %s %s\n", term->name, term_options);
else
fputs("# set terminal unknown\n", fp);
if (outstr)
fprintf(fp, "# set output '%s'\n", outstr);
else
fputs("# set output\n", fp);
fprintf(fp, "\
%sset clip points\n\
%sset clip one\n\
%sset clip two\n\
set bar %f\n",
(clip_points) ? "" : "un",
(clip_lines1) ? "" : "un",
(clip_lines2) ? "" : "un",
bar_size);
if (draw_border)
/* HBB 980609: handle border linestyle, too */
fprintf(fp, "set border %d lt %d lw %.3f\n",
draw_border, border_lp.l_type + 1, border_lp.l_width);
else
fputs("unset border\n", fp);
fprintf(fp, "\
set xdata%s\n\
set ydata%s\n\
set zdata%s\n\
set x2data%s\n\
set y2data%s\n",
datatype[FIRST_X_AXIS] == TIME ? " time" : "",
datatype[FIRST_Y_AXIS] == TIME ? " time" : "",
datatype[FIRST_Z_AXIS] == TIME ? " time" : "",
datatype[SECOND_X_AXIS] == TIME ? " time" : "",
datatype[SECOND_Y_AXIS] == TIME ? " time" : "");
if (boxwidth < 0.0)
fputs("set boxwidth\n", fp);
else
fprintf(fp, "set boxwidth %g\n", boxwidth);
if (dgrid3d)
fprintf(fp, "set dgrid3d %d,%d, %d\n",
dgrid3d_row_fineness,
dgrid3d_col_fineness,
dgrid3d_norm_value);
fprintf(fp, "set dummy %s,%s\n", dummy_var[0], dummy_var[1]);
fprintf(fp, "set format x \"%s\"\n", conv_text(xformat));
fprintf(fp, "set format y \"%s\"\n", conv_text(yformat));
fprintf(fp, "set format x2 \"%s\"\n", conv_text(x2format));
fprintf(fp, "set format y2 \"%s\"\n", conv_text(y2format));
fprintf(fp, "set format z \"%s\"\n", conv_text(zformat));
fprintf(fp, "set angles %s\n",
(angles_format == ANGLES_RADIANS) ? "radians" : "degrees");
if (work_grid.l_type == 0)
fputs("unset grid\n", fp);
else {
/* FIXME */
if (polar_grid_angle) /* set angle already output */
fprintf(fp, "set grid polar %f\n", polar_grid_angle / ang2rad);
else
fputs("unset grid polar\n", fp);
fprintf(fp,
"set grid %sxtics %sytics %sztics %sx2tics %sy2tics %smxtics %smytics %smztics %smx2tics %smy2tics lt %d lw %.3f, lt %d lw %.3f\n",
work_grid.l_type & GRID_X ? "" : "no",
work_grid.l_type & GRID_Y ? "" : "no",
work_grid.l_type & GRID_Z ? "" : "no",
work_grid.l_type & GRID_X2 ? "" : "no",
work_grid.l_type & GRID_Y2 ? "" : "no",
work_grid.l_type & GRID_MX ? "" : "no",
work_grid.l_type & GRID_MY ? "" : "no",
work_grid.l_type & GRID_MZ ? "" : "no",
work_grid.l_type & GRID_MX2 ? "" : "no",
work_grid.l_type & GRID_MY2 ? "" : "no",
grid_lp.l_type + 1, grid_lp.l_width,
mgrid_lp.l_type + 1, mgrid_lp.l_width);
}
fprintf(fp, "set key title \"%s\"\n", conv_text(key_title));
switch (key) {
case -1:{
fputs("set key", fp);
switch (key_hpos) {
case TRIGHT:
fputs(" right", fp);
break;
case TLEFT:
fputs(" left", fp);
break;
case TOUT:
fputs(" out", fp);
break;
}
switch (key_vpos) {
case TTOP:
fputs(" top", fp);
break;
case TBOTTOM:
fputs(" bottom", fp);
break;
case TUNDER:
fputs(" below", fp);
break;
}
break;
}
case 0:
fputs("unset key\n", fp);
break;
case 1:
fputs("set key ", fp);
save_position(fp, &key_user_pos);
break;
}
if (key) {
fprintf(fp, " %s %sreverse box linetype %d linewidth %.3f samplen %g spacing %g width %g\n",
key_just == JLEFT ? "Left" : "Right",
key_reverse ? "" : "no",
key_box.l_type + 1, key_box.l_width, key_swidth, key_vert_factor, key_width_fix);
}
fputs("unset label\n", fp);
for (this_label = first_label; this_label != NULL;
this_label = this_label->next) {
fprintf(fp, "set label %d \"%s\" at ",
this_label->tag,
conv_text(this_label->text));
save_position(fp, &this_label->place);
switch (this_label->pos) {
case LEFT:
fputs(" left", fp);
break;
case CENTRE:
fputs(" centre", fp);
break;
case RIGHT:
fputs(" right", fp);
break;
}
fprintf(fp, " %srotate", this_label->rotate ? "" : "no");
if (this_label->font != NULL)
fprintf(fp, " font \"%s\"", this_label->font);
if (-1 == this_label->pointstyle)
fprintf(fp, " nopointstyle");
else {
fprintf(fp, " pointstyle %d offset %f,%f",
this_label->pointstyle, this_label->hoffset, this_label->voffset);
}
/* Entry font added by DJL */
fputc('\n', fp);
}
fputs("unset arrow\n", fp);
for (this_arrow = first_arrow; this_arrow != NULL;
this_arrow = this_arrow->next) {
fprintf(fp, "set arrow %d from ", this_arrow->tag);
save_position(fp, &this_arrow->start);
fputs(this_arrow->relative ? " rto " : " to ", fp);
save_position(fp, &this_arrow->end);
fprintf(fp, " %s linetype %d linewidth %.3f\n",
this_arrow->head ? "" : " nohead",
this_arrow->lp_properties.l_type + 1,
this_arrow->lp_properties.l_width);
}
fputs("unset style line\n", fp);
for (this_linestyle = first_linestyle; this_linestyle != NULL;
this_linestyle = this_linestyle->next) {
fprintf(fp, "set style line %d ", this_linestyle->tag);
#ifdef PM3D
if (this_linestyle->lp_properties.use_palette)
fprintf(fp, "linetype palette ");
else
#endif
fprintf(fp, "linetype %d ", this_linestyle->lp_properties.l_type + 1);
fprintf(fp, "linewidth %.3f pointtype %d pointsize %.3f\n",
this_linestyle->lp_properties.l_width,
this_linestyle->lp_properties.p_type + 1,
this_linestyle->lp_properties.p_size);
}
fputs("unset logscale\n", fp);
if (is_log_x)
fprintf(fp, "set logscale x %g\n", base_log_x);
if (is_log_y)
fprintf(fp, "set logscale y %g\n", base_log_y);
if (is_log_z)
fprintf(fp, "set logscale z %g\n", base_log_z);
if (is_log_x2)
fprintf(fp, "set logscale x2 %g\n", base_log_x2);
if (is_log_y2)
fprintf(fp, "set logscale y2 %g\n", base_log_y2);
/* FIXME */
fprintf(fp, "\
set offsets %g, %g, %g, %g\n\
set pointsize %g\n\
set encoding %s\n\
%sset polar\n\
%sset parametric\n",
loff, roff, toff, boff,
pointsize,
encoding_names[encoding],
(polar) ? "" : "un",
(parametric) ? "" : "un");
fprintf(fp, "\
set view %g, %g, %g, %g\n\
set samples %d, %d\n\
set isosamples %d, %d\n\
%sset surface\n\
%sset contour",
surface_rot_x, surface_rot_z, surface_scale, surface_zscale,
samples_1, samples_2,
iso_samples_1, iso_samples_2,
(draw_surface) ? "" : "un",
(draw_contour) ? "" : "un");
switch (draw_contour) {
case CONTOUR_NONE:
fputc('\n', fp);
break;
case CONTOUR_BASE:
fputs(" base\n", fp);
break;
case CONTOUR_SRF:
fputs(" surface\n", fp);
break;
case CONTOUR_BOTH:
fputs(" both\n", fp);
break;
}
if (label_contours)
fprintf(fp, "set clabel '%s'\n", contour_format);
else
fputs("unset clabel\n", fp);
fputs("set mapping ", fp);
switch (mapping3d) {
case MAP3D_SPHERICAL:
fputs("spherical\n", fp);
break;
case MAP3D_CYLINDRICAL:
fputs("cylindrical\n", fp);
break;
case MAP3D_CARTESIAN:
default:
fputs("cartesian\n", fp);
break;
}
if (missing_val != NULL)
fprintf(fp, "set missing %s\n", missing_val);
save_hidden3doptions(fp);
fprintf(fp, "set cntrparam order %d\n", contour_order);
fputs("set cntrparam ", fp);
switch (contour_kind) {
case CONTOUR_KIND_LINEAR:
fputs("linear\n", fp);
break;
case CONTOUR_KIND_CUBIC_SPL:
fputs("cubicspline\n", fp);
break;
case CONTOUR_KIND_BSPLINE:
fputs("bspline\n", fp);
break;
}
fputs("set cntrparam levels ", fp);
switch (levels_kind) {
case LEVELS_AUTO:
fprintf(fp, "auto %d\n", contour_levels);
break;
case LEVELS_INCREMENTAL:
fprintf(fp, "incremental %g,%g,%g\n",
levels_list[0], levels_list[1],
levels_list[0] + levels_list[1] * contour_levels);
break;
case LEVELS_DISCRETE:
{
int i;
fprintf(fp, "discrete %g", levels_list[0]);
for (i = 1; i < contour_levels; i++)
fprintf(fp, ",%g ", levels_list[i]);
fputc('\n', fp);
}
}
fprintf(fp, "\
set cntrparam points %d\n\
set size ratio %g %g,%g\n\
set origin %g,%g\n\
set style data ",
contour_pts,
aspect_ratio, xsize, ysize,
xoffset, yoffset);
switch (data_style) {
case LINES:
fputs("lines\n", fp);
break;
case POINTSTYLE:
fputs("points\n", fp);
break;
case IMPULSES:
fputs("impulses\n", fp);
break;
case LINESPOINTS:
fputs("linespoints\n", fp);
break;
case DOTS:
fputs("dots\n", fp);
break;
case YERRORLINES:
fputs("yerrorlines\n", fp);
break;
case XERRORLINES:
fputs("xerrorlines\n", fp);
break;
case XYERRORLINES:
fputs("xyerrorlines\n", fp);
break;
case YERRORBARS:
fputs("yerrorbars\n", fp);
break;
case XERRORBARS:
fputs("xerrorbars\n", fp);
break;
case XYERRORBARS:
fputs("xyerrorbars\n", fp);
break;
case BOXES:
fputs("boxes\n", fp);
break;
case BOXERROR:
fputs("boxerrorbars\n", fp);
break;
case BOXXYERROR:
fputs("boxxyerrorbars\n", fp);
break;
case STEPS:
fputs("steps\n", fp);
break; /* JG */
case FSTEPS:
fputs("fsteps\n", fp);
break; /* HOE */
case HISTEPS:
fputs("histeps\n", fp);
break; /* CAC */
case VECTOR:
fputs("vector\n", fp);
break;
case FINANCEBARS:
fputs("financebars\n", fp);
break;
case CANDLESTICKS:
fputs("candlesticks\n", fp);
break;
}
fputs("set style function ", fp);
switch (func_style) {
case LINES:
fputs("lines\n", fp);
break;
case POINTSTYLE:
fputs("points\n", fp);
break;
case IMPULSES:
fputs("impulses\n", fp);
break;
case LINESPOINTS:
fputs("linespoints\n", fp);
break;
case DOTS:
fputs("dots\n", fp);
break;
case YERRORLINES:
fputs("yerrorlines\n", fp);
break;
case XERRORLINES:
fputs("xerrorlines\n", fp);
break;
case XYERRORLINES:
fputs("xyerrorlines\n", fp);
break;
case YERRORBARS:
fputs("yerrorbars\n", fp);
break;
case XERRORBARS:
fputs("xerrorbars\n", fp);
break;
case XYERRORBARS:
fputs("xyerrorbars\n", fp);
break;
case BOXXYERROR:
fputs("boxxyerrorbars\n", fp);
break;
case BOXES:
fputs("boxes\n", fp);
break;
case BOXERROR:
fputs("boxerrorbars\n", fp);
break;
case STEPS:
fputs("steps\n", fp);
break; /* JG */
case FSTEPS:
fputs("fsteps\n", fp);
break; /* HOE */
case HISTEPS:
fputs("histeps\n", fp);
break; /* CAC */
case VECTOR:
fputs("vector\n", fp);
break;
case FINANCEBARS:
fputs("financebars\n", fp);
break;
case CANDLESTICKS:
fputs("candlesticks\n", fp);
break;
default:
fputs("---error!---\n", fp);
break;
}
fprintf(fp, "\
set xzeroaxis lt %d lw %.3f\n\
set x2zeroaxis lt %d lw %.3f\n\
set yzeroaxis lt %d lw %.3f\n\
set y2zeroaxis lt %d lw %.3f\n\
set tics %s\n\
set ticslevel %g\n\
set ticscale %g %g\n",
xzeroaxis.l_type + 1, xzeroaxis.l_width,
x2zeroaxis.l_type + 1, x2zeroaxis.l_width,
yzeroaxis.l_type + 1, yzeroaxis.l_width,
y2zeroaxis.l_type + 1, y2zeroaxis.l_width,
(tic_in) ? "in" : "out",
ticslevel,
ticscale, miniticscale);
#define SAVE_XYZLABEL(name,lab) { \
fprintf(fp, "set %s \"%s\" %f,%f ", \
name, conv_text(lab.text),lab.xoffset,lab.yoffset); \
fprintf(fp, " \"%s\"\n", conv_text(lab.font)); \
}
#define SAVE_MINI(name,m,freq) switch(m&TICS_MASK) { \
case 0: fprintf(fp, "set no%s\n", name); break; \
case MINI_AUTO: fprintf(fp, "set %s\n",name); break; \
case MINI_DEFAULT: fprintf(fp, "set %s default\n",name); break; \
case MINI_USER: fprintf(fp, "set %s %f\n", name, freq); break; \
}
SAVE_MINI("mxtics", mxtics, mxtfreq)
SAVE_MINI("mytics", mytics, mytfreq)
SAVE_MINI("mx2tics", mx2tics, mx2tfreq)
SAVE_MINI("my2tics", my2tics, my2tfreq)
save_tics(fp, xtics, FIRST_X_AXIS, &xticdef, rotate_xtics, "x");
save_tics(fp, ytics, FIRST_Y_AXIS, &yticdef, rotate_ytics, "y");
save_tics(fp, ztics, FIRST_Z_AXIS, &zticdef, rotate_ztics, "z");
save_tics(fp, x2tics, SECOND_X_AXIS, &x2ticdef, rotate_x2tics, "x2");
save_tics(fp, y2tics, SECOND_Y_AXIS, &y2ticdef, rotate_y2tics, "y2");
SAVE_XYZLABEL("title", title);
/* FIXME */
fprintf(fp, "set %s \"%s\" %s %srotate %f,%f ",
"timestamp", conv_text(timelabel.text),
(timelabel_bottom ? "bottom" : "top"),
(timelabel_rotate ? "" : "no"),
timelabel.xoffset, timelabel.yoffset);
fprintf(fp, " \"%s\"\n", conv_text(timelabel.font));
save_range(fp, R_AXIS, rmin, rmax, autoscale_r, "r");
save_range(fp, T_AXIS, tmin, tmax, autoscale_t, "t");
save_range(fp, U_AXIS, umin, umax, autoscale_u, "u");
save_range(fp, V_AXIS, vmin, vmax, autoscale_v, "v");
SAVE_XYZLABEL("xlabel", xlabel);
SAVE_XYZLABEL("x2label", x2label);
if (strlen(timefmt)) {
fprintf(fp, "set timefmt \"%s\"\n", conv_text(timefmt));
}
save_range(fp, FIRST_X_AXIS, xmin, xmax, autoscale_x, "x");
save_range(fp, SECOND_X_AXIS, x2min, x2max, autoscale_x2, "x2");
SAVE_XYZLABEL("ylabel", ylabel);
SAVE_XYZLABEL("y2label", y2label);
save_range(fp, FIRST_Y_AXIS, ymin, ymax, autoscale_y, "y");
save_range(fp, SECOND_Y_AXIS, y2min, y2max, autoscale_y2, "y2");
SAVE_XYZLABEL("zlabel", zlabel);
save_range(fp, FIRST_Z_AXIS, zmin, zmax, autoscale_z, "z");
fprintf(fp, "set zero %g\n", zero);
fprintf(fp, "set lmargin %d\nset bmargin %d\nset rmargin %d\nset tmargin %d\n",
lmargin, bmargin, rmargin, tmargin);
fprintf(fp, "set locale \"%s\"\n", get_locale());
fputs("set loadpath ", fp);
{
char *s;
while ((s = save_loadpath()) != NULL)
fprintf(fp, "\"%s\" ", s);
fputc('\n', fp);
}
}
static void
save_tics(fp, where, axis, tdef, rotate, text)
FILE *fp;
int where;
int axis;
struct ticdef *tdef;
TBOOLEAN rotate;
const char *text;
{
if (where == NO_TICS) {
fprintf(fp, "set no%stics\n", text);
return;
}
fprintf(fp, "set %stics %s %smirror %srotate ", text,
(where & TICS_MASK) == TICS_ON_AXIS ? "axis" : "border",
(where & TICS_MIRROR) ? "" : "no", rotate ? "" : "no");
switch (tdef->type) {
case TIC_COMPUTED:{
fputs("autofreq ", fp);
break;
}
case TIC_MONTH:{
fprintf(fp, "\nset %smtics", text);
break;
}
case TIC_DAY:{
fprintf(fp, "\nset %cdtics", axis);
break;
}
case TIC_SERIES:
if (datatype[axis] == TIME) {
if (tdef->def.series.start != -VERYLARGE) {
char fd[26];
gstrftime(fd, 24, timefmt, (double) tdef->def.series.start);
fprintf(fp, "\"%s\",", conv_text(fd));
}
fprintf(fp, "%g", tdef->def.series.incr);
if (tdef->def.series.end != VERYLARGE) {
char td[26];
gstrftime(td, 24, timefmt, (double) tdef->def.series.end);
fprintf(fp, ",\"%s\"", conv_text(td));
}
} else { /* !TIME */
if (tdef->def.series.start != -VERYLARGE)
fprintf(fp, "%g,", tdef->def.series.start);
fprintf(fp, "%g", tdef->def.series.incr);
if (tdef->def.series.end != VERYLARGE)
fprintf(fp, ",%g", tdef->def.series.end);
}
break;
case TIC_USER:{
register struct ticmark *t;
int flag_time;
flag_time = (datatype[axis] == TIME);
fputs(" (", fp);
for (t = tdef->def.user; t != NULL; t = t->next) {
if (t->label)
fprintf(fp, "\"%s\" ", conv_text(t->label));
if (flag_time) {
char td[26];
gstrftime(td, 24, timefmt, (double) t->position);
fprintf(fp, "\"%s\"", conv_text(td));
} else {
fprintf(fp, "%g", t->position);
}
if (t->next) {
fputs(", ", fp);
}
}
fputs(")", fp);
break;
}
}
putc('\n', fp);
}
static void
save_position(fp, pos)
FILE *fp;
struct position *pos;
{
static const char *msg[] = { "first ", "second ", "graph ", "screen " };
assert(first_axes == 0 && second_axes == 1 && graph == 2 && screen == 3);
fprintf(fp, "%s%g, %s%g, %s%g",
pos->scalex == first_axes ? "" : msg[pos->scalex], pos->x,
pos->scaley == pos->scalex ? "" : msg[pos->scaley], pos->y,
pos->scalez == pos->scaley ? "" : msg[pos->scalez], pos->z);
}
static void
save_range(fp, axis, min, max, autosc, text)
FILE *fp;
int axis;
double min, max;
TBOOLEAN autosc;
const char *text;
{
int i;
i = axis;
fprintf(fp, "set %srange [ ", text);
if (autosc & 1) {
putc('*', fp);
} else {
SAVE_NUM_OR_TIME(fp, min, axis);
}
fputs(" : ", fp);
if (autosc & 2) {
putc('*', fp);
} else {
SAVE_NUM_OR_TIME(fp, max, axis);
}
fprintf(fp, " ] %sreverse %swriteback",
range_flags[axis] & RANGE_REVERSE ? "" : "no",
range_flags[axis] & RANGE_WRITEBACK ? "" : "no");
if (autosc) {
/* add current (hidden) range as comments */
fputs(" # (currently [", fp);
if (autosc & 1) {
SAVE_NUM_OR_TIME(fp, min, axis);
}
putc(':', fp);
if (autosc & 2) {
SAVE_NUM_OR_TIME(fp, max, axis);
}
fputs("] )", fp);
}
putc('\n', fp);
}