[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.3

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

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