#ifndef lint static char *RCSid() { return RCSid("$Id: set.c,v 1.35.2.7 2000/10/24 18:58:12 broeker Exp $"); } #endif /* GNUPLOT - set.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. ]*/ /* * 19 September 1992 Lawrence Crowl (crowl@cs.orst.edu) * Added user-specified bases for log scaling. */ #include "setshow.h" #include "alloc.h" #include "axis.h" #include "command.h" #include "contour.h" #include "datafile.h" #include "gp_time.h" #include "hidden3d.h" #include "misc.h" #include "parse.h" #include "plot.h" #include "plot2d.h" #include "plot3d.h" #include "tables.h" #include "term_api.h" #include "util.h" #include "variable.h" #ifdef USE_MOUSE # include "mouse.h" #endif #include /* for isdigit() */ static void set_angles __PROTO((void)); static void set_arrow __PROTO((void)); static int assign_arrow_tag __PROTO((void)); static void set_autoscale __PROTO((void)); static void set_bars __PROTO((void)); static void set_border __PROTO((void)); static void set_boxwidth __PROTO((void)); static void set_clabel __PROTO((void)); static void set_clip __PROTO((void)); static void set_cntrparam __PROTO((void)); static void set_contour __PROTO((void)); static void set_dgrid3d __PROTO((void)); static void set_dummy __PROTO((void)); static void set_encoding __PROTO((void)); static void set_format __PROTO((void)); static void set_grid __PROTO((void)); static void set_hidden3d __PROTO((void)); #if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) static void set_historysize __PROTO((void)); #endif static void set_isosamples __PROTO((void)); static void set_key __PROTO((void)); static void set_keytitle __PROTO((void)); static void set_label __PROTO((void)); static int assign_label_tag __PROTO((void)); static void set_loadpath __PROTO((void)); static void set_locale __PROTO((void)); static void set_logscale __PROTO((void)); static void set_mapping __PROTO((void)); static void set_bmargin __PROTO((void)); static void set_lmargin __PROTO((void)); static void set_rmargin __PROTO((void)); static void set_tmargin __PROTO((void)); static void set_missing __PROTO((void)); #ifdef USE_MOUSE static void set_mouse __PROTO((void)); #endif static void set_offsets __PROTO((void)); static void set_origin __PROTO((void)); static void set_output __PROTO((void)); static void set_parametric __PROTO((void)); static void set_pointsize __PROTO((void)); static void set_polar __PROTO((void)); static void set_samples __PROTO((void)); static void set_size __PROTO((void)); static void set_style __PROTO((void)); static void set_surface __PROTO((void)); static void set_terminal __PROTO((void)); static void set_termoptions __PROTO((void)); static void set_tics __PROTO((void)); static void set_ticscale __PROTO((void)); static void set_ticslevel __PROTO((void)); static void set_timefmt __PROTO((void)); static void set_timestamp __PROTO((void)); static void set_view __PROTO((void)); static void set_zero __PROTO((void)); static void set_timedata __PROTO((AXIS_INDEX)); static void set_range __PROTO((AXIS_INDEX)); static void set_zeroaxis __PROTO((AXIS_INDEX)); static void set_allzeroaxis __PROTO((void)); /******** Local functions ********/ static void get_position __PROTO((struct position * pos)); static void get_position_type __PROTO((enum position_type * type, int *axes)); static void set_xyzlabel __PROTO((label_struct * label)); static void load_tics __PROTO((AXIS_INDEX axis)); static void load_tic_user __PROTO((AXIS_INDEX axis)); static void free_marklist __PROTO((struct ticmark * list)); static void load_tic_series __PROTO((AXIS_INDEX axis)); static void load_offsets __PROTO((double *a, double *b, double *c, double *d)); static void set_linestyle __PROTO((void)); static int assign_linestyle_tag __PROTO((void)); static int looks_like_numeric __PROTO((char *)); static void reset_lp_properties __PROTO((struct lp_style_type *arg)); static int set_tic_prop __PROTO((AXIS_INDEX)); static char *fill_numbers_into_string __PROTO((char *pattern)); /* Backwards compatibility ... */ static void set_nolinestyle __PROTO((void)); /******** The 'set' command ********/ void set_command() { static char GPFAR setmess[] = "valid set options: [] = choose one, {} means optional\n\n\ \t'angles', 'arrow', 'autoscale', 'bars', 'border', 'boxwidth',\n\ \t'clabel', 'clip', 'cntrparam', 'contour', 'data style', 'dgrid3d',\n\ \t'dummy', 'encoding', 'format', 'function style', 'grid',\n\ \t'hidden3d', 'historysize', 'isosamples', 'key', 'label', 'linestyle',\n\ \t'locale', 'logscale', '[blrt]margin', 'mapping', 'missing', 'mouse',\n\ \t'multiplot', 'offsets', 'origin', 'output', 'parametric', 'pointsize',\n\ \t'polar', '[rtuv]range', 'samples', 'size', 'surface', 'terminal',\n\ \t'tics', 'ticscale', 'ticslevel', 'timestamp', 'timefmt',\n\ \t'title', 'view', '[xyz]{2}data', '[xyz]{2}label', '[xyz]{2}range',\n\ \t'{no}{m}[xyz]{2}tics', '[xyz]{2}[md]tics', '{[xyz]{2}}zeroaxis', 'zero'"; c_token++; #ifdef BACKWARDS_COMPATIBLE /* retain backwards compatibility to the old syntax for now * Oh, such ugliness ... */ if (almost_equals(c_token,"da$ta")) { if (interactive) int_warn(c_token, "deprecated syntax, use \"set style data\""); if (!almost_equals(++c_token,"s$tyle")) int_error(c_token,"expecting keyword 'style'"); else data_style = get_style(); } else if (almost_equals(c_token,"fu$nction")) { if (interactive) int_warn(c_token, "deprecated syntax, use \"set style function\""); if (!almost_equals(++c_token,"s$tyle")) int_error(c_token,"expecting keyword 'style'"); else func_style = get_style(); } else if (almost_equals(c_token,"li$nestyle") || equals(c_token, "ls" )) { if (interactive) int_warn(c_token, "deprecated syntax, use \"set style line\""); c_token++; set_linestyle(); } else if (almost_equals(c_token,"noli$nestyle") || equals(c_token, "nols" )) { c_token++; set_nolinestyle(); } else if (input_line[token[c_token].start_index] == 'n' && input_line[token[c_token].start_index+1] == 'o') { if (interactive) int_warn(c_token, "deprecated syntax, use \"unset\""); token[c_token].start_index += 2; token[c_token].length -= 2; c_token--; unset_command(); } else { #endif /* BACKWARDS_COMPATIBLE */ switch(lookup_table(&set_tbl[0],c_token)) { case S_ANGLES: set_angles(); break; case S_ARROW: set_arrow(); break; case S_AUTOSCALE: set_autoscale(); break; case S_BARS: set_bars(); break; case S_BORDER: set_border(); break; case S_BOXWIDTH: set_boxwidth(); break; case S_CLABEL: set_clabel(); break; case S_CLIP: set_clip(); break; case S_CNTRPARAM: set_cntrparam(); break; case S_CONTOUR: set_contour(); break; case S_DGRID3D: set_dgrid3d(); break; case S_DUMMY: set_dummy(); break; case S_ENCODING: set_encoding(); break; case S_FORMAT: set_format(); break; case S_GRID: set_grid(); break; case S_HIDDEN3D: set_hidden3d(); break; #if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) case S_HISTORYSIZE: set_historysize(); break; #endif case S_ISOSAMPLES: set_isosamples(); break; case S_KEY: set_key(); break; case S_KEYTITLE: set_keytitle(); break; case S_LABEL: set_label(); break; case S_LOADPATH: set_loadpath(); break; case S_LOCALE: set_locale(); break; case S_LOGSCALE: set_logscale(); break; case S_MAPPING: set_mapping(); break; case S_BMARGIN: set_bmargin(); break; case S_LMARGIN: set_lmargin(); break; case S_RMARGIN: set_rmargin(); break; case S_TMARGIN: set_tmargin(); break; case S_MISSING: set_missing(); break; #ifdef USE_MOUSE case S_MOUSE: set_mouse(); break; #endif case S_MULTIPLOT: term_start_multiplot(); break; case S_OFFSETS: set_offsets(); break; case S_ORIGIN: set_origin(); break; case S_OUTPUT: set_output(); break; case S_PARAMETRIC: set_parametric(); break; case S_POINTSIZE: set_pointsize(); break; case S_POLAR: set_polar(); break; case S_SAMPLES: set_samples(); break; case S_SIZE: set_size(); break; case S_STYLE: set_style(); break; case S_SURFACE: set_surface(); break; case S_TERMINAL: set_terminal(); break; case S_TERMOPTIONS: set_termoptions(); break; case S_TICS: set_tics(); break; case S_TICSCALE: set_ticscale(); break; case S_TICSLEVEL: set_ticslevel(); break; case S_TIMEFMT: set_timefmt(); break; case S_TIMESTAMP: set_timestamp(); break; case S_TITLE: set_xyzlabel(&title); break; case S_VIEW: set_view(); break; case S_ZERO: set_zero(); break; /* FIXME */ case S_MXTICS: case S_NOMXTICS: case S_XTICS: case S_NOXTICS: case S_XDTICS: case S_NOXDTICS: case S_XMTICS: case S_NOXMTICS: set_tic_prop(FIRST_X_AXIS); break; case S_MYTICS: case S_NOMYTICS: case S_YTICS: case S_NOYTICS: case S_YDTICS: case S_NOYDTICS: case S_YMTICS: case S_NOYMTICS: set_tic_prop(FIRST_Y_AXIS); break; case S_MX2TICS: case S_NOMX2TICS: case S_X2TICS: case S_NOX2TICS: case S_X2DTICS: case S_NOX2DTICS: case S_X2MTICS: case S_NOX2MTICS: set_tic_prop(SECOND_X_AXIS); break; case S_MY2TICS: case S_NOMY2TICS: case S_Y2TICS: case S_NOY2TICS: case S_Y2DTICS: case S_NOY2DTICS: case S_Y2MTICS: case S_NOY2MTICS: set_tic_prop(SECOND_Y_AXIS); break; case S_MZTICS: case S_NOMZTICS: case S_ZTICS: case S_NOZTICS: case S_ZDTICS: case S_NOZDTICS: case S_ZMTICS: case S_NOZMTICS: set_tic_prop(FIRST_Z_AXIS); break; case S_XDATA: set_timedata(FIRST_X_AXIS); /* HBB 20000506: the old cod this this, too, although it * serves no useful purpose, AFAICS */ set_timedata(T_AXIS); set_timedata(U_AXIS); break; case S_YDATA: set_timedata(FIRST_Y_AXIS); /* dito */ set_timedata(V_AXIS); break; case S_ZDATA: set_timedata(FIRST_Z_AXIS); break; case S_X2DATA: set_timedata(SECOND_X_AXIS); break; case S_Y2DATA: set_timedata(SECOND_Y_AXIS); break; case S_XLABEL: set_xyzlabel(&axis_array[FIRST_X_AXIS].label); break; case S_YLABEL: set_xyzlabel(&axis_array[FIRST_Y_AXIS].label); break; case S_ZLABEL: set_xyzlabel(&axis_array[FIRST_Z_AXIS].label); break; case S_X2LABEL: set_xyzlabel(&axis_array[SECOND_X_AXIS].label); break; case S_Y2LABEL: set_xyzlabel(&axis_array[SECOND_Y_AXIS].label); break; case S_XRANGE: set_range(FIRST_X_AXIS); break; case S_X2RANGE: set_range(SECOND_X_AXIS); break; case S_YRANGE: set_range(FIRST_Y_AXIS); break; case S_Y2RANGE: set_range(SECOND_Y_AXIS); break; case S_ZRANGE: set_range(FIRST_Z_AXIS); break; case S_RRANGE: set_range(R_AXIS); break; case S_TRANGE: set_range(T_AXIS); break; case S_URANGE: set_range(U_AXIS); break; case S_VRANGE: set_range(V_AXIS); break; case S_XZEROAXIS: set_zeroaxis(FIRST_X_AXIS); break; case S_YZEROAXIS: set_zeroaxis(FIRST_Y_AXIS); break; case S_X2ZEROAXIS: set_zeroaxis(SECOND_X_AXIS); break; case S_Y2ZEROAXIS: set_zeroaxis(SECOND_Y_AXIS); break; case S_ZEROAXIS: set_allzeroaxis(); break; default: int_error(c_token, setmess); break; } #ifdef BACKWARDS_COMPATIBLE } #endif } /* process 'set angles' command */ static void set_angles() { c_token++; if (END_OF_COMMAND) { /* assuming same as defaults */ ang2rad = 1; } else if (almost_equals(c_token, "r$adians")) { c_token++; ang2rad = 1; } else if (almost_equals(c_token, "d$egrees")) { c_token++; ang2rad = DEG2RAD; } else int_error(c_token, "expecting 'radians' or 'degrees'"); if (polar && axis_array[T_AXIS].set_autoscale) { /* set trange if in polar mode and no explicit range */ axis_array[T_AXIS].set_min = 0; axis_array[T_AXIS].set_max = 2 * M_PI / ang2rad; } } /* process a 'set arrow' command */ /* set arrow {tag} {from x,y} {to x,y} {{no}head} */ static void set_arrow() { struct value a; struct arrow_def *this_arrow = NULL; struct arrow_def *new_arrow = NULL; struct arrow_def *prev_arrow = NULL; struct position spos, epos, headsize; struct lp_style_type loc_lp; int tag; TBOOLEAN set_start, set_end, head = 1; TBOOLEAN set_line = 0, set_headsize = 0, set_layer = 0; TBOOLEAN relative = 0; int layer = 0; headsize.x = 0; /* length being zero means the default head size */ c_token++; /* Init struct lp_style_type loc_lp */ reset_lp_properties (&loc_lp); /* get tag */ if (!END_OF_COMMAND && !equals(c_token, "from") && !equals(c_token, "to") && !equals(c_token, "rto") ) { /* must be a tag expression! */ tag = (int) real(const_express(&a)); if (tag <= 0) int_error(c_token, "tag must be > zero"); } else tag = assign_arrow_tag(); /* default next tag */ /* HBB 20001018: removed code here that accepted 'first' or * 'second' keywords. The resulting variables 'axes' and * 'set_axes' effected nothing, anyway --> deleted them, too. */ /* get start position */ if (!END_OF_COMMAND && equals(c_token, "from")) { c_token++; if (END_OF_COMMAND) int_error(c_token, "start coordinates expected"); /* get coordinates */ get_position(&spos); set_start = TRUE; } else { spos.x = spos.y = spos.z = 0; spos.scalex = spos.scaley = spos.scalez = first_axes; set_start = FALSE; } /* get end position */ if (!END_OF_COMMAND && equals(c_token, "to")) { c_token++; if (END_OF_COMMAND) int_error(c_token, "end coordinates expected"); /* get coordinates */ get_position(&epos); set_end = TRUE; } else if (!END_OF_COMMAND && equals(c_token, "rto")) { c_token++; if (END_OF_COMMAND) int_error(c_token, "end coordinates expected"); /* get coordinates */ get_position(&epos); set_end = TRUE; relative = 1; } else { epos.x = epos.y = epos.z = 0; epos.scalex = epos.scaley = epos.scalez = first_axes; set_end = FALSE; } /* get start position - what the heck, either order is ok */ if (!END_OF_COMMAND && equals(c_token, "from")) { if (set_start) int_error(c_token, "only one 'from' is allowed"); c_token++; if (END_OF_COMMAND) int_error(c_token, "start coordinates expected"); /* get coordinates */ get_position(&spos); set_start = TRUE; } if (!END_OF_COMMAND && equals(c_token, "nohead")) { c_token++; head = 0; } if (!END_OF_COMMAND && equals(c_token, "head")) { c_token++; head = 1; } if (!END_OF_COMMAND && equals(c_token, "heads")) { c_token++; head = 2; } if (!END_OF_COMMAND && equals(c_token, "size")) { headsize.scalex = headsize.scaley = headsize.scalez = first_axes; /* only scalex used; scaley is angle of the head in [deg] */ c_token++; if (END_OF_COMMAND) int_error(c_token, "head size expected"); get_position(&headsize); set_headsize = TRUE; } set_layer = FALSE; if (!END_OF_COMMAND && equals(c_token, "back")) { c_token++; layer = 0; set_layer = TRUE; } if (!END_OF_COMMAND && equals(c_token, "front")) { c_token++; layer = 1; set_layer = TRUE; } set_line = 1; /* pick up a line spec - allow ls, but no point. */ lp_parse(&loc_lp, 1, 0, 0, 0); loc_lp.pointflag = 0; /* standard value for arrows, don't use points */ if (!END_OF_COMMAND) int_error(c_token, "extraneous or out-of-order arguments in set arrow"); /* OK! add arrow */ if (first_arrow != NULL) { /* skip to last arrow */ for (this_arrow = first_arrow; this_arrow != NULL; prev_arrow = this_arrow, this_arrow = this_arrow->next) /* is this the arrow we want? */ if (tag <= this_arrow->tag) break; } if (this_arrow != NULL && tag == this_arrow->tag) { /* changing the arrow */ if (set_start) { this_arrow->start = spos; } if (set_end) { this_arrow->end = epos; this_arrow->relative = relative; } this_arrow->head = head; if (set_layer) { this_arrow->layer = layer; } if (set_headsize) { this_arrow->headsize = headsize; } if (set_line) { this_arrow->lp_properties = loc_lp; } } else { /* adding the arrow */ new_arrow = (struct arrow_def *) gp_alloc(sizeof(struct arrow_def), "arrow"); if (prev_arrow != NULL) prev_arrow->next = new_arrow; /* add it to end of list */ else first_arrow = new_arrow; /* make it start of list */ new_arrow->tag = tag; new_arrow->next = this_arrow; new_arrow->start = spos; new_arrow->end = epos; new_arrow->head = head; new_arrow->headsize = headsize; new_arrow->layer = layer; new_arrow->relative = relative; new_arrow->lp_properties = loc_lp; } } /* assign a new arrow tag * arrows are kept sorted by tag number, so this is easy * returns the lowest unassigned tag number */ static int assign_arrow_tag() { struct arrow_def *this_arrow; int last = 0; /* previous tag value */ for (this_arrow = first_arrow; this_arrow != NULL; this_arrow = this_arrow->next) if (this_arrow->tag == last + 1) last++; else break; return (last + 1); } /* process 'set autoscale' command */ static void set_autoscale() { char min_string[20], max_string[20]; c_token++; if (END_OF_COMMAND) { INIT_AXIS_ARRAY(set_autoscale , DTRUE); return; } else if (equals(c_token, "xy") || equals(c_token, "yx")) { axis_array[FIRST_X_AXIS].set_autoscale = axis_array[FIRST_Y_AXIS].set_autoscale = DTRUE; c_token++; return; } /* save on replication with a macro */ #define PROCESS_AUTO_LETTER(axis) \ do { \ if (equals(c_token, axis_defaults[axis].name)) { \ axis_array[axis].set_autoscale = DTRUE; \ ++c_token; \ return; \ } \ sprintf(min_string, "%smi$n", axis_defaults[axis].name); \ if (almost_equals(c_token, min_string)) { \ axis_array[axis].set_autoscale |= 1; \ ++c_token; \ return; \ } \ sprintf(max_string, "%sma$x", axis_defaults[axis].name); \ if (almost_equals(c_token, max_string)) { \ axis_array[axis].set_autoscale |= 2; \ ++c_token; \ return; \ } \ } while(0) PROCESS_AUTO_LETTER(R_AXIS); PROCESS_AUTO_LETTER(T_AXIS); PROCESS_AUTO_LETTER(U_AXIS); PROCESS_AUTO_LETTER(V_AXIS); PROCESS_AUTO_LETTER(FIRST_X_AXIS); PROCESS_AUTO_LETTER(FIRST_Y_AXIS); PROCESS_AUTO_LETTER(FIRST_Z_AXIS); PROCESS_AUTO_LETTER(SECOND_X_AXIS); PROCESS_AUTO_LETTER(SECOND_Y_AXIS); /* came here only if nothing found: */ int_error(c_token, "Invalid range"); } /* process 'set bars' command */ static void set_bars() { struct value a; c_token++; if(END_OF_COMMAND) { bar_size = 1.0; } else if(almost_equals(c_token,"s$mall")) { bar_size = 0.0; ++c_token; } else if(almost_equals(c_token,"l$arge")) { bar_size = 1.0; ++c_token; } else { bar_size = real(const_express(&a)); } } /* process 'set border' command */ static void set_border() { struct value a; c_token++; if(END_OF_COMMAND){ draw_border = 31; } else { draw_border = (int)real(const_express(&a)); } /* HBB 980609: add linestyle handling for 'set border...' */ /* For now, you have to give a border bitpattern to be able to specify * a linestyle. Sorry for this, but the gnuplot parser really is too messy * for any other solution, currently */ /* not for long, I hope. Lars */ if(END_OF_COMMAND) { set_lp_properties(&border_lp, 0, -2, 0, 1.0, 1.0); } else { lp_parse(&border_lp, 1, 0, -2, 0); } } /* process 'set boxwidth' command */ static void set_boxwidth() { struct value a; c_token++; if (END_OF_COMMAND) boxwidth = -1.0; else { /* if((boxwidth = real(const_express(&a))) != -2.0) */ /* boxwidth = magnitude(const_express(&a));*/ boxwidth = real(const_express(&a)); } } /* process 'set clabel' command */ static void set_clabel() { c_token++; label_contours = TRUE; if (isstring(c_token)) quote_str(contour_format, c_token++, 30); } /* process 'set clip' command */ static void set_clip() { c_token++; if (END_OF_COMMAND) /* assuming same as points */ clip_points = TRUE; else if (almost_equals(c_token, "p$oints")) clip_points = TRUE; else if (almost_equals(c_token, "o$ne")) clip_lines1 = TRUE; else if (almost_equals(c_token, "t$wo")) clip_lines2 = TRUE; else int_error(c_token, "expecting 'points', 'one', or 'two'"); c_token++; } /* process 'set cntrparam' command */ static void set_cntrparam() { struct value a; c_token++; if (END_OF_COMMAND) { /* assuming same as defaults */ contour_pts = DEFAULT_NUM_APPROX_PTS; contour_kind = CONTOUR_KIND_LINEAR; contour_order = DEFAULT_CONTOUR_ORDER; contour_levels = DEFAULT_CONTOUR_LEVELS; contour_levels_kind = LEVELS_AUTO; } else if (almost_equals(c_token, "p$oints")) { c_token++; contour_pts = (int) real(const_express(&a)); } else if (almost_equals(c_token, "li$near")) { c_token++; contour_kind = CONTOUR_KIND_LINEAR; } else if (almost_equals(c_token, "c$ubicspline")) { c_token++; contour_kind = CONTOUR_KIND_CUBIC_SPL; } else if (almost_equals(c_token, "b$spline")) { c_token++; contour_kind = CONTOUR_KIND_BSPLINE; } else if (almost_equals(c_token, "le$vels")) { c_token++; init_dynarray(&dyn_contour_levels_list, sizeof(double), 5, 10); /* RKC: I have modified the next two: * to use commas to separate list elements as in xtics * so that incremental lists start,incr[,end]as in " */ if (almost_equals(c_token, "di$screte")) { contour_levels_kind = LEVELS_DISCRETE; c_token++; if(END_OF_COMMAND) int_error(c_token, "expecting discrete level"); else *(double *)nextfrom_dynarray(&dyn_contour_levels_list) = real(const_express(&a)); while(!END_OF_COMMAND) { if (!equals(c_token, ",")) int_error(c_token, "expecting comma to separate discrete levels"); c_token++; *(double *)nextfrom_dynarray(&dyn_contour_levels_list) = real(const_express(&a)); } contour_levels = dyn_contour_levels_list.end; } else if (almost_equals(c_token, "in$cremental")) { int i = 0; /* local counter */ contour_levels_kind = LEVELS_INCREMENTAL; c_token++; contour_levels_list[i++] = real(const_express(&a)); if (!equals(c_token, ",")) int_error(c_token, "expecting comma to separate start,incr levels"); c_token++; if((contour_levels_list[i++] = real(const_express(&a))) == 0) int_error(c_token, "increment cannot be 0"); if(!END_OF_COMMAND) { if (!equals(c_token, ",")) int_error(c_token, "expecting comma to separate incr,stop levels"); c_token++; /* need to round up, since 10,10,50 is 5 levels, not four, * but 10,10,49 is four */ dyn_contour_levels_list.end = i; contour_levels = (int) ( (real(const_express(&a))-contour_levels_list[0])/contour_levels_list[1] + 1.0); } } else if (almost_equals(c_token, "au$to")) { contour_levels_kind = LEVELS_AUTO; c_token++; if(!END_OF_COMMAND) contour_levels = (int) real(const_express(&a)); } else { if(contour_levels_kind == LEVELS_DISCRETE) int_error(c_token, "Levels type is discrete, ignoring new number of contour levels"); contour_levels = (int) real(const_express(&a)); } } else if (almost_equals(c_token, "o$rder")) { int order; c_token++; order = (int) real(const_express(&a)); if ( order < 2 || order > MAX_BSPLINE_ORDER ) int_error(c_token, "bspline order must be in [2..10] range."); contour_order = order; } else int_error(c_token, "expecting 'linear', 'cubicspline', 'bspline', 'points', 'levels' or 'order'"); } /* process 'set contour' command */ static void set_contour() { c_token++; if (END_OF_COMMAND) /* assuming same as points */ draw_contour = CONTOUR_BASE; else { if (almost_equals(c_token, "ba$se")) draw_contour = CONTOUR_BASE; else if (almost_equals(c_token, "s$urface")) draw_contour = CONTOUR_SRF; else if (almost_equals(c_token, "bo$th")) draw_contour = CONTOUR_BOTH; else int_error(c_token, "expecting 'base', 'surface', or 'both'"); c_token++; } } /* process 'set dgrid3d' command */ static void set_dgrid3d() { struct value a; int local_vals[3]; int i; TBOOLEAN was_comma = TRUE; c_token++; local_vals[0] = dgrid3d_row_fineness; local_vals[1] = dgrid3d_col_fineness; local_vals[2] = dgrid3d_norm_value; for (i = 0; i < 3 && !(END_OF_COMMAND);) { if (equals(c_token,",")) { if (was_comma) i++; was_comma = TRUE; c_token++; } else { if (!was_comma) int_error(c_token, "',' expected"); local_vals[i] = real(const_express(&a)); i++; was_comma = FALSE; } } if (local_vals[0] < 2 || local_vals[0] > 1000) int_error(c_token, "Row size must be in [2:1000] range; size unchanged"); if (local_vals[1] < 2 || local_vals[1] > 1000) int_error(c_token, "Col size must be in [2:1000] range; size unchanged"); if (local_vals[2] < 1 || local_vals[2] > 100) int_error(c_token, "Norm must be in [1:100] range; norm unchanged"); dgrid3d_row_fineness = local_vals[0]; dgrid3d_col_fineness = local_vals[1]; dgrid3d_norm_value = local_vals[2]; dgrid3d = TRUE; } /* process 'set dummy' command */ static void set_dummy() { c_token++; if (END_OF_COMMAND) int_error(c_token, "expecting dummy variable name"); else { if (!equals(c_token,",")) copy_str(set_dummy_var[0],c_token++, MAX_ID_LEN); if (!END_OF_COMMAND && equals(c_token,",")) { c_token++; if (END_OF_COMMAND) int_error(c_token, "expecting second dummy variable name"); copy_str(set_dummy_var[1],c_token++, MAX_ID_LEN); } } } /* process 'set encoding' command */ static void set_encoding() { int temp; c_token++; if(END_OF_COMMAND) temp = S_ENC_DEFAULT; else { temp = lookup_table(&set_encoding_tbl[0],c_token); if (temp == S_ENC_INVALID) int_error(c_token, "expecting one of 'default', 'iso_8859_1', 'cp437' or 'cp850'"); c_token++; } encoding = temp; } /* process 'set format' command */ static void set_format() { TBOOLEAN set_for_axis[AXIS_ARRAY_SIZE] = AXIS_ARRAY_INITIALIZER(FALSE); int axis; c_token++; if ((axis = lookup_table(axisname_tbl, c_token)) >= 0) { set_for_axis[axis] = TRUE; c_token++; } else if (equals(c_token,"xy") || equals(c_token,"yx")) { set_for_axis[FIRST_X_AXIS] = set_for_axis[FIRST_Y_AXIS] = TRUE; c_token++; } else if (isstring(c_token) || END_OF_COMMAND) { /* Assume he wants all */ for (axis = 0; axis < AXIS_ARRAY_SIZE; axis++) set_for_axis[axis] = TRUE; } if (END_OF_COMMAND) { SET_DEFFORMAT(FIRST_X_AXIS , set_for_axis); SET_DEFFORMAT(FIRST_Y_AXIS , set_for_axis); SET_DEFFORMAT(FIRST_Z_AXIS , set_for_axis); SET_DEFFORMAT(SECOND_X_AXIS, set_for_axis); SET_DEFFORMAT(SECOND_Y_AXIS, set_for_axis); } else { if (!isstring(c_token)) int_error(c_token, "expecting format string"); else { #define SET_FORMATSTRING(axis) \ if (set_for_axis[axis]) { \ quote_str(axis_array[axis].formatstring,c_token, MAX_ID_LEN); \ axis_array[axis].format_is_numeric = \ looks_like_numeric(axis_array[axis].formatstring); \ } SET_FORMATSTRING(FIRST_X_AXIS); SET_FORMATSTRING(FIRST_Y_AXIS); SET_FORMATSTRING(FIRST_Z_AXIS); SET_FORMATSTRING(SECOND_X_AXIS); SET_FORMATSTRING(SECOND_Y_AXIS); #undef SET_FORMATSTRING c_token++; } } } /* process 'set grid' command */ #define GRID_MATCH(string, neg, mask) \ if (almost_equals(c_token, string)) { \ grid_selection |= mask; \ ++c_token; \ } else if (almost_equals(c_token, neg)) { \ grid_selection &= ~(mask); \ ++c_token; \ } static void set_grid() { c_token++; if (END_OF_COMMAND && !grid_selection) grid_selection = GRID_X|GRID_Y; else while (!END_OF_COMMAND) { GRID_MATCH("x$tics", "nox$tics", GRID_X) else GRID_MATCH("y$tics", "noy$tics", GRID_Y) else GRID_MATCH("z$tics", "noz$tics", GRID_Z) else GRID_MATCH("x2$tics", "nox2$tics", GRID_X2) else GRID_MATCH("y2$tics", "noy2$tics", GRID_Y2) else GRID_MATCH("mx$tics", "nomx$tics", GRID_MX) else GRID_MATCH("my$tics", "nomy$tics", GRID_MY) else GRID_MATCH("mz$tics", "nomz$tics", GRID_MZ) else GRID_MATCH("mx2$tics", "nomx2$tics", GRID_MX2) else GRID_MATCH("my2$tics", "nomy2$tics", GRID_MY2) else if (almost_equals(c_token,"po$lar")) { if (!grid_selection) grid_selection = GRID_X; c_token++; if (END_OF_COMMAND) { polar_grid_angle = 30*DEG2RAD; } else { /* get radial interval */ struct value a; polar_grid_angle = ang2rad*real(const_express(&a)); } } else if (almost_equals(c_token,"nopo$lar")) { polar_grid_angle = 0; /* not polar grid */ c_token++; } else break; /* might be a linetype */ } if (!END_OF_COMMAND) { struct value a; int old_token = c_token; lp_parse(&grid_lp,1,0,-1,1); if (c_token == old_token) { /* nothing parseable found... */ grid_lp.l_type = real(const_express(&a)) - 1; } if (!grid_selection) grid_selection = GRID_X|GRID_Y; /* probably just set grid */ if (END_OF_COMMAND) { memcpy(&mgrid_lp,&grid_lp,sizeof(struct lp_style_type)); } else { if (equals(c_token,",")) c_token++; old_token = c_token; lp_parse(&mgrid_lp,1,0,-1,1); if (c_token == old_token) { mgrid_lp.l_type = real(const_express(&a)) -1; } } if (!grid_selection) grid_selection = GRID_X|GRID_Y; /* probably just set grid */ } } /* process 'set hidden3d' command */ static void set_hidden3d() { c_token++; #ifdef LITE printf(" Hidden Line Removal Not Supported in LITE version\n"); #else /* HBB 970618: new parsing engine for hidden3d options */ set_hidden3doptions(); hidden3d = TRUE; #endif } #if defined(HAVE_LIBREADLINE) && defined(GNUPLOT_HISTORY) /* process 'set historysize' command */ static void set_historysize() { struct value a; c_token++; gnuplot_history_size = (int) real(const_express(&a)); if (gnuplot_history_size < 0) { gnuplot_history_size = 0; } } #endif /* process 'set isosamples' command */ static void set_isosamples() { register int tsamp1, tsamp2; struct value a; c_token++; tsamp1 = (int)magnitude(const_express(&a)); tsamp2 = tsamp1; if (!END_OF_COMMAND) { if (!equals(c_token,",")) int_error(c_token, "',' expected"); c_token++; tsamp2 = (int)magnitude(const_express(&a)); } if (tsamp1 < 2 || tsamp2 < 2) int_error(c_token, "sampling rate must be > 1; sampling unchanged"); else { register struct curve_points *f_p = first_plot; register struct surface_points *f_3dp = first_3dplot; first_plot = NULL; first_3dplot = NULL; cp_free(f_p); sp_free(f_3dp); iso_samples_1 = tsamp1; iso_samples_2 = tsamp2; } } /* FIXME - old bug in this parser * to exercise: set key left hiho */ /* process 'set key' command */ static void set_key() { struct value a; c_token++; if (END_OF_COMMAND) { reset_key(); /* reset to defaults */ key_title[0] = 0; } else { while (!END_OF_COMMAND) { switch(lookup_table(&set_key_tbl[0],c_token)) { case S_KEY_TOP: key_vpos = TTOP; key = KEY_AUTO_PLACEMENT; break; case S_KEY_BOTTOM: key_vpos = TBOTTOM; key = KEY_AUTO_PLACEMENT; break; case S_KEY_LEFT: key_hpos = TLEFT; /* key_just = TRIGHT; */ key = KEY_AUTO_PLACEMENT; break; case S_KEY_RIGHT: key_hpos = TRIGHT; key = KEY_AUTO_PLACEMENT; break; case S_KEY_UNDER: key_vpos = TUNDER; if (key_hpos == TOUT) key_hpos = TRIGHT; key = KEY_AUTO_PLACEMENT; break; case S_KEY_OUTSIDE: key_hpos = TOUT; if (key_vpos == TUNDER) key_vpos = TBOTTOM; key = KEY_AUTO_PLACEMENT; break; case S_KEY_LLEFT: /* key_hpos = TLEFT; */ key_just = JLEFT; break; case S_KEY_RRIGHT: /* key_hpos = TLEFT; */ key_just = JRIGHT; break; case S_KEY_REVERSE: key_reverse = TRUE; break; case S_KEY_NOREVERSE: key_reverse = FALSE; break; case S_KEY_BOX: c_token++; if (END_OF_COMMAND) key_box.l_type = -2; else { int old_token = c_token; lp_parse(&key_box,1,0,-2,0); if (old_token == c_token) key_box.l_type = real(const_express(&a)) -1; } c_token--; /* is incremented after loop */ break; case S_KEY_NOBOX: key_box.l_type = -3; break; case S_KEY_SAMPLEN: c_token++; key_swidth = real(const_express(&a)); c_token--; /* it is incremented after loop */ break; case S_KEY_SPACING: c_token++; key_vert_factor = real(const_express(&a)); if (key_vert_factor < 0.0) key_vert_factor = 0.0; c_token--; /* it is incremented after loop */ break; case S_KEY_WIDTH: c_token++; key_width_fix = real(const_express(&a)); c_token--; /* it is incremented after loop */ break; case S_KEY_TITLE: if (isstring(c_token+1)) { /* We have string specified - grab it. */ quote_str(key_title,++c_token, MAX_LINE_LEN); } else key_title[0] = 0; break; case S_KEY_INVALID: default: get_position(&key_user_pos); key = KEY_USER_PLACEMENT; c_token--; /* will be incremented again soon */ break; } c_token++; } } } /* process 'set keytitle' command */ static void set_keytitle() { c_token++; if (END_OF_COMMAND) { /* set to default */ key_title[0] = NUL; } else { if (isstring(c_token)) { /* We have string specified - grab it. */ quote_str(key_title,c_token, MAX_LINE_LEN); c_token++; } /* c_token++; */ } } /* process 'set label' command */ /* set label {tag} {label_text} {at x,y} {pos} {font name,size} */ /* Entry font added by DJL */ static void set_label() { struct value a; struct text_label *this_label = NULL; struct text_label *new_label = NULL; struct text_label *prev_label = NULL; struct position pos; char *text = NULL, *font = NULL; enum JUSTIFY just = LEFT; int rotate = 0; int tag; TBOOLEAN set_text, set_position, set_just = FALSE, set_rot = FALSE; TBOOLEAN set_font, set_offset = FALSE; TBOOLEAN set_layer = FALSE; int layer = 0; int pointstyle = -2; /* untouched (this is /not/ -1) */ float hoff = 1.0; float voff = 1.0; c_token++; /* get tag */ if (!END_OF_COMMAND && !isstring(c_token) && !equals(c_token, "at") && !equals(c_token, "left") && !equals(c_token, "center") && !equals(c_token, "centre") && !equals(c_token, "right") && !equals(c_token, "front") && !equals(c_token, "back") && !almost_equals(c_token, "rot$ate") && !almost_equals(c_token, "norot$ate") && !equals(c_token, "font")) { /* must be a tag expression! */ tag = (int) real(const_express(&a)); if (tag <= 0) int_error(c_token, "tag must be > zero"); } else tag = assign_label_tag(); /* default next tag */ /* get text */ if (!END_OF_COMMAND && isstring(c_token)) { /* get text */ text = gp_alloc (token_len(c_token), "text_label->text"); quote_str(text, c_token, token_len(c_token)); c_token++; /* HBB 20001021: new functionality. If next token is a ',' * treat it as a numeric expression whose value is to be * sprintf()ed into the label string (which contains an * appropriate %f format string) */ if (!END_OF_COMMAND && equals(c_token, ",")) text = fill_numbers_into_string(text); set_text = TRUE; } else set_text = FALSE; /* default no text */ /* get justification - what the heck, let him put it here */ if (!END_OF_COMMAND #if 0 /* HBB 20001021: unnecessary checks */ && !equals(c_token, "at") && !equals(c_token, "font") && !almost_equals(c_token, "rot$ate") && !almost_equals(c_token, "norot$ate") && !equals(c_token, "front") && !equals(c_token, "back") #endif ) { if (almost_equals(c_token, "l$eft")) { just = LEFT; c_token++; set_just = TRUE; } else if (almost_equals(c_token, "c$entre") || almost_equals(c_token, "c$enter")) { just = CENTRE; c_token++; set_just = TRUE; } else if (almost_equals(c_token, "r$ight")) { just = RIGHT; c_token++; set_just = TRUE; #if 0 /* HBB 20001021: with the above change, this is not an error */ } else { int_error(c_token, "bad syntax in set label"); #endif } } /* get position */ if (!END_OF_COMMAND && equals(c_token, "at")) { c_token++; get_position(&pos); set_position = TRUE; } else { pos.x = pos.y = pos.z = 0; pos.scalex = pos.scaley = pos.scalez = first_axes; set_position = FALSE; } /* get justification */ if (!END_OF_COMMAND #if 0 /* HBB 20001021: none of these are needed */ && !almost_equals(c_token, "rot$ate") && !almost_equals(c_token, "norot$ate") && !equals(c_token, "front") && !equals(c_token, "back") && !equals(c_token, "font") && !almost_equals(c_token, "po$intstyle") && !almost_equals(c_token, "nopo$intstyle") #endif ) { if (set_just) int_error(c_token, "only one justification is allowed"); if (almost_equals(c_token, "l$eft")) { just = LEFT; c_token++; set_just = TRUE; } else if (almost_equals(c_token, "c$entre") || almost_equals(c_token, "c$enter")) { just = CENTRE; c_token++; set_just = TRUE; } else if (almost_equals(c_token, "r$ight")) { just = RIGHT; c_token++; set_just = TRUE; #if 0 /* HBB 20001021: not an error, in this version */ } else { int_error(c_token, "bad syntax in set label"); #endif } } /* get rotation (added by RCC) */ if (!END_OF_COMMAND #if 0 /* HBB 20001021: no need to check all these */ && !equals(c_token, "font") && !equals(c_token, "front") && !equals(c_token, "back") && !almost_equals(c_token, "po$intstyle") && !almost_equals(c_token, "nopo$intstyle") #endif ) { if (almost_equals(c_token, "rot$ate")) { rotate = TRUE; c_token++; set_rot = TRUE; } else if (almost_equals(c_token, "norot$ate")) { rotate = FALSE; c_token++; set_rot = TRUE; #if 0 /* HBB 20001021: not an error, in this version */ } else { int_error(c_token, "bad syntax in set label"); #endif } } /* get font */ /* Entry font added by DJL */ set_font = FALSE; if (!END_OF_COMMAND && equals(c_token, "font") #if 0 /* HBB 20001021: the followin cannot possibly happen... */ && !equals(c_token, "front") && !equals(c_token, "back") && !almost_equals(c_token, "po$intstyle") && !almost_equals(c_token, "nopo$intstyle") #endif /* 1/0 HBB 20001021 */ ) { c_token++; if (END_OF_COMMAND) int_error(c_token, "font name and size expected"); if (isstring(c_token)) { font = gp_alloc (token_len(c_token), "text_label->font"); quote_str(font, c_token, token_len(c_token)); /* get 'name,size', no further check */ set_font = TRUE; } else int_error(c_token, "'fontname,fontsize' expected"); c_token++; } /* get front/back (added by JDP) */ set_layer = FALSE; if (!END_OF_COMMAND && equals(c_token, "back") #if 0 /* HBB 20001021: none of these can happen */ && !equals(c_token, "front") && !almost_equals(c_token, "po$intstyle") && !almost_equals(c_token, "nopo$intstyle") #endif ) { layer = 0; c_token++; set_layer = TRUE; } if(!END_OF_COMMAND && equals(c_token, "front") #if 0 /* HBB 20001021: none of these can happen */ && !almost_equals(c_token, "po$intstyle") && !almost_equals(c_token, "nopo$intstyle") #endif ) { if (set_layer) int_error(c_token, "only one of front or back expected"); layer = 1; c_token++; set_layer = TRUE; } if(!END_OF_COMMAND && almost_equals(c_token, "po$intstyle")) { c_token++; pointstyle = (int) real(const_express(&a)); if (pointstyle < 0) pointstyle = -1; /* UNSET */ else #define POINT_TYPES 6 /* compare with term.c */ pointstyle %= POINT_TYPES; } if(!END_OF_COMMAND && almost_equals(c_token, "nopo$intstyle")) { pointstyle = -1; /* UNSET */ c_token++; } if(!END_OF_COMMAND && almost_equals(c_token, "of$fset")) { c_token++; if (END_OF_COMMAND) int_error(c_token, "Expected horizontal offset"); hoff = real(const_express(&a)); /* c_token++; */ if (!equals(c_token, ",")) int_error(c_token, "Expected comma"); c_token++; if (END_OF_COMMAND) int_error(c_token, "Expected vertical offset"); voff = real(const_express(&a)); set_offset = TRUE; } if (!END_OF_COMMAND) int_error(c_token, "extraenous or out-of-order arguments in set label"); /* OK! add label */ if (first_label != NULL) { /* skip to last label */ for (this_label = first_label; this_label != NULL; prev_label = this_label, this_label = this_label->next) /* is this the label we want? */ if (tag <= this_label->tag) break; } if (this_label != NULL && tag == this_label->tag) { /* changing the label */ if (set_position) { this_label->place = pos; } if (set_text) this_label->text = text; if (set_just) this_label->pos = just; if (set_rot) this_label->rotate = rotate; if (set_layer) this_label->layer = layer; if (set_font) this_label->font = font; if (pointstyle != -2) this_label->pointstyle = pointstyle; if (set_offset) { this_label->hoffset = hoff; this_label->voffset = voff; } } else { /* adding the label */ new_label = (struct text_label *) gp_alloc(sizeof(struct text_label), "label"); if (prev_label != NULL) prev_label->next = new_label; /* add it to end of list */ else first_label = new_label; /* make it start of list */ new_label->tag = tag; new_label->next = this_label; new_label->place = pos; new_label->text = text; new_label->pos = just; new_label->rotate = rotate; new_label->layer = layer; new_label->font = font; if (pointstyle == -2) new_label->pointstyle = -1; /* unset */ else new_label->pointstyle = pointstyle; new_label->hoffset = hoff; new_label->voffset = voff; } } /* Entry font added by DJL */ /* assign a new label tag * labels are kept sorted by tag number, so this is easy * returns the lowest unassigned tag number */ static int assign_label_tag() { struct text_label *this_label; int last = 0; /* previous tag value */ for (this_label = first_label; this_label != NULL; this_label = this_label->next) if (this_label->tag == last + 1) last++; else break; return (last + 1); } /* process 'set loadpath' command */ static void set_loadpath() { /* We pick up all loadpath elements here before passing * them on to set_var_loadpath() */ char *collect = NULL; c_token++; if (END_OF_COMMAND) { clear_loadpath(); } else while (!END_OF_COMMAND) { if (isstring(c_token)) { int len; char *ss = gp_alloc(token_len(c_token), "tmp storage"); len = (collect? strlen(collect) : 0); quote_str(ss,c_token,token_len(c_token)); collect = gp_realloc(collect, len+1+strlen(ss)+1, "tmp loadpath"); if (len != 0) { strcpy(collect+len+1,ss); *(collect+len) = PATHSEP; } else strcpy(collect,ss); free(ss); ++c_token; } else { int_error(c_token, "Expected string"); } } if (collect) { set_var_loadpath(collect); free(collect); } } /* process 'set locale' command */ static void set_locale() { c_token++; if (END_OF_COMMAND) { init_locale(); } else if (isstring(c_token)) { char *ss = gp_alloc (token_len(c_token), "tmp locale"); quote_str(ss,c_token,token_len(c_token)); set_var_locale(ss); free(ss); ++c_token; } else { int_error(c_token, "Expected string"); } } /* FIXME - check whether the next two functions can be merged */ /* process 'set logscale' command */ static void set_logscale() { c_token++; if (END_OF_COMMAND) { INIT_AXIS_ARRAY(log,TRUE); INIT_AXIS_ARRAY(base, 10.0); } else { TBOOLEAN set_for_axis[AXIS_ARRAY_SIZE] = AXIS_ARRAY_INITIALIZER(FALSE); int axis; double newbase = 10; if ((axis = lookup_table(axisname_tbl, c_token)) >= 0) { set_for_axis[axis] = TRUE; } else { /* must not see x when x2, etc */ if (chr_in_str(c_token, 'x')) set_for_axis[FIRST_X_AXIS] = TRUE; if (chr_in_str(c_token, 'y')) set_for_axis[FIRST_X_AXIS] = TRUE; if (chr_in_str(c_token, 'z')) set_for_axis[FIRST_X_AXIS] = TRUE; } c_token++; if (!END_OF_COMMAND) { struct value a; newbase = magnitude(const_express(&a)); if (newbase < 1.1) int_error(c_token, "log base must be >= 1.1; logscale unchanged"); } for (axis = 0; axis < AXIS_ARRAY_SIZE; axis++) if (set_for_axis[axis]) { axis_array[axis].log = TRUE; axis_array[axis].base = newbase; } } } /* process 'set mapping3d' command */ static void set_mapping() { c_token++; if (END_OF_COMMAND) /* assuming same as points */ mapping3d = MAP3D_CARTESIAN; else if (almost_equals(c_token, "ca$rtesian")) mapping3d = MAP3D_CARTESIAN; else if (almost_equals(c_token, "s$pherical")) mapping3d = MAP3D_SPHERICAL; else if (almost_equals(c_token, "cy$lindrical")) mapping3d = MAP3D_CYLINDRICAL; else int_error(c_token, "expecting 'cartesian', 'spherical', or 'cylindrical'"); c_token++; } /* FIXME - merge set_*margin() functions */ #define PROCESS_MARGIN(MARGIN) \ c_token++; \ if (END_OF_COMMAND) \ MARGIN = -1; \ else { \ struct value a; \ MARGIN = real(const_express(&a)); \ } /* process 'set bmargin' command */ static void set_bmargin() { PROCESS_MARGIN(bmargin); } /* process 'set lmargin' command */ static void set_lmargin() { PROCESS_MARGIN(lmargin); } /* process 'set rmargin' command */ static void set_rmargin() { PROCESS_MARGIN(rmargin); } /* process 'set tmargin' command */ static void set_tmargin() { PROCESS_MARGIN(tmargin); } /* process 'set missing' command */ static void set_missing() { c_token++; if (END_OF_COMMAND) { if (missing_val) free(missing_val); missing_val = NULL; } else { if (!isstring(c_token)) int_error(c_token, "Expected missing-value string"); m_quote_capture(&missing_val, c_token, c_token); c_token++; } } #ifdef USE_MOUSE static void set_mouse() { c_token++; mouse_setting.on = 1; while (!END_OF_COMMAND) { if (almost_equals(c_token, "do$ubleclick")) { struct value a; ++c_token; mouse_setting.doubleclick = real(const_express(&a)); if (mouse_setting.doubleclick < 0) mouse_setting.doubleclick = 0; } else if (almost_equals(c_token, "nodo$ubleclick")) { mouse_setting.doubleclick = 0; /* double click off */ ++c_token; } else if (almost_equals(c_token, "zoomco$ordinates")) { mouse_setting.annotate_zoom_box = 1; ++c_token; } else if (almost_equals(c_token, "nozoomco$ordinates")) { mouse_setting.annotate_zoom_box = 0; ++c_token; } else if (almost_equals(c_token, "po$lardistance")) { mouse_setting.polardistance = 1; ++c_token; } else if (almost_equals(c_token, "nopo$lardistance")) { mouse_setting.polardistance = 0; ++c_token; } else if (equals(c_token, "labels")) { mouse_setting.label = 1; ++c_token; /* check if the optional argument "