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