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>