[BACK]Return to set.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/set.c, Revision 1.1

1.1     ! maekawa     1: #ifndef lint
        !             2: static char *RCSid = "$Id: set.c,v 1.68 1998/06/22 12:24:54 ddenholm Exp $";
        !             3: #endif
        !             4:
        !             5: /* GNUPLOT - set.c */
        !             6:
        !             7: /*[
        !             8:  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
        !             9:  *
        !            10:  * Permission to use, copy, and distribute this software and its
        !            11:  * documentation for any purpose with or without fee is hereby granted,
        !            12:  * provided that the above copyright notice appear in all copies and
        !            13:  * that both that copyright notice and this permission notice appear
        !            14:  * in supporting documentation.
        !            15:  *
        !            16:  * Permission to modify the software is granted, but not the right to
        !            17:  * distribute the complete modified source code.  Modifications are to
        !            18:  * be distributed as patches to the released version.  Permission to
        !            19:  * distribute binaries produced by compiling modified sources is granted,
        !            20:  * provided you
        !            21:  *   1. distribute the corresponding source modifications from the
        !            22:  *    released version in the form of a patch file along with the binaries,
        !            23:  *   2. add special version identification to distinguish your version
        !            24:  *    in addition to the base release version number,
        !            25:  *   3. provide your name and address as the primary contact for the
        !            26:  *    support of your modified version, and
        !            27:  *   4. retain our contact information in regard to use of the base
        !            28:  *    software.
        !            29:  * Permission to distribute the released version of the source code along
        !            30:  * with corresponding source modifications in the form of a patch file is
        !            31:  * granted with same provisions 2 through 4 for binary distributions.
        !            32:  *
        !            33:  * This software is provided "as is" without express or implied warranty
        !            34:  * to the extent permitted by applicable law.
        !            35: ]*/
        !            36:
        !            37:
        !            38: /*
        !            39:  * 19 September 1992  Lawrence Crowl  (crowl@cs.orst.edu)
        !            40:  * Added user-specified bases for log scaling.
        !            41:  */
        !            42:
        !            43: #include "plot.h"
        !            44: #include "stdfn.h"
        !            45: #include "setshow.h"
        !            46: #include "national.h"
        !            47:
        !            48: #define DEF_FORMAT   "%g"      /* default format for tic mark labels */
        !            49: #define SIGNIF (0.01)          /* less than one hundredth of a tic mark */
        !            50:
        !            51: /*
        !            52:  * global variables to hold status of 'set' options
        !            53:  *
        !            54:  * IMPORTANT NOTE:
        !            55:  * ===============
        !            56:  * If you change the default values of one of the variables below, or if
        !            57:  * you add another global variable, make sure that the change you make is
        !            58:  * done in reset_command() as well (if that makes sense).
        !            59:  */
        !            60:
        !            61: TBOOLEAN autoscale_r = DTRUE;
        !            62: TBOOLEAN autoscale_t = DTRUE;
        !            63: TBOOLEAN autoscale_u = DTRUE;
        !            64: TBOOLEAN autoscale_v = DTRUE;
        !            65: TBOOLEAN autoscale_x = DTRUE;
        !            66: TBOOLEAN autoscale_y = DTRUE;
        !            67: TBOOLEAN autoscale_z = DTRUE;
        !            68: TBOOLEAN autoscale_x2 = DTRUE;
        !            69: TBOOLEAN autoscale_y2 = DTRUE;
        !            70: TBOOLEAN autoscale_lt = DTRUE;
        !            71: TBOOLEAN autoscale_lu = DTRUE;
        !            72: TBOOLEAN autoscale_lv = DTRUE;
        !            73: TBOOLEAN autoscale_lx = DTRUE;
        !            74: TBOOLEAN autoscale_ly = DTRUE;
        !            75: TBOOLEAN autoscale_lz = DTRUE;
        !            76: TBOOLEAN multiplot = FALSE;
        !            77:
        !            78: double boxwidth = -1.0;                /* box width (automatic) */
        !            79: TBOOLEAN clip_points = FALSE;
        !            80: TBOOLEAN clip_lines1 = TRUE;
        !            81: TBOOLEAN clip_lines2 = FALSE;
        !            82: struct lp_style_type border_lp = { 0, -2, 0, 1.0, 1.0 };
        !            83: int draw_border = 31;
        !            84: TBOOLEAN draw_surface = TRUE;
        !            85: char dummy_var[MAX_NUM_VAR][MAX_ID_LEN+1] = { "x", "y" };
        !            86: char default_font[MAX_ID_LEN+1] = "";  /* Entry font added by DJL */
        !            87: char xformat[MAX_ID_LEN+1] = DEF_FORMAT;
        !            88: char yformat[MAX_ID_LEN+1] = DEF_FORMAT;
        !            89: char zformat[MAX_ID_LEN+1] = DEF_FORMAT;
        !            90: char x2format[MAX_ID_LEN+1] = DEF_FORMAT;
        !            91: char y2format[MAX_ID_LEN+1] = DEF_FORMAT;
        !            92:
        !            93: /* do formats look like times - use FIRST_X_AXIS etc as index
        !            94:  * - never saved or shown ...
        !            95:  */
        !            96: #if AXIS_ARRAY_SIZE != 10
        !            97: # error error in initialiser for format_is_numeric
        !            98: #endif
        !            99:
        !           100: int format_is_numeric[AXIS_ARRAY_SIZE] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
        !           101:
        !           102: enum PLOT_STYLE data_style = POINTSTYLE;
        !           103: enum PLOT_STYLE func_style = LINES;
        !           104: double bar_size = 1.0;
        !           105: struct lp_style_type work_grid = { 0, GRID_OFF, 0, 1.0, 1.0 };
        !           106: struct lp_style_type grid_lp   = { 0, -1, 0, 1.0, 1.0 };
        !           107: struct lp_style_type mgrid_lp  = { 0, -1, 0, 1.0, 1.0 };
        !           108: double polar_grid_angle = 0;   /* nonzero means a polar grid */
        !           109: int key = -1;                  /* default position */
        !           110: struct position key_user_pos;  /* user specified position for key */
        !           111: TBOOLEAN key_reverse = FALSE;  /* reverse text & sample ? */
        !           112: struct lp_style_type key_box = { 0, -3, 0, 1.0, 1.0 };         /* -3 = no linetype */
        !           113: double key_swidth = 4.0;
        !           114: double key_vert_factor = 1.0;
        !           115: double key_width_fix = 0.0;
        !           116: TBOOLEAN is_log_x = FALSE;
        !           117: TBOOLEAN is_log_y = FALSE;
        !           118: TBOOLEAN is_log_z = FALSE;
        !           119: TBOOLEAN is_log_x2 = FALSE;
        !           120: TBOOLEAN is_log_y2 = FALSE;
        !           121: double base_log_x = 0.0;
        !           122: double base_log_y = 0.0;
        !           123: double base_log_z = 0.0;
        !           124: double base_log_x2 = 0.0;
        !           125: double base_log_y2 = 0.0;
        !           126: double log_base_log_x = 0.0;
        !           127: double log_base_log_y = 0.0;
        !           128: double log_base_log_z = 0.0;
        !           129: double log_base_log_x2 = 0.0;
        !           130: double log_base_log_y2 = 0.0;
        !           131: FILE *gpoutfile;
        !           132: char *outstr = NULL;           /* means "STDOUT" */
        !           133: TBOOLEAN parametric = FALSE;
        !           134: double pointsize = 1.0;
        !           135: int encoding;
        !           136: char *encoding_names[] = { "default", "iso_8859_1", "cp437", "cp850", NULL };
        !           137: TBOOLEAN polar = FALSE;
        !           138: TBOOLEAN hidden3d = FALSE;
        !           139: TBOOLEAN label_contours = TRUE;        /* different linestyles are used for contours when set */
        !           140: char contour_format[32] = "%8.3g";     /* format for contour key entries */
        !           141: int angles_format = ANGLES_RADIANS;
        !           142: double ang2rad = 1.0;          /* 1 or pi/180, tracking angles_format */
        !           143: int mapping3d = MAP3D_CARTESIAN;
        !           144: int samples = SAMPLES;         /* samples is always equal to samples_1 */
        !           145: int samples_1 = SAMPLES;
        !           146: int samples_2 = SAMPLES;
        !           147: int iso_samples_1 = ISO_SAMPLES;
        !           148: int iso_samples_2 = ISO_SAMPLES;
        !           149: float xsize = 1.0;             /* scale factor for size */
        !           150: float ysize = 1.0;             /* scale factor for size */
        !           151: float zsize = 1.0;             /* scale factor for size */
        !           152: float xoffset = 0.0;           /* x origin */
        !           153: float yoffset = 0.0;           /* y origin */
        !           154: float aspect_ratio = 0.0;      /* don't attempt to force it */
        !           155: float surface_rot_z = 30.0;    /* Default 3d transform. */
        !           156: float surface_rot_x = 60.0;
        !           157: float surface_scale = 1.0;
        !           158: float surface_zscale = 1.0;
        !           159: struct termentry *term = NULL; /* unknown */
        !           160: char term_options[MAX_LINE_LEN+1] = "";
        !           161: label_struct title = { "", 0.0, 0.0, "" };
        !           162: label_struct timelabel = { "", 0.0, 0.0, "" };
        !           163: label_struct xlabel = { "", 0.0, 0.0, "" };
        !           164: label_struct ylabel = { "", 0.0, 0.0, "" };
        !           165: label_struct zlabel = { "", 0.0, 0.0, "" };
        !           166: label_struct x2label = { "", 0.0, 0.0, "" };
        !           167: label_struct y2label = { "", 0.0, 0.0, "" };
        !           168:
        !           169: int timelabel_rotate = FALSE;
        !           170: int timelabel_bottom = TRUE;
        !           171: char key_title[MAX_LINE_LEN+1] = "";
        !           172: double rmin = -0.0;
        !           173: double rmax = 10.0;
        !           174: double tmin = -5.0;
        !           175: double tmax = 5.0;
        !           176: double umin = -5.0;
        !           177: double umax = 5.0;
        !           178: double vmin = -5.0;
        !           179: double vmax = 5.0;
        !           180: double xmin = -10.0;
        !           181: double xmax = 10.0;
        !           182: double ymin = -10.0;
        !           183: double ymax = 10.0;
        !           184: double zmin = -10.0;
        !           185: double zmax = 10.0;
        !           186: double x2min = -10.0;
        !           187: double x2max = 10.0;
        !           188: double y2min = -10.0;
        !           189: double y2max = 10.0;
        !           190: double loff = 0.0;
        !           191: double roff = 0.0;
        !           192: double toff = 0.0;
        !           193: double boff = 0.0;
        !           194: int draw_contour = CONTOUR_NONE;
        !           195: int contour_pts = 5;
        !           196: int contour_kind = CONTOUR_KIND_LINEAR;
        !           197: int contour_order = 4;
        !           198: int contour_levels = 5;
        !           199: double zero = ZERO;            /* zero threshold, not 0! */
        !           200: int levels_kind = LEVELS_AUTO;
        !           201: double levels_list[MAX_DISCRETE_LEVELS];       /* storage for z levels to draw contours at */
        !           202:
        !           203: int dgrid3d_row_fineness = 10;
        !           204: int dgrid3d_col_fineness = 10;
        !           205: int dgrid3d_norm_value = 1;
        !           206: TBOOLEAN dgrid3d = FALSE;
        !           207:
        !           208: struct lp_style_type xzeroaxis = { 0, -3, 0, 1.0, 1.0 };
        !           209: struct lp_style_type yzeroaxis = { 0, -3, 0, 1.0, 1.0 };
        !           210: struct lp_style_type x2zeroaxis = { 0, -3, 0, 1.0, 1.0 };
        !           211: struct lp_style_type y2zeroaxis = { 0, -3, 0, 1.0, 1.0 };
        !           212:
        !           213: /* perhaps make these into an array one day */
        !           214:
        !           215: int xtics = TICS_ON_BORDER | TICS_MIRROR;
        !           216: int ytics = TICS_ON_BORDER | TICS_MIRROR;
        !           217: int ztics = TICS_ON_BORDER;    /* no mirror by default for ztics */
        !           218: int x2tics = NO_TICS;
        !           219: int y2tics = NO_TICS;
        !           220:
        !           221: TBOOLEAN rotate_xtics = FALSE;
        !           222: TBOOLEAN rotate_ytics = FALSE;
        !           223: TBOOLEAN rotate_ztics = FALSE;
        !           224: TBOOLEAN rotate_x2tics = FALSE;
        !           225: TBOOLEAN rotate_y2tics = FALSE;
        !           226:
        !           227: int range_flags[AXIS_ARRAY_SIZE];      /* = {0,0,...} */
        !           228:
        !           229: int mxtics = MINI_DEFAULT;
        !           230: int mytics = MINI_DEFAULT;
        !           231: int mztics = MINI_DEFAULT;
        !           232: int mx2tics = MINI_DEFAULT;
        !           233: int my2tics = MINI_DEFAULT;
        !           234:
        !           235: double mxtfreq = 10;           /* # intervals between major */
        !           236: double mytfreq = 10;           /* tic marks */
        !           237: double mztfreq = 10;
        !           238: double mx2tfreq = 10;
        !           239: double my2tfreq = 10;
        !           240:
        !           241: double ticscale = 1.0;         /* scale factor for tic mark */
        !           242: double miniticscale = 0.5;     /* and for minitics */
        !           243:
        !           244: float ticslevel = 0.5;
        !           245:
        !           246: struct ticdef xticdef = { TIC_COMPUTED };
        !           247: struct ticdef yticdef = { TIC_COMPUTED };
        !           248: struct ticdef zticdef = { TIC_COMPUTED };
        !           249: struct ticdef x2ticdef = { TIC_COMPUTED };
        !           250: struct ticdef y2ticdef = { TIC_COMPUTED };
        !           251:
        !           252: TBOOLEAN tic_in = TRUE;
        !           253:
        !           254: struct text_label *first_label = NULL;
        !           255: struct arrow_def *first_arrow = NULL;
        !           256: struct linestyle_def *first_linestyle = NULL;
        !           257:
        !           258: int lmargin = -1;              /* space between left edge and xleft in chars (-1: computed) */
        !           259: int bmargin = -1;              /* space between bottom and ybot in chars (-1: computed) */
        !           260: int rmargin = -1;              /* space between right egde and xright in chars (-1: computed) */
        !           261: int tmargin = -1;              /* space between top egde and ytop in chars (-1: computed) */
        !           262:
        !           263: /* string representing missing values in ascii datafiles */
        !           264: char *missing_val = NULL;
        !           265:
        !           266: /* date&time language conversions */
        !           267:                                 /* extern struct dtconv *dtc; *//* HBB 980317: unused and not defined anywhere !? */
        !           268:
        !           269: /*** other things we need *****/
        !           270:
        !           271: /* input data, parsing variables */
        !           272:
        !           273: extern TBOOLEAN is_3d_plot;
        !           274:
        !           275: /* From plot2d.c */
        !           276: extern struct curve_points *first_plot;
        !           277: /* From plot3d.c */
        !           278: extern struct surface_points *first_3dplot;
        !           279:
        !           280: int key_hpos = TRIGHT;         /* place for curve-labels, corner or outside */
        !           281: int key_vpos = TTOP;           /* place for curve-labels, corner or below */
        !           282: int key_just = JRIGHT;         /* alignment of key labels, left or right */
        !           283:
        !           284: #ifndef TIMEFMT
        !           285: #define TIMEFMT "%d/%m/%y\n%H:%M"
        !           286: #endif
        !           287: /* format for date/time for reading time in datafile */
        !           288: char timefmt[25] = TIMEFMT;
        !           289:
        !           290: /* array of datatypes (x in 0,y in 1,z in 2,..(rtuv)) */
        !           291: /* not sure how rtuv come into it ?
        !           292:  * oh well, make first six compatible with FIRST_X_AXIS, etc
        !           293:  */
        !           294: int datatype[DATATYPE_ARRAY_SIZE];
        !           295:
        !           296: char cur_locale[MAX_ID_LEN+1] = "C";
        !           297:
        !           298: /* not set or shown directly, but controlled by 'set locale'
        !           299:  * defined in national.h
        !           300:  */
        !           301:
        !           302: char full_month_names[12][32] =
        !           303: { FMON01, FMON02, FMON03, FMON04, FMON05, FMON06, FMON07, FMON08, FMON09, FMON10, FMON11, FMON12 };
        !           304: char abbrev_month_names[12][8] =
        !           305: { AMON01, AMON02, AMON03, AMON04, AMON05, AMON06, AMON07, AMON08, AMON09, AMON10, AMON11, AMON12 };
        !           306:
        !           307: char full_day_names[7][32] =
        !           308: { FDAY0, FDAY1, FDAY2, FDAY3, FDAY4, FDAY5, FDAY6 };
        !           309: char abbrev_day_names[7][8] =
        !           310: { ADAY0, ADAY1, ADAY2, ADAY3, ADAY4, ADAY5, ADAY6 };
        !           311:
        !           312:
        !           313:
        !           314: /******** Local functions ********/
        !           315: static void get_position __PROTO((struct position * pos));
        !           316: static void get_position_type __PROTO((enum position_type * type, int *axes));
        !           317: static void set_xyzlabel __PROTO((label_struct * label));
        !           318: static void set_label __PROTO((void));
        !           319: static void set_nolabel __PROTO((void));
        !           320: static void set_arrow __PROTO((void));
        !           321: static void set_noarrow __PROTO((void));
        !           322: static void load_tics __PROTO((int axis, struct ticdef * tdef));
        !           323: static void load_tic_user __PROTO((int axis, struct ticdef * tdef));
        !           324: static void free_marklist __PROTO((struct ticmark * list));
        !           325: static void load_tic_series __PROTO((int axis, struct ticdef * tdef));
        !           326: static void load_offsets __PROTO((double *a, double *b, double *c, double *d));
        !           327: static void delete_label __PROTO((struct text_label * prev, struct text_label * this));
        !           328: static int assign_label_tag __PROTO((void));
        !           329: static void delete_arrow __PROTO((struct arrow_def * prev, struct arrow_def * this));
        !           330: static int assign_arrow_tag __PROTO((void));
        !           331: static void set_linestyle __PROTO((void));
        !           332: static void set_nolinestyle __PROTO((void));
        !           333: static int assign_linestyle_tag __PROTO((void));
        !           334: static void delete_linestyle __PROTO((struct linestyle_def * prev, struct linestyle_def * this));
        !           335: static TBOOLEAN set_one __PROTO((void));
        !           336: static TBOOLEAN set_two __PROTO((void));
        !           337: static TBOOLEAN set_three __PROTO((void));
        !           338: static int looks_like_numeric __PROTO((char *));
        !           339: static void set_lp_properties __PROTO((struct lp_style_type * arg, int allow_points, int lt, int pt, double lw, double ps));
        !           340: static void reset_lp_properties __PROTO((struct lp_style_type *arg));
        !           341: static void set_locale __PROTO((char *));
        !           342:
        !           343: static int set_tic_prop __PROTO((int *TICS, int *MTICS, double *FREQ,
        !           344:      struct ticdef * tdef, int AXIS, TBOOLEAN * ROTATE, char *tic_side));
        !           345:
        !           346:
        !           347: /* following code segment appears over and over again */
        !           348: #define GET_NUM_OR_TIME(store,axis) \
        !           349: do{if ( datatype[axis] == TIME && isstring(c_token) ) { \
        !           350:     char ss[80]; struct tm tm; \
        !           351:     quote_str(ss,c_token, 80); ++c_token; \
        !           352:     if (gstrptime(ss,timefmt,&tm)) store = (double) gtimegm(&tm); else store = 0;\
        !           353:    } else {\
        !           354:     struct value value; \
        !           355:     store = real(const_express(&value));\
        !           356:   }}while(0)
        !           357:
        !           358: /******** The 'reset' command ********/
        !           359: void reset_command()
        !           360: {
        !           361:     register struct curve_points *f_p = first_plot;
        !           362:     register struct surface_points *f_3dp = first_3dplot;
        !           363:
        !           364:     c_token++;
        !           365:     first_plot = NULL;
        !           366:     first_3dplot = NULL;
        !           367:     cp_free(f_p);
        !           368:     sp_free(f_3dp);
        !           369:     /* delete arrows */
        !           370:     while (first_arrow != NULL)
        !           371:        delete_arrow((struct arrow_def *) NULL, first_arrow);
        !           372:     /* delete labels */
        !           373:     while (first_label != NULL)
        !           374:        delete_label((struct text_label *) NULL, first_label);
        !           375:     /* delete linestyles */
        !           376:     while (first_linestyle != NULL)
        !           377:        delete_linestyle((struct linestyle_def *) NULL, first_linestyle);
        !           378:     strcpy(dummy_var[0], "x");
        !           379:     strcpy(dummy_var[1], "y");
        !           380:     strcpy(title.text, "");
        !           381:     strcpy(xlabel.text, "");
        !           382:     strcpy(ylabel.text, "");
        !           383:     strcpy(zlabel.text, "");
        !           384:     strcpy(x2label.text, "");
        !           385:     strcpy(y2label.text, "");
        !           386:     *title.font = 0;
        !           387:     *xlabel.font = 0;
        !           388:     *ylabel.font = 0;
        !           389:     *zlabel.font = 0;
        !           390:     *x2label.font = 0;
        !           391:     *y2label.font = 0;
        !           392:     strcpy(key_title, "");
        !           393:     strcpy(timefmt, TIMEFMT);
        !           394:     strcpy(xformat, DEF_FORMAT);
        !           395:     strcpy(yformat, DEF_FORMAT);
        !           396:     strcpy(zformat, DEF_FORMAT);
        !           397:     strcpy(x2format, DEF_FORMAT);
        !           398:     strcpy(y2format, DEF_FORMAT);
        !           399:     format_is_numeric[FIRST_X_AXIS] = format_is_numeric[SECOND_X_AXIS] = 1;
        !           400:     format_is_numeric[FIRST_Y_AXIS] = format_is_numeric[SECOND_Y_AXIS] = 1;
        !           401:     format_is_numeric[FIRST_Z_AXIS] = format_is_numeric[SECOND_Z_AXIS] = 1;
        !           402:     autoscale_r = DTRUE;
        !           403:     autoscale_t = DTRUE;
        !           404:     autoscale_u = DTRUE;
        !           405:     autoscale_v = DTRUE;
        !           406:     autoscale_x = DTRUE;
        !           407:     autoscale_y = DTRUE;
        !           408:     autoscale_z = DTRUE;
        !           409:     autoscale_x2 = DTRUE;
        !           410:     autoscale_y2 = DTRUE;
        !           411:     autoscale_lt = DTRUE;
        !           412:     autoscale_lu = DTRUE;
        !           413:     autoscale_lv = DTRUE;
        !           414:     autoscale_lx = DTRUE;
        !           415:     autoscale_ly = DTRUE;
        !           416:     autoscale_lz = DTRUE;
        !           417:     boxwidth = -1.0;
        !           418:     clip_points = FALSE;
        !           419:     clip_lines1 = TRUE;
        !           420:     clip_lines2 = FALSE;
        !           421:     set_lp_properties(&border_lp, 0, -2, 0, 1.0, 1.0);
        !           422:     draw_border = 31;
        !           423:     draw_surface = TRUE;
        !           424:     data_style = POINTSTYLE;
        !           425:     func_style = LINES;
        !           426:     bar_size = 1.0;
        !           427:     set_lp_properties(&work_grid, 0, GRID_OFF, 0, 0.5, 1.0);
        !           428:     set_lp_properties(&grid_lp, 0, -1, 0, 0.5, 1.0);
        !           429:     set_lp_properties(&mgrid_lp, 0, -1, 0, 0.5, 1.0);
        !           430:     polar_grid_angle = 0;
        !           431:     key = -1;
        !           432:     is_log_x = FALSE;
        !           433:     is_log_y = FALSE;
        !           434:     is_log_z = FALSE;
        !           435:     is_log_x2 = FALSE;
        !           436:     is_log_y2 = FALSE;
        !           437:     base_log_x = 0.0;
        !           438:     base_log_y = 0.0;
        !           439:     base_log_z = 0.0;
        !           440:     base_log_x2 = 0.0;
        !           441:     base_log_y2 = 0.0;
        !           442:     log_base_log_x = 0.0;
        !           443:     log_base_log_y = 0.0;
        !           444:     log_base_log_z = 0.0;
        !           445:     log_base_log_x2 = 0.0;
        !           446:     log_base_log_y2 = 0.0;
        !           447:     parametric = FALSE;
        !           448:     polar = FALSE;
        !           449:     hidden3d = FALSE;
        !           450:     label_contours = TRUE;
        !           451:     strcpy(contour_format, "%8.3g");
        !           452:     angles_format = ANGLES_RADIANS;
        !           453:     ang2rad = 1.0;
        !           454:     mapping3d = MAP3D_CARTESIAN;
        !           455:     samples = SAMPLES;
        !           456:     samples_1 = SAMPLES;
        !           457:     samples_2 = SAMPLES;
        !           458:     iso_samples_1 = ISO_SAMPLES;
        !           459:     iso_samples_2 = ISO_SAMPLES;
        !           460:     xsize = 1.0;
        !           461:     ysize = 1.0;
        !           462:     zsize = 1.0;
        !           463:     xoffset = 0.0;
        !           464:     yoffset = 0.0;
        !           465:     aspect_ratio = 0.0;                /* dont force it */
        !           466:     surface_rot_z = 30.0;
        !           467:     surface_rot_x = 60.0;
        !           468:     surface_scale = 1.0;
        !           469:     surface_zscale = 1.0;
        !           470:     *timelabel.text = 0;
        !           471:     timelabel.xoffset = 0;
        !           472:     timelabel.yoffset = 0;
        !           473:     *timelabel.font = 0;
        !           474:     timelabel_rotate = FALSE;
        !           475:     timelabel_bottom = TRUE;
        !           476:     title.xoffset = 0;
        !           477:     title.yoffset = 0;
        !           478:     xlabel.xoffset = 0;
        !           479:     xlabel.yoffset = 0;
        !           480:     ylabel.xoffset = 0;
        !           481:     ylabel.yoffset = 0;
        !           482:     zlabel.xoffset = 0;
        !           483:     zlabel.yoffset = 0;
        !           484:     x2label.xoffset = 0;
        !           485:     x2label.yoffset = 0;
        !           486:     y2label.xoffset = 0;
        !           487:     y2label.yoffset = 0;
        !           488:     rmin = -0.0;
        !           489:     rmax = 10.0;
        !           490:     tmin = -5.0;
        !           491:     tmax = 5.0;
        !           492:     umin = -5.0;
        !           493:     umax = 5.0;
        !           494:     vmin = -5.0;
        !           495:     vmax = 5.0;
        !           496:     xmin = -10.0;
        !           497:     xmax = 10.0;
        !           498:     ymin = -10.0;
        !           499:     ymax = 10.0;
        !           500:     zmin = -10.0;
        !           501:     zmax = 10.0;
        !           502:     x2min = -10.0;
        !           503:     x2max = 10.0;
        !           504:     y2min = -10.0;
        !           505:     y2max = 10.0;
        !           506:     memset(range_flags, 0, sizeof(range_flags));       /* all = 0 */
        !           507:
        !           508:     loff = 0.0;
        !           509:     roff = 0.0;
        !           510:     toff = 0.0;
        !           511:     boff = 0.0;
        !           512:     draw_contour = CONTOUR_NONE;
        !           513:     contour_pts = 5;
        !           514:     contour_kind = CONTOUR_KIND_LINEAR;
        !           515:     contour_order = 4;
        !           516:     contour_levels = 5;
        !           517:     zero = ZERO;
        !           518:     levels_kind = LEVELS_AUTO;
        !           519:     dgrid3d_row_fineness = 10;
        !           520:     dgrid3d_col_fineness = 10;
        !           521:     dgrid3d_norm_value = 1;
        !           522:     dgrid3d = FALSE;
        !           523:     set_lp_properties(&xzeroaxis, 0, -3, 0, 1.0, 1.0);
        !           524:     set_lp_properties(&yzeroaxis, 0, -3, 0, 1.0, 1.0);
        !           525:     set_lp_properties(&x2zeroaxis, 0, -3, 0, 1.0, 1.0);
        !           526:     set_lp_properties(&y2zeroaxis, 0, -3, 0, 1.0, 1.0);
        !           527:     xtics =
        !           528:        ytics = TICS_ON_BORDER | TICS_MIRROR;
        !           529:     ztics = TICS_ON_BORDER;    /* no mirror by default */
        !           530:     x2tics = NO_TICS;
        !           531:     y2tics = NO_TICS;
        !           532:     mxtics =
        !           533:        mytics =
        !           534:        mztics =
        !           535:        mx2tics =
        !           536:        my2tics = MINI_DEFAULT;
        !           537:     mxtfreq = 10.0;
        !           538:     mytfreq = 10.0;
        !           539:     mztfreq = 10.0;
        !           540:     mx2tfreq = 10.0;
        !           541:     my2tfreq = 10.0;
        !           542:     ticscale = 1.0;
        !           543:     miniticscale = 0.5;
        !           544:     ticslevel = 0.5;
        !           545:     xticdef.type = TIC_COMPUTED;
        !           546:     yticdef.type = TIC_COMPUTED;
        !           547:     zticdef.type = TIC_COMPUTED;
        !           548:     x2ticdef.type = TIC_COMPUTED;
        !           549:     y2ticdef.type = TIC_COMPUTED;
        !           550:     tic_in = TRUE;
        !           551:     lmargin =
        !           552:        bmargin =
        !           553:        rmargin =
        !           554:        tmargin = -1;           /* autocomputed */
        !           555:     key_hpos = TRIGHT;
        !           556:     key_vpos = TTOP;
        !           557:     key_just = JRIGHT;
        !           558:     key_reverse = FALSE;
        !           559:     set_lp_properties(&key_box, 0, -3, 0, 1.0, 1.0);
        !           560:     key_swidth = 4;
        !           561:     key_vert_factor = 1;
        !           562:     key_width_fix = 0;
        !           563:     datatype[FIRST_X_AXIS] = FALSE;
        !           564:     datatype[FIRST_Y_AXIS] = FALSE;
        !           565:     datatype[FIRST_Z_AXIS] = FALSE;
        !           566:     datatype[SECOND_X_AXIS] = FALSE;
        !           567:     datatype[SECOND_Y_AXIS] = FALSE;
        !           568:     datatype[SECOND_Z_AXIS] = FALSE;
        !           569:     datatype[R_AXIS] = FALSE;
        !           570:     datatype[T_AXIS] = FALSE;
        !           571:     datatype[U_AXIS] = FALSE;
        !           572:     datatype[V_AXIS] = FALSE;
        !           573:
        !           574:     pointsize = 1.0;
        !           575:     encoding = ENCODING_DEFAULT;
        !           576:
        !           577:     set_locale("C");           /* default */
        !           578: }
        !           579:
        !           580: /******** The 'set' command ********/
        !           581: void set_command()
        !           582: {
        !           583:     static char GPFAR setmess[] = "\
        !           584: valid set options:  [] = choose one, {} means optional\n\n\
        !           585: \t'angles',  '{no}arrow',  '{no}autoscale',  'bars',  '{no}border',\n\
        !           586: \t'boxwidth', '{no}clabel', '{no}clip', 'cntrparam', '{no}contour',\n\
        !           587: \t'data style',  '{no}dgrid3d',  'dummy',  'encoding',  'format',\n\
        !           588: \t'function style',   '{no}grid',   '{no}hidden3d',   'isosamples',\n\
        !           589: \t'{no}key', '{no}label', '{no}linestyle', 'locale', '{no}logscale',\n\
        !           590: \t'[blrt]margin', 'mapping', 'missing', '{no}multiplot', 'offsets',\n\
        !           591: \t'origin', 'output', '{no}parametric', 'pointsize', '{no}polar',\n\
        !           592: \t'[rtuv]range',  'samples',  'size',  '{no}surface',  'terminal',\n\
        !           593: \t'tics',  'ticscale',  'ticslevel',  '{no}timestamp',  'timefmt',\n\
        !           594: \t'title', 'view', '[xyz]{2}data', '[xyz]{2}label', '[xyz]{2}range',\n\
        !           595: \t'{no}{m}[xyz]{2}tics', '[xyz]{2}[md]tics', '{no}{[xyz]{2}}zeroaxis',\n\
        !           596: \t'zero'";
        !           597:
        !           598:     c_token++;
        !           599:
        !           600:     if (!set_one() && !set_two() && !set_three())
        !           601:        int_error(setmess, c_token);
        !           602: }
        !           603:
        !           604: /* return TRUE if a command match, FALSE if not */
        !           605: static TBOOLEAN
        !           606: set_one()
        !           607: {
        !           608: /* save on replication with a macro */
        !           609: #define PROCESS_AUTO_LETTER(AUTO, STRING,MIN,MAX) \
        !           610: else if (equals(c_token, STRING))       { AUTO = DTRUE; ++c_token; } \
        !           611: else if (almost_equals(c_token, MIN)) { AUTO |= 1;    ++c_token; } \
        !           612: else if (almost_equals(c_token, MAX)) { AUTO |= 2;    ++c_token; }
        !           613:
        !           614:     if (almost_equals(c_token, "ar$row")) {
        !           615:        c_token++;
        !           616:        set_arrow();
        !           617:     } else if (almost_equals(c_token, "noar$row")) {
        !           618:        c_token++;
        !           619:        set_noarrow();
        !           620:     } else if (almost_equals(c_token, "au$toscale")) {
        !           621:        c_token++;
        !           622:        if (END_OF_COMMAND) {
        !           623:            autoscale_r = autoscale_t = autoscale_x = autoscale_y = autoscale_z = autoscale_x2 = autoscale_y2 = DTRUE;
        !           624:        } else if (equals(c_token, "xy") || equals(c_token, "yx")) {
        !           625:            autoscale_x = autoscale_y = DTRUE;
        !           626:            c_token++;
        !           627:        }
        !           628:        PROCESS_AUTO_LETTER(autoscale_r, "r", "rmi$n", "rma$x")
        !           629:        PROCESS_AUTO_LETTER(autoscale_t, "t", "tmi$n", "tma$x")
        !           630:        PROCESS_AUTO_LETTER(autoscale_u, "u", "umi$n", "uma$x")
        !           631:        PROCESS_AUTO_LETTER(autoscale_v, "v", "vmi$n", "vma$x")
        !           632:        PROCESS_AUTO_LETTER(autoscale_x, "x", "xmi$n", "xma$x")
        !           633:        PROCESS_AUTO_LETTER(autoscale_y, "y", "ymi$n", "yma$x")
        !           634:        PROCESS_AUTO_LETTER(autoscale_z, "z", "zmi$n", "zma$x")
        !           635:        PROCESS_AUTO_LETTER(autoscale_x2, "x2", "x2mi$n", "x2ma$x")
        !           636:        PROCESS_AUTO_LETTER(autoscale_y2, "y2", "y2mi$n", "y2ma$x")
        !           637:        else
        !           638:            int_error("Invalid range", c_token);
        !           639:     } else if (almost_equals(c_token,"noau$toscale")) {
        !           640:        c_token++;
        !           641:        if (END_OF_COMMAND) {
        !           642:            autoscale_r = autoscale_t = autoscale_x = autoscale_y = autoscale_z = FALSE;
        !           643:        } else if (equals(c_token, "xy") || equals(c_token, "tyx")) {
        !           644:            autoscale_x = autoscale_y = FALSE;
        !           645:            c_token++;
        !           646:        } else if (equals(c_token, "r")) {
        !           647:            autoscale_r = FALSE;
        !           648:            c_token++;
        !           649:        } else if (equals(c_token, "t")) {
        !           650:            autoscale_t = FALSE;
        !           651:            c_token++;
        !           652:        } else if (equals(c_token, "u")) {
        !           653:            autoscale_u = FALSE;
        !           654:            c_token++;
        !           655:        } else if (equals(c_token, "v")) {
        !           656:            autoscale_v = FALSE;
        !           657:            c_token++;
        !           658:        } else if (equals(c_token, "x")) {
        !           659:            autoscale_x = FALSE;
        !           660:            c_token++;
        !           661:        } else if (equals(c_token, "y")) {
        !           662:            autoscale_y = FALSE;
        !           663:            c_token++;
        !           664:        } else if (equals(c_token, "z")) {
        !           665:            autoscale_z = FALSE;
        !           666:            c_token++;
        !           667:        }
        !           668:     } else if (almost_equals(c_token,"nobor$der")) {
        !           669:        draw_border = 0;
        !           670:        c_token++;
        !           671:        }
        !           672:     else if (almost_equals(c_token,"box$width")) {
        !           673:        struct value a;
        !           674:        c_token++;
        !           675:        if (END_OF_COMMAND)
        !           676:            boxwidth = -1.0;
        !           677:        else
        !           678: /*              if((boxwidth = real(const_express(&a))) != -2.0)*/
        !           679: /*                      boxwidth = magnitude(const_express(&a));*/
        !           680:            boxwidth = real(const_express(&a));
        !           681:     } else if (almost_equals(c_token,"c$lip")) {
        !           682:        c_token++;
        !           683:        if (END_OF_COMMAND)
        !           684:            /* assuming same as points */
        !           685:            clip_points = TRUE;
        !           686:        else if (almost_equals(c_token, "p$oints"))
        !           687:            clip_points = TRUE;
        !           688:        else if (almost_equals(c_token, "o$ne"))
        !           689:            clip_lines1 = TRUE;
        !           690:        else if (almost_equals(c_token, "t$wo"))
        !           691:            clip_lines2 = TRUE;
        !           692:        else
        !           693:            int_error("expecting 'points', 'one', or 'two'", c_token);
        !           694:        c_token++;
        !           695:     } else if (almost_equals(c_token,"noc$lip")) {
        !           696:        c_token++;
        !           697:        if (END_OF_COMMAND) {
        !           698:            /* same as all three */
        !           699:            clip_points = FALSE;
        !           700:            clip_lines1 = FALSE;
        !           701:            clip_lines2 = FALSE;
        !           702:        } else if (almost_equals(c_token, "p$oints"))
        !           703:            clip_points = FALSE;
        !           704:        else if (almost_equals(c_token, "o$ne"))
        !           705:            clip_lines1 = FALSE;
        !           706:        else if (almost_equals(c_token, "t$wo"))
        !           707:            clip_lines2 = FALSE;
        !           708:        else
        !           709:            int_error("expecting 'points', 'one', or 'two'", c_token);
        !           710:        c_token++;
        !           711:     } else if (almost_equals(c_token,"hi$dden3d")) {
        !           712: #ifdef LITE
        !           713:        printf(" Hidden Line Removal Not Supported in LITE version\n");
        !           714:        c_token++;
        !           715: #else
        !           716:        /* HBB 970618: new parsing engine for hidden3d options */
        !           717:        set_hidden3doptions();
        !           718:        hidden3d = TRUE;
        !           719: #endif /* LITE */
        !           720:     } else if (almost_equals(c_token,"nohi$dden3d")) {
        !           721: #ifdef LITE
        !           722:        printf(" Hidden Line Removal Not Supported in LITE version\n");
        !           723: #else
        !           724:        hidden3d = FALSE;
        !           725: #endif /* LITE */
        !           726:        c_token++;
        !           727:     } else if (almost_equals(c_token,"cla$bel")) {
        !           728:        label_contours = TRUE;
        !           729:        c_token++;
        !           730:        if (isstring(c_token))
        !           731:            quote_str(contour_format, c_token++, 30);
        !           732:     } else if (almost_equals(c_token,"nocla$bel")) {
        !           733:        label_contours = FALSE;
        !           734:        c_token++;
        !           735:     } else if (almost_equals(c_token,"ma$pping3d")) {
        !           736:        c_token++;
        !           737:        if (END_OF_COMMAND)
        !           738:            /* assuming same as points */
        !           739:            mapping3d = MAP3D_CARTESIAN;
        !           740:        else if (almost_equals(c_token, "ca$rtesian"))
        !           741:            mapping3d = MAP3D_CARTESIAN;
        !           742:        else if (almost_equals(c_token, "s$pherical"))
        !           743:            mapping3d = MAP3D_SPHERICAL;
        !           744:        else if (almost_equals(c_token, "cy$lindrical"))
        !           745:            mapping3d = MAP3D_CYLINDRICAL;
        !           746:        else
        !           747:            int_error("expecting 'cartesian', 'spherical', or 'cylindrical'", c_token);
        !           748:        c_token++;
        !           749:     } else if (almost_equals(c_token,"co$ntour")) {
        !           750:        c_token++;
        !           751:        if (END_OF_COMMAND)
        !           752:            /* assuming same as points */
        !           753:            draw_contour = CONTOUR_BASE;
        !           754:        else {
        !           755:            if (almost_equals(c_token, "ba$se"))
        !           756:                draw_contour = CONTOUR_BASE;
        !           757:            else if (almost_equals(c_token, "s$urface"))
        !           758:                draw_contour = CONTOUR_SRF;
        !           759:            else if (almost_equals(c_token, "bo$th"))
        !           760:                draw_contour = CONTOUR_BOTH;
        !           761:            else
        !           762:                int_error("expecting 'base', 'surface', or 'both'", c_token);
        !           763:            c_token++;
        !           764:        }
        !           765:     } else if (almost_equals(c_token,"noco$ntour")) {
        !           766:        c_token++;
        !           767:        draw_contour = CONTOUR_NONE;
        !           768:     } else if (almost_equals(c_token,"cntrp$aram")) {
        !           769:        struct value a;
        !           770:
        !           771:        c_token++;
        !           772:        if (END_OF_COMMAND) {
        !           773:            /* assuming same as defaults */
        !           774:            contour_pts = 5;
        !           775:            contour_kind = CONTOUR_KIND_LINEAR;
        !           776:            contour_order = 4;
        !           777:            contour_levels = 5;
        !           778:            levels_kind = LEVELS_AUTO;
        !           779:        } else if (almost_equals(c_token, "p$oints")) {
        !           780:            c_token++;
        !           781:            contour_pts = (int) real(const_express(&a));
        !           782:        } else if (almost_equals(c_token, "li$near")) {
        !           783:            c_token++;
        !           784:            contour_kind = CONTOUR_KIND_LINEAR;
        !           785:        } else if (almost_equals(c_token, "c$ubicspline")) {
        !           786:            c_token++;
        !           787:            contour_kind = CONTOUR_KIND_CUBIC_SPL;
        !           788:        } else if (almost_equals(c_token, "b$spline")) {
        !           789:            c_token++;
        !           790:            contour_kind = CONTOUR_KIND_BSPLINE;
        !           791:        } else if (almost_equals(c_token, "le$vels")) {
        !           792:            int i = 0;  /* local counter */
        !           793:            c_token++;
        !           794:            /*  RKC: I have modified the next two:
        !           795:             *   to use commas to separate list elements as in xtics
        !           796:             *   so that incremental lists start,incr[,end]as in "
        !           797:             */
        !           798:            if (almost_equals(c_token, "di$screte")) {
        !           799:                levels_kind = LEVELS_DISCRETE;
        !           800:                c_token++;
        !           801:                if(END_OF_COMMAND)
        !           802:                    int_error("expecting discrete level", c_token);
        !           803:                else
        !           804:                    levels_list[i++] = real(const_express(&a));
        !           805:
        !           806:                while(!END_OF_COMMAND) {
        !           807:                    if (!equals(c_token, ","))
        !           808:                        int_error("expecting comma to separate discrete levels", c_token);
        !           809:                    c_token++;
        !           810:                    levels_list[i++] = real(const_express(&a));
        !           811:                }
        !           812:                contour_levels = i;
        !           813:            } else if (almost_equals(c_token, "in$cremental")) {
        !           814:                levels_kind = LEVELS_INCREMENTAL;
        !           815:                c_token++;
        !           816:                levels_list[i++] = real(const_express(&a));
        !           817:                if (!equals(c_token, ","))
        !           818:                    int_error("expecting comma to separate start,incr levels", c_token);
        !           819:                c_token++;
        !           820:                if((levels_list[i++] = real(const_express(&a))) == 0)
        !           821:                    int_error("increment cannot be 0", c_token);
        !           822:                if(!END_OF_COMMAND) {
        !           823:                    if (!equals(c_token, ","))
        !           824:                        int_error("expecting comma to separate incr,stop levels", c_token);
        !           825:                    c_token++;
        !           826:                    /* need to round up, since 10,10,50 is 5 levels, not four,
        !           827:                     * but 10,10,49 is four
        !           828:                     */
        !           829:                    contour_levels = (int) ( (real(const_express(&a))-levels_list[0])/levels_list[1] + 1.0);
        !           830:                }
        !           831:            } else if (almost_equals(c_token, "au$to")) {
        !           832:                levels_kind = LEVELS_AUTO;
        !           833:                c_token++;
        !           834:                if(!END_OF_COMMAND)
        !           835:                    contour_levels = (int) real(const_express(&a));
        !           836:            } else {
        !           837:                if(levels_kind == LEVELS_DISCRETE)
        !           838:                    int_error("Levels type is discrete, ignoring new number of contour levels", c_token);
        !           839:                contour_levels = (int) real(const_express(&a));
        !           840:            }
        !           841:        } else if (almost_equals(c_token, "o$rder")) {
        !           842:            int order;
        !           843:            c_token++;
        !           844:            order = (int) real(const_express(&a));
        !           845:            if ( order < 2 || order > 10 )
        !           846:                int_error("bspline order must be in [2..10] range.", c_token);
        !           847:                contour_order = order;
        !           848:        } else
        !           849:            int_error("expecting 'linear', 'cubicspline', 'bspline', 'points', 'levels' or 'order'", c_token);
        !           850:     } else if (almost_equals(c_token,"da$ta")) {
        !           851:        c_token++;
        !           852:        if (!almost_equals(c_token,"s$tyle"))
        !           853:            int_error("expecting keyword 'style'",c_token);
        !           854:        data_style = get_style();
        !           855:     } else if (almost_equals(c_token,"dg$rid3d")) {
        !           856:        int i;
        !           857:        TBOOLEAN was_comma = TRUE;
        !           858:        int local_vals[3];
        !           859:        struct value a;
        !           860:
        !           861:        local_vals[0] = dgrid3d_row_fineness;
        !           862:        local_vals[1] = dgrid3d_col_fineness;
        !           863:        local_vals[2] = dgrid3d_norm_value;
        !           864:        c_token++;
        !           865:        for (i = 0; i < 3 && !(END_OF_COMMAND);) {
        !           866:            if (equals(c_token,",")) {
        !           867:                if (was_comma) i++;
        !           868:                    was_comma = TRUE;
        !           869:                c_token++;
        !           870:            } else {
        !           871:                if (!was_comma)
        !           872:                    int_error("',' expected",c_token);
        !           873:                local_vals[i] = real(const_express(&a));
        !           874:                i++;
        !           875:                was_comma = FALSE;
        !           876:            }
        !           877:        }
        !           878:
        !           879:        if (local_vals[0] < 2 || local_vals[0] > 1000)
        !           880:            int_error("Row size must be in [2:1000] range; size unchanged",
        !           881:                      c_token);
        !           882:        if (local_vals[1] < 2 || local_vals[1] > 1000)
        !           883:            int_error("Col size must be in [2:1000] range; size unchanged",
        !           884:                      c_token);
        !           885:        if (local_vals[2] < 1 || local_vals[2] > 100)
        !           886:            int_error("Norm must be in [1:100] range; norm unchanged", c_token);
        !           887:
        !           888:        dgrid3d_row_fineness = local_vals[0];
        !           889:        dgrid3d_col_fineness = local_vals[1];
        !           890:        dgrid3d_norm_value = local_vals[2];
        !           891:        dgrid3d = TRUE;
        !           892:     } else if (almost_equals(c_token,"nodg$rid3d")) {
        !           893:        c_token++;
        !           894:        dgrid3d = FALSE;
        !           895:     } else if (almost_equals(c_token,"mis$sing")) {
        !           896:        c_token++;
        !           897:        if (END_OF_COMMAND) {
        !           898:            if (missing_val)
        !           899:                free(missing_val);
        !           900:            missing_val = NULL;
        !           901:        } else {
        !           902:            if (!isstring(c_token))
        !           903:                int_error("Expected missing-value string", c_token);
        !           904:            m_quote_capture(&missing_val, c_token, c_token);
        !           905:            c_token++;
        !           906:        }
        !           907:     } else if (almost_equals(c_token,"nomis$sing")) {
        !           908:        ++c_token;
        !           909:        if (missing_val)
        !           910:            free(missing_val);
        !           911:        missing_val = NULL;
        !           912:     } else if (almost_equals(c_token,"du$mmy")) {
        !           913:        c_token++;
        !           914:        if (END_OF_COMMAND)
        !           915:            int_error("expecting dummy variable name", c_token);
        !           916:        else {
        !           917:            if (!equals(c_token,","))
        !           918:                copy_str(dummy_var[0],c_token++, MAX_ID_LEN);
        !           919:            if (!END_OF_COMMAND && equals(c_token,",")) {
        !           920:                c_token++;
        !           921:                if (END_OF_COMMAND)
        !           922:                    int_error("expecting second dummy variable name", c_token);
        !           923:                copy_str(dummy_var[1],c_token++, MAX_ID_LEN);
        !           924:            }
        !           925:        }
        !           926:     } else if (almost_equals(c_token,"fo$rmat")) {
        !           927:        TBOOLEAN setx = FALSE, sety = FALSE, setz = FALSE;
        !           928:        TBOOLEAN setx2 = FALSE, sety2 = FALSE;
        !           929:        c_token++;
        !           930:        if (equals(c_token,"x")) {
        !           931:            setx = TRUE;
        !           932:            c_token++;
        !           933:        } else if (equals(c_token,"y")) {
        !           934:            sety = TRUE;
        !           935:            c_token++;
        !           936:        } else if (equals(c_token,"x2")) {
        !           937:                setx2 = TRUE;
        !           938:                c_token++;
        !           939:        } else if (equals(c_token,"y2")) {
        !           940:                sety2 = TRUE;
        !           941:                c_token++;
        !           942:        } else if (equals(c_token,"z")) {
        !           943:                setz = TRUE;
        !           944:                c_token++;
        !           945:        } else if (equals(c_token,"xy") || equals(c_token,"yx")) {
        !           946:                setx = sety = TRUE;
        !           947:                c_token++;
        !           948:        } else if (isstring(c_token) || END_OF_COMMAND) {
        !           949:                /* Assume he wants all */
        !           950:                setx = sety = setz = setx2 = sety2 = TRUE;
        !           951:        }
        !           952:
        !           953:        if (END_OF_COMMAND) {
        !           954:            if (setx) {
        !           955:                (void) strcpy(xformat,DEF_FORMAT);
        !           956:                format_is_numeric[FIRST_X_AXIS] = 1;
        !           957:            }
        !           958:            if (sety) {
        !           959:                (void) strcpy(yformat,DEF_FORMAT);
        !           960:                format_is_numeric[FIRST_Y_AXIS] = 1;
        !           961:            }
        !           962:            if (setz) {
        !           963:                (void) strcpy(zformat,DEF_FORMAT);
        !           964:                format_is_numeric[FIRST_Z_AXIS] = 1;
        !           965:            }
        !           966:            if (setx2) {
        !           967:                (void) strcpy(x2format,DEF_FORMAT);
        !           968:                format_is_numeric[SECOND_X_AXIS] = 1;
        !           969:            }
        !           970:            if (sety2) {
        !           971:                (void) strcpy(y2format,DEF_FORMAT);
        !           972:                format_is_numeric[SECOND_Y_AXIS] = 1;
        !           973:            }
        !           974:        } else {
        !           975:            if (!isstring(c_token))
        !           976:                int_error("expecting format string",c_token);
        !           977:            else {
        !           978:                if (setx) {
        !           979:                    quote_str(xformat,c_token, MAX_ID_LEN);
        !           980:                    format_is_numeric[FIRST_X_AXIS] = looks_like_numeric(xformat);
        !           981:                }
        !           982:                if (sety) {
        !           983:                    quote_str(yformat,c_token, MAX_ID_LEN);
        !           984:                    format_is_numeric[FIRST_Y_AXIS] = looks_like_numeric(yformat);
        !           985:                }
        !           986:                if (setz) {
        !           987:                    quote_str(zformat,c_token, MAX_ID_LEN);
        !           988:                    format_is_numeric[FIRST_Z_AXIS] =looks_like_numeric(zformat);
        !           989:                }
        !           990:                if (setx2) {
        !           991:                    quote_str(x2format,c_token, MAX_ID_LEN);
        !           992:                    format_is_numeric[SECOND_X_AXIS] = looks_like_numeric(x2format);
        !           993:                }
        !           994:                if (sety2) {
        !           995:                    quote_str(y2format,c_token, MAX_ID_LEN);
        !           996:                    format_is_numeric[SECOND_Y_AXIS] = looks_like_numeric(y2format);
        !           997:                }
        !           998:                c_token++;
        !           999:            }
        !          1000:        }
        !          1001:     } else if (almost_equals(c_token,"fu$nction")) {
        !          1002:        c_token++;
        !          1003:        if (!almost_equals(c_token,"s$tyle"))
        !          1004:            int_error("expecting keyword 'style'",c_token);
        !          1005:        func_style = get_style();
        !          1006:     } else if (almost_equals(c_token,"la$bel")) {
        !          1007:        c_token++;
        !          1008:        set_label();
        !          1009:     } else if (almost_equals(c_token,"nola$bel")) {
        !          1010:        c_token++;
        !          1011:        set_nolabel();
        !          1012:     } else if (almost_equals(c_token,"li$nestyle") || equals(c_token, "ls" )) {
        !          1013:        c_token++;
        !          1014:        set_linestyle();
        !          1015:     } else if (almost_equals(c_token,"noli$nestyle") || equals(c_token, "nols" )) {
        !          1016:        c_token++;
        !          1017:        set_nolinestyle();
        !          1018:     } else if (almost_equals(c_token,"lo$gscale")) {
        !          1019:        c_token++;
        !          1020:        if (END_OF_COMMAND) {
        !          1021:            is_log_x = is_log_y = is_log_z = is_log_x2 = is_log_y2 = TRUE;
        !          1022:            base_log_x = base_log_y = base_log_z = base_log_x2 = base_log_y2 = 10.0;
        !          1023:            log_base_log_x = log_base_log_y = log_base_log_z = log_base_log_x2 = log_base_log_y2 = M_LN10;
        !          1024:        } else {
        !          1025:            TBOOLEAN change_x = FALSE;
        !          1026:            TBOOLEAN change_y = FALSE;
        !          1027:            TBOOLEAN change_z = FALSE;
        !          1028:            TBOOLEAN change_x2 = FALSE;
        !          1029:            TBOOLEAN change_y2 = FALSE;
        !          1030:            double newbase = 10, log_newbase;
        !          1031:
        !          1032:            if (equals(c_token, "x2"))
        !          1033:                change_x2 = TRUE;
        !          1034:            else if (equals(c_token, "y2"))
        !          1035:                change_y2 = TRUE;
        !          1036:            else { /* must not see x when x2, etc */
        !          1037:                if (chr_in_str(c_token, 'x'))
        !          1038:                    change_x = TRUE;
        !          1039:                if (chr_in_str(c_token, 'y'))
        !          1040:                    change_y = TRUE;
        !          1041:                if (chr_in_str(c_token, 'z'))
        !          1042:                    change_z = TRUE;
        !          1043:            }
        !          1044:            c_token++;
        !          1045:            if (!END_OF_COMMAND) {
        !          1046:                struct value a;
        !          1047:                newbase = magnitude(const_express(&a));
        !          1048:                if (newbase < 1.1)
        !          1049:                    int_error("log base must be >= 1.1; logscale unchanged",
        !          1050:                c_token);
        !          1051:            }
        !          1052:            log_newbase = log(newbase);
        !          1053:
        !          1054:            if (change_x) {
        !          1055:                is_log_x = TRUE;
        !          1056:                base_log_x = newbase;
        !          1057:                log_base_log_x = log_newbase;
        !          1058:            }
        !          1059:            if (change_y) {
        !          1060:                is_log_y = TRUE;
        !          1061:                base_log_y = newbase;
        !          1062:                log_base_log_y = log_newbase;
        !          1063:            }
        !          1064:            if (change_z) {
        !          1065:                is_log_z = TRUE;
        !          1066:                base_log_z = newbase;
        !          1067:                log_base_log_z = log_newbase;
        !          1068:            }
        !          1069:            if (change_x2) {
        !          1070:                is_log_x2 = TRUE;
        !          1071:                base_log_x2 = newbase;
        !          1072:                log_base_log_x2 = log_newbase;
        !          1073:            }
        !          1074:            if (change_y2) {
        !          1075:                is_log_y2 = TRUE;
        !          1076:                base_log_y2 = newbase;
        !          1077:                log_base_log_y2 = log_newbase;
        !          1078:            }
        !          1079:        }
        !          1080:     } else if (almost_equals(c_token,"nolo$gscale")) {
        !          1081:        c_token++;
        !          1082:        if (END_OF_COMMAND) {
        !          1083:            is_log_x = is_log_y = is_log_z = is_log_x2 = is_log_y2 = FALSE;
        !          1084:        } else if (equals(c_token, "x2")) {
        !          1085:            is_log_x2 = FALSE; ++c_token;
        !          1086:        } else if (equals(c_token, "y2")) {
        !          1087:            is_log_y2 = FALSE; ++c_token;
        !          1088:        } else {
        !          1089:            if (chr_in_str(c_token, 'x')) {
        !          1090:                is_log_x = FALSE;
        !          1091:                base_log_x = 0.0;
        !          1092:                log_base_log_x = 0.0;
        !          1093:            }
        !          1094:            if (chr_in_str(c_token, 'y')) {
        !          1095:                is_log_y = FALSE;
        !          1096:                base_log_y = 0.0;
        !          1097:                log_base_log_y = 0.0;
        !          1098:            }
        !          1099:            if (chr_in_str(c_token, 'z')) {
        !          1100:                is_log_z = FALSE;
        !          1101:                base_log_z = 0.0;
        !          1102:                log_base_log_z = 0.0;
        !          1103:            }
        !          1104:            c_token++;
        !          1105:        }
        !          1106:     } else if (almost_equals(c_token,"of$fsets")) {
        !          1107:        c_token++;
        !          1108:        if (END_OF_COMMAND) {
        !          1109:            loff = roff = toff = boff = 0.0;  /* Reset offsets */
        !          1110:        } else {
        !          1111:            load_offsets (&loff,&roff,&toff,&boff);
        !          1112:        }
        !          1113:     } else if (almost_equals(c_token, "noof$fsets")) {
        !          1114:        loff = roff = toff = boff = 0.0;
        !          1115:        ++c_token;
        !          1116:     } else if(almost_equals(c_token,"b$ars")) {
        !          1117:        c_token++;
        !          1118:        if(END_OF_COMMAND) {
        !          1119:            bar_size = 1.0;
        !          1120:        } else if(almost_equals(c_token,"s$mall")) {
        !          1121:            bar_size = 0.0;
        !          1122:            ++c_token;
        !          1123:        } else if(almost_equals(c_token,"l$arge")) {
        !          1124:            bar_size = 1.0;
        !          1125:            ++c_token;
        !          1126:        } else {
        !          1127:            struct value a;
        !          1128:            bar_size = real(const_express(&a));
        !          1129:        }
        !          1130:     } else if (almost_equals(c_token, "nob$ars")) {
        !          1131:        ++c_token;
        !          1132:        bar_size = 0.0;
        !          1133:     } else if (almost_equals(c_token, "enco$ding")) {
        !          1134:        c_token++;
        !          1135:        if(END_OF_COMMAND) {
        !          1136:            encoding = ENCODING_DEFAULT;
        !          1137:        } else if (almost_equals(c_token,"def$ault")) {
        !          1138:            c_token++;
        !          1139:            encoding = ENCODING_DEFAULT;
        !          1140:        } else if (almost_equals(c_token,"iso$_8859_1")) {
        !          1141:            c_token++;
        !          1142:            encoding = ENCODING_ISO_8859_1;
        !          1143:        } else if (almost_equals(c_token,"cp4$37")) {
        !          1144:            c_token++;
        !          1145:            encoding = ENCODING_CP_437;
        !          1146:        } else if (almost_equals(c_token,"cp8$50")) {
        !          1147:            c_token++;
        !          1148:            encoding = ENCODING_CP_850;
        !          1149:        } else {
        !          1150:            int_error("expecting one of 'default', 'iso_8859_1', 'cp437' or 'cp850'", c_token);
        !          1151:        }
        !          1152:     } else
        !          1153:        return(FALSE);  /* no command match */
        !          1154:
        !          1155:     return(TRUE);
        !          1156: }
        !          1157:
        !          1158:
        !          1159: /* return TRUE if a command match, FALSE if not */
        !          1160: static TBOOLEAN
        !          1161: set_two()
        !          1162: {
        !          1163:     if (almost_equals(c_token,"o$utput")) {
        !          1164:        if (multiplot) {
        !          1165:            int_error("you can't change the output in multiplot mode", c_token);
        !          1166:        }
        !          1167:
        !          1168:        c_token++;
        !          1169:        if (END_OF_COMMAND) {   /* no file specified */
        !          1170:            term_set_output(NULL);
        !          1171:            if (outstr) {
        !          1172:                free(outstr);
        !          1173:                outstr = NULL; /* means STDOUT */
        !          1174:            }
        !          1175:        } else if (!isstring(c_token)) {
        !          1176:            int_error("expecting filename",c_token);
        !          1177:        } else {
        !          1178:            /* on int_error, we'd like to remember that this is allocated */
        !          1179:            static char *testfile = NULL;
        !          1180:            m_quote_capture(&testfile,c_token, c_token); /* reallocs store */
        !          1181:            /* Skip leading whitespace */
        !          1182:            while (isspace((int)*testfile))
        !          1183:                testfile++;
        !          1184:            ++c_token;
        !          1185:            term_set_output(testfile);
        !          1186:            /* if we get here then it worked, and outstr now = testfile */
        !          1187:            testfile = NULL;
        !          1188:        }
        !          1189:     } else if (almost_equals(c_token,"origin")) {
        !          1190:        struct value s;
        !          1191:        c_token++;
        !          1192:        if (END_OF_COMMAND) {
        !          1193:            xoffset = 0.0;
        !          1194:            yoffset = 0.0;
        !          1195:        } else {
        !          1196:            xoffset = real(const_express(&s));
        !          1197:            if (!equals(c_token,","))
        !          1198:                int_error("',' expected",c_token);
        !          1199:            c_token++;
        !          1200:            yoffset = real(const_express(&s));
        !          1201:        }
        !          1202:     } else if (almost_equals(c_token,"tit$le")) {
        !          1203:        set_xyzlabel(&title);
        !          1204:     } else if (almost_equals(c_token,"xl$abel")) {
        !          1205:        set_xyzlabel(&xlabel);
        !          1206:     } else if (almost_equals(c_token,"yl$abel")) {
        !          1207:        set_xyzlabel(&ylabel);
        !          1208:     } else if (almost_equals(c_token,"zl$abel")) {
        !          1209:        set_xyzlabel(&zlabel);
        !          1210:     } else if (almost_equals(c_token,"x2l$abel")) {
        !          1211:        set_xyzlabel(&x2label);
        !          1212:     } else if (almost_equals(c_token,"y2l$abel")) {
        !          1213:        set_xyzlabel(&y2label);
        !          1214:     } else if (almost_equals(c_token,"keyt$itle")) {
        !          1215:        c_token++;
        !          1216:        if (END_OF_COMMAND) {   /* set to default */
        !          1217:            key_title[0] = NUL;
        !          1218:        } else {
        !          1219:            if (isstring(c_token)) {
        !          1220:                /* We have string specified - grab it. */
        !          1221:                quote_str(key_title,c_token, MAX_LINE_LEN);
        !          1222:                c_token++;
        !          1223:            }
        !          1224:            /* c_token++; */
        !          1225:        }
        !          1226:     } else if (almost_equals(c_token, "nokeyt$itle")) {
        !          1227:        ++c_token;
        !          1228:        *key_title = 0;
        !          1229:     } else if (almost_equals(c_token,"timef$mt")) {
        !          1230:        c_token++;
        !          1231:        if (END_OF_COMMAND) {   /* set to default */
        !          1232:            strcpy(timefmt,TIMEFMT);
        !          1233:        } else {
        !          1234:            if (isstring(c_token)) {
        !          1235:                /* We have string specified - grab it. */
        !          1236:                quote_str(timefmt,c_token, 25);
        !          1237:            }
        !          1238:            c_token++;
        !          1239:        }
        !          1240:     } else if (almost_equals(c_token,"loc$ale")) {
        !          1241:        c_token++;
        !          1242:        if (END_OF_COMMAND) {
        !          1243:            set_locale("C");
        !          1244:        } else if (isstring(c_token)) {
        !          1245:            char ss[MAX_ID_LEN+1];
        !          1246:            quote_str(ss,c_token,MAX_ID_LEN);
        !          1247:            set_locale(ss);
        !          1248:            ++c_token;
        !          1249:        } else {
        !          1250:            int_error("Expected string", c_token);
        !          1251:        }
        !          1252:     }
        !          1253:
        !          1254: #define DO_ZEROAX(variable, string,neg) \
        !          1255: else if (almost_equals(c_token, string)) { \
        !          1256:    ++c_token; if (END_OF_COMMAND) variable.l_type = -1; \
        !          1257:    else { \
        !          1258:       struct value a; \
        !          1259:       int old_token = c_token;\
        !          1260:       LP_PARSE(variable,1,0,-1,0); \
        !          1261:       if (old_token == c_token) \
        !          1262:          variable.l_type = real(const_express(&a)) - 1; \
        !          1263:    }\
        !          1264: } else if (almost_equals(c_token, neg)) { \
        !          1265:    ++c_token; variable.l_type = -3; \
        !          1266: }
        !          1267:
        !          1268:     DO_ZEROAX(xzeroaxis, "xzero$axis", "noxzero$axis")
        !          1269:     DO_ZEROAX(yzeroaxis, "yzero$axis", "noyzero$axis")
        !          1270:     DO_ZEROAX(x2zeroaxis, "x2zero$axis", "nox2zero$axis")
        !          1271:     DO_ZEROAX(y2zeroaxis, "y2zero$axis", "noy2zero$axis")
        !          1272:
        !          1273:     else if (almost_equals(c_token,"zeroa$xis")) {
        !          1274:        c_token++;
        !          1275:        LP_PARSE(xzeroaxis,1,0,-1,0);
        !          1276:        memcpy(&yzeroaxis,&xzeroaxis,sizeof(struct lp_style_type));
        !          1277:     } else if (almost_equals(c_token,"nozero$axis")) {
        !          1278:        c_token++;
        !          1279:        xzeroaxis.l_type  = -3;
        !          1280:        yzeroaxis.l_type  = -3;
        !          1281:        x2zeroaxis.l_type = -3;
        !          1282:        y2zeroaxis.l_type = -3;
        !          1283:     } else if (almost_equals(c_token,"par$ametric")) {
        !          1284:        if (!parametric) {
        !          1285:            parametric = TRUE;
        !          1286:            if (!polar) { /* already done for polar */
        !          1287:                strcpy (dummy_var[0], "t");
        !          1288:                strcpy (dummy_var[1], "y");
        !          1289:                if (interactive)
        !          1290:                     (void) fprintf(stderr,"\n\tdummy variable is t for curves, u/v for surfaces\n");
        !          1291:            }
        !          1292:        }
        !          1293:        c_token++;
        !          1294:     } else if (almost_equals(c_token,"nopar$ametric")) {
        !          1295:        if (parametric) {
        !          1296:            parametric = FALSE;
        !          1297:            if (!polar) { /* keep t for polar */
        !          1298:                strcpy (dummy_var[0], "x");
        !          1299:                strcpy (dummy_var[1], "y");
        !          1300:                if (interactive)
        !          1301:                   (void) fprintf(stderr,"\n\tdummy variable is x for curves, x/y for surfaces\n");
        !          1302:            }
        !          1303:        }
        !          1304:        c_token++;
        !          1305:     } else if (almost_equals(c_token, "poi$ntsize")) {
        !          1306:        struct value a;
        !          1307:        c_token++;
        !          1308:        if (END_OF_COMMAND)
        !          1309:           pointsize = 1.0;
        !          1310:        else
        !          1311:            pointsize = real(const_express(&a));
        !          1312:        if(pointsize <= 0) pointsize = 1;
        !          1313:     } else if (almost_equals(c_token,"pol$ar")) {
        !          1314:        if (!polar) {
        !          1315:            if (!parametric) {
        !          1316:                if (interactive)
        !          1317:                    (void) fprintf(stderr,"\n\tdummy variable is t for curves\n");
        !          1318:                strcpy (dummy_var[0], "t");
        !          1319:            }
        !          1320:            polar = TRUE;
        !          1321:            if (autoscale_t) {
        !          1322:                /* only if user has not set a range manually */
        !          1323:                tmin = 0.0;
        !          1324:                tmax = 2*Pi / ang2rad;  /* 360 if degrees, 2pi if radians */
        !          1325:            }
        !          1326:        }
        !          1327:        c_token++;
        !          1328:     } else if (almost_equals(c_token,"nopo$lar")) {
        !          1329:        if (polar) {
        !          1330:            polar = FALSE;
        !          1331:            if (parametric && autoscale_t) {
        !          1332:                /* only if user has not set an explicit range */
        !          1333:                tmin = -5.0;
        !          1334:                tmax = 5.0;
        !          1335:            }
        !          1336:            if (!parametric) {
        !          1337:                strcpy (dummy_var[0], "x");
        !          1338:                if (interactive)
        !          1339:                    (void) fprintf(stderr,"\n\tdummy variable is x for curves\n");
        !          1340:            }
        !          1341:        }
        !          1342:        c_token++;
        !          1343:     } else if (almost_equals(c_token,"an$gles")) {
        !          1344:        c_token++;
        !          1345:        if (END_OF_COMMAND) {
        !          1346:            /* assuming same as defaults */
        !          1347:            angles_format = ANGLES_RADIANS;
        !          1348:            ang2rad = 1;
        !          1349:        } else if (almost_equals(c_token, "r$adians")) {
        !          1350:            angles_format = ANGLES_RADIANS;
        !          1351:            c_token++;
        !          1352:            ang2rad = 1;
        !          1353:        } else if (almost_equals(c_token, "d$egrees")) {
        !          1354:            angles_format = ANGLES_DEGREES;
        !          1355:            c_token++;
        !          1356:            ang2rad = DEG2RAD;
        !          1357:        } else
        !          1358:            int_error("expecting 'radians' or 'degrees'", c_token);
        !          1359:
        !          1360:        if (polar && autoscale_t) {
        !          1361:            /* set trange if in polar mode and no explicit range */
        !          1362:            tmin = 0;
        !          1363:            tmax = 2*Pi/ang2rad;
        !          1364:        }
        !          1365:     }
        !          1366:
        !          1367: #define GRID_MATCH(string, neg, mask) \
        !          1368: if (almost_equals(c_token, string)) { work_grid.l_type |= mask; ++c_token; } \
        !          1369: else if (almost_equals(c_token, neg)) { work_grid.l_type &= ~(mask); ++c_token; }
        !          1370:
        !          1371:     else if (almost_equals(c_token,"g$rid")) {
        !          1372:        c_token++;
        !          1373:        if (END_OF_COMMAND && !work_grid.l_type)
        !          1374:            work_grid.l_type = GRID_X|GRID_Y;
        !          1375:        else
        !          1376:            while (!END_OF_COMMAND) {
        !          1377:                GRID_MATCH("x$tics", "nox$tics", GRID_X)
        !          1378:                else GRID_MATCH("y$tics", "noy$tics", GRID_Y)
        !          1379:                else GRID_MATCH("z$tics", "noz$tics", GRID_Z)
        !          1380:                else GRID_MATCH("x2$tics", "nox2$tics", GRID_X2)
        !          1381:                else GRID_MATCH("y2$tics", "noy2$tics", GRID_Y2)
        !          1382:                else GRID_MATCH("mx$tics", "nomx$tics", GRID_MX)
        !          1383:                else GRID_MATCH("my$tics", "nomy$tics", GRID_MY)
        !          1384:                else GRID_MATCH("mz$tics", "nomz$tics", GRID_MZ)
        !          1385:                else GRID_MATCH("mx2$tics", "nomx2$tics", GRID_MX2)
        !          1386:                else GRID_MATCH("my2$tics", "nomy2$tics", GRID_MY2)
        !          1387:                else if (almost_equals(c_token,"po$lar")) {
        !          1388:                    if (!work_grid.l_type)
        !          1389:                        work_grid.l_type = GRID_X;
        !          1390:                    c_token++;
        !          1391:                    if (END_OF_COMMAND) {
        !          1392:                        polar_grid_angle = 30*DEG2RAD;
        !          1393:                    } else {
        !          1394:                        /* get radial interval */
        !          1395:                        struct value a;
        !          1396:                        polar_grid_angle = ang2rad*real(const_express(&a));
        !          1397:                    }
        !          1398:                } else if (almost_equals(c_token,"nopo$lar")) {
        !          1399:                    polar_grid_angle = 0; /* not polar grid */
        !          1400:                    c_token++;
        !          1401:                } else
        !          1402:                    break; /* might be a linetype */
        !          1403:            }
        !          1404:
        !          1405:        if (!END_OF_COMMAND) {
        !          1406:            struct value a;
        !          1407:            int old_token = c_token;
        !          1408:
        !          1409:            LP_PARSE(grid_lp,1,0,-1,1);
        !          1410:            if (c_token == old_token) { /* nothing parseable found... */
        !          1411:                grid_lp.l_type = real(const_express(&a)) - 1;
        !          1412:            }
        !          1413:
        !          1414:            if (!work_grid.l_type)
        !          1415:                work_grid.l_type = GRID_X|GRID_Y;
        !          1416:                /* probably just  set grid <linetype> */
        !          1417:
        !          1418:            if (END_OF_COMMAND) {
        !          1419:                memcpy(&mgrid_lp,&grid_lp,sizeof(struct lp_style_type));
        !          1420:            } else {
        !          1421:                if (equals(c_token,","))
        !          1422:                    c_token++;
        !          1423:                old_token = c_token;
        !          1424:                LP_PARSE(mgrid_lp,1,0,-1,1);
        !          1425:                if (c_token == old_token) {
        !          1426:                    mgrid_lp.l_type = real(const_express(&a)) -1;
        !          1427:                }
        !          1428:            }
        !          1429:
        !          1430:            if (!work_grid.l_type)
        !          1431:                work_grid.l_type = GRID_X|GRID_Y;
        !          1432:            /* probably just  set grid <linetype> */
        !          1433:        }
        !          1434:
        !          1435:     } else if (almost_equals(c_token,"nog$rid")) {
        !          1436:        work_grid.l_type = GRID_OFF;
        !          1437:        c_token++;
        !          1438:     } else if (almost_equals(c_token,"su$rface")) {
        !          1439:        draw_surface = TRUE;
        !          1440:        c_token++;
        !          1441:     } else if (almost_equals(c_token,"nosu$rface")) {
        !          1442:        draw_surface = FALSE;
        !          1443:        c_token++;
        !          1444:     } else if (almost_equals(c_token,"bor$der")) {
        !          1445:        struct value a;
        !          1446:        c_token++;
        !          1447:        if(END_OF_COMMAND){
        !          1448:            draw_border = 31;
        !          1449:        } else {
        !          1450:            draw_border = (int)real(const_express(&a));
        !          1451:        }
        !          1452:        /* HBB 980609: add linestyle handling for 'set border...' */
        !          1453:        /* For now, you have to give a border bitpattern to be able to specify a linestyle. Sorry for this,
        !          1454:         * but the gnuplot parser really is too messy for any other solution, currently */
        !          1455:        if(END_OF_COMMAND) {
        !          1456:            set_lp_properties(&border_lp, 0, -2, 0, 1.0, 1.0);
        !          1457:        } else {
        !          1458:            LP_PARSE(border_lp, 1, 0, -2, 0);
        !          1459:        }
        !          1460:     } else if (almost_equals(c_token,"k$ey")) {
        !          1461:        struct value a;
        !          1462:        c_token++;
        !          1463:        if (END_OF_COMMAND) {
        !          1464:            key = -1;
        !          1465:            key_vpos = TTOP;
        !          1466:            key_hpos = TRIGHT;
        !          1467:            key_just = JRIGHT;
        !          1468:            key_reverse = FALSE;
        !          1469:            set_lp_properties(&key_box,0,-3,0,1.0,1.0);
        !          1470:            key_swidth = 4;
        !          1471:            key_vert_factor = 1;
        !          1472:            key_width_fix = 0;
        !          1473:            key_title[0] = 0;
        !          1474:        } else {
        !          1475:            while (!END_OF_COMMAND) {
        !          1476:                if (almost_equals(c_token,"t$op")) {
        !          1477:                    key_vpos = TTOP;
        !          1478:                    key = -1;
        !          1479:                } else if (almost_equals(c_token,"b$ottom")) {
        !          1480:                    key_vpos = TBOTTOM;
        !          1481:                    key = -1;
        !          1482:                } else if (almost_equals(c_token,"l$eft")) {
        !          1483:                    key_hpos = TLEFT;
        !          1484:                    /* key_just = TRIGHT; */
        !          1485:                    key = -1;
        !          1486:                } else if (almost_equals(c_token,"r$ight")) {
        !          1487:                    key_hpos = TRIGHT;
        !          1488:                    key = -1;
        !          1489:                } else if (almost_equals(c_token,"u$nder") ||
        !          1490:                           almost_equals(c_token,"be$low")) {
        !          1491:                    key_vpos = TUNDER;
        !          1492:                    if (key_hpos == TOUT)
        !          1493:                        key_hpos--;
        !          1494:                    key = -1;
        !          1495:                } else if (almost_equals(c_token,"o$utside")) {
        !          1496:                    key_hpos = TOUT;
        !          1497:                    if (key_vpos == TUNDER)
        !          1498:                        key_vpos--;
        !          1499:                    key = -1;
        !          1500:                } else if (almost_equals(c_token,"L$eft")) {
        !          1501:                    /* key_hpos = TLEFT; */
        !          1502:                    key_just = JLEFT;
        !          1503:                    /* key = -1; */
        !          1504:                } else if (almost_equals(c_token,"R$ight")) {
        !          1505:                    /* key_hpos = TLEFT; */
        !          1506:                    key_just = JRIGHT;
        !          1507:                    /* key = -1; */
        !          1508:                } else if (almost_equals(c_token,"rev$erse")) {
        !          1509:                    key_reverse = TRUE;
        !          1510:                } else if (almost_equals(c_token,"norev$erse")) {
        !          1511:                    key_reverse = FALSE;
        !          1512:                } else if (equals(c_token,"box")) {
        !          1513:                    ++c_token;
        !          1514:                    if (END_OF_COMMAND)
        !          1515:                        key_box.l_type = -2;
        !          1516:                    else {
        !          1517:                        int old_token = c_token;
        !          1518:
        !          1519:                        LP_PARSE(key_box,1,0,-2,0);
        !          1520:                        if (old_token == c_token) {
        !          1521:                            key_box.l_type = real(const_express(&a)) -1;
        !          1522:                        }
        !          1523:                    }
        !          1524:                    --c_token;  /* is incremented after loop */
        !          1525:                } else if (almost_equals(c_token,"nob$ox")) {
        !          1526:                    key_box.l_type = -3;
        !          1527:                } else if (almost_equals(c_token, "sa$mplen")) {
        !          1528:                    ++c_token;
        !          1529:                    key_swidth = real(const_express(&a));
        !          1530:                    --c_token; /* it is incremented after loop */
        !          1531:                } else if (almost_equals(c_token, "sp$acing")) {
        !          1532:                    ++c_token;
        !          1533:                    key_vert_factor = real(const_express(&a));
        !          1534:                    if (key_vert_factor < 0.0)
        !          1535:                        key_vert_factor = 0.0;
        !          1536:                    --c_token; /* it is incremented after loop */
        !          1537:                } else if (almost_equals(c_token, "w$idth")) {
        !          1538:                    ++c_token;
        !          1539:                    key_width_fix = real(const_express(&a));
        !          1540:                    --c_token; /* it is incremented after loop */
        !          1541:                } else if (almost_equals(c_token,"ti$tle")) {
        !          1542:                    if (isstring(c_token+1)) {
        !          1543:                        /* We have string specified - grab it. */
        !          1544:                        quote_str(key_title,++c_token, MAX_LINE_LEN);
        !          1545:                    }
        !          1546:                    else
        !          1547:                        key_title[0] = 0;
        !          1548:                } else {
        !          1549:                    get_position(&key_user_pos);
        !          1550:                    key = 1;
        !          1551:                    --c_token;  /* will be incremented again soon */
        !          1552:                }
        !          1553:                c_token++;
        !          1554:            }
        !          1555:        }
        !          1556:     } else if (almost_equals(c_token,"nok$ey")) {
        !          1557:        key = 0;
        !          1558:        c_token++;
        !          1559:     } else if (almost_equals(c_token,"tic$s")) {
        !          1560:        tic_in = TRUE;
        !          1561:        c_token++;
        !          1562:        if (almost_equals(c_token,"i$n")) {
        !          1563:            tic_in = TRUE;
        !          1564:            c_token++;
        !          1565:        } else if (almost_equals(c_token,"o$ut")) {
        !          1566:            tic_in = FALSE;
        !          1567:            c_token++;
        !          1568:        }
        !          1569:     } else if (almost_equals(c_token,"xda$ta")) {
        !          1570:        c_token++;
        !          1571:        if(END_OF_COMMAND) {
        !          1572:            datatype[FIRST_X_AXIS] = FALSE;
        !          1573:            /* eh ? - t and u have nothing to do with x */
        !          1574:            datatype[T_AXIS] = FALSE;
        !          1575:            datatype[U_AXIS] = FALSE;
        !          1576:        } else {
        !          1577:            if (almost_equals(c_token,"t$ime")) {
        !          1578:                datatype[FIRST_X_AXIS] = TIME;
        !          1579:                datatype[T_AXIS] = TIME;
        !          1580:                datatype[U_AXIS] = TIME;
        !          1581:            } else {
        !          1582:                datatype[FIRST_X_AXIS] = FALSE;
        !          1583:                datatype[T_AXIS] = FALSE;
        !          1584:                datatype[U_AXIS] = FALSE;
        !          1585:            }
        !          1586:            c_token++;
        !          1587:        }
        !          1588:     } else if (almost_equals(c_token,"yda$ta")) {
        !          1589:        c_token++;
        !          1590:        if(END_OF_COMMAND) {
        !          1591:            datatype[FIRST_Y_AXIS] = FALSE;
        !          1592:            datatype[V_AXIS] = FALSE;
        !          1593:        } else {
        !          1594:            if (almost_equals(c_token,"t$ime")) {
        !          1595:                datatype[FIRST_Y_AXIS] = TIME;
        !          1596:                datatype[V_AXIS] = TIME;
        !          1597:            } else {
        !          1598:                datatype[FIRST_Y_AXIS] = FALSE;
        !          1599:                datatype[V_AXIS] = FALSE;
        !          1600:            }
        !          1601:            c_token++;
        !          1602:        }
        !          1603:     } else if (almost_equals(c_token,"zda$ta")) {
        !          1604:        c_token++;
        !          1605:        if(END_OF_COMMAND) {
        !          1606:            datatype[FIRST_Z_AXIS] = FALSE;
        !          1607:        } else {
        !          1608:            if (almost_equals(c_token,"t$ime")) {
        !          1609:                datatype[FIRST_Z_AXIS] = TIME;
        !          1610:            } else {
        !          1611:                datatype[FIRST_Z_AXIS] = FALSE;
        !          1612:            }
        !          1613:            c_token++;
        !          1614:        }
        !          1615:     } else if (almost_equals(c_token,"x2da$ta")) {
        !          1616:        c_token++;
        !          1617:        if(END_OF_COMMAND) {
        !          1618:            datatype[SECOND_X_AXIS] = FALSE;
        !          1619:        } else {
        !          1620:            if (almost_equals(c_token,"t$ime")) {
        !          1621:                datatype[SECOND_X_AXIS] = TIME;
        !          1622:            } else {
        !          1623:                datatype[SECOND_X_AXIS] = FALSE;
        !          1624:            }
        !          1625:            c_token++;
        !          1626:        }
        !          1627:     } else if (almost_equals(c_token,"y2da$ta")) {
        !          1628:        c_token++;
        !          1629:        if(END_OF_COMMAND) {
        !          1630:            datatype[SECOND_Y_AXIS] = FALSE;
        !          1631:        } else {
        !          1632:            if (almost_equals(c_token,"t$ime")) {
        !          1633:                datatype[SECOND_Y_AXIS] = TIME;
        !          1634:            } else {
        !          1635:                datatype[SECOND_Y_AXIS] = FALSE;
        !          1636:            }
        !          1637:            c_token++;
        !          1638:        }
        !          1639:     }
        !          1640:
        !          1641: /* to save duplicating code for x/y/z/x2/y2, make a macro
        !          1642:  * (should perhaps be a function ?)
        !          1643:  * unfortunately, string concatenation is not supported on all compilers,
        !          1644:  * so we have to explicitly include both 'on' and 'no' strings in
        !          1645:  * the args
        !          1646:  */
        !          1647:
        !          1648: /* change to a function: lph 25.09.1998 */
        !          1649:
        !          1650: #define PROCESS_TIC_COMMANDS  set_tic_prop
        !          1651:
        !          1652:     else if
        !          1653:        (PROCESS_TIC_COMMANDS(&x2tics, &mx2tics, &mx2tfreq, &x2ticdef,
        !          1654:         SECOND_X_AXIS, &rotate_x2tics, "x2") );
        !          1655:     else if
        !          1656:        (PROCESS_TIC_COMMANDS(&y2tics, &my2tics, &my2tfreq, &y2ticdef,
        !          1657:         SECOND_Y_AXIS, &rotate_y2tics, "y2") );
        !          1658:     else if
        !          1659:        (PROCESS_TIC_COMMANDS(&xtics,   &mxtics, &mxtfreq,  &xticdef,
        !          1660:         FIRST_X_AXIS, &rotate_xtics, "x") );
        !          1661:     else if
        !          1662:        (PROCESS_TIC_COMMANDS(&ytics,   &mytics, &mytfreq,  &yticdef,
        !          1663:         FIRST_Y_AXIS, &rotate_ytics, "y") );
        !          1664:     else if
        !          1665:        (PROCESS_TIC_COMMANDS(&ztics,   &mztics, &mztfreq,  &zticdef,
        !          1666:         FIRST_Z_AXIS, &rotate_ztics, "z") );
        !          1667:
        !          1668:     else if (almost_equals(c_token,"ticsl$evel")) {
        !          1669:        double tlvl;
        !          1670:        struct value a;
        !          1671:
        !          1672:        c_token++;
        !          1673:        /* is datatype 'time' relevant here ? */
        !          1674:        tlvl = real(const_express(&a));
        !          1675:        ticslevel = tlvl;
        !          1676:     }
        !          1677:
        !          1678: #define PROCESS_MARGIN(variable, string) \
        !          1679: else if (almost_equals(c_token,string)) {\
        !          1680:  ++c_token; if (END_OF_COMMAND) variable = -1;\
        !          1681:  else { struct value a; variable = real(const_express(&a)); } \
        !          1682: }
        !          1683:
        !          1684:     PROCESS_MARGIN(lmargin, "lmar$gin")
        !          1685:     PROCESS_MARGIN(bmargin, "bmar$gin")
        !          1686:     PROCESS_MARGIN(rmargin, "rmar$gin")
        !          1687:     PROCESS_MARGIN(tmargin, "tmar$gin")
        !          1688:
        !          1689:     else
        !          1690:        return(FALSE);  /* no command match */
        !          1691:
        !          1692:     return(TRUE);
        !          1693: }
        !          1694:
        !          1695:
        !          1696:
        !          1697: /* return TRUE if a command match, FALSE if not */
        !          1698: static TBOOLEAN
        !          1699: set_three()
        !          1700: {
        !          1701:     if (almost_equals(c_token,"sa$mples")) {
        !          1702:        register int tsamp1, tsamp2;
        !          1703:        struct value a;
        !          1704:
        !          1705:        c_token++;
        !          1706:        tsamp1 = (int)magnitude(const_express(&a));
        !          1707:        tsamp2 = tsamp1;
        !          1708:        if (!END_OF_COMMAND) {
        !          1709:            if (!equals(c_token,","))
        !          1710:                int_error("',' expected",c_token);
        !          1711:            c_token++;
        !          1712:            tsamp2 = (int)magnitude(const_express(&a));
        !          1713:        }
        !          1714:        if (tsamp1 < 2 || tsamp2 < 2)
        !          1715:            int_error("sampling rate must be > 1; sampling unchanged",c_token);
        !          1716:        else {
        !          1717:            register struct surface_points *f_3dp = first_3dplot;
        !          1718:
        !          1719:            first_3dplot = NULL;
        !          1720:            sp_free(f_3dp);
        !          1721:
        !          1722:            samples = tsamp1;
        !          1723:            samples_1 = tsamp1;
        !          1724:            samples_2 = tsamp2;
        !          1725:        }
        !          1726:     } else if (almost_equals(c_token,"isosa$mples")) {
        !          1727:        register int tsamp1, tsamp2;
        !          1728:        struct value a;
        !          1729:
        !          1730:        c_token++;
        !          1731:        tsamp1 = (int)magnitude(const_express(&a));
        !          1732:        tsamp2 = tsamp1;
        !          1733:        if (!END_OF_COMMAND) {
        !          1734:            if (!equals(c_token,","))
        !          1735:                int_error("',' expected",c_token);
        !          1736:            c_token++;
        !          1737:            tsamp2 = (int)magnitude(const_express(&a));
        !          1738:        }
        !          1739:        if (tsamp1 < 2 || tsamp2 < 2)
        !          1740:            int_error("sampling rate must be > 1; sampling unchanged",c_token);
        !          1741:        else {
        !          1742:            register struct curve_points *f_p = first_plot;
        !          1743:            register struct surface_points *f_3dp = first_3dplot;
        !          1744:
        !          1745:            first_plot = NULL;
        !          1746:            first_3dplot = NULL;
        !          1747:            cp_free(f_p);
        !          1748:            sp_free(f_3dp);
        !          1749:
        !          1750:            iso_samples_1 = tsamp1;
        !          1751:            iso_samples_2 = tsamp2;
        !          1752:        }
        !          1753:     } else if (almost_equals(c_token,"si$ze")) {
        !          1754:        struct value s;
        !          1755:        c_token++;
        !          1756:        if (END_OF_COMMAND) {
        !          1757:            xsize = 1.0;
        !          1758:            ysize = 1.0;
        !          1759:        } else {
        !          1760:            if (almost_equals(c_token, "sq$uare")) {
        !          1761:                aspect_ratio = 1.0;
        !          1762:                ++c_token;
        !          1763:            } else if (almost_equals(c_token,"ra$tio")) {
        !          1764:                ++c_token;
        !          1765:                aspect_ratio = real(const_express(&s));
        !          1766:            } else if (almost_equals(c_token, "nora$tio") || almost_equals(c_token, "nosq$uare")) {
        !          1767:                aspect_ratio = 0.0;
        !          1768:                ++c_token;
        !          1769:            }
        !          1770:
        !          1771:            if (!END_OF_COMMAND) {
        !          1772:                xsize = real(const_express(&s));
        !          1773:                if (equals(c_token,",")) {
        !          1774:                    c_token++;
        !          1775:                    ysize = real(const_express(&s));
        !          1776:                } else {
        !          1777:                    ysize = xsize;
        !          1778:                }
        !          1779:            }
        !          1780:        }
        !          1781:     } else if (almost_equals(c_token,"ticsc$ale")) {
        !          1782:        struct value tscl;
        !          1783:        c_token++;
        !          1784:        if (END_OF_COMMAND) {
        !          1785:            ticscale = 1.0;
        !          1786:            miniticscale = 0.5;
        !          1787:        } else {
        !          1788:            ticscale = real(const_express(&tscl));
        !          1789:            if (END_OF_COMMAND) {
        !          1790:                miniticscale = ticscale*0.5;
        !          1791:            } else {
        !          1792:                miniticscale = real(const_express(&tscl));
        !          1793:            }
        !          1794:        }
        !          1795:     } else if (almost_equals(c_token,"t$erminal")) {
        !          1796:        if (multiplot) {
        !          1797:            int_error("You can't change the terminal in multiplot mode", c_token);
        !          1798:        }
        !          1799:
        !          1800:        c_token++;
        !          1801:        if (END_OF_COMMAND) {
        !          1802:            list_terms();
        !          1803:            screen_ok = FALSE;
        !          1804:        } else {
        !          1805:            term_reset();
        !          1806:            term = 0; /* in case set_term() fails */
        !          1807:            term = set_term(c_token);
        !          1808:            c_token++;
        !          1809:
        !          1810:            /* get optional mode parameters
        !          1811:             * not all drivers reset the option string before
        !          1812:             * strcat-ing to it, so we reset it for them
        !          1813:             */
        !          1814:            *term_options = 0;
        !          1815:            if (term)
        !          1816:                (*term->options)();
        !          1817:            if (interactive && *term_options)
        !          1818:                fprintf(stderr,"Options are '%s'\n",term_options);
        !          1819:        }
        !          1820:     } else if (almost_equals(c_token,"tim$estamp")) {
        !          1821:        c_token++;
        !          1822:        if (END_OF_COMMAND || !isstring(c_token))
        !          1823:            strcpy(timelabel.text, DEFAULT_TIMESTAMP_FORMAT);
        !          1824:
        !          1825:        if (!END_OF_COMMAND) {
        !          1826:            struct value a;
        !          1827:
        !          1828:            if (isstring(c_token)) {
        !          1829:                /* we have a format string */
        !          1830:                quote_str(timelabel.text, c_token, MAX_LINE_LEN);
        !          1831:                ++c_token;
        !          1832:            } else {
        !          1833:                strcpy(timelabel.text, DEFAULT_TIMESTAMP_FORMAT);
        !          1834:            }
        !          1835:            if (almost_equals(c_token,"t$op")) {
        !          1836:                timelabel_bottom = FALSE;
        !          1837:                ++c_token;
        !          1838:            } else if (almost_equals(c_token, "b$ottom")) {
        !          1839:                timelabel_bottom = TRUE;
        !          1840:                ++c_token;
        !          1841:            }
        !          1842:            if (almost_equals(c_token,"r$otate")) {
        !          1843:                timelabel_rotate = TRUE;
        !          1844:                ++c_token;
        !          1845:            } else if (almost_equals(c_token, "n$orotate")) {
        !          1846:                timelabel_rotate = FALSE;
        !          1847:                ++c_token;
        !          1848:            }
        !          1849:            /* We have x,y offsets specified */
        !          1850:            if (!END_OF_COMMAND && !equals(c_token,","))
        !          1851:                timelabel.xoffset = real(const_express(&a));
        !          1852:            if (!END_OF_COMMAND && equals(c_token,",")) {
        !          1853:                c_token++;
        !          1854:                timelabel.yoffset = real(const_express(&a));
        !          1855:            }
        !          1856:            if (!END_OF_COMMAND && isstring(c_token)) {
        !          1857:                quote_str(timelabel.font, c_token, MAX_LINE_LEN);
        !          1858:                ++c_token;
        !          1859:            } else {
        !          1860:                *timelabel.font = 0;
        !          1861:            }
        !          1862:        }
        !          1863:     } else if (almost_equals(c_token,"not$imestamp")) {
        !          1864:        *timelabel.text = 0;
        !          1865:        c_token++;
        !          1866:     } else if (almost_equals(c_token,"vi$ew")) {
        !          1867:        int i;
        !          1868:        TBOOLEAN was_comma = TRUE;
        !          1869:        double local_vals[4];
        !          1870:        struct value a;
        !          1871:
        !          1872:        local_vals[0] = surface_rot_x;
        !          1873:        local_vals[1] = surface_rot_z;
        !          1874:        local_vals[2] = surface_scale;
        !          1875:        local_vals[3] = surface_zscale;
        !          1876:        c_token++;
        !          1877:        for (i = 0; i < 4 && !(END_OF_COMMAND);) {
        !          1878:            if (equals(c_token,",")) {
        !          1879:                if (was_comma) i++;
        !          1880:                    was_comma = TRUE;
        !          1881:                c_token++;
        !          1882:            } else {
        !          1883:                if (!was_comma)
        !          1884:                    int_error("',' expected",c_token);
        !          1885:                local_vals[i] = real(const_express(&a));
        !          1886:                i++;
        !          1887:                was_comma = FALSE;
        !          1888:            }
        !          1889:        }
        !          1890:
        !          1891:        if (local_vals[0] < 0 || local_vals[0] > 180)
        !          1892:            int_error("rot_x must be in [0:180] degrees range; view unchanged", c_token);
        !          1893:        if (local_vals[1] < 0 || local_vals[1] > 360)
        !          1894:            int_error("rot_z must be in [0:360] degrees range; view unchanged", c_token);
        !          1895:        if (local_vals[2] < 1e-6)
        !          1896:            int_error("scale must be > 0; view unchanged", c_token);
        !          1897:        if (local_vals[3] < 1e-6)
        !          1898:            int_error("zscale must be > 0; view unchanged", c_token);
        !          1899:
        !          1900:        surface_rot_x = local_vals[0];
        !          1901:        surface_rot_z = local_vals[1];
        !          1902:        surface_scale = local_vals[2];
        !          1903:        surface_zscale = local_vals[3];
        !          1904:     }
        !          1905:
        !          1906: /* to save replicated code, define a macro */
        !          1907: #define PROCESS_RANGE(AXIS,STRING, MIN, MAX, AUTO) \
        !          1908: else if (almost_equals(c_token, STRING)) { \
        !          1909:  if (!equals(++c_token,"[")) int_error("expecting '['",c_token); \
        !          1910:  c_token++; \
        !          1911:  AUTO = load_range(AXIS,&MIN,&MAX,AUTO); \
        !          1912:  if (!equals(c_token,"]")) int_error("expecting ']'",c_token); \
        !          1913:  c_token++; \
        !          1914:  if (almost_equals(c_token, "rev$erse")) { \
        !          1915:    ++c_token; range_flags[AXIS] |= RANGE_REVERSE;\
        !          1916:  } else if (almost_equals(c_token, "norev$erse")) { \
        !          1917:    ++c_token; range_flags[AXIS] &= ~RANGE_REVERSE;\
        !          1918:  } if (almost_equals(c_token, "wr$iteback")) { \
        !          1919:    ++c_token; range_flags[AXIS] |= RANGE_WRITEBACK;\
        !          1920:  } else if (almost_equals(c_token, "nowri$teback")) { \
        !          1921:    ++c_token; range_flags[AXIS] &= ~RANGE_WRITEBACK;\
        !          1922: }}
        !          1923:
        !          1924:     PROCESS_RANGE(R_AXIS, "rr$ange", rmin, rmax, autoscale_r)
        !          1925:     PROCESS_RANGE(T_AXIS, "tr$ange", tmin, tmax, autoscale_t)
        !          1926:     PROCESS_RANGE(U_AXIS, "ur$ange", umin, umax, autoscale_u)
        !          1927:     PROCESS_RANGE(V_AXIS, "vr$ange", vmin, vmax, autoscale_v)
        !          1928:     PROCESS_RANGE(FIRST_X_AXIS, "xr$ange", xmin, xmax, autoscale_x)
        !          1929:     PROCESS_RANGE(FIRST_Y_AXIS, "yr$ange", ymin, ymax, autoscale_y)
        !          1930:     PROCESS_RANGE(FIRST_Z_AXIS, "zr$ange", zmin, zmax, autoscale_z)
        !          1931:     PROCESS_RANGE(SECOND_X_AXIS, "x2r$ange", x2min, x2max, autoscale_x2)
        !          1932:     PROCESS_RANGE(SECOND_Y_AXIS, "y2r$ange", y2min, y2max, autoscale_y2)
        !          1933:
        !          1934:     else if (almost_equals(c_token,"z$ero")) {
        !          1935:        struct value a;
        !          1936:        c_token++;
        !          1937:        zero = magnitude(const_express(&a));
        !          1938:     } else if (almost_equals(c_token,"multi$plot")) {
        !          1939:        term_start_multiplot();
        !          1940:        c_token++;
        !          1941:     } else if (almost_equals(c_token,"nomulti$plot")) {
        !          1942:        term_end_multiplot();
        !          1943:        c_token++;
        !          1944:     } else
        !          1945:        return(FALSE);  /* no command match */
        !          1946:
        !          1947:     return(TRUE);
        !          1948: }
        !          1949:
        !          1950:
        !          1951: /*********** Support functions for set_command ***********/
        !          1952:
        !          1953: /*
        !          1954:  * The set.c PROCESS_TIC_PROP macro has the following characteristics:
        !          1955:  *   (a) options must in the correct order
        !          1956:  *   (b) 'set xtics' (no option) resets only the interval (FREQ)
        !          1957:  *       {it will also negate NO_TICS, see (d)}
        !          1958:  *   (c) changing any property also resets the interval to automatic
        !          1959:  *   (d) set no[xy]tics; set [xy]tics changes border to nomirror, rather
        !          1960:  *       than to the default, mirror.
        !          1961:  *   (e) effect of 'set no[]tics; set []tics border ...' is compiler
        !          1962:  *       dependent;  if '!(TICS)' is evaluated first, 'border' is an
        !          1963:  *       undefined variable :-(
        !          1964:  *
        !          1965:  * This function replaces the macro, and introduces a new option
        !          1966:  * 'au$tofreq' to give somewhat different behaviour:
        !          1967:  *   (a) no change
        !          1968:  *   (b) 'set xtics' (no option) only affects NO_TICS;  'autofreq' resets
        !          1969:  *       the interval calulation to automatic
        !          1970:  *   (c) the interval mode is not affected by changing some other option
        !          1971:  *   (d) if NO_TICS, set []tics will restore defaults (borders, mirror
        !          1972:  *       where appropriate)
        !          1973:  *   (e) if (NO_TICS), border option is processed.
        !          1974:  *
        !          1975:  *  A 'default' option could easily be added to reset all options to
        !          1976:  *  the initial values - mostly book-keeping.
        !          1977:  *
        !          1978:  *  To retain tic properties after setting no[]tics may also be
        !          1979:  *  straightforward (save value as negative), but requires changes
        !          1980:  *  in other code ( e.g. for  'if (xtics)', use 'if (xtics > 0)'
        !          1981:  */
        !          1982:
        !          1983: static int set_tic_prop(TICS, MTICS, FREQ, tdef, AXIS, ROTATE, tic_side)
        !          1984: /*    generates PROCESS_TIC_PROP strings from tic_side, e.g. "x2"
        !          1985:    STRING, NOSTRING, MONTH, NOMONTH, DAY, NODAY, MINISTRING, NOMINI
        !          1986:    "nox2t$ics"     "nox2m$tics"  "nox2d$tics"    "nomx2t$ics"
        !          1987:  */
        !          1988:
        !          1989: int *TICS, *MTICS, AXIS;
        !          1990: double *FREQ;
        !          1991: struct ticdef *tdef;
        !          1992: TBOOLEAN *ROTATE;
        !          1993: char *tic_side;
        !          1994:
        !          1995:
        !          1996: {
        !          1997:     int match = 0;             /* flag, set by matching a tic command */
        !          1998:     char nocmd[12];            /* fill w/ "no"+'tic_side'+suffix */
        !          1999:     char *cmdptr, *sfxptr;
        !          2000:
        !          2001:     (void) strcpy(nocmd, "no");
        !          2002:     cmdptr = &nocmd[2];
        !          2003:     (void) strcpy(cmdptr, tic_side);
        !          2004:     sfxptr = &nocmd[strlen(nocmd)];
        !          2005:     (void) strcpy(sfxptr, "t$ics");    /* STRING */
        !          2006:
        !          2007:     if (almost_equals(c_token, cmdptr)) {
        !          2008:        match = 1;
        !          2009:        if (almost_equals(++c_token, "ax$is")) {
        !          2010:            *TICS &= ~TICS_ON_BORDER;
        !          2011:            *TICS |= TICS_ON_AXIS;
        !          2012:            ++c_token;
        !          2013:        }
        !          2014:        /* if tics are off, reset to default (border) */
        !          2015:        if (*TICS == NO_TICS) {
        !          2016:            *TICS = TICS_ON_BORDER;
        !          2017:            if (!strcmp(tic_side, "x") || !strcmp(tic_side, "y")) {
        !          2018:                *TICS |= TICS_MIRROR;
        !          2019:            }
        !          2020:        }
        !          2021:        if (almost_equals(c_token, "bo$rder")) {
        !          2022:            *TICS &= ~TICS_ON_AXIS;
        !          2023:            *TICS |= TICS_ON_BORDER;
        !          2024:            ++c_token;
        !          2025:        }
        !          2026:        if (almost_equals(c_token, "mi$rror")) {
        !          2027:            *TICS |= TICS_MIRROR;
        !          2028:            ++c_token;
        !          2029:        } else if (almost_equals(c_token, "nomi$rror")) {
        !          2030:            *TICS &= ~TICS_MIRROR;
        !          2031:            ++c_token;
        !          2032:        }
        !          2033:        if (almost_equals(c_token, "ro$tate")) {
        !          2034:            *ROTATE = TRUE;
        !          2035:            ++c_token;
        !          2036:        } else if (almost_equals(c_token, "noro$tate")) {
        !          2037:            *ROTATE = FALSE;
        !          2038:            ++c_token;
        !          2039:        }
        !          2040:        if (almost_equals(c_token, "au$tofreq")) {      /* auto tic interval */
        !          2041:            ++c_token;
        !          2042:            if (tdef->type == TIC_USER) {
        !          2043:                free_marklist(tdef->def.user);
        !          2044:                tdef->def.user = NULL;
        !          2045:            }
        !          2046:            tdef->type = TIC_COMPUTED;
        !          2047:        }
        !          2048:        /* user spec. is last */
        !          2049:        else if (!END_OF_COMMAND) {
        !          2050:            load_tics(AXIS, tdef);
        !          2051:        }
        !          2052:     }
        !          2053:     if (almost_equals(c_token, nocmd)) {       /* NOSTRING */
        !          2054:        *TICS = NO_TICS;
        !          2055:        c_token++;
        !          2056:        match = 1;
        !          2057:     }
        !          2058: /* other options */
        !          2059:
        !          2060:     (void) strcpy(sfxptr, "m$tics");   /* MONTH */
        !          2061:     if (almost_equals(c_token, cmdptr)) {
        !          2062:        if (tdef->type == TIC_USER) {
        !          2063:            free_marklist(tdef->def.user);
        !          2064:            tdef->def.user = NULL;
        !          2065:        }
        !          2066:        tdef->type = TIC_MONTH;
        !          2067:        ++c_token;
        !          2068:        match = 1;
        !          2069:     }
        !          2070:     if (almost_equals(c_token, nocmd)) {       /* NOMONTH */
        !          2071:        tdef->type = TIC_COMPUTED;
        !          2072:        ++c_token;
        !          2073:        match = 1;
        !          2074:     }
        !          2075:     (void) strcpy(sfxptr, "d$tics");   /* DAYS */
        !          2076:     if (almost_equals(c_token, cmdptr)) {
        !          2077:        match = 1;
        !          2078:        if (tdef->type == TIC_USER) {
        !          2079:            free_marklist(tdef->def.user);
        !          2080:            tdef->def.user = NULL;
        !          2081:        }
        !          2082:        tdef->type = TIC_DAY;
        !          2083:        ++c_token;
        !          2084:     }
        !          2085:     if (almost_equals(c_token, nocmd)) {       /* NODAYS */
        !          2086:        tdef->type = TIC_COMPUTED;
        !          2087:        ++c_token;
        !          2088:        match = 1;
        !          2089:     }
        !          2090:     *cmdptr = 'm';
        !          2091:     (void) strcpy(cmdptr + 1, tic_side);
        !          2092:     (void) strcat(cmdptr, "t$ics");    /* MINISTRING */
        !          2093:
        !          2094:     if (almost_equals(c_token, cmdptr)) {
        !          2095:        struct value freq;
        !          2096:        c_token++;
        !          2097:        match = 1;
        !          2098:        if (END_OF_COMMAND) {
        !          2099:            *MTICS = MINI_AUTO;
        !          2100:        } else if (almost_equals(c_token, "def$ault")) {
        !          2101:            *MTICS = MINI_DEFAULT;
        !          2102:            ++c_token;
        !          2103:        } else {
        !          2104:            *FREQ = real(const_express(&freq));
        !          2105:            *FREQ = floor(*FREQ);
        !          2106:            *MTICS = MINI_USER;
        !          2107:        }
        !          2108:     }
        !          2109:     if (almost_equals(c_token, nocmd)) {       /* NOMINI */
        !          2110:        *MTICS = FALSE;
        !          2111:        c_token++;
        !          2112:        match = 1;
        !          2113:     }
        !          2114:     return (match);
        !          2115: }
        !          2116:
        !          2117:
        !          2118: /* process a 'set {x/y/z}label command */
        !          2119: /* set {x/y/z}label {label_text} {x}{,y} */
        !          2120: static void set_xyzlabel(label)
        !          2121: label_struct *label;
        !          2122: {
        !          2123:     c_token++;
        !          2124:     if (END_OF_COMMAND) {      /* no label specified */
        !          2125:        *label->text = '\0';
        !          2126:        return;
        !          2127:     }
        !          2128:     if (isstring(c_token)) {
        !          2129:        /* We have string specified - grab it. */
        !          2130:        quote_str(label->text, c_token, MAX_LINE_LEN);
        !          2131:        c_token++;
        !          2132:     }
        !          2133:     if (END_OF_COMMAND)
        !          2134:        return;
        !          2135:
        !          2136:     if (!almost_equals(c_token, "font") && !isstring(c_token)) {
        !          2137:        /* We have x,y offsets specified */
        !          2138:        struct value a;
        !          2139:        if (!equals(c_token, ","))
        !          2140:            label->xoffset = real(const_express(&a));
        !          2141:
        !          2142:        if (END_OF_COMMAND)
        !          2143:            return;
        !          2144:
        !          2145:        if (equals(c_token, ",")) {
        !          2146:            c_token++;
        !          2147:            label->yoffset = real(const_express(&a));
        !          2148:        }
        !          2149:     }
        !          2150:     if (END_OF_COMMAND)
        !          2151:        return;
        !          2152:
        !          2153:     /* optional keyword 'font' can go here */
        !          2154:
        !          2155:     if (almost_equals(c_token, "f$ont"))
        !          2156:        ++c_token;              /* skip it */
        !          2157:
        !          2158:     if (!isstring(c_token))
        !          2159:        int_error("Expected font", c_token);
        !          2160:
        !          2161:     quote_str(label->font, c_token, MAX_LINE_LEN);
        !          2162:     c_token++;
        !          2163: }
        !          2164:
        !          2165: /* process a 'set label' command */
        !          2166: /* set label {tag} {label_text} {at x,y} {pos} {font name,size} */
        !          2167: /* Entry font added by DJL */
        !          2168: static void set_label()
        !          2169: {
        !          2170:     struct value a;
        !          2171:     struct text_label *this_label = NULL;
        !          2172:     struct text_label *new_label = NULL;
        !          2173:     struct text_label *prev_label = NULL;
        !          2174:     struct position pos;
        !          2175:     char text[MAX_LINE_LEN + 1], font[MAX_LINE_LEN + 1];
        !          2176:     enum JUSTIFY just = LEFT;
        !          2177:     int rotate = 0;
        !          2178:     int tag;
        !          2179:     TBOOLEAN set_text, set_position, set_just = FALSE, set_rot = FALSE,
        !          2180:      set_font;
        !          2181:
        !          2182:     /* get tag */
        !          2183:     if (!END_OF_COMMAND
        !          2184:        && !isstring(c_token)
        !          2185:        && !equals(c_token, "at")
        !          2186:        && !equals(c_token, "left")
        !          2187:        && !equals(c_token, "center")
        !          2188:        && !equals(c_token, "centre")
        !          2189:        && !equals(c_token, "right")
        !          2190:        && !almost_equals(c_token, "rot$ate")
        !          2191:        && !almost_equals(c_token, "norot$ate")
        !          2192:        && !equals(c_token, "font")) {
        !          2193:        /* must be a tag expression! */
        !          2194:        tag = (int) real(const_express(&a));
        !          2195:        if (tag <= 0)
        !          2196:            int_error("tag must be > zero", c_token);
        !          2197:     } else
        !          2198:        tag = assign_label_tag();       /* default next tag */
        !          2199:
        !          2200:     /* get text */
        !          2201:     if (!END_OF_COMMAND && isstring(c_token)) {
        !          2202:        /* get text */
        !          2203:        quote_str(text, c_token, MAX_LINE_LEN);
        !          2204:        c_token++;
        !          2205:        set_text = TRUE;
        !          2206:     } else {
        !          2207:        text[0] = '\0';         /* default no text */
        !          2208:        set_text = FALSE;
        !          2209:     }
        !          2210:
        !          2211:     /* get justification - what the heck, let him put it here */
        !          2212:     if (!END_OF_COMMAND && !equals(c_token, "at") && !equals(c_token, "font")
        !          2213:        && !almost_equals(c_token, "rot$ate") && !almost_equals(c_token, "norot$ate")) {
        !          2214:        if (almost_equals(c_token, "l$eft")) {
        !          2215:            just = LEFT;
        !          2216:        } else if (almost_equals(c_token, "c$entre")
        !          2217:                   || almost_equals(c_token, "c$enter")) {
        !          2218:            just = CENTRE;
        !          2219:        } else if (almost_equals(c_token, "r$ight")) {
        !          2220:            just = RIGHT;
        !          2221:        } else
        !          2222:            int_error("bad syntax in set label", c_token);
        !          2223:        c_token++;
        !          2224:        set_just = TRUE;
        !          2225:     }
        !          2226:     /* get position */
        !          2227:     if (!END_OF_COMMAND && equals(c_token, "at")) {
        !          2228:        c_token++;
        !          2229:
        !          2230:        get_position(&pos);
        !          2231:        set_position = TRUE;
        !          2232:     } else {
        !          2233:        pos.x = pos.y = pos.z = 0;
        !          2234:        pos.scalex = pos.scaley = pos.scalez = first_axes;
        !          2235:        set_position = FALSE;
        !          2236:     }
        !          2237:
        !          2238:     /* get justification */
        !          2239:     if (!END_OF_COMMAND && !almost_equals(c_token, "rot$ate") && !almost_equals(c_token, "norot$ate") && !equals(c_token, "font")) {
        !          2240:        if (set_just)
        !          2241:            int_error("only one justification is allowed", c_token);
        !          2242:        if (almost_equals(c_token, "l$eft")) {
        !          2243:            just = LEFT;
        !          2244:        } else if (almost_equals(c_token, "c$entre")
        !          2245:                   || almost_equals(c_token, "c$enter")) {
        !          2246:            just = CENTRE;
        !          2247:        } else if (almost_equals(c_token, "r$ight")) {
        !          2248:            just = RIGHT;
        !          2249:        } else
        !          2250:            int_error("bad syntax in set label", c_token);
        !          2251:
        !          2252:        c_token++;
        !          2253:        set_just = TRUE;
        !          2254:     }
        !          2255:     /* get rotation (added by RCC) */
        !          2256:     if (!END_OF_COMMAND && !equals(c_token, "font")) {
        !          2257:        if (almost_equals(c_token, "rot$ate")) {
        !          2258:            rotate = TRUE;
        !          2259:        } else if (almost_equals(c_token, "norot$ate")) {
        !          2260:            rotate = FALSE;
        !          2261:        } else
        !          2262:            int_error("bad syntax in set label", c_token);
        !          2263:
        !          2264:        c_token++;
        !          2265:        set_rot = TRUE;
        !          2266:     }
        !          2267:     /* get font */
        !          2268:     font[0] = NUL;
        !          2269:     set_font = FALSE;
        !          2270:     if (!END_OF_COMMAND && equals(c_token, "font")) {
        !          2271:        c_token++;
        !          2272:        if (END_OF_COMMAND)
        !          2273:            int_error("font name and size expected", c_token);
        !          2274:        if (isstring(c_token)) {
        !          2275:            quote_str(font, c_token, MAX_ID_LEN);
        !          2276:            /* get 'name,size', no further check */
        !          2277:            set_font = TRUE;
        !          2278:        } else
        !          2279:            int_error("'fontname,fontsize' expected", c_token);
        !          2280:
        !          2281:        c_token++;
        !          2282:     }                          /* Entry font added by DJL */
        !          2283:     if (!END_OF_COMMAND)
        !          2284:        int_error("extraenous or out-of-order arguments in set label", c_token);
        !          2285:
        !          2286:     /* OK! add label */
        !          2287:     if (first_label != NULL) { /* skip to last label */
        !          2288:        for (this_label = first_label; this_label != NULL;
        !          2289:             prev_label = this_label, this_label = this_label->next)
        !          2290:            /* is this the label we want? */
        !          2291:            if (tag <= this_label->tag)
        !          2292:                break;
        !          2293:     }
        !          2294:     if (this_label != NULL && tag == this_label->tag) {
        !          2295:        /* changing the label */
        !          2296:        if (set_position) {
        !          2297:            this_label->place = pos;
        !          2298:        }
        !          2299:        if (set_text)
        !          2300:            (void) strcpy(this_label->text, text);
        !          2301:        if (set_just)
        !          2302:            this_label->pos = just;
        !          2303:        if (set_rot)
        !          2304:            this_label->rotate = rotate;
        !          2305:        if (set_font)
        !          2306:            (void) strcpy(this_label->font, font);
        !          2307:     } else {
        !          2308:        /* adding the label */
        !          2309:        new_label = (struct text_label *)
        !          2310:            gp_alloc((unsigned long) sizeof(struct text_label), "label");
        !          2311:        if (prev_label != NULL)
        !          2312:            prev_label->next = new_label;       /* add it to end of list */
        !          2313:        else
        !          2314:            first_label = new_label;    /* make it start of list */
        !          2315:        new_label->tag = tag;
        !          2316:        new_label->next = this_label;
        !          2317:        new_label->place = pos;
        !          2318:        (void) strcpy(new_label->text, text);
        !          2319:        new_label->pos = just;
        !          2320:        new_label->rotate = rotate;
        !          2321:        (void) strcpy(new_label->font, font);
        !          2322:     }
        !          2323: }                              /* Entry font added by DJL */
        !          2324:
        !          2325: /* process 'set nolabel' command */
        !          2326: /* set nolabel {tag} */
        !          2327: static void set_nolabel()
        !          2328: {
        !          2329:     struct value a;
        !          2330:     struct text_label *this_label;
        !          2331:     struct text_label *prev_label;
        !          2332:     int tag;
        !          2333:
        !          2334:     if (END_OF_COMMAND) {
        !          2335:        /* delete all labels */
        !          2336:        while (first_label != NULL)
        !          2337:            delete_label((struct text_label *) NULL, first_label);
        !          2338:     } else {
        !          2339:        /* get tag */
        !          2340:        tag = (int) real(const_express(&a));
        !          2341:        if (!END_OF_COMMAND)
        !          2342:            int_error("extraneous arguments to set nolabel", c_token);
        !          2343:        for (this_label = first_label, prev_label = NULL;
        !          2344:             this_label != NULL;
        !          2345:             prev_label = this_label, this_label = this_label->next) {
        !          2346:            if (this_label->tag == tag) {
        !          2347:                delete_label(prev_label, this_label);
        !          2348:                return;         /* exit, our job is done */
        !          2349:            }
        !          2350:        }
        !          2351:        int_error("label not found", c_token);
        !          2352:     }
        !          2353: }
        !          2354:
        !          2355: /* assign a new label tag */
        !          2356: /* labels are kept sorted by tag number, so this is easy */
        !          2357: static int /* the lowest unassigned tag number */ assign_label_tag()
        !          2358: {
        !          2359:     struct text_label *this_label;
        !          2360:     int last = 0;              /* previous tag value */
        !          2361:
        !          2362:     for (this_label = first_label; this_label != NULL;
        !          2363:         this_label = this_label->next)
        !          2364:        if (this_label->tag == last + 1)
        !          2365:            last++;
        !          2366:        else
        !          2367:            break;
        !          2368:
        !          2369:     return (last + 1);
        !          2370: }
        !          2371:
        !          2372: /* delete label from linked list started by first_label.
        !          2373:  * called with pointers to the previous label (prev) and the
        !          2374:  * label to delete (this).
        !          2375:  * If there is no previous label (the label to delete is
        !          2376:  * first_label) then call with prev = NULL.
        !          2377:  */
        !          2378: static void delete_label(prev, this)
        !          2379: struct text_label *prev, *this;
        !          2380: {
        !          2381:     if (this != NULL) {                /* there really is something to delete */
        !          2382:        if (prev != NULL)       /* there is a previous label */
        !          2383:            prev->next = this->next;
        !          2384:        else                    /* this = first_label so change first_label */
        !          2385:            first_label = this->next;
        !          2386:        free((char *) this);
        !          2387:     }
        !          2388: }
        !          2389:
        !          2390:
        !          2391: /* process a 'set arrow' command */
        !          2392: /* set arrow {tag} {from x,y} {to x,y} {{no}head} */
        !          2393: static void set_arrow()
        !          2394: {
        !          2395:     struct value a;
        !          2396:     struct arrow_def *this_arrow = NULL;
        !          2397:     struct arrow_def *new_arrow = NULL;
        !          2398:     struct arrow_def *prev_arrow = NULL;
        !          2399:     struct position spos, epos;
        !          2400:     struct lp_style_type loc_lp;
        !          2401:     int axes = FIRST_AXES;
        !          2402:     int tag;
        !          2403:     TBOOLEAN set_start, set_end, head = 1, set_axes = 0, set_line = 0;
        !          2404:
        !          2405:     /* Init struct lp_style_type loc_lp */
        !          2406:     reset_lp_properties (&loc_lp);
        !          2407:
        !          2408:     /* get tag */
        !          2409:     if (!END_OF_COMMAND
        !          2410:        && !equals(c_token, "from")
        !          2411:        && !equals(c_token, "to")
        !          2412:        && !equals(c_token, "first")
        !          2413:        && !equals(c_token, "second")) {
        !          2414:        /* must be a tag expression! */
        !          2415:        tag = (int) real(const_express(&a));
        !          2416:        if (tag <= 0)
        !          2417:            int_error("tag must be > zero", c_token);
        !          2418:     } else
        !          2419:        tag = assign_arrow_tag();       /* default next tag */
        !          2420:
        !          2421:     if (!END_OF_COMMAND && equals(c_token, "first")) {
        !          2422:        ++c_token;
        !          2423:        axes = FIRST_AXES;
        !          2424:        set_axes = 1;
        !          2425:     } else if (!END_OF_COMMAND && equals(c_token, "second")) {
        !          2426:        ++c_token;
        !          2427:        axes = SECOND_AXES;
        !          2428:        set_axes = 1;
        !          2429:     }
        !          2430:     /* get start position */
        !          2431:     if (!END_OF_COMMAND && equals(c_token, "from")) {
        !          2432:        c_token++;
        !          2433:        if (END_OF_COMMAND)
        !          2434:            int_error("start coordinates expected", c_token);
        !          2435:        /* get coordinates */
        !          2436:        get_position(&spos);
        !          2437:        set_start = TRUE;
        !          2438:     } else {
        !          2439:        spos.x = spos.y = spos.z = 0;
        !          2440:        spos.scalex = spos.scaley = spos.scalez = first_axes;
        !          2441:        set_start = FALSE;
        !          2442:     }
        !          2443:
        !          2444:     /* get end position */
        !          2445:     if (!END_OF_COMMAND && equals(c_token, "to")) {
        !          2446:        c_token++;
        !          2447:        if (END_OF_COMMAND)
        !          2448:            int_error("end coordinates expected", c_token);
        !          2449:        /* get coordinates */
        !          2450:        get_position(&epos);
        !          2451:        set_end = TRUE;
        !          2452:     } else {
        !          2453:        epos.x = epos.y = epos.z = 0;
        !          2454:        epos.scalex = epos.scaley = epos.scalez = first_axes;
        !          2455:        set_end = FALSE;
        !          2456:     }
        !          2457:
        !          2458:     /* get start position - what the heck, either order is ok */
        !          2459:     if (!END_OF_COMMAND && equals(c_token, "from")) {
        !          2460:        if (set_start)
        !          2461:            int_error("only one 'from' is allowed", c_token);
        !          2462:        c_token++;
        !          2463:        if (END_OF_COMMAND)
        !          2464:            int_error("start coordinates expected", c_token);
        !          2465:        /* get coordinates */
        !          2466:        get_position(&spos);
        !          2467:        set_start = TRUE;
        !          2468:     }
        !          2469:     if (!END_OF_COMMAND && equals(c_token, "nohead")) {
        !          2470:        c_token++;
        !          2471:        head = 0;
        !          2472:     }
        !          2473:     if (!END_OF_COMMAND && equals(c_token, "head")) {
        !          2474:        c_token++;
        !          2475:        head = 1;
        !          2476:     }
        !          2477:     set_line = 1;
        !          2478:
        !          2479:     /* pick up a line spec - allow ls, but no point. */
        !          2480:     LP_PARSE(loc_lp, 1, 0, 0, 0);
        !          2481:     loc_lp.pointflag = 0;      /* standard value for arrows, don't use points */
        !          2482:
        !          2483:     if (!END_OF_COMMAND)
        !          2484:        int_error("extraneous or out-of-order arguments in set arrow", c_token);
        !          2485:
        !          2486:     /* OK! add arrow */
        !          2487:     if (first_arrow != NULL) { /* skip to last arrow */
        !          2488:        for (this_arrow = first_arrow; this_arrow != NULL;
        !          2489:             prev_arrow = this_arrow, this_arrow = this_arrow->next)
        !          2490:            /* is this the arrow we want? */
        !          2491:            if (tag <= this_arrow->tag)
        !          2492:                break;
        !          2493:     }
        !          2494:     if (this_arrow != NULL && tag == this_arrow->tag) {
        !          2495:        /* changing the arrow */
        !          2496:        if (set_start) {
        !          2497:            this_arrow->start = spos;
        !          2498:        }
        !          2499:        if (set_end) {
        !          2500:            this_arrow->end = epos;
        !          2501:        }
        !          2502:        this_arrow->head = head;
        !          2503:        if (set_line) {
        !          2504:            this_arrow->lp_properties = loc_lp;
        !          2505:        }
        !          2506:     } else {
        !          2507:        /* adding the arrow */
        !          2508:        new_arrow = (struct arrow_def *)
        !          2509:            gp_alloc((unsigned long) sizeof(struct arrow_def), "arrow");
        !          2510:        if (prev_arrow != NULL)
        !          2511:            prev_arrow->next = new_arrow;       /* add it to end of list */
        !          2512:        else
        !          2513:            first_arrow = new_arrow;    /* make it start of list */
        !          2514:        new_arrow->tag = tag;
        !          2515:        new_arrow->next = this_arrow;
        !          2516:        new_arrow->start = spos;
        !          2517:        new_arrow->end = epos;
        !          2518:        new_arrow->head = head;
        !          2519:        new_arrow->lp_properties = loc_lp;
        !          2520:     }
        !          2521: }
        !          2522:
        !          2523: /* process 'set noarrow' command */
        !          2524: /* set noarrow {tag} */
        !          2525: static void set_noarrow()
        !          2526: {
        !          2527:     struct value a;
        !          2528:     struct arrow_def *this_arrow;
        !          2529:     struct arrow_def *prev_arrow;
        !          2530:     int tag;
        !          2531:
        !          2532:     if (END_OF_COMMAND) {
        !          2533:        /* delete all arrows */
        !          2534:        while (first_arrow != NULL)
        !          2535:            delete_arrow((struct arrow_def *) NULL, first_arrow);
        !          2536:     } else {
        !          2537:        /* get tag */
        !          2538:        tag = (int) real(const_express(&a));
        !          2539:        if (!END_OF_COMMAND)
        !          2540:            int_error("extraneous arguments to set noarrow", c_token);
        !          2541:        for (this_arrow = first_arrow, prev_arrow = NULL;
        !          2542:             this_arrow != NULL;
        !          2543:             prev_arrow = this_arrow, this_arrow = this_arrow->next) {
        !          2544:            if (this_arrow->tag == tag) {
        !          2545:                delete_arrow(prev_arrow, this_arrow);
        !          2546:                return;         /* exit, our job is done */
        !          2547:            }
        !          2548:        }
        !          2549:        int_error("arrow not found", c_token);
        !          2550:     }
        !          2551: }
        !          2552:
        !          2553: /* assign a new arrow tag */
        !          2554: /* arrows are kept sorted by tag number, so this is easy */
        !          2555: static int /* the lowest unassigned tag number */ assign_arrow_tag()
        !          2556: {
        !          2557:     struct arrow_def *this_arrow;
        !          2558:     int last = 0;              /* previous tag value */
        !          2559:
        !          2560:     for (this_arrow = first_arrow; this_arrow != NULL;
        !          2561:         this_arrow = this_arrow->next)
        !          2562:        if (this_arrow->tag == last + 1)
        !          2563:            last++;
        !          2564:        else
        !          2565:            break;
        !          2566:
        !          2567:     return (last + 1);
        !          2568: }
        !          2569:
        !          2570: /* delete arrow from linked list started by first_arrow.
        !          2571:  * called with pointers to the previous arrow (prev) and the
        !          2572:  * arrow to delete (this).
        !          2573:  * If there is no previous arrow (the arrow to delete is
        !          2574:  * first_arrow) then call with prev = NULL.
        !          2575:  */
        !          2576: static void delete_arrow(prev, this)
        !          2577: struct arrow_def *prev, *this;
        !          2578: {
        !          2579:     if (this != NULL) {                /* there really is something to delete */
        !          2580:        if (prev != NULL)       /* there is a previous arrow */
        !          2581:            prev->next = this->next;
        !          2582:        else                    /* this = first_arrow so change first_arrow */
        !          2583:            first_arrow = this->next;
        !          2584:        free((char *) this);
        !          2585:     }
        !          2586: }
        !          2587:
        !          2588: /* ======================================================== */
        !          2589: /* process a 'set linestyle' command */
        !          2590: /* set linestyle {tag} {linetype n} {linewidth x} {pointtype n} {pointsize x} */
        !          2591: static void set_linestyle()
        !          2592: {
        !          2593:     struct value a;
        !          2594:     struct linestyle_def *this_linestyle = NULL;
        !          2595:     struct linestyle_def *new_linestyle = NULL;
        !          2596:     struct linestyle_def *prev_linestyle = NULL;
        !          2597:     struct lp_style_type loc_lp;
        !          2598:     int tag;
        !          2599:
        !          2600:     /* Init struct lp_style_type loc_lp */
        !          2601:     reset_lp_properties (&loc_lp);
        !          2602:
        !          2603:     /* get tag */
        !          2604:     if (!END_OF_COMMAND) {
        !          2605:        /* must be a tag expression! */
        !          2606:        tag = (int) real(const_express(&a));
        !          2607:        if (tag <= 0)
        !          2608:            int_error("tag must be > zero", c_token);
        !          2609:     } else
        !          2610:        tag = assign_linestyle_tag();   /* default next tag */
        !          2611:
        !          2612:     /* pick up a line spec : dont allow ls, do allow point type
        !          2613:      * default to same line type = point type = tag
        !          2614:      */
        !          2615:     LP_PARSE(loc_lp, 0, 1, tag - 1, tag - 1);
        !          2616:
        !          2617:     if (!END_OF_COMMAND)
        !          2618:        int_error("extraneous or out-of-order arguments in set linestyle", c_token);
        !          2619:
        !          2620:     /* OK! add linestyle */
        !          2621:     if (first_linestyle != NULL) {     /* skip to last linestyle */
        !          2622:        for (this_linestyle = first_linestyle; this_linestyle != NULL;
        !          2623:             prev_linestyle = this_linestyle, this_linestyle = this_linestyle->next)
        !          2624:            /* is this the linestyle we want? */
        !          2625:            if (tag <= this_linestyle->tag)
        !          2626:                break;
        !          2627:     }
        !          2628:     if (this_linestyle != NULL && tag == this_linestyle->tag) {
        !          2629:        /* changing the linestyle */
        !          2630:        this_linestyle->lp_properties = loc_lp;
        !          2631:     } else {
        !          2632:        /* adding the linestyle */
        !          2633:        new_linestyle = (struct linestyle_def *)
        !          2634:            gp_alloc((unsigned long) sizeof(struct linestyle_def), "linestyle");
        !          2635:        if (prev_linestyle != NULL)
        !          2636:            prev_linestyle->next = new_linestyle;       /* add it to end of list */
        !          2637:        else
        !          2638:            first_linestyle = new_linestyle;    /* make it start of list */
        !          2639:        new_linestyle->tag = tag;
        !          2640:        new_linestyle->next = this_linestyle;
        !          2641:        new_linestyle->lp_properties = loc_lp;
        !          2642:     }
        !          2643: }
        !          2644:
        !          2645: /* process 'set nolinestyle' command */
        !          2646: /* set nolinestyle {tag} */
        !          2647: static void set_nolinestyle()
        !          2648: {
        !          2649:     struct value a;
        !          2650:     struct linestyle_def *this, *prev;
        !          2651:     int tag;
        !          2652:
        !          2653:     if (END_OF_COMMAND) {
        !          2654:        /* delete all linestyles */
        !          2655:        while (first_linestyle != NULL)
        !          2656:            delete_linestyle((struct linestyle_def *) NULL, first_linestyle);
        !          2657:     } else {
        !          2658:        /* get tag */
        !          2659:        tag = (int) real(const_express(&a));
        !          2660:        if (!END_OF_COMMAND)
        !          2661:            int_error("extraneous arguments to set nolinestyle", c_token);
        !          2662:        for (this = first_linestyle, prev = NULL;
        !          2663:             this != NULL;
        !          2664:             prev = this, this = this->next) {
        !          2665:            if (this->tag == tag) {
        !          2666:                delete_linestyle(prev, this);
        !          2667:                return;         /* exit, our job is done */
        !          2668:            }
        !          2669:        }
        !          2670:        int_error("linestyle not found", c_token);
        !          2671:     }
        !          2672: }
        !          2673:
        !          2674: /* assign a new linestyle tag */
        !          2675: /* linestyles are kept sorted by tag number, so this is easy */
        !          2676: static int /* the lowest unassigned tag number */ assign_linestyle_tag()
        !          2677: {
        !          2678:     struct linestyle_def *this;
        !          2679:     int last = 0;              /* previous tag value */
        !          2680:
        !          2681:     for (this = first_linestyle; this != NULL; this = this->next)
        !          2682:        if (this->tag == last + 1)
        !          2683:            last++;
        !          2684:        else
        !          2685:            break;
        !          2686:
        !          2687:     return (last + 1);
        !          2688: }
        !          2689:
        !          2690: /* delete linestyle from linked list started by first_linestyle.
        !          2691:  * called with pointers to the previous linestyle (prev) and the
        !          2692:  * linestyle to delete (this).
        !          2693:  * If there is no previous linestyle (the linestyle to delete is
        !          2694:  * first_linestyle) then call with prev = NULL.
        !          2695:  */
        !          2696: static void delete_linestyle(prev, this)
        !          2697: struct linestyle_def *prev, *this;
        !          2698: {
        !          2699:     if (this != NULL) {                /* there really is something to delete */
        !          2700:        if (prev != NULL)       /* there is a previous linestyle */
        !          2701:            prev->next = this->next;
        !          2702:        else                    /* this = first_linestyle so change first_linestyle */
        !          2703:            first_linestyle = this->next;
        !          2704:        free((char *) this);
        !          2705:     }
        !          2706: }
        !          2707:
        !          2708: /*
        !          2709:  * auxiliary functions for the `set linestyle` command
        !          2710:  */
        !          2711:
        !          2712: void lp_use_properties(lp, tag, pointflag)
        !          2713: struct lp_style_type *lp;
        !          2714: int tag, pointflag;
        !          2715: {
        !          2716:     /*  This function looks for a linestyle defined by 'tag' and copies
        !          2717:      *  its data into the structure 'lp'.
        !          2718:      *
        !          2719:      *  If 'pointflag' equals ZERO, the properties belong to a linestyle
        !          2720:      *  used with arrows.  In this case no point properties will be
        !          2721:      *  passed to the terminal (cf. function 'term_apply_lp_properties' below).
        !          2722:      */
        !          2723:
        !          2724:     struct linestyle_def *this;
        !          2725:
        !          2726:     this = first_linestyle;
        !          2727:     while (this != NULL) {
        !          2728:        if (this->tag == tag) {
        !          2729:            *lp = this->lp_properties;
        !          2730:            lp->pointflag = pointflag;
        !          2731:            return;
        !          2732:        } else {
        !          2733:            this = this->next;
        !          2734:        }
        !          2735:     }
        !          2736:
        !          2737:     /* tag not found: */
        !          2738:     int_error("linestyle not found", NO_CARET);
        !          2739: }
        !          2740:
        !          2741: /* ======================================================== */
        !          2742:
        !          2743: enum PLOT_STYLE /* not static; used by command.c */ get_style()
        !          2744: {
        !          2745:     register enum PLOT_STYLE ps = LINES;       /* HBB: initial value, for 'gcc -W} */
        !          2746:
        !          2747:     c_token++;
        !          2748:     if (almost_equals(c_token, "l$ines"))
        !          2749:        ps = LINES;
        !          2750:     else if (almost_equals(c_token, "i$mpulses"))
        !          2751:        ps = IMPULSES;
        !          2752:     else if (almost_equals(c_token, "p$oints"))
        !          2753:        ps = POINTSTYLE;
        !          2754:     else if (almost_equals(c_token, "linesp$oints") || equals(c_token, "lp"))
        !          2755:        ps = LINESPOINTS;
        !          2756:     else if (almost_equals(c_token, "d$ots"))
        !          2757:        ps = DOTS;
        !          2758:     else if (almost_equals(c_token, "ye$rrorbars"))
        !          2759:        ps = YERRORBARS;
        !          2760:     else if (almost_equals(c_token, "e$rrorbars"))
        !          2761:        ps = YERRORBARS;
        !          2762:     else if (almost_equals(c_token, "xe$rrorbars"))
        !          2763:        ps = XERRORBARS;
        !          2764:     else if (almost_equals(c_token, "xye$rrorbars"))
        !          2765:        ps = XYERRORBARS;
        !          2766:     else if (almost_equals(c_token, "boxes"))
        !          2767:        ps = BOXES;
        !          2768:     else if (almost_equals(c_token, "boxer$rorbars"))
        !          2769:        ps = BOXERROR;
        !          2770:     else if (almost_equals(c_token, "boxx$yerrorbars"))
        !          2771:        ps = BOXXYERROR;
        !          2772:     else if (almost_equals(c_token, "st$eps"))
        !          2773:        ps = STEPS;
        !          2774:     else if (almost_equals(c_token, "fs$teps"))
        !          2775:        ps = FSTEPS;
        !          2776:     else if (almost_equals(c_token, "his$teps"))
        !          2777:        ps = HISTEPS;
        !          2778:     else if (almost_equals(c_token, "vec$tor"))                /* HBB: minor cosmetic change */
        !          2779:        ps = VECTOR;
        !          2780:     else if (almost_equals(c_token, "fin$ancebars"))
        !          2781:        ps = FINANCEBARS;
        !          2782:     else if (almost_equals(c_token, "can$dlesticks"))
        !          2783:        ps = CANDLESTICKS;
        !          2784:     else {
        !          2785:        int_error("expecting 'lines', 'points', 'linespoints', 'dots', 'impulses',\n\
        !          2786:         'yerrorbars', 'xerrorbars', 'xyerrorbars', 'steps', 'fsteps', 'histeps',\n\
        !          2787:         'boxes', 'boxerrorbars', 'boxxyerrorbars', 'vector', 'financebars', 'candlesticks'", c_token);
        !          2788:        return LINES;           /* keep gcc -Wuninitialised happy */
        !          2789:     }
        !          2790:     c_token++;
        !          2791:     return (ps);
        !          2792: }
        !          2793:
        !          2794: /* For set [xy]tics... command */
        !          2795: static void load_tics(axis, tdef)
        !          2796: int axis;
        !          2797: struct ticdef *tdef;           /* change this ticdef */
        !          2798: {
        !          2799:     if (equals(c_token, "(")) {        /* set : TIC_USER */
        !          2800:        c_token++;
        !          2801:        load_tic_user(axis, tdef);
        !          2802:     } else {                   /* series : TIC_SERIES */
        !          2803:        load_tic_series(axis, tdef);
        !          2804:     }
        !          2805: }
        !          2806:
        !          2807: /* load TIC_USER definition */
        !          2808: /* (tic[,tic]...)
        !          2809:  * where tic is ["string"] value
        !          2810:  * Left paren is already scanned off before entry.
        !          2811:  */
        !          2812: static void load_tic_user(axis, tdef)
        !          2813: int axis;
        !          2814: struct ticdef *tdef;
        !          2815: {
        !          2816:     struct ticmark *list = NULL;       /* start of list */
        !          2817:     struct ticmark *last = NULL;       /* end of list */
        !          2818:     struct ticmark *tic = NULL;        /* new ticmark */
        !          2819:     char temp_string[MAX_LINE_LEN];
        !          2820:
        !          2821:     while (!END_OF_COMMAND) {
        !          2822:        /* parse a new ticmark */
        !          2823:        tic = (struct ticmark *) gp_alloc((unsigned long) sizeof(struct ticmark), (char *) NULL);
        !          2824:        if (tic == (struct ticmark *) NULL) {
        !          2825:            free_marklist(list);
        !          2826:            int_error("out of memory for tic mark", c_token);
        !          2827:        }
        !          2828:        /* syntax is  (  ['format'] value , ... )
        !          2829:         * but for timedata, the value itself is a string, which
        !          2830:         * complicates things somewhat
        !          2831:         */
        !          2832:
        !          2833:        /* has a string with it? */
        !          2834:        if (isstring(c_token) &&
        !          2835:            (datatype[axis] != TIME || isstring(c_token + 1))) {
        !          2836:            quote_str(temp_string, c_token, MAX_LINE_LEN);
        !          2837:            tic->label = gp_alloc((unsigned long) strlen(temp_string) + 1, "tic label");
        !          2838:            (void) strcpy(tic->label, temp_string);
        !          2839:            c_token++;
        !          2840:        } else
        !          2841:            tic->label = NULL;
        !          2842:
        !          2843:        /* in any case get the value */
        !          2844:        GET_NUM_OR_TIME(tic->position, axis);
        !          2845:        tic->next = NULL;
        !          2846:
        !          2847:        /* append to list */
        !          2848:        if (list == NULL)
        !          2849:            last = list = tic;  /* new list */
        !          2850:        else {                  /* append to list */
        !          2851:            last->next = tic;
        !          2852:            last = tic;
        !          2853:        }
        !          2854:
        !          2855:        /* expect "," or ")" here */
        !          2856:        if (!END_OF_COMMAND && equals(c_token, ","))
        !          2857:            c_token++;          /* loop again */
        !          2858:        else
        !          2859:            break;              /* hopefully ")" */
        !          2860:     }
        !          2861:
        !          2862:     if (END_OF_COMMAND || !equals(c_token, ")")) {
        !          2863:        free_marklist(list);
        !          2864:        int_error("expecting right parenthesis )", c_token);
        !          2865:     }
        !          2866:     c_token++;
        !          2867:
        !          2868:     /* successful list */
        !          2869:     if (tdef->type == TIC_USER) {
        !          2870:        /* remove old list */
        !          2871:        /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
        !          2872:        free_marklist(tdef->def.user);
        !          2873:        tdef->def.user = NULL;
        !          2874:     }
        !          2875:     tdef->type = TIC_USER;
        !          2876:     tdef->def.user = list;
        !          2877: }
        !          2878:
        !          2879: static void free_marklist(list)
        !          2880: struct ticmark *list;
        !          2881: {
        !          2882:     register struct ticmark *freeable;
        !          2883:
        !          2884:     while (list != NULL) {
        !          2885:        freeable = list;
        !          2886:        list = list->next;
        !          2887:        if (freeable->label != NULL)
        !          2888:            free((char *) freeable->label);
        !          2889:        free((char *) freeable);
        !          2890:     }
        !          2891: }
        !          2892:
        !          2893: /* load TIC_SERIES definition */
        !          2894: /* [start,]incr[,end] */
        !          2895: static void load_tic_series(axis, tdef)
        !          2896: int axis;
        !          2897: struct ticdef *tdef;
        !          2898: {
        !          2899:     double start, incr, end;
        !          2900:     int incr_token;
        !          2901:
        !          2902:     GET_NUM_OR_TIME(start, axis);
        !          2903:
        !          2904:     if (!equals(c_token, ",")) {
        !          2905:        /* only step specified */
        !          2906:        incr = start;
        !          2907:        start = -VERYLARGE;
        !          2908:        end = VERYLARGE;
        !          2909:     } else {
        !          2910:
        !          2911:        c_token++;
        !          2912:
        !          2913:        incr_token = c_token;
        !          2914:        GET_NUM_OR_TIME(incr, axis);
        !          2915:
        !          2916:        if (END_OF_COMMAND)
        !          2917:            end = VERYLARGE;
        !          2918:        else {
        !          2919:            if (!equals(c_token, ","))
        !          2920:                int_error("expecting comma to separate incr,end", c_token);
        !          2921:            c_token++;
        !          2922:            GET_NUM_OR_TIME(end, axis);
        !          2923:        }
        !          2924:        if (!END_OF_COMMAND)
        !          2925:            int_error("tic series is defined by [start,]increment[,end]", c_token);
        !          2926:
        !          2927:        if (start < end && incr <= 0)
        !          2928:            int_error("increment must be positive", incr_token);
        !          2929:        if (start > end && incr >= 0)
        !          2930:            int_error("increment must be negative", incr_token);
        !          2931:        if (start > end) {
        !          2932:            /* put in order */
        !          2933:            double numtics;
        !          2934:            numtics = floor((end * (1 + SIGNIF) - start) / incr);
        !          2935:            end = start;
        !          2936:            start = end + numtics * incr;
        !          2937:            incr = -incr;
        !          2938: /*
        !          2939:    double temp = start;
        !          2940:    start = end;
        !          2941:    end = temp;
        !          2942:    incr = -incr;
        !          2943:  */
        !          2944:        }
        !          2945:     }
        !          2946:
        !          2947:     if (tdef->type == TIC_USER) {
        !          2948:        /* remove old list */
        !          2949:        /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
        !          2950:        free_marklist(tdef->def.user);
        !          2951:        tdef->def.user = NULL;
        !          2952:     }
        !          2953:     tdef->type = TIC_SERIES;
        !          2954:     tdef->def.series.start = start;
        !          2955:     tdef->def.series.incr = incr;
        !          2956:     tdef->def.series.end = end;
        !          2957: }
        !          2958:
        !          2959: static void load_offsets(a, b, c, d)
        !          2960: double *a, *b, *c, *d;
        !          2961: {
        !          2962:     struct value t;
        !          2963:
        !          2964:     *a = real(const_express(&t));      /* loff value */
        !          2965:     if (!equals(c_token, ","))
        !          2966:        return;
        !          2967:
        !          2968:     c_token++;
        !          2969:     *b = real(const_express(&t));      /* roff value */
        !          2970:     if (!equals(c_token, ","))
        !          2971:        return;
        !          2972:
        !          2973:     c_token++;
        !          2974:     *c = real(const_express(&t));      /* toff value */
        !          2975:     if (!equals(c_token, ","))
        !          2976:        return;
        !          2977:
        !          2978:     c_token++;
        !          2979:     *d = real(const_express(&t));      /* boff value */
        !          2980: }
        !          2981:
        !          2982: TBOOLEAN                       /* new value for autosc */
        !          2983: load_range(axis, a, b, autosc)         /* also used by command.c */
        !          2984: int axis;
        !          2985: double *a, *b;
        !          2986: TBOOLEAN autosc;
        !          2987: {
        !          2988:     if (equals(c_token, "]"))
        !          2989:        return (autosc);
        !          2990:     if (END_OF_COMMAND) {
        !          2991:        int_error("starting range value or ':' or 'to' expected", c_token);
        !          2992:     } else if (!equals(c_token, "to") && !equals(c_token, ":")) {
        !          2993:        if (equals(c_token, "*")) {
        !          2994:            autosc |= 1;
        !          2995:            c_token++;
        !          2996:        } else {
        !          2997:            GET_NUM_OR_TIME(*a, axis);
        !          2998:            autosc &= 2;
        !          2999:        }
        !          3000:     }
        !          3001:     if (!equals(c_token, "to") && !equals(c_token, ":"))
        !          3002:        int_error("':' or keyword 'to' expected", c_token);
        !          3003:     c_token++;
        !          3004:     if (!equals(c_token, "]")) {
        !          3005:        if (equals(c_token, "*")) {
        !          3006:            autosc |= 2;
        !          3007:            c_token++;
        !          3008:        } else {
        !          3009:            GET_NUM_OR_TIME(*b, axis);
        !          3010:            autosc &= 1;
        !          3011:        }
        !          3012:     }
        !          3013:     return (autosc);
        !          3014: }
        !          3015:
        !          3016: /* return 1 if format looks like a numeric format
        !          3017:  * ie more than one %{efg}, or %something-else
        !          3018:  */
        !          3019:
        !          3020: static int looks_like_numeric(format)
        !          3021: char *format;
        !          3022: {
        !          3023:     if (!(format = strchr(format, '%')))
        !          3024:        return 0;
        !          3025:
        !          3026:     while (++format, (*format >= '0' && *format <= '9') || *format == '.');
        !          3027:
        !          3028:     return (*format == 'f' || *format == 'g' || *format == 'e');
        !          3029: }
        !          3030:
        !          3031:
        !          3032: /* parse a position of the form
        !          3033:  *    [coords] x, [coords] y {,[coords] z}
        !          3034:  * where coords is one of first,second.graph,screen
        !          3035:  * if first or second, we need to take datatype into account
        !          3036:  * mixed co-ordinates are for specialists, but it's not particularly
        !          3037:  * hard to implement...
        !          3038:  */
        !          3039:
        !          3040: #define GET_NUMBER_OR_TIME(store,axes,axis) \
        !          3041: do{if (axes >= 0 && datatype[axes+axis] == TIME && isstring(c_token) ) { \
        !          3042:     char ss[80]; struct tm tm; \
        !          3043:     quote_str(ss,c_token, 80); ++c_token; \
        !          3044:     if (gstrptime(ss,timefmt,&tm)) store = (double) gtimegm(&tm); \
        !          3045:    } else {\
        !          3046:     struct value value; \
        !          3047:     store = real(const_express(&value));\
        !          3048:   }}while(0)
        !          3049:
        !          3050:
        !          3051: /* get_position_type - for use by get_position().
        !          3052:  * parses first/second/graph/screen keyword
        !          3053:  */
        !          3054:
        !          3055: static void get_position_type(type, axes)
        !          3056: enum position_type *type;
        !          3057: int *axes;
        !          3058: {
        !          3059:     if (almost_equals(c_token, "fir$st")) {
        !          3060:        ++c_token;
        !          3061:        *type = first_axes;
        !          3062:     } else if (almost_equals(c_token, "sec$ond")) {
        !          3063:        ++c_token;
        !          3064:        *type = second_axes;
        !          3065:     } else if (almost_equals(c_token, "gr$aph")) {
        !          3066:        ++c_token;
        !          3067:        *type = graph;
        !          3068:     } else if (almost_equals(c_token, "sc$reen")) {
        !          3069:        ++c_token;
        !          3070:        *type = screen;
        !          3071:     }
        !          3072:     switch (*type) {
        !          3073:     case first_axes:
        !          3074:        *axes = FIRST_AXES;
        !          3075:        return;
        !          3076:     case second_axes:
        !          3077:        *axes = SECOND_AXES;
        !          3078:        return;
        !          3079:     default:
        !          3080:        *axes = (-1);
        !          3081:        return;
        !          3082:     }
        !          3083: }
        !          3084:
        !          3085: /* get_position() - reads a position for label,arrow,key,... */
        !          3086:
        !          3087: static void get_position(pos)
        !          3088: struct position *pos;
        !          3089: {
        !          3090:     int axes;
        !          3091:     enum position_type type = first_axes;
        !          3092:
        !          3093:     get_position_type(&type, &axes);
        !          3094:     pos->scalex = type;
        !          3095:     GET_NUMBER_OR_TIME(pos->x, axes, FIRST_X_AXIS);
        !          3096:     if (!equals(c_token, ","))
        !          3097:        int_error("Expected comma", c_token);
        !          3098:     ++c_token;
        !          3099:     get_position_type(&type, &axes);
        !          3100:     pos->scaley = type;
        !          3101:     GET_NUMBER_OR_TIME(pos->y, axes, FIRST_Y_AXIS);
        !          3102:
        !          3103:     /* z is not really allowed for a screen co-ordinate, but keep it simple ! */
        !          3104:     if (equals(c_token, ",")) {
        !          3105:        ++c_token;
        !          3106:        get_position_type(&type, &axes);
        !          3107:        pos->scalez = type;
        !          3108:        GET_NUMBER_OR_TIME(pos->z, axes, FIRST_Z_AXIS);
        !          3109:     } else {
        !          3110:        pos->z = 0;
        !          3111:        pos->scalez = type;     /* same as y */
        !          3112:     }
        !          3113: }
        !          3114:
        !          3115: static void set_lp_properties(arg, allow_points, lt, pt, lw, ps)
        !          3116: struct lp_style_type *arg;
        !          3117: int allow_points, lt, pt;
        !          3118: double lw, ps;
        !          3119: {
        !          3120:     arg->pointflag = allow_points;
        !          3121:     arg->l_type = lt;
        !          3122:     arg->p_type = pt;
        !          3123:     arg->l_width = lw;
        !          3124:     arg->p_size = ps;
        !          3125: }
        !          3126:
        !          3127: static void reset_lp_properties(arg)
        !          3128: struct lp_style_type *arg;
        !          3129: {
        !          3130:     /* See plot.h for struct lp_style_type */
        !          3131:     arg->pointflag = arg->l_type = arg->p_type = 0;
        !          3132:     arg->l_width = arg->p_size = 1.0;
        !          3133: }
        !          3134:
        !          3135: static void set_locale(lcl)
        !          3136: char *lcl;
        !          3137: {
        !          3138: #ifndef NO_LOCALE_H
        !          3139:     int i;
        !          3140:     struct tm tm;
        !          3141:
        !          3142:     if (setlocale(LC_TIME, lcl))
        !          3143:        safe_strncpy(cur_locale, lcl, sizeof(cur_locale));
        !          3144:     else
        !          3145:        int_error("Locale not available", c_token);
        !          3146:
        !          3147:     /* we can do a *lot* better than this ; eg use system functions
        !          3148:      * where available; create values on first use, etc
        !          3149:      */
        !          3150:     memset(&tm, 0, sizeof(struct tm));
        !          3151:     for (i = 0; i < 7; ++i) {
        !          3152:        tm.tm_wday = i;         /* hope this enough */
        !          3153:        strftime(full_day_names[i], sizeof(full_day_names[i]), "%A", &tm);
        !          3154:        strftime(abbrev_day_names[i], sizeof(abbrev_day_names[i]), "%a", &tm);
        !          3155:     }
        !          3156:     for (i = 0; i < 12; ++i) {
        !          3157:        tm.tm_mon = i;          /* hope this enough */
        !          3158:        strftime(full_month_names[i], sizeof(full_month_names[i]), "%B", &tm);
        !          3159:        strftime(abbrev_month_names[i], sizeof(abbrev_month_names[i]), "%b", &tm);
        !          3160:     }
        !          3161: #else
        !          3162:     safe_strncpy(cur_locale, lcl, sizeof(cur_locale));
        !          3163: #endif /* NO_LOCALE_H */
        !          3164: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>