1 %{
2 /*
3 * Grace - GRaphing, Advanced Computation and Exploration of data
4 *
5 * Home page: http://plasma-gate.weizmann.ac.il/Grace/
6 *
7 * Copyright (c) 1991-1995 Paul J Turner, Portland, OR
8 * Copyright (c) 1996-2003 Grace Development Team
9 *
10 * Maintained by Evgeny Stambulchik
11 *
12 *
13 * All Rights Reserved
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30 /*
31 *
32 * evaluate expressions, commands, parameter files
33 *
34 */
35
36 #include <config.h>
37 #include <cmath.h>
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <string.h>
43 #include <ctype.h>
44 #if defined(HAVE_SYS_PARAM_H)
45 # include <sys/param.h>
46 #endif
47
48 /* bison not always handles it well itself */
49 #if defined(HAVE_ALLOCA_H)
50 # include <alloca.h>
51 #endif
52
53 #include "defines.h"
54 #include "globals.h"
55 #include "cephes/cephes.h"
56 #include "device.h"
57 #include "utils.h"
58 #include "files.h"
59 #include "graphs.h"
60 #include "graphutils.h"
61 #include "plotone.h"
62 #include "dlmodule.h"
63 #include "t1fonts.h"
64 #include "ssdata.h"
65 #include "protos.h"
66 #include "parser.h"
67 #include "mathstuff.h"
68
69 #define MAX_PARS_STRING_LENGTH 4096
70
71 #define CAST_DBL_TO_BOOL(x) (fabs(x) < 0.5 ? 0:1)
72
73 typedef double (*ParserFnc)();
74
75 extern graph *g;
76
77 static double s_result; /* return value if a scalar expression is scanned*/
78 static grarr *v_result; /* return value if a vector expression is scanned*/
79
80 static int expr_parsed, vexpr_parsed;
81
82 static int interr;
83
84 static grarr freelist[100]; /* temporary vectors */
85 static int fcnt = 0; /* number of the temporary vectors allocated */
86
87 static target trgt_pool[100]; /* pool of temporary targets */
88 static int tgtn = 0; /* number of the temporary targets used */
89
90 int naxis = 0; /* current axis */
91 static int curline, curbox, curellipse, curstring;
92 /* these guys attempt to avoid reentrancy problems */
93 static int gotparams = FALSE, gotread = FALSE, gotnlfit = FALSE;
94 int readxformat;
95 static int nlfit_gno, nlfit_setno, nlfit_nsteps;
96 static double *nlfit_warray = NULL;
97
98 char batchfile[GR_MAXPATHLEN] = "",
99 paramfile[GR_MAXPATHLEN] = "",
100 readfile[GR_MAXPATHLEN] = "";
101
102 static char f_string[MAX_PARS_STRING_LENGTH]; /* buffer for string to parse */
103 static int pos;
104
105 /* the graph, set, and its length of the parser's current state */
106 static int whichgraph;
107 static int whichset;
108
109 /* the graph and set of the left part of a vector assignment */
110 static int vasgn_gno;
111 static int vasgn_setno;
112
113 static int alias_force = FALSE; /* controls whether aliases can override
114 existing keywords */
115
116 extern char print_file[];
117 extern char *close_input;
118
119 static int filltype_obs;
120
121 static int index_shift = 0; /* 0 for C, 1 for F77 index notation */
122
123 static void free_tmpvrbl(grarr *vrbl);
124 static void copy_vrbl(grarr *dest, grarr *src);
125 static int find_set_bydata(double *data, target *tgt);
126
127 static int getcharstr(void);
128 static void ungetchstr(void);
129 static int follow(int expect, int ifyes, int ifno);
130
131 static int yylex(void);
132 static int yyparse(void);
133 static void yyerror(char *s);
134
135 static int findf(symtab_entry *keytable, char *s);
136
137 /* Total (intrinsic + user-defined) list of functions and keywords */
138 symtab_entry *key;
139
140 %}
141
142 %union {
143 int ival;
144 double dval;
145 char *sval;
146 double *dptr;
147 target *trgt;
148 grarr *vrbl;
149 }
150
151 %token KEY_VAR
152 %token KEY_VEC
153
154 %token KEY_CONST
155 %token KEY_UNIT
156 %token KEY_FUNC_I
157 %token KEY_FUNC_D
158 %token KEY_FUNC_NN
159 %token KEY_FUNC_ND
160 %token KEY_FUNC_DD
161 %token KEY_FUNC_NND
162 %token KEY_FUNC_PPD
163 %token KEY_FUNC_PPPD
164 %token KEY_FUNC_PPPPD
165 %token KEY_FUNC_PPPPPD
166
167 %token <ival> INDEX
168 %token <ival> DATE
169
170 %token <dptr> VAR_D /* a (pointer to) double variable */
171 %token <vrbl> VEC_D /* a (pointer to) double array variable */
172
173 %token <ival> CONSTANT /* a (double) constant */
174 %token <ival> UCONSTANT /* a (double) unit constant */
175 %token <ival> FUNC_I /* a function of 1 int variable */
176 %token <ival> FUNC_D /* a function of 1 double variable */
177 %token <ival> FUNC_NN /* a function of 2 int parameters */
178 %token <ival> FUNC_ND /* a function of 1 int parameter and 1 double variable */
179 %token <ival> FUNC_DD /* a function of 2 double variables */
180 %token <ival> FUNC_NND /* a function of 2 int parameters and 1 double variable */
181 %token <ival> FUNC_PPD /* a function of 2 double parameters and 1 double variable */
182 %token <ival> FUNC_PPPD /* a function of 3 double parameters and 1 double variable */
183 %token <ival> FUNC_PPPPD /* a function of 4 double parameters and 1 double variable */
184 %token <ival> FUNC_PPPPPD/* a function of 5 double parameters and 1 double variable */
185
186 %token <ival> ABOVE
187 %token <ival> ABSOLUTE
188 %token <ival> ALIAS
189 %token <ival> ALT
190 %token <ival> ALTXAXIS
191 %token <ival> ALTYAXIS
192 %token <ival> ANGLE
193 %token <ival> ANTIALIASING
194 %token <ival> APPEND
195 %token <ival> ARRANGE
196 %token <ival> ARROW
197 %token <ival> ASCENDING
198 %token <ival> ASPLINE
199 %token <ival> AUTO
200 %token <ival> AUTOSCALE
201 %token <ival> AUTOTICKS
202 %token <ival> AVALUE
203 %token <ival> AVG
204 %token <ival> BACKGROUND
205 %token <ival> BAR
206 %token <ival> BARDY
207 %token <ival> BARDYDY
208 %token <ival> BASELINE
209 %token <ival> BATCH
210 %token <ival> BEGIN
211 %token <ival> BELOW
212 %token <ival> BETWEEN
213 %token <ival> BLACKMAN
214 %token <ival> BLOCK
215 %token <ival> BOTH
216 %token <ival> BOTTOM
217 %token <ival> BOX
218 %token <ival> CD
219 %token <ival> CENTER
220 %token <ival> CHAR
221 %token <ival> CHART
222 %token <sval> CHRSTR
223 %token <ival> CLEAR
224 %token <ival> CLICK
225 %token <ival> CLIP
226 %token <ival> CLOSE
227 %token <ival> COEFFICIENTS
228 %token <ival> COLOR
229 %token <ival> COMMENT
230 %token <ival> COMPLEX
231 %token <ival> COMPUTING
232 %token <ival> CONSTRAINTS
233 %token <ival> COPY
234 %token <ival> CYCLE
235 %token <ival> DAYMONTH
236 %token <ival> DAYOFWEEKL
237 %token <ival> DAYOFWEEKS
238 %token <ival> DAYOFYEAR
239 %token <ival> DDMMYY
240 %token <ival> DECIMAL
241 %token <ival> DEF
242 %token <ival> DEFAULT
243 %token <ival> DEFINE
244 %token <ival> DEGREESLAT
245 %token <ival> DEGREESLON
246 %token <ival> DEGREESMMLAT
247 %token <ival> DEGREESMMLON
248 %token <ival> DEGREESMMSSLAT
249 %token <ival> DEGREESMMSSLON
250 %token <ival> DESCENDING
251 %token <ival> DESCRIPTION
252 %token <ival> DEVICE
253 %token <ival> DFT
254 %token <ival> DIFFERENCE
255 %token <ival> DISK
256 %token <ival> DOWN
257 %token <ival> DPI
258 %token <ival> DROP
259 %token <ival> DROPLINE
260 %token <ival> ECHO
261 %token <ival> ELLIPSE
262 %token <ival> ENGINEERING
263 %token <ival> ERRORBAR
264 %token <ival> EXIT
265 %token <ival> EXPONENTIAL
266 %token <ival> FFT
267 %token <ival> FILEP
268 %token <ival> FILL
269 %token <ival> FIT
270 %token <ival> FIXED
271 %token <ival> FIXEDPOINT
272 %token <ival> FLUSH
273 %token <ival> FOCUS
274 %token <ival> FOLLOWS
275 %token <ival> FONTP
276 %token <ival> FORCE
277 %token <ival> FORMAT
278 %token <ival> FORMULA
279 %token <ival> FRAMEP
280 %token <ival> FREE
281 %token <ival> FREQUENCY
282 %token <ival> FROM
283 %token <ival> GENERAL
284 %token <ival> GETP
285 %token <ival> GRAPH
286 %token <ival> GRAPHNO
287 %token <ival> GRID
288 %token <ival> HAMMING
289 %token <ival> HANNING
290 %token <ival> HARDCOPY
291 %token <ival> HBAR
292 %token <ival> HELP
293 %token <ival> HGAP
294 %token <ival> HIDDEN
295 %token <ival> HISTOGRAM
296 %token <ival> HMS
297 %token <ival> HORIZI
298 %token <ival> HORIZONTAL
299 %token <ival> HORIZO
300 %token <ival> ID
301 %token <ival> IFILTER
302 %token <ival> IMAX
303 %token <ival> IMIN
304 %token <ival> IN
305 %token <ival> INCREMENT
306 %token <ival> INOUT
307 %token <ival> INT
308 %token <ival> INTEGRATE
309 %token <ival> INTERPOLATE
310 %token <ival> INVDFT
311 %token <ival> INVERT
312 %token <ival> INVFFT
313 %token <ival> JUST
314 %token <ival> KILL
315 %token <ival> LABEL
316 %token <ival> LANDSCAPE
317 %token <ival> LAYOUT
318 %token <ival> LEFT
319 %token <ival> LEGEND
320 %token <ival> LENGTH
321 %token <ival> LINCONV
322 %token <ival> LINE
323 %token <ival> LINEAR
324 %token <ival> LINESTYLE
325 %token <ival> LINEWIDTH
326 %token <ival> LINK
327 %token <ival> LOAD
328 %token <ival> LOCTYPE
329 %token <ival> LOG
330 %token <ival> LOGARITHMIC
331 %token <ival> LOGIT
332 %token <ival> LOGX
333 %token <ival> LOGXY
334 %token <ival> LOGY
335 %token <ival> MAGIC
336 %token <ival> MAGNITUDE
337 %token <ival> MAJOR
338 %token <ival> MAP
339 %token <ival> MAXP
340 %token <ival> MESH
341 %token <ival> MINP
342 %token <ival> MINOR
343 %token <ival> MMDD
344 %token <ival> MMDDHMS
345 %token <ival> MMDDYY
346 %token <ival> MMDDYYHMS
347 %token <ival> MMSSLAT
348 %token <ival> MMSSLON
349 %token <ival> MMYY
350 %token <ival> MONTHDAY
351 %token <ival> MONTHL
352 %token <ival> MONTHS
353 %token <ival> MONTHSY
354 %token <ival> MOVE
355 %token <ival> NEGATE
356 %token <ival> NEW
357 %token <ival> NONE
358 %token <ival> NONLFIT
359 %token <ival> NORMAL
360 %token <ival> NXY
361 %token <ival> OFF
362 %token <ival> OFFSET
363 %token <ival> OFFSETX
364 %token <ival> OFFSETY
365 %token <ival> OFILTER
366 %token <ival> ON
367 %token <ival> ONREAD
368 %token <ival> OP
369 %token <ival> OPPOSITE
370 %token <ival> OUT
371 %token <ival> PAGE
372 %token <ival> PARA
373 %token <ival> PARAMETERS
374 %token <ival> PARZEN
375 %token <ival> PATTERN
376 %token <ival> PERIOD
377 %token <ival> PERP
378 %token <ival> PHASE
379 %token <ival> PIE
380 %token <ival> PIPE
381 %token <ival> PLACE
382 %token <ival> POINT
383 %token <ival> POLAR
384 %token <ival> POLYI
385 %token <ival> POLYO
386 %token <ival> POP
387 %token <ival> PORTRAIT
388 %token <ival> POWER
389 %token <ival> PREC
390 %token <ival> PREPEND
391 %token <ival> PRINT
392 %token <ival> PS
393 %token <ival> PUSH
394 %token <ival> PUTP
395 %token <ival> RAND
396 %token <ival> READ
397 %token <ival> REAL
398 %token <ival> RECIPROCAL
399 %token <ival> REDRAW
400 %token <ival> REFERENCE
401 %token <ival> REGNUM
402 %token <ival> REGRESS
403 %token <ival> RESIZE
404 %token <ival> RESTRICT
405 %token <ival> REVERSE
406 %token <ival> RIGHT
407 %token <ival> RISER
408 %token <ival> ROT
409 %token <ival> ROUNDED
410 %token <ival> RSUM
411 %token <ival> RULE
412 %token <ival> RUNAVG
413 %token <ival> RUNMAX
414 %token <ival> RUNMED
415 %token <ival> RUNMIN
416 %token <ival> RUNSTD
417 %token <ival> SAVEALL
418 %token <ival> SCALE
419 %token <ival> SCIENTIFIC
420 %token <ival> SCROLL
421 %token <ival> SD
422 %token <ival> SET
423 %token <ival> SETNUM
424 %token <ival> SFORMAT
425 %token <ival> SIGN
426 %token <ival> SIZE
427 %token <ival> SKIP
428 %token <ival> SLEEP
429 %token <ival> SMITH
430 %token <ival> SORT
431 %token <ival> SOURCE
432 %token <ival> SPEC
433 %token <ival> SPLINE
434 %token <ival> SPLIT
435 %token <ival> STACK
436 %token <ival> STACKED
437 %token <ival> STACKEDBAR
438 %token <ival> STACKEDHBAR
439 %token <ival> STAGGER
440 %token <ival> START
441 %token <ival> STOP
442 %token <ival> STRING
443 %token <ival> SUM
444 %token <ival> SUBTITLE
445 %token <ival> SWAP
446 %token <ival> SYMBOL
447 %token <ival> TARGET
448 %token <ival> TICKLABEL
449 %token <ival> TICKP
450 %token <ival> TICKSP
451 %token <ival> TIMER
452 %token <ival> TIMESTAMP
453 %token <ival> TITLE
454 %token <ival> TO
455 %token <ival> TOP
456 %token <ival> TRIANGULAR
457 %token <ival> TYPE
458 %token <ival> UP
459 %token <ival> UPDATEALL
460 %token <ival> USE
461 %token <ival> VERSION
462 %token <ival> VERTI
463 %token <ival> VERTICAL
464 %token <ival> VERTO
465 %token <ival> VGAP
466 %token <ival> VIEW
467 %token <ival> VX1
468 %token <ival> VX2
469 %token <ival> VXMAX
470 %token <ival> VY1
471 %token <ival> VY2
472 %token <ival> VYMAX
473 %token <ival> WELCH
474 %token <ival> WITH
475 %token <ival> WORLD
476 %token <ival> WRAP
477 %token <ival> WRITE
478 %token <ival> WX1
479 %token <ival> WX2
480 %token <ival> WY1
481 %token <ival> WY2
482 %token <ival> X_TOK
483 %token <ival> X0
484 %token <ival> X1
485 %token <ival> XAXES
486 %token <ival> XAXIS
487 %token <ival> XCOR
488 %token <ival> XMAX
489 %token <ival> XMIN
490 %token <ival> XY
491 %token <ival> XYAXES
492 %token <ival> XYBOXPLOT
493 %token <ival> XYCOLOR
494 %token <ival> XYCOLPAT
495 %token <ival> XYDX
496 %token <ival> XYDXDX
497 %token <ival> XYDXDXDYDY
498 %token <ival> XYDXDY
499 %token <ival> XYDY
500 %token <ival> XYDYDY
501 %token <ival> XYHILO
502 %token <ival> XYR
503 %token <ival> XYSIZE
504 %token <ival> XYSTRING
505 %token <ival> XYVMAP
506 %token <ival> XYZ
507 %token <ival> Y_TOK
508 %token <ival> Y0
509 %token <ival> Y1
510 %token <ival> Y2
511 %token <ival> Y3
512 %token <ival> Y4
513 %token <ival> YAXES
514 %token <ival> YAXIS
515 %token <ival> YEAR
516 %token <ival> YMAX
517 %token <ival> YMIN
518 %token <ival> YYMMDD
519 %token <ival> YYMMDDHMS
520 %token <ival> ZERO
521 %token <ival> ZNORM
522
523 %token <ival> FITPARM
524 %token <ival> FITPMAX
525 %token <ival> FITPMIN
526 %token <dval> NUMBER
527
528 %token <sval> NEW_TOKEN
529
530 %type <ival> onoff
531
532 %type <ival> selectgraph
533 %type <trgt> selectset
534
535 %type <ival> pagelayout
536 %type <ival> pageorient
537
538 %type <ival> regiontype
539
540 %type <ival> color_select
541 %type <ival> pattern_select
542 %type <ival> font_select
543
544 %type <ival> lines_select
545 %type <dval> linew_select
546
547 %type <ival> graphtype
548 %type <ival> xytype
549
550 %type <ival> scaletype
551 %type <ival> signchoice
552
553 %type <ival> colpat_obs
554 %type <ival> direction
555
556 %type <ival> formatchoice
557 %type <ival> inoutchoice
558 %type <ival> justchoice
559
560 %type <ival> opchoice
561 %type <ival> opchoice_sel
562 %type <ival> opchoice_obs
563 %type <ival> opchoice_sel_obs
564
565 %type <ival> worldview
566
567 %type <ival> filtermethod
568 %type <ival> filtertype
569
570 %type <ival> tickspectype
571
572 %type <ival> sourcetype
573
574 %type <ival> interpmethod
575 %type <ival> stattype
576
577 %type <ival> datacolumn
578
579 %type <ival> runtype
580
581 %type <ival> ffttype
582 %type <ival> fourierdata
583 %type <ival> fourierloadx
584 %type <ival> fourierloady
585 %type <ival> windowtype
586
587 %type <ival> nonlfitopts
588
589 %type <ival> sortdir
590 %type <ival> sorton
591
592 %type <ival> proctype
593
594 %type <ival> indx
595 %type <ival> iexpr
596 %type <ival> nexpr
597 %type <sval> sexpr
598 %type <dval> jdate
599 %type <dval> jrawdate
600 %type <dval> expr
601
602 %type <vrbl> array
603 %type <vrbl> lside_array
604
605 %type <vrbl> vexpr
606
607 /* Precedence */
608 %nonassoc '?' ':'
609 %left OR
610 %left AND
611 %nonassoc GT LT LE GE EQ NE
612 %right UCONSTANT
613 %left '+' '-'
614 %left '*' '/' '%'
615 %nonassoc UMINUS NOT /* negation--unary minus */
616 %right '^' /* exponentiation */
617 %left '.'
618
619
620 %%
621
622 full_list:
623 multi_list
624 | expr {
625 expr_parsed = TRUE;
626 s_result = $1;
627 }
628 | vexpr {
629 vexpr_parsed = TRUE;
630 v_result = $1;
631 }
632 ;
633
634 multi_list:
635 list
636 | multi_list ';' list
637 ;
638
639 list:
640 /* empty */
641 | parmset {}
642 | parmset_obs {}
643 | regionset {}
644 | setaxis {}
645 | set_setprop {}
646 | actions {}
647 | options {}
648 | asgn {}
649 | vasgn {}
650 | defines {}
651 | error {
652 return 1;
653 }
654 ;
655
656
657
658 expr: NUMBER {
659 $$ = $1;
660 }
661 | VAR_D {
662 $$ = *($1);
663 }
664 | FITPARM {
665 $$ = nonl_parms[$1].value;
666 }
667 | FITPMAX {
668 $$ = nonl_parms[$1].max;
669 }
670 | FITPMIN {
671 $$ = nonl_parms[$1].min;
672 }
673 | array indx {
674 if ($2 >= $1->length) {
675 errmsg("Access beyond array bounds");
676 return 1;
677 }
678 $$ = $1->data[$2];
679 }
680 | stattype '(' vexpr ')' {
681 double dummy, dummy2;
682 int idummy, ind, length = $3->length;
683 if ($3->data == NULL) {
684 yyerror("NULL variable, check set type");
685 return 1;
686 }
687 switch ($1) {
688 case MINP:
689 $$ = vmin($3->data, length);
690 break;
691 case MAXP:
692 $$ = vmax($3->data, length);
693 break;
694 case AVG:
695 stasum($3->data, length, &$$, &dummy);
696 break;
697 case SD:
698 stasum($3->data, length, &dummy, &$$);
699 break;
700 case SUM:
701 stasum($3->data, length, &$$, &dummy);
702 $$ *= length;
703 break;
704 case IMIN:
705 minmax($3->data, length, &dummy, &dummy2, &ind, &idummy);
706 $$ = (double) ind;
707 break;
708 case IMAX:
709 minmax($3->data, length, &dummy, &dummy2, &idummy, &ind);
710 $$ = (double) ind;
711 break;
712 }
713 }
714 | INT '(' vexpr ',' vexpr ')' {
715 if ($3->length != $5->length) {
716 yyerror("X and Y are of different length");
717 return 1;
718 } else {
719 $$ = trapint($3->data, $5->data, NULL, NULL, $3->length);
720 }
721 }
722 | array '.' LENGTH {
723 $$ = $1->length;
724 }
725 | selectset '.' LENGTH {
726 $$ = getsetlength($1->gno, $1->setno);
727 }
728 | selectset '.' ID {
729 $$ = $1->setno;
730 }
731 | selectgraph '.' ID {
732 $$ = $1;
733 }
734 | CONSTANT
735 {
736 $$ = ((ParserFnc) (key[$1].data)) ();
737 }
738 | expr UCONSTANT
739 {
740 $$ = $1 * ((ParserFnc) (key[$2].data)) ();
741 }
742 | RAND
743 {
744 $$ = drand48();
745 }
746 | FUNC_I '(' iexpr ')'
747 {
748 $$ = ((ParserFnc) (key[$1].data)) ($3);
749 }
750 | FUNC_D '(' expr ')'
751 {
752 $$ = ((ParserFnc) (key[$1].data)) ($3);
753 }
754 | FUNC_ND '(' iexpr ',' expr ')'
755 {
756 $$ = ((ParserFnc) (key[$1].data)) ($3, $5);
757 }
758 | FUNC_NN '(' iexpr ',' iexpr ')'
759 {
760 $$ = ((ParserFnc) (key[$1].data)) ($3, $5);
761 }
762 | FUNC_DD '(' expr ',' expr ')'
763 {
764 $$ = ((ParserFnc) (key[$1].data)) ($3, $5);
765 }
766 | FUNC_NND '(' iexpr ',' iexpr ',' expr ')'
767 {
768 $$ = ((ParserFnc) (key[$1].data)) ($3, $5, $7);
769 }
770 | FUNC_PPD '(' expr ',' expr ',' expr ')'
771 {
772 $$ = ((ParserFnc) (key[$1].data)) ($3, $5, $7);
773 }
774 | FUNC_PPPD '(' expr ',' expr ',' expr ',' expr ')'
775 {
776 $$ = ((ParserFnc) (key[$1].data)) ($3, $5, $7, $9);
777 }
778 | FUNC_PPPPD '(' expr ',' expr ',' expr ',' expr ',' expr ')'
779 {
780 $$ = ((ParserFnc) (key[$1].data)) ($3, $5, $7, $9, $11);
781 }
782 | FUNC_PPPPPD '(' expr ',' expr ',' expr ',' expr ',' expr ',' expr ')'
783 {
784 $$ = ((ParserFnc) (key[$1].data)) ($3, $5, $7, $9, $11, $13);
785 }
786 | selectgraph '.' VX1 {
787 $$ = g[$1].v.xv1;
788 }
789 | selectgraph '.' VX2 {
790 $$ = g[$1].v.xv2;
791 }
792 | selectgraph '.' VY1 {
793 $$ = g[$1].v.yv1;
794 }
795 | selectgraph '.' VY2 {
796 $$ = g[$1].v.yv2;
797 }
798 | selectgraph '.' WX1 {
799 $$ = g[$1].w.xg1;
800 }
801 | selectgraph '.' WX2 {
802 $$ = g[$1].w.xg2;
803 }
804 | selectgraph '.' WY1 {
805 $$ = g[$1].w.yg1;
806 }
807 | selectgraph '.' WY2 {
808 $$ = g[$1].w.yg2;
809 }
810 | DATE '(' jdate ')' {
811 $$ = $3;
812 }
813 | DATE '(' iexpr ',' nexpr ',' nexpr ')' { /* yr, mo, day */
814 $$ = cal_and_time_to_jul($3, $5, $7, 12, 0, 0.0);
815 }
816 | DATE '(' iexpr ',' nexpr ',' nexpr ',' nexpr ',' nexpr ',' expr ')'
817 { /* yr, mo, day, hr, min, sec */
818 $$ = cal_and_time_to_jul($3, $5, $7, $9, $11, $13);
819 }
820 | VX1 {
821 if (!is_valid_gno(whichgraph)) {
822 yyerror("No valid graph selected");
823 return 1;
824 }
825 $$ = g[whichgraph].v.xv1;
826 }
827 | VX2 {
828 if (!is_valid_gno(whichgraph)) {
829 yyerror("No valid graph selected");
830 return 1;
831 }
832 $$ = g[whichgraph].v.xv2;
833 }
834 | VY1 {
835 if (!is_valid_gno(whichgraph)) {
836 yyerror("No valid graph selected");
837 return 1;
838 }
839 $$ = g[whichgraph].v.yv1;
840 }
841 | VY2 {
842 if (!is_valid_gno(whichgraph)) {
843 yyerror("No valid graph selected");
844 return 1;
845 }
846 $$ = g[whichgraph].v.yv2;
847 }
848 | WX1 {
849 if (!is_valid_gno(whichgraph)) {
850 yyerror("No valid graph selected");
851 return 1;
852 }
853 $$ = g[whichgraph].w.xg1;
854 }
855 | WX2 {
856 if (!is_valid_gno(whichgraph)) {
857 yyerror("No valid graph selected");
858 return 1;
859 }
860 $$ = g[whichgraph].w.xg2;
861 }
862 | WY1 {
863 if (!is_valid_gno(whichgraph)) {
864 yyerror("No valid graph selected");
865 return 1;
866 }
867 $$ = g[whichgraph].w.yg1;
868 }
869 | WY2 {
870 if (!is_valid_gno(whichgraph)) {
871 yyerror("No valid graph selected");
872 return 1;
873 }
874 $$ = g[whichgraph].w.yg2;
875 }
876 | VXMAX {
877 double vx, vy;
878 get_page_viewport(&vx, &vy);
879 $$ = vx;
880 }
881 | VYMAX {
882 double vx, vy;
883 get_page_viewport(&vx, &vy);
884 $$ = vy;
885 }
886 | '(' expr ')' {
887 $$ = $2;
888 }
889 | expr '+' expr {
890 $$ = $1 + $3;
891 }
892 | expr '-' expr {
893 $$ = $1 - $3;
894 }
895 | '-' expr %prec UMINUS {
896 $$ = -$2;
897 }
898 | '+' expr %prec UMINUS {
899 $$ = $2;
900 }
901 | expr '*' expr {
902 $$ = $1 * $3;
903 }
904 | expr '/' expr
905 {
906 if ($3 != 0.0) {
907 $$ = $1 / $3;
908 } else {
909 yyerror("Divide by zero");
910 return 1;
911 }
912 }
913 | expr '%' expr {
914 if ($3 != 0.0) {
915 $$ = fmod($1, $3);
916 } else {
917 yyerror("Divide by zero");
918 return 1;
919 }
920 }
921 | expr '^' expr {
922 if ($1 < 0 && rint($3) != $3) {
923 yyerror("Negative value raised to non-integer power");
924 return 1;
925 } else if ($1 == 0.0 && $3 <= 0.0) {
926 yyerror("Zero raised to non-positive power");
927 return 1;
928 } else {
929 $$ = pow($1, $3);
930 }
931 }
932 | expr '?' expr ':' expr {
933 $$ = $1 ? $3 : $5;
934 }
935 | expr GT expr {
936 $$ = ($1 > $3);
937 }
938 | expr LT expr {
939 $$ = ($1 < $3);
940 }
941 | expr LE expr {
942 $$ = ($1 <= $3);
943 }
944 | expr GE expr {
945 $$ = ($1 >= $3);
946 }
947 | expr EQ expr {
948 $$ = ($1 == $3);
949 }
950 | expr NE expr {
951 $$ = ($1 != $3);
952 }
953 | expr AND expr {
954 $$ = $1 && $3;
955 }
956 | expr OR expr {
957 $$ = $1 || $3;
958 }
959 | NOT expr {
960 $$ = !($2);
961 }
962 ;
963
964 sexpr: CHRSTR {
965 $$ = $1;
966 }
967 | sexpr '.' sexpr {
968 $$ = concat_strings($1, $3);
969 xfree($3);
970 }
971 | sexpr '.' expr {
972 char buf[32];
973 set_locale_num(TRUE);
974 sprintf(buf, "%g", $3);
975 set_locale_num(FALSE);
976 $$ = concat_strings($1, buf);
977 }
978 ;
979
980 iexpr: expr {
981 int itmp = rint($1);
982 if (fabs(itmp - $1) > 1.e-6) {
983 yyerror("Non-integer value supplied for integer");
984 return 1;
985 }
986 $$ = itmp;
987 }
988 ;
989
990 nexpr: iexpr {
991 if ($1 < 0) {
992 yyerror("Negative value supplied for non-negative");
993 return 1;
994 }
995 $$ = $1;
996 }
997 ;
998
999 indx: '[' iexpr ']' {
1000 int itmp = $2 - index_shift;
1001 if (itmp < 0) {
1002 yyerror("Negative index");
1003 return 1;
1004 }
1005 $$ = itmp;
1006 }
1007 ;
1008
1009 jdate: expr {
1010 $$ = $1;
1011 }
1012 | sexpr {
1013 double jul;
1014 Dates_format dummy;
1015 if (parse_date($1, get_date_hint(), FALSE, &jul, &dummy)
1016 == RETURN_SUCCESS) {
1017 xfree($1);
1018 $$ = jul;
1019 } else {
1020 xfree($1);
1021 yyerror("Invalid date");
1022 return 1;
1023 }
1024 }
1025 ;
1026
1027 jrawdate: expr {
1028 $$ = $1;
1029 }
1030 | sexpr {
1031 double jul;
1032 Dates_format dummy;
1033 if (parse_date($1, get_date_hint(), TRUE, &jul, &dummy)
1034 == RETURN_SUCCESS) {
1035 xfree($1);
1036 $$ = jul;
1037 } else {
1038 xfree($1);
1039 yyerror("Invalid date");
1040 return 1;
1041 }
1042 }
1043 ;
1044
1045 array:
1046 VEC_D
1047 {
1048 $$ = $1;
1049 }
1050 | datacolumn
1051 {
1052 double *ptr = getcol(vasgn_gno, vasgn_setno, $1);
1053 $$ = &freelist[fcnt++];
1054 $$->type = GRARR_SET;
1055 $$->data = ptr;
1056 if (ptr == NULL) {
1057 errmsg("NULL variable - check set type");
1058 return 1;
1059 } else {
1060 $$->length = getsetlength(vasgn_gno, vasgn_setno);
1061 }
1062 }
1063 | selectset '.' datacolumn
1064 {
1065 double *ptr = getcol($1->gno, $1->setno, $3);
1066 $$ = &freelist[fcnt++];
1067 $$->type = GRARR_SET;
1068 $$->data = ptr;
1069 if (ptr == NULL) {
1070 errmsg("NULL variable - check set type");
1071 return 1;
1072 } else {
1073 $$->length = getsetlength($1->gno, $1->setno);
1074 }
1075 }
1076 ;
1077
1078 vexpr:
1079 array
1080 {
1081 $$ = $1;
1082 }
1083 | array '[' iexpr ':' iexpr ']'
1084 {
1085 int start = $3 - index_shift, stop = $5 - index_shift;
1086 if (start < 0 || stop < start || stop >= $1->length) {
1087 yyerror("Invalid index range");
1088 } else {
1089 int len = stop - start + 1;
1090 double *ptr = xmalloc(len*SIZEOF_DOUBLE);
1091 if ($$->data == NULL) {
1092 yyerror("Not enough memory");
1093 } else {
1094 int i;
1095 $$ = &freelist[fcnt++];
1096 $$->data = ptr;
1097 $$->length = len;
1098 $$->type = GRARR_TMP;
1099 for (i = 0; i < len; i++) {
1100 $$->data[i] = $1->data[i + $3];
1101 }
1102 }
1103 }
1104 }
1105 | MESH '(' nexpr ')'
1106 {
1107 int len = $3;
1108 if (len < 1) {
1109 yyerror("npoints must be > 0");
1110 } else {
1111 double *ptr = allocate_index_data(len);
1112 if (ptr == NULL) {
1113 errmsg("Malloc failed");
1114 return 1;
1115 } else {
1116 $$ = &freelist[fcnt++];
1117 $$->type = GRARR_TMP;
1118 $$->data = ptr;
1119 $$->length = len;
1120 }
1121 }
1122 }
1123 | MESH '(' expr ',' expr ',' nexpr ')'
1124 {
1125 int len = $7;
1126 if (len < 2) {
1127 yyerror("npoints must be > 1");
1128 } else {
1129 double *ptr = allocate_mesh($3, $5, len);
1130 if (ptr == NULL) {
1131 errmsg("Malloc failed");
1132 return 1;
1133 } else {
1134 $$ = &freelist[fcnt++];
1135 $$->type = GRARR_TMP;
1136 $$->data = ptr;
1137 $$->length = len;
1138 }
1139 }
1140 }
1141 | RAND '(' nexpr ')'
1142 {
1143 int i;
1144 $$ = &freelist[fcnt++];
1145 $$->data = xmalloc($3*SIZEOF_DOUBLE);
1146 if ($$->data == NULL) {
1147 errmsg("Not enough memory");
1148 return 1;
1149 } else {
1150 $$->length = $3;
1151 $$->type = GRARR_TMP;
1152 }
1153 for (i = 0; i < $$->length; i++) {
1154 $$->data[i] = drand48();
1155 }
1156 }
1157 | REGNUM '(' selectset ')'
1158 {
1159 int rtype, i, len;
1160 char *rarray;
1161
1162 rtype = RESTRICT_REG0 + $1;
1163
1164 if (get_restriction_array($3->gno, $3->setno,
1165 rtype, FALSE, &rarray) != RETURN_SUCCESS) {
1166 errmsg("Error in region evaluation");
1167 return 1;
1168 }
1169
1170 len = getsetlength($3->gno, $3->setno);
1171 $$ = &freelist[fcnt++];
1172 $$->data = xmalloc(len*SIZEOF_DOUBLE);
1173 if ($$->data == NULL) {
1174 errmsg("Not enough memory");
1175 return 1;
1176 } else {
1177 $$->length = len;
1178 $$->type = GRARR_TMP;
1179 }
1180 for (i = 0; i < $$->length; i++) {
1181 $$->data[i] = rarray[i];
1182 }
1183
1184 xfree(rarray);
1185 }
1186 | RSUM '(' vexpr ')'
1187 {
1188 int i;
1189 $$ = &freelist[fcnt++];
1190 copy_vrbl($$, $3);
1191 $$->type = GRARR_TMP;
1192 for (i = 1; i < $$->length; i++) {
1193 $$->data[i] += $$->data[i - 1];
1194 }
1195 }
1196 | FUNC_I '(' vexpr ')'
1197 {
1198 int i;
1199 $$ = &freelist[fcnt++];
1200 copy_vrbl($$, $3);
1201 $$->type = GRARR_TMP;
1202 for (i = 0; i < $$->length; i++) {
1203 $$->data[i] = ((ParserFnc) (key[$1].data)) ((int) ($3->data[i]));
1204 }
1205 }
1206 | FUNC_D '(' vexpr ')'
1207 {
1208 int i;
1209 $$ = &freelist[fcnt++];
1210 copy_vrbl($$, $3);
1211 $$->type = GRARR_TMP;
1212 for (i = 0; i < $$->length; i++) {
1213 $$->data[i] = ((ParserFnc) (key[$1].data)) (($3->data[i]));
1214 }
1215 }
1216 | FUNC_DD '(' vexpr ',' vexpr ')'
1217 {
1218 int i;
1219 if ($3->length != $5->length) {
1220 errmsg("Can't operate on vectors of different lengths");
1221 return 1;
1222 }
1223 $$ = &freelist[fcnt++];
1224 copy_vrbl($$, $3);
1225 $$->type = GRARR_TMP;
1226
1227 for (i = 0; i < $$->length; i++) {
1228 $$->data[i] = ((ParserFnc) (key[$1].data)) ($3->data[i], $5->data[i]);
1229 }
1230 }
1231 | FUNC_DD '(' expr ',' vexpr ')'
1232 {
1233 int i;
1234 $$ = &freelist[fcnt++];
1235 copy_vrbl($$, $5);
1236 $$->type = GRARR_TMP;
1237
1238 for (i = 0; i < $$->length; i++) {
1239 $$->data[i] = ((ParserFnc) (key[$1].data)) ($3, $5->data[i]);
1240 }
1241 }
1242 | FUNC_DD '(' vexpr ',' expr ')'
1243 {
1244 int i;
1245 $$ = &freelist[fcnt++];
1246 copy_vrbl($$, $3);
1247 $$->type = GRARR_TMP;
1248
1249 for (i = 0; i < $$->length; i++) {
1250 $$->data[i] = ((ParserFnc) (key[$1].data)) ($3->data[i], $5);
1251 }
1252 }
1253 | FUNC_ND '(' iexpr ',' vexpr ')'
1254 {
1255 int i;
1256 $$ = &freelist[fcnt++];
1257 copy_vrbl($$, $5);
1258 $$->type = GRARR_TMP;
1259
1260 for (i = 0; i < $$->length; i++) {
1261 $$->data[i] = ((ParserFnc) (key[$1].data)) ($3, $5->data[i]);
1262 }
1263 }
1264 | FUNC_NND '(' iexpr ',' iexpr ',' vexpr ')'
1265 {
1266 int i;
1267 $$ = &freelist[fcnt++];
1268 copy_vrbl($$, $7);
1269 $$->type = GRARR_TMP;
1270
1271 for (i = 0; i < $$->length; i++) {
1272 $$->data[i] = ((ParserFnc) (key[$1].data)) ($3, $5, $7->data[i]);
1273 }
1274 }
1275 | FUNC_PPD '(' expr ',' expr ',' vexpr ')'
1276 {
1277 int i;
1278 $$ = &freelist[fcnt++];
1279 copy_vrbl($$, $7);
1280 $$->type = GRARR_TMP;
1281
1282 for (i = 0; i < $$->length; i++) {
1283 $$->data[i] = ((ParserFnc) (key[$1].data)) ($3, $5, $7->data[i]);
1284 }
1285 }
1286 | FUNC_PPPD '(' expr ',' expr ',' expr ',' vexpr ')'
1287 {
1288 int i;
1289 $$ = &freelist[fcnt++];
1290 copy_vrbl($$, $9);
1291 $$->type = GRARR_TMP;
1292
1293 for (i = 0; i < $$->length; i++) {
1294 $$->data[i] = ((ParserFnc) (key[$1].data)) ($3, $5, $7, $9->data[i]);
1295 }
1296 }
1297 | FUNC_PPPPD '(' expr ',' expr ',' expr ',' expr ',' vexpr ')'
1298 {
1299 int i;
1300 $$ = &freelist[fcnt++];
1301 copy_vrbl($$, $11);
1302 $$->type = GRARR_TMP;
1303
1304 for (i = 0; i < $$->length; i++) {
1305 $$->data[i] = ((ParserFnc) (key[$1].data)) ($3, $5, $7, $9, $11->data[i]);
1306 }
1307 }
1308 | FUNC_PPPPPD '(' expr ',' expr ',' expr ',' expr ',' expr ',' vexpr ')'
1309 {
1310 int i;
1311 $$ = &freelist[fcnt++];
1312 copy_vrbl($$, $13);
1313 $$->type = GRARR_TMP;
1314
1315 for (i = 0; i < $$->length; i++) {
1316 $$->data[i] = ((ParserFnc) (key[$1].data)) ($3, $5, $7, $9, $11, $13->data[i]);
1317 }
1318 }
1319 | vexpr '+' vexpr
1320 {
1321 int i;
1322 if ($1->length != $3->length) {
1323 errmsg("Can't operate on vectors of different lengths");
1324 return 1;
1325 }
1326 $$ = &freelist[fcnt++];
1327 copy_vrbl($$, $1);
1328 $$->type = GRARR_TMP;
1329
1330 for (i = 0; i < $$->length; i++) {
1331 $$->data[i] = $1->data[i] + $3->data[i];
1332 }
1333 }
1334 | vexpr '+' expr
1335 {
1336 int i;
1337 $$ = &freelist[fcnt++];
1338 copy_vrbl($$, $1);
1339 $$->type = GRARR_TMP;
1340
1341 for (i = 0; i < $$->length; i++) {
1342 $$->data[i] = $1->data[i] + $3;
1343 }
1344 }
1345 | expr '+' vexpr
1346 {
1347 int i;
1348 $$ = &freelist[fcnt++];
1349 copy_vrbl($$, $3);
1350 $$->type = GRARR_TMP;
1351
1352 for (i = 0; i < $$->length; i++) {
1353 $$->data[i] = $1 + $3->data[i];
1354 }
1355 }
1356 | vexpr '-' vexpr
1357 {
1358 int i;
1359 if ($1->length != $3->length) {
1360 errmsg("Can't operate on vectors of different lengths");
1361 return 1;
1362 }
1363 $$ = &freelist[fcnt++];
1364 copy_vrbl($$, $1);
1365 $$->type = GRARR_TMP;
1366
1367 for (i = 0; i < $$->length; i++) {
1368 $$->data[i] = $1->data[i] - $3->data[i];
1369 }
1370 }
1371 | vexpr '-' expr
1372 {
1373 int i;
1374 $$ = &freelist[fcnt++];
1375 copy_vrbl($$, $1);
1376 $$->type = GRARR_TMP;
1377
1378 for (i = 0; i < $$->length; i++) {
1379 $$->data[i] = $1->data[i] - $3;
1380 }
1381 }
1382 | expr '-' vexpr
1383 {
1384 int i;
1385 $$ = &freelist[fcnt++];
1386 copy_vrbl($$, $3);
1387 $$->type = GRARR_TMP;
1388
1389 for (i = 0; i < $$->length; i++) {
1390 $$->data[i] = $1 - $3->data[i];
1391 }
1392 }
1393 | vexpr '*' vexpr
1394 {
1395 int i;
1396 if ($1->length != $3->length) {
1397 errmsg("Can't operate on vectors of different lengths");
1398 return 1;
1399 }
1400 $$ = &freelist[fcnt++];
1401 copy_vrbl($$, $1);
1402 $$->type = GRARR_TMP;
1403
1404 for (i = 0; i < $$->length; i++) {
1405 $$->data[i] = $1->data[i] * $3->data[i];
1406 }
1407 }
1408 | vexpr '*' expr
1409 {
1410 int i;
1411 $$ = &freelist[fcnt++];
1412 copy_vrbl($$, $1);
1413 $$->type = GRARR_TMP;
1414
1415 for (i = 0; i < $$->length; i++) {
1416 $$->data[i] = $1->data[i] * $3;
1417 }
1418 }
1419 | expr '*' vexpr
1420 {
1421 int i;
1422 $$ = &freelist[fcnt++];
1423 copy_vrbl($$, $3);
1424 $$->type = GRARR_TMP;
1425
1426 for (i = 0; i < $$->length; i++) {
1427 $$->data[i] = $1 * $3->data[i];
1428 }
1429 }
1430 | vexpr '/' vexpr
1431 {
1432 int i;
1433 if ($1->length != $3->length) {
1434 errmsg("Can't operate on vectors of different lengths");
1435 return 1;
1436 }
1437 $$ = &freelist[fcnt++];
1438 copy_vrbl($$, $1);
1439 $$->type = GRARR_TMP;
1440
1441 for (i = 0; i < $$->length; i++) {
1442 if ($3->data[i] == 0.0) {
1443 errmsg("Divide by zero");
1444 return 1;
1445 }
1446 $$->data[i] = $1->data[i] / $3->data[i];
1447 }
1448 }
1449 | vexpr '/' expr
1450 {
1451 int i;
1452 if ($3 == 0.0) {
1453 errmsg("Divide by zero");
1454 return 1;
1455 }
1456 $$ = &freelist[fcnt++];
1457 copy_vrbl($$, $1);
1458 $$->type = GRARR_TMP;
1459
1460 for (i = 0; i < $$->length; i++) {
1461 $$->data[i] = $1->data[i] / $3;
1462 }
1463 }
1464 | expr '/' vexpr
1465 {
1466 int i;
1467 $$ = &freelist[fcnt++];
1468 copy_vrbl($$, $3);
1469 $$->type = GRARR_TMP;
1470
1471 for (i = 0; i < $$->length; i++) {
1472 if ($3->data[i] == 0.0) {
1473 errmsg("Divide by zero");
1474 return 1;
1475 }
1476 $$->data[i] = $1 / $3->data[i];
1477 }
1478 }
1479 | vexpr '%' vexpr
1480 {
1481 int i;
1482 if ($1->length != $3->length) {
1483 errmsg("Can't operate on vectors of different lengths");
1484 return 1;
1485 }
1486 $$ = &freelist[fcnt++];
1487 copy_vrbl($$, $1);
1488 $$->type = GRARR_TMP;
1489
1490 for (i = 0; i < $$->length; i++) {
1491 if ($3->data[i] == 0.0) {
1492 errmsg("Divide by zero");
1493 return 1;
1494 } else {
1495 $$->data[i] = fmod($1->data[i], $3->data[i]);
1496 }
1497 }
1498 }
1499 | vexpr '%' expr
1500 {
1501 int i;
1502 if ($3 == 0.0) {
1503 errmsg("Divide by zero");
1504 return 1;
1505 }
1506 $$ = &freelist[fcnt++];
1507 copy_vrbl($$, $1);
1508 $$->type = GRARR_TMP;
1509
1510 for (i = 0; i < $$->length; i++) {
1511 $$->data[i] = fmod($1->data[i], $3);
1512 }
1513 }
1514 | expr '%' vexpr
1515 {
1516 int i;
1517 $$ = &freelist[fcnt++];
1518 copy_vrbl($$, $3);
1519 $$->type = GRARR_TMP;
1520
1521 for (i = 0; i < $$->length; i++) {
1522 if ($3->data[i] == 0.0) {
1523 errmsg("Divide by zero");
1524 return 1;
1525 } else {
1526 $$->data[i] = fmod($1, $3->data[i]);
1527 }
1528 }
1529 }
1530 | vexpr '^' vexpr
1531 {
1532 int i;
1533 if ($1->length != $3->length) {
1534 errmsg("Can't operate on vectors of different lengths");
1535 return 1;
1536 }
1537 $$ = &freelist[fcnt++];
1538 copy_vrbl($$, $1);
1539 $$->type = GRARR_TMP;
1540
1541 for (i = 0; i < $$->length; i++) {
1542 if ($1->data[i] < 0 && rint($3->data[i]) != $3->data[i]) {
1543 yyerror("Negative value raised to non-integer power");
1544 return 1;
1545 } else if ($1->data[i] == 0.0 && $3->data[i] <= 0.0) {
1546 yyerror("Zero raised to non-positive power");
1547 return 1;
1548 } else {
1549 $$->data[i] = pow($1->data[i], $3->data[i]);
1550 }
1551 }
1552 }
1553 | vexpr '^' expr
1554 {
1555 int i;
1556 $$ = &freelist[fcnt++];
1557 copy_vrbl($$, $1);
1558 $$->type = GRARR_TMP;
1559
1560 for (i = 0; i < $$->length; i++) {
1561 if ($1->data[i] < 0 && rint($3) != $3) {
1562 yyerror("Negative value raised to non-integer power");
1563 return 1;
1564 } else if ($1->data[i] == 0.0 && $3 <= 0.0) {
1565 yyerror("Zero raised to non-positive power");
1566 return 1;
1567 } else {
1568 $$->data[i] = pow($1->data[i], $3);
1569 }
1570 }
1571 }
1572 | expr '^' vexpr
1573 {
1574 int i;
1575 $$ = &freelist[fcnt++];
1576 copy_vrbl($$, $3);
1577 $$->type = GRARR_TMP;
1578
1579 for (i = 0; i < $$->length; i++) {
1580 if ($1 < 0 && rint($3->data[i]) != $3->data[i]) {
1581 yyerror("Negative value raised to non-integer power");
1582 return 1;
1583 } else if ($1 == 0.0 && $3->data[i] <= 0.0) {
1584 yyerror("Zero raised to non-positive power");
1585 return 1;
1586 } else {
1587 $$->data[i] = pow($1, $3->data[i]);
1588 }
1589 }
1590 }
1591 | vexpr UCONSTANT
1592 {
1593 int i;
1594 $$ = &freelist[fcnt++];
1595 copy_vrbl($$, $1);
1596 $$->type = GRARR_TMP;
1597 for (i = 0; i < $$->length; i++) {
1598 $$->data[i] = $1->data[i] * ((ParserFnc) (key[$2].data)) ();
1599 }
1600 }
1601 | vexpr '?' expr ':' expr {
1602 int i;
1603 $$ = &freelist[fcnt++];
1604 copy_vrbl($$, $1);
1605 $$->type = GRARR_TMP;
1606 for (i = 0; i < $$->length; i++) {
1607 $$->data[i] = CAST_DBL_TO_BOOL($1->data[i]) ? $3 : $5;
1608 }
1609 }
1610 | vexpr '?' expr ':' vexpr {
1611 int i;
1612 if ($1->length != $5->length) {
1613 errmsg("Can't operate on vectors of different lengths");
1614 return 1;
1615 }
1616 $$ = &freelist[fcnt++];
1617 copy_vrbl($$, $1);
1618 $$->type = GRARR_TMP;
1619 for (i = 0; i < $$->length; i++) {
1620 $$->data[i] = CAST_DBL_TO_BOOL($1->data[i]) ? $3 : $5->data[i];
1621 }
1622 }
1623 | vexpr '?' vexpr ':' expr {
1624 int i;
1625 if ($1->length != $3->length) {
1626 errmsg("Can't operate on vectors of different lengths");
1627 return 1;
1628 }
1629 $$ = &freelist[fcnt++];
1630 copy_vrbl($$, $1);
1631 $$->type = GRARR_TMP;
1632 for (i = 0; i < $$->length; i++) {
1633 $$->data[i] = CAST_DBL_TO_BOOL($1->data[i]) ? $3->data[i] : $5;
1634 }
1635 }
1636 | vexpr '?' vexpr ':' vexpr {
1637 int i;
1638 if ($1->length != $5->length || $1->length != $3->length) {
1639 errmsg("Can't operate on vectors of different lengths");
1640 return 1;
1641 }
1642 $$ = &freelist[fcnt++];
1643 copy_vrbl($$, $1);
1644 $$->type = GRARR_TMP;
1645 for (i = 0; i < $$->length; i++) {
1646 $$->data[i] = CAST_DBL_TO_BOOL($1->data[i]) ? $3->data[i] : $5->data[i];
1647 }
1648 }
1649 | vexpr OR vexpr
1650 {
1651 int i;
1652 if ($1->length != $3->length) {
1653 errmsg("Can't operate on vectors of different lengths");
1654 return 1;
1655 }
1656 $$ = &freelist[fcnt++];
1657 copy_vrbl($$, $1);
1658 $$->type = GRARR_TMP;
1659
1660 for (i = 0; i < $$->length; i++) {
1661 $$->data[i] = $1->data[i] || $3->data[i];
1662 }
1663 }
1664 | vexpr OR expr
1665 {
1666 int i;
1667 $$ = &freelist[fcnt++];
1668 copy_vrbl($$, $1);
1669 $$->type = GRARR_TMP;
1670
1671 for (i = 0; i < $$->length; i++) {
1672 $$->data[i] = $1->data[i] || $3;
1673 }
1674 }
1675 | expr OR vexpr
1676 {
1677 int i;
1678 $$ = &freelist[fcnt++];
1679 copy_vrbl($$, $3);
1680 $$->type = GRARR_TMP;
1681
1682 for (i = 0; i < $$->length; i++) {
1683 $$->data[i] = $1 || $3->data[i];
1684 }
1685 }
1686 | vexpr AND vexpr
1687 {
1688 int i;
1689 if ($1->length != $3->length) {
1690 errmsg("Can't operate on vectors of different lengths");
1691 return 1;
1692 }
1693 $$ = &freelist[fcnt++];
1694 copy_vrbl($$, $1);
1695 $$->type = GRARR_TMP;
1696
1697 for (i = 0; i < $$->length; i++) {
1698 $$->data[i] = $1->data[i] && $3->data[i];
1699 }
1700 }
1701 | vexpr AND expr
1702 {
1703 int i;
1704 $$ = &freelist[fcnt++];
1705 copy_vrbl($$, $1);
1706 $$->type = GRARR_TMP;
1707
1708 for (i = 0; i < $$->length; i++) {
1709 $$->data[i] = $1->data[i] && $3;
1710 }
1711 }
1712 | expr AND vexpr
1713 {
1714 int i;
1715 $$ = &freelist[fcnt++];
1716 copy_vrbl($$, $3);
1717 $$->type = GRARR_TMP;
1718
1719 for (i = 0; i < $$->length; i++) {
1720 $$->data[i] = $1 && $3->data[i];
1721 }
1722 }
1723 | vexpr GT vexpr
1724 {
1725 int i;
1726 if ($1->length != $3->length) {
1727 errmsg("Can't operate on vectors of different lengths");
1728 return 1;
1729 }
1730 $$ = &freelist[fcnt++];
1731 copy_vrbl($$, $1);
1732 $$->type = GRARR_TMP;
1733
1734 for (i = 0; i < $$->length; i++) {
1735 $$->data[i] = ($1->data[i] > $3->data[i]);
1736 }
1737 }
1738 | vexpr GT expr
1739 {
1740 int i;
1741 $$ = &freelist[fcnt++];
1742 copy_vrbl($$, $1);
1743 $$->type = GRARR_TMP;
1744
1745 for (i = 0; i < $$->length; i++) {
1746 $$->data[i] = ($1->data[i] > $3);
1747 }
1748 }
1749 | expr GT vexpr
1750 {
1751 int i;
1752 $$ = &freelist[fcnt++];
1753 copy_vrbl($$, $3);
1754 $$->type = GRARR_TMP;
1755
1756 for (i = 0; i < $$->length; i++) {
1757 $$->data[i] = ($1 > $3->data[i]);
1758 }
1759 }
1760 | vexpr LT vexpr
1761 {
1762 int i;
1763 if ($1->length != $3->length) {
1764 errmsg("Can't operate on vectors of different lengths");
1765 return 1;
1766 }
1767 $$ = &freelist[fcnt++];
1768 copy_vrbl($$, $1);
1769 $$->type = GRARR_TMP;
1770
1771 for (i = 0; i < $$->length; i++) {
1772 $$->data[i] = ($1->data[i] < $3->data[i]);
1773 }
1774 }
1775 | vexpr LT expr
1776 {
1777 int i;
1778 $$ = &freelist[fcnt++];
1779 copy_vrbl($$, $1);
1780 $$->type = GRARR_TMP;
1781
1782 for (i = 0; i < $$->length; i++) {
1783 $$->data[i] = ($1->data[i] < $3);
1784 }
1785 }
1786 | expr LT vexpr
1787 {
1788 int i;
1789 $$ = &freelist[fcnt++];
1790 copy_vrbl($$, $3);
1791 $$->type = GRARR_TMP;
1792
1793 for (i = 0; i < $$->length; i++) {
1794 $$->data[i] = ($1 < $3->data[i]);
1795 }
1796 }
1797 | vexpr GE vexpr
1798 {
1799 int i;
1800 if ($1->length != $3->length) {
1801 errmsg("Can't operate on vectors of different lengths");
1802 return 1;
1803 }
1804 $$ = &freelist[fcnt++];
1805 copy_vrbl($$, $1);
1806 $$->type = GRARR_TMP;
1807
1808 for (i = 0; i < $$->length; i++) {
1809 $$->data[i] = ($1->data[i] >= $3->data[i]);
1810 }
1811 }
1812 | vexpr GE expr
1813 {
1814 int i;
1815 $$ = &freelist[fcnt++];
1816 copy_vrbl($$, $1);
1817 $$->type = GRARR_TMP;
1818
1819 for (i = 0; i < $$->length; i++) {
1820 $$->data[i] = ($1->data[i] >= $3);
1821 }
1822 }
1823 | expr GE vexpr
1824 {
1825 int i;
1826 $$ = &freelist[fcnt++];
1827 copy_vrbl($$, $3);
1828 $$->type = GRARR_TMP;
1829
1830 for (i = 0; i < $$->length; i++) {
1831 $$->data[i] = ($1 >= $3->data[i]);
1832 }
1833 }
1834 | vexpr LE vexpr
1835 {
1836 int i;
1837 if ($1->length != $3->length) {
1838 errmsg("Can't operate on vectors of different lengths");
1839 return 1;
1840 }
1841 $$ = &freelist[fcnt++];
1842 copy_vrbl($$, $1);
1843 $$->type = GRARR_TMP;
1844
1845 for (i = 0; i < $$->length; i++) {
1846 $$->data[i] = ($1->data[i] <= $3->data[i]);
1847 }
1848 }
1849 | vexpr LE expr
1850 {
1851 int i;
1852 $$ = &freelist[fcnt++];
1853 copy_vrbl($$, $1);
1854 $$->type = GRARR_TMP;
1855
1856 for (i = 0; i < $$->length; i++) {
1857 $$->data[i] = ($1->data[i] <= $3);
1858 }
1859 }
1860 | expr LE vexpr
1861 {
1862 int i;
1863 $$ = &freelist[fcnt++];
1864 copy_vrbl($$, $3);
1865 $$->type = GRARR_TMP;
1866
1867 for (i = 0; i < $$->length; i++) {
1868 $$->data[i] = ($1 <= $3->data[i]);
1869 }
1870 }
1871 | vexpr EQ vexpr
1872 {
1873 int i;
1874 if ($1->length != $3->length) {
1875 errmsg("Can't operate on vectors of different lengths");
1876 return 1;
1877 }
1878 $$ = &freelist[fcnt++];
1879 copy_vrbl($$, $1);
1880 $$->type = GRARR_TMP;
1881
1882 for (i = 0; i < $$->length; i++) {
1883 $$->data[i] = ($1->data[i] == $3->data[i]);
1884 }
1885 }
1886 | vexpr EQ expr
1887 {
1888 int i;
1889 $$ = &freelist[fcnt++];
1890 copy_vrbl($$, $1);
1891 $$->type = GRARR_TMP;
1892
1893 for (i = 0; i < $$->length; i++) {
1894 $$->data[i] = ($1->data[i] == $3);
1895 }
1896 }
1897 | expr EQ vexpr
1898 {
1899 int i;
1900 $$ = &freelist[fcnt++];
1901 copy_vrbl($$, $3);
1902 $$->type = GRARR_TMP;
1903
1904 for (i = 0; i < $$->length; i++) {
1905 $$->data[i] = ($1 == $3->data[i]);
1906 }
1907 }
1908 | vexpr NE vexpr
1909 {
1910 int i;
1911 if ($1->length != $3->length) {
1912 errmsg("Can't operate on vectors of different lengths");
1913 return 1;
1914 }
1915 $$ = &freelist[fcnt++];
1916 copy_vrbl($$, $1);
1917 $$->type = GRARR_TMP;
1918
1919 for (i = 0; i < $$->length; i++) {
1920 $$->data[i] = ($1->data[i] != $3->data[i]);
1921 }
1922 }
1923 | vexpr NE expr
1924 {
1925 int i;
1926 $$ = &freelist[fcnt++];
1927 copy_vrbl($$, $1);
1928 $$->type = GRARR_TMP;
1929
1930 for (i = 0; i < $$->length; i++) {
1931 $$->data[i] = ($1->data[i] != $3);
1932 }
1933 }
1934 | expr NE vexpr
1935 {
1936 int i;
1937 $$ = &freelist[fcnt++];
1938 copy_vrbl($$, $3);
1939 $$->type = GRARR_TMP;
1940
1941 for (i = 0; i < $$->length; i++) {
1942 $$->data[i] = ($1 != $3->data[i]);
1943 }
1944 }
1945 | NOT vexpr
1946 {
1947 int i;
1948 $$ = &freelist[fcnt++];
1949 copy_vrbl($$, $2);
1950 $$->type = GRARR_TMP;
1951 for (i = 0; i < $$->length; i++) {
1952 $$->data[i] = !$2->data[i];
1953 }
1954 }
1955 | '(' vexpr ')'
1956 {
1957 int i;
1958 $$ = &freelist[fcnt++];
1959 copy_vrbl($$, $2);
1960 $$->type = GRARR_TMP;
1961 for (i = 0; i < $$->length; i++) {
1962 $$->data[i] = $2->data[i];
1963 }
1964 }
1965 | '-' vexpr %prec UMINUS {
1966 int i;
1967 $$ = &freelist[fcnt++];
1968 copy_vrbl($$, $2);
1969 $$->type = GRARR_TMP;
1970 for (i = 0; i < $$->length; i++) {
1971 $$->data[i] = - $2->data[i];
1972 }
1973 }
1974 ;
1975
1976
1977 asgn:
1978 VAR_D '=' expr
1979 {
1980 *($1) = $3;
1981 }
1982 | FITPARM '=' expr
1983 {
1984 nonl_parms[$1].value = $3;
1985 }
1986 | FITPMAX '=' expr
1987 {
1988 nonl_parms[$1].max = $3;
1989 }
1990 | FITPMIN '=' expr
1991 {
1992 nonl_parms[$1].min = $3;
1993 }
1994 | array indx '=' expr
1995 {
1996 if ($2 >= $1->length) {
1997 yyerror("Access beyond array bounds");
1998 return 1;
1999 }
2000 $1->data[$2] = $4;
2001 }
2002 ;
2003
2004 lside_array:
2005 array
2006 {
2007 target tgt;
2008 switch ($1->type) {
2009 case GRARR_SET:
2010 if (find_set_bydata($1->data, &tgt) == RETURN_SUCCESS) {
2011 vasgn_gno = tgt.gno;
2012 vasgn_setno = tgt.setno;
2013 } else {
2014 errmsg("Internal error");
2015 return 1;
2016 }
2017 break;
2018 case GRARR_VEC:
2019 vasgn_gno = -1;
2020 vasgn_setno = -1;
2021 break;
2022 default:
2023 /* It can NOT be a tmp array on the left side! */
2024 errmsg("Internal error");
2025 return 1;
2026 }
2027 $$ = $1;
2028 }
2029 ;
2030
2031 vasgn:
2032 lside_array '=' vexpr
2033 {
2034 int i;
2035 if ($1->length != $3->length) {
2036 errmsg("Left and right vectors are of different lengths");
2037 return 1;
2038 }
2039 for (i = 0; i < $1->length; i++) {
2040 $1->data[i] = $3->data[i];
2041 }
2042 }
2043 | lside_array '=' expr
2044 {
2045 int i;
2046 for (i = 0; i < $1->length; i++) {
2047 $1->data[i] = $3;
2048 }
2049 }
2050 ;
2051
2052 defines:
2053 DEFINE NEW_TOKEN
2054 {
2055 symtab_entry tmpkey;
2056 double *var;
2057
2058 var = xmalloc(SIZEOF_DOUBLE);
2059 *var = 0.0;
2060
2061 tmpkey.s = $2;
2062 tmpkey.type = KEY_VAR;
2063 tmpkey.data = (void *) var;
2064 if (addto_symtab(tmpkey) != RETURN_SUCCESS) {
2065 yyerror("Adding new symbol failed");
2066 }
2067
2068 xfree($2);
2069 }
2070 | DEFINE NEW_TOKEN '[' ']'
2071 {
2072 if (define_parser_arr($2) == NULL) {
2073 yyerror("Adding new symbol failed");
2074 }
2075
2076 xfree($2);
2077 }
2078 | DEFINE NEW_TOKEN '[' nexpr ']'
2079 {
2080 grarr *var;
2081 if ((var = define_parser_arr($2)) == NULL) {
2082 yyerror("Adding new symbol failed");
2083 } else {
2084 realloc_vrbl(var, $4);
2085 }
2086
2087 xfree($2);
2088 }
2089 | DEFINE VAR_D
2090 {
2091 yyerror("Keyword already exists");
2092 }
2093 | DEFINE VEC_D
2094 {
2095 yyerror("Keyword already exists");
2096 }
2097 | CLEAR VAR_D
2098 {
2099 undefine_parser_var((void *) $2);
2100 xfree($2);
2101 }
2102 | CLEAR VEC_D
2103 {
2104 realloc_vrbl($2, 0);
2105 undefine_parser_var((void *) $2);
2106 xfree($2);
2107 }
2108 | ALIAS sexpr sexpr {
2109 int position;
2110
2111 lowtoupper($3);
2112 if ((position = findf(key, $3)) >= 0) {
2113 symtab_entry tmpkey;
2114 tmpkey.s = $2;
2115 tmpkey.type = key[position].type;
2116 tmpkey.data = key[position].data;
2117 if (addto_symtab(tmpkey) != RETURN_SUCCESS) {
2118 yyerror("Keyword already exists");
2119 }
2120 } else {
2121 yyerror("Aliased keyword not found");
2122 }
2123 xfree($2);
2124 xfree($3);
2125 }
2126 | ALIAS FORCE onoff {
2127 alias_force = $3;
2128 }
2129 | USE sexpr TYPE proctype FROM sexpr {
2130 if (load_module($6, $2, $2, $4) != 0) {
2131 yyerror("DL module load failed");
2132 }
2133 xfree($2);
2134 xfree($6);
2135 }
2136 | USE sexpr TYPE proctype FROM sexpr ALIAS sexpr {
2137 if (load_module($6, $2, $8, $4) != 0) {
2138 yyerror("DL module load failed");
2139 }
2140 xfree($2);
2141 xfree($6);
2142 xfree($8);
2143 }
2144 ;
2145
2146 regionset:
2147 REGNUM onoff {
2148 rg[$1].active = $2;
2149 }
2150 | REGNUM TYPE regiontype {
2151 rg[$1].type = $3;
2152 }
2153 | REGNUM color_select {
2154 rg[$1].color = $2;
2155 }
2156 | REGNUM lines_select {
2157 rg[$1].lines = $2;
2158 }
2159 | REGNUM linew_select {
2160 rg[$1].linew = $2;
2161 }
2162 | REGNUM LINE expr ',' expr ',' expr ',' expr
2163 {
2164 rg[$1].x1 = $3;
2165 rg[$1].y1 = $5;
2166 rg[$1].x2 = $7;
2167 rg[$1].y2 = $9;
2168 }
2169 | REGNUM XY expr ',' expr
2170 {
2171 rg[$1].x = xrealloc(rg[$1].x, (rg[$1].n + 1) * SIZEOF_DOUBLE);
2172 rg[$1].y = xrealloc(rg[$1].y, (rg[$1].n + 1) * SIZEOF_DOUBLE);
2173 rg[$1].x[rg[$1].n] = $3;
2174 rg[$1].y[rg[$1].n] = $5;
2175 rg[$1].n++;
2176 }
2177 | LINK REGNUM TO selectgraph {
2178 rg[$2].linkto = $4;
2179 }
2180 ;
2181
2182
2183 parmset:
2184 VERSION nexpr {
2185 if (set_project_version($2) != RETURN_SUCCESS) {
2186 errmsg("Project version is newer than software!");
2187 }
2188 if (get_project_version() < 50001) {
2189 map_fonts(FONT_MAP_ACEGR);
2190 } else {
2191 map_fonts(FONT_MAP_DEFAULT);
2192 }
2193 }
2194 | PAGE RESIZE nexpr ',' nexpr {
2195 set_page_dimensions($3, $5, TRUE);
2196 }
2197 | PAGE SIZE nexpr ',' nexpr {
2198 set_page_dimensions($3, $5, FALSE);
2199 }
2200 | DEVICE sexpr PAGE SIZE nexpr ',' nexpr {
2201 int device_id;
2202 Device_entry dev;
2203
2204 device_id = get_device_by_name($2);
2205 xfree($2);
2206 if (device_id < 0) {
2207 yyerror("Unknown device");
2208 } else {
2209 dev = get_device_props(device_id);
2210 dev.pg.width = (long) ($5*dev.pg.dpi/72);
2211 dev.pg.height = (long) ($7*dev.pg.dpi/72);
2212 set_device_props(device_id, dev);
2213 }
2214 }
2215 | DEVICE sexpr DPI expr {
2216 int device_id;
2217 Device_entry dev;
2218
2219 device_id = get_device_by_name($2);
2220 if (device_id < 0) {
2221 yyerror("Unknown device");
2222 } else {
2223 dev = get_device_props(device_id);
2224 dev.pg.dpi = $4;
2225 set_device_props(device_id, dev);
2226 }
2227 xfree($2);
2228 }
2229 | DEVICE sexpr FONTP ANTIALIASING onoff {
2230 int device_id;
2231 Device_entry dev;
2232
2233 device_id = get_device_by_name($2);
2234 if (device_id < 0) {
2235 yyerror("Unknown device");
2236 } else {
2237 dev = get_device_props(device_id);
2238 dev.fontaa = $5;
2239 set_device_props(device_id, dev);
2240 }
2241 xfree($2);
2242 }
2243 | DEVICE sexpr FONTP onoff {
2244 int device_id;
2245 Device_entry dev;
2246
2247 device_id = get_device_by_name($2);
2248 if (device_id < 0) {
2249 yyerror("Unknown device");
2250 } else {
2251 dev = get_device_props(device_id);
2252 dev.devfonts = $4;
2253 set_device_props(device_id, dev);
2254 }
2255 xfree($2);
2256 }
2257 | DEVICE sexpr OP sexpr {
2258 int device_id;
2259
2260 device_id = get_device_by_name($2);
2261 if (device_id < 0) {
2262 yyerror("Unknown device");
2263 } else {
2264 if (parse_device_options(device_id, $4) !=
2265 RETURN_SUCCESS) {
2266 yyerror("Incorrect device option string");
2267 }
2268 }
2269 xfree($2);
2270 xfree($4);
2271 }
2272 | HARDCOPY DEVICE sexpr {
2273 set_printer_by_name($3);
2274 xfree($3);
2275 }
2276 | REFERENCE DATE jrawdate {
2277 set_ref_date($3);
2278 }
2279 | DATE WRAP onoff {
2280 allow_two_digits_years($3);
2281 }
2282 | DATE WRAP YEAR iexpr {
2283 set_wrap_year($4);
2284 }
2285 | BACKGROUND color_select {
2286 setbgcolor($2);
2287 }
2288 | PAGE BACKGROUND FILL onoff {
2289 setbgfill($4);
2290 }
2291 | PAGE SCROLL expr '%' {
2292 scroll_proc((int) $3);
2293 }
2294 | PAGE INOUT expr '%' {
2295 scrollinout_proc((int) $3);
2296 }
2297 | LINK PAGE onoff {
2298 scrolling_islinked = $3;
2299 }
2300
2301 | STACK WORLD expr ',' expr ',' expr ',' expr
2302 {
2303 add_world(whichgraph, $3, $5, $7, $9);
2304 }
2305
2306 | TIMER nexpr {
2307 timer_delay = $2;
2308 }
2309
2310 | TARGET selectset {
2311 target_set = *($2);
2312 set_parser_setno(target_set.gno, target_set.setno);
2313 }
2314 | WITH selectgraph {
2315 set_parser_gno($2);
2316 }
2317 | WITH selectset {
2318 set_parser_setno($2->gno, $2->setno);
2319 }
2320
2321 /* Hot links */
2322 | selectset LINK sourcetype sexpr {
2323 set_hotlink($1->gno, $1->setno, 1, $4, $3);
2324 xfree($4);
2325 }
2326 | selectset LINK onoff {
2327 set_hotlink($1->gno, $1->setno, $3, NULL, 0);
2328 }
2329
2330 /* boxes */
2331 | WITH BOX {
2332 curbox = next_box();
2333 }
2334 | WITH BOX nexpr {
2335 int no = $3;
2336 if (is_valid_box(no) ||
2337 realloc_boxes(no + 1) == RETURN_SUCCESS) {
2338 curbox = no;
2339 }
2340 }
2341 | BOX onoff {
2342 if (!is_valid_box(curbox)) {
2343 yyerror("Box not active");
2344 } else {
2345 boxes[curbox].active = $2;
2346 }
2347 }
2348 | BOX selectgraph {
2349 if (!is_valid_box(curbox)) {
2350 yyerror("Box not active");
2351 } else {
2352 boxes[curbox].gno = $2;
2353 }
2354 }
2355 | BOX expr ',' expr ',' expr ',' expr {
2356 if (!is_valid_box(curbox)) {
2357 yyerror("Box not active");
2358 } else {
2359 boxes[curbox].x1 = $2;
2360 boxes[curbox].y1 = $4;
2361 boxes[curbox].x2 = $6;
2362 boxes[curbox].y2 = $8;
2363 }
2364 }
2365 | BOX LOCTYPE worldview {
2366 box_loctype = $3;
2367 }
2368 | BOX lines_select {
2369 box_lines = $2;
2370 }
2371 | BOX linew_select {
2372 box_linew = $2;
2373 }
2374 | BOX color_select {
2375 box_color = $2;
2376 }
2377 | BOX FILL color_select {
2378 box_fillcolor = $3;
2379 }
2380 | BOX FILL pattern_select {
2381 box_fillpat = $3;
2382 }
2383 | BOX DEF {
2384 if (!is_valid_box(curbox)) {
2385 yyerror("Box not active");
2386 } else {
2387 boxes[curbox].lines = box_lines;
2388 boxes[curbox].linew = box_linew;
2389 boxes[curbox].color = box_color;
2390 if (get_project_version() <= 40102) {
2391 switch (filltype_obs) {
2392 case COLOR:
2393 boxes[curbox].fillcolor = box_fillcolor;
2394 boxes[curbox].fillpattern = 1;
2395 break;
2396 case PATTERN:
2397 boxes[curbox].fillcolor = 1;
2398 boxes[curbox].fillpattern = box_fillpat;
2399 break;
2400 default: /* NONE */
2401 boxes[curbox].fillcolor = box_fillcolor;
2402 boxes[curbox].fillpattern = 0;
2403 break;
2404 }
2405 } else {
2406 boxes[curbox].fillcolor = box_fillcolor;
2407 boxes[curbox].fillpattern = box_fillpat;
2408 }
2409 boxes[curbox].loctype = box_loctype;
2410 }
2411 }
2412
2413 /* ellipses */
2414 | WITH ELLIPSE {
2415 curellipse = next_ellipse();
2416 }
2417 | WITH ELLIPSE nexpr {
2418 int no = $3;
2419 if (is_valid_ellipse(no) ||
2420 realloc_ellipses(no + 1) == RETURN_SUCCESS) {
2421 curellipse = no;
2422 }
2423 }
2424 | ELLIPSE onoff {
2425 if (!is_valid_ellipse(curellipse)) {
2426 yyerror("Ellipse not active");
2427 } else {
2428 ellip[curellipse].active = $2;
2429 }
2430 }
2431 | ELLIPSE selectgraph {
2432 if (!is_valid_ellipse(curellipse)) {
2433 yyerror("Ellipse not active");
2434 } else {
2435 ellip[curellipse].gno = $2;
2436 }
2437 }
2438 | ELLIPSE expr ',' expr ',' expr ',' expr {
2439 if (!is_valid_ellipse(curellipse)) {
2440 yyerror("Ellipse not active");
2441 } else {
2442 ellip[curellipse].x1 = $2;
2443 ellip[curellipse].y1 = $4;
2444 ellip[curellipse].x2 = $6;
2445 ellip[curellipse].y2 = $8;
2446 }
2447 }
2448 | ELLIPSE LOCTYPE worldview {
2449 ellipse_loctype = $3;
2450 }
2451 | ELLIPSE lines_select {
2452 ellipse_lines = $2;
2453 }
2454 | ELLIPSE linew_select {
2455 ellipse_linew = $2;
2456 }
2457 | ELLIPSE color_select {
2458 ellipse_color = $2;
2459 }
2460 | ELLIPSE FILL color_select {
2461 ellipse_fillcolor = $3;
2462 }
2463 | ELLIPSE FILL pattern_select {
2464 ellipse_fillpat = $3;
2465 }
2466 | ELLIPSE DEF {
2467 if (!is_valid_ellipse(curellipse)) {
2468 yyerror("Ellipse not active");
2469 } else {
2470 ellip[curellipse].lines = ellipse_lines;
2471 ellip[curellipse].linew = ellipse_linew;
2472 ellip[curellipse].color = ellipse_color;
2473 if (get_project_version() <= 40102) {
2474 switch (filltype_obs) {
2475 case COLOR:
2476 ellip[curellipse].fillcolor = ellipse_fillcolor;
2477 ellip[curellipse].fillpattern = 1;
2478 break;
2479 case PATTERN:
2480 ellip[curellipse].fillcolor = 1;
2481 ellip[curellipse].fillpattern = ellipse_fillpat;
2482 break;
2483 default: /* NONE */
2484 ellip[curellipse].fillcolor = ellipse_fillcolor;
2485 ellip[curellipse].fillpattern = 0;
2486 break;
2487 }
2488 } else {
2489 ellip[curellipse].fillcolor = ellipse_fillcolor;
2490 ellip[curellipse].fillpattern = ellipse_fillpat;
2491 }
2492 ellip[curellipse].loctype = ellipse_loctype;
2493 }
2494 }
2495
2496 /* lines */
2497 | WITH LINE {
2498 curline = next_line();
2499 }
2500 | WITH LINE nexpr {
2501 int no = $3;
2502 if (is_valid_line(no) ||
2503 realloc_lines(no + 1) == RETURN_SUCCESS) {
2504 curline = no;
2505 }
2506 }
2507 | LINE onoff {
2508 if (!is_valid_line(curline)) {
2509 yyerror("Line not active");
2510 } else {
2511 lines[curline].active = $2;
2512 }
2513 }
2514 | LINE selectgraph {
2515 if (!is_valid_line(curline)) {
2516 yyerror("Line not active");
2517 } else {
2518 lines[curline].gno = $2;
2519 }
2520 }
2521 | LINE expr ',' expr ',' expr ',' expr {
2522 if (!is_valid_line(curline)) {
2523 yyerror("Line not active");
2524 } else {
2525 lines[curline].x1 = $2;
2526 lines[curline].y1 = $4;
2527 lines[curline].x2 = $6;
2528 lines[curline].y2 = $8;
2529 }
2530 }
2531 | LINE LOCTYPE worldview {
2532 line_loctype = $3;
2533 }
2534 | LINE linew_select {
2535 line_linew = $2;
2536 }
2537 | LINE lines_select {
2538 line_lines = $2;
2539 }
2540 | LINE color_select {
2541 line_color = $2;
2542 }
2543 | LINE ARROW nexpr {
2544 line_arrow_end = $3;
2545 }
2546 | LINE ARROW LENGTH expr {
2547 line_asize = $4;
2548 }
2549 | LINE ARROW TYPE nexpr {
2550 line_atype = $4;
2551 }
2552 | LINE ARROW LAYOUT expr ',' expr {
2553 line_a_dL_ff = $4;
2554 line_a_lL_ff = $6;
2555 }
2556 | LINE DEF {
2557 if (!is_valid_line(curline)) {
2558 yyerror("Line not active");
2559 } else {
2560 lines[curline].lines = line_lines;
2561 lines[curline].linew = line_linew;
2562 lines[curline].color = line_color;
2563 lines[curline].arrow_end = line_arrow_end;
2564 lines[curline].arrow.length = line_asize;
2565 lines[curline].arrow.type = line_atype;
2566 lines[curline].arrow.dL_ff = line_a_dL_ff;
2567 lines[curline].arrow.lL_ff = line_a_lL_ff;
2568 lines[curline].loctype = line_loctype;
2569 }
2570 }
2571
2572 /* strings */
2573 | WITH STRING {
2574 curstring = next_string();
2575 }
2576 | WITH STRING nexpr {
2577 int no = $3;
2578 if (is_valid_string(no) ||
2579 realloc_strings(no + 1) == RETURN_SUCCESS) {
2580 curstring = no;
2581 }
2582 }
2583 | STRING onoff {
2584 if (!is_valid_string(curstring)) {
2585 yyerror("String not active");
2586 } else {
2587 pstr[curstring].active = $2;
2588 }
2589 }
2590 | STRING selectgraph {
2591 if (!is_valid_string(curstring)) {
2592 yyerror("String not active");
2593 } else {
2594 pstr[curstring].gno = $2;
2595 }
2596 }
2597 | STRING expr ',' expr {
2598 if (!is_valid_string(curstring)) {
2599 yyerror("String not active");
2600 } else {
2601 pstr[curstring].x = $2;
2602 pstr[curstring].y = $4;
2603 }
2604 }
2605 | STRING LOCTYPE worldview {
2606 string_loctype = $3;
2607 }
2608 | STRING color_select {
2609 string_color = $2;
2610 }
2611 | STRING ROT nexpr {
2612 string_rot = $3;
2613 }
2614 | STRING font_select {
2615 string_font = $2;
2616 }
2617 | STRING JUST nexpr {
2618 string_just = $3;
2619 }
2620 | STRING CHAR SIZE expr {
2621 string_size = $4;
2622 }
2623 | STRING DEF sexpr {
2624 if (!is_valid_string(curstring)) {
2625 yyerror("String not active");
2626 } else {
2627 set_plotstr_string(&pstr[curstring], $3);
2628 pstr[curstring].color = string_color;
2629 pstr[curstring].font = string_font;
2630 pstr[curstring].just = string_just;
2631 pstr[curstring].loctype = string_loctype;
2632 pstr[curstring].rot = string_rot;
2633 pstr[curstring].charsize = string_size;
2634 }
2635 xfree($3);
2636 }
2637
2638 /* timestamp */
2639 | TIMESTAMP onoff {
2640 timestamp.active = $2;
2641 }
2642 | TIMESTAMP font_select {
2643 timestamp.font = $2;
2644 }
2645 | TIMESTAMP CHAR SIZE expr {
2646 timestamp.charsize = $4;
2647 }
2648 | TIMESTAMP ROT nexpr {
2649 timestamp.rot = $3;
2650 }
2651 | TIMESTAMP color_select {
2652 timestamp.color = $2;
2653 }
2654 | TIMESTAMP expr ',' expr {
2655 timestamp.x = $2;
2656 timestamp.y = $4;
2657 }
2658 | TIMESTAMP DEF sexpr {
2659 set_plotstr_string(×tamp, $3);
2660 xfree($3);
2661 }
2662
2663 /* defaults */
2664 | DEFAULT lines_select {
2665 grdefaults.lines = $2;
2666 box_lines = ellipse_lines = line_lines = $2;
2667 }
2668 | DEFAULT linew_select {
2669 grdefaults.linew = $2;
2670 box_linew = ellipse_linew = line_linew = $2;
2671 }
2672 | DEFAULT color_select {
2673 grdefaults.color = $2;
2674 box_color = ellipse_color = line_color = string_color = $2;
2675 }
2676 | DEFAULT pattern_select {
2677 grdefaults.pattern = $2;
2678 }
2679 | DEFAULT CHAR SIZE expr {
2680 grdefaults.charsize = $4;
2681 string_size = $4;
2682 }
2683 | DEFAULT font_select {
2684 grdefaults.font = $2;
2685 string_font = $2;
2686 }
2687 | DEFAULT SYMBOL SIZE expr {
2688 grdefaults.symsize = $4;
2689 }
2690 | DEFAULT SFORMAT sexpr {
2691 strcpy(sformat, $3);
2692 xfree($3);
2693 }
2694 | MAP FONTP nexpr TO sexpr ',' sexpr {
2695 if ((map_font_by_name($5, $3) != RETURN_SUCCESS) &&
2696 (map_font_by_name($7, $3) != RETURN_SUCCESS)) {
2697 errmsg("Failed mapping a font");
2698 }
2699 xfree($5);
2700 xfree($7);
2701 }
2702 | MAP COLOR nexpr TO '(' nexpr ',' nexpr ',' nexpr ')' ',' sexpr {
2703 CMap_entry cmap;
2704 cmap.rgb.red = $6;
2705 cmap.rgb.green = $8;
2706 cmap.rgb.blue = $10;
2707 cmap.ctype = COLOR_MAIN;
2708 cmap.cname = $13;
2709 if (store_color($3, cmap) == RETURN_FAILURE) {
2710 errmsg("Failed mapping a color");
2711 }
2712 xfree($13);
2713 }
2714
2715 | WORLD expr ',' expr ',' expr ',' expr {
2716 if (!is_valid_gno(whichgraph)) {
2717 yyerror("No valid graph selected");
2718 return 1;
2719 }
2720 g[whichgraph].w.xg1 = $2;
2721 g[whichgraph].w.yg1 = $4;
2722 g[whichgraph].w.xg2 = $6;
2723 g[whichgraph].w.yg2 = $8;
2724 }
2725 | ZNORM expr {
2726 set_graph_znorm(whichgraph, $2);
2727 }
2728 | VIEW expr ',' expr ',' expr ',' expr {
2729 if (!is_valid_gno(whichgraph)) {
2730 yyerror("No valid graph selected");
2731 return 1;
2732 }
2733 g[whichgraph].v.xv1 = $2;
2734 g[whichgraph].v.yv1 = $4;
2735 g[whichgraph].v.xv2 = $6;
2736 g[whichgraph].v.yv2 = $8;
2737 }
2738 | TITLE sexpr {
2739 if (!is_valid_gno(whichgraph)) {
2740 yyerror("No valid graph selected");
2741 return 1;
2742 }
2743 set_plotstr_string(&g[whichgraph].labs.title, $2);
2744 xfree($2);
2745 }
2746 | TITLE font_select {
2747 if (!is_valid_gno(whichgraph)) {
2748 yyerror("No valid graph selected");
2749 return 1;
2750 }
2751 g[whichgraph].labs.title.font = $2;
2752 }
2753 | TITLE SIZE expr {
2754 if (!is_valid_gno(whichgraph)) {
2755 yyerror("No valid graph selected");
2756 return 1;
2757 }
2758 g[whichgraph].labs.title.charsize = $3;
2759 }
2760 | TITLE color_select {
2761 if (!is_valid_gno(whichgraph)) {
2762 yyerror("No valid graph selected");
2763 return 1;
2764 }
2765 g[whichgraph].labs.title.color = $2;
2766 }
2767 | SUBTITLE sexpr {
2768 if (!is_valid_gno(whichgraph)) {
2769 yyerror("No valid graph selected");
2770 return 1;
2771 }
2772 set_plotstr_string(&g[whichgraph].labs.stitle, $2);
2773 xfree($2);
2774 }
2775 | SUBTITLE font_select {
2776 if (!is_valid_gno(whichgraph)) {
2777 yyerror("No valid graph selected");
2778 return 1;
2779 }
2780 g[whichgraph].labs.stitle.font = $2;
2781 }
2782 | SUBTITLE SIZE expr {
2783 if (!is_valid_gno(whichgraph)) {
2784 yyerror("No valid graph selected");
2785 return 1;
2786 }
2787 g[whichgraph].labs.stitle.charsize = $3;
2788 }
2789 | SUBTITLE color_select {
2790 if (!is_valid_gno(whichgraph)) {
2791 yyerror("No valid graph selected");
2792 return 1;
2793 }
2794 g[whichgraph].labs.stitle.color = $2;
2795 }
2796
2797 | XAXES SCALE scaletype {
2798 if (!is_valid_gno(whichgraph)) {
2799 yyerror("No valid graph selected");
2800 return 1;
2801 }
2802 g[whichgraph].xscale = $3;
2803 }
2804 | YAXES SCALE scaletype {
2805 if (!is_valid_gno(whichgraph)) {
2806 yyerror("No valid graph selected");
2807 return 1;
2808 }
2809 g[whichgraph].yscale = $3;
2810 }
2811 | XAXES INVERT onoff {
2812 if (!is_valid_gno(whichgraph)) {
2813 yyerror("No valid graph selected");
2814 return 1;
2815 }
2816 g[whichgraph].xinvert = $3;
2817 }
2818 | YAXES INVERT onoff {
2819 if (!is_valid_gno(whichgraph)) {
2820 yyerror("No valid graph selected");
2821 return 1;
2822 }
2823 g[whichgraph].yinvert = $3;
2824 }
2825 | AUTOSCALE ONREAD NONE {
2826 autoscale_onread = AUTOSCALE_NONE;
2827 }
2828 | AUTOSCALE ONREAD XAXES {
2829 autoscale_onread = AUTOSCALE_X;
2830 }
2831 | AUTOSCALE ONREAD YAXES {
2832 autoscale_onread = AUTOSCALE_Y;
2833 }
2834 | AUTOSCALE ONREAD XYAXES {
2835 autoscale_onread = AUTOSCALE_XY;
2836 }
2837
2838 | DESCRIPTION sexpr {
2839 char *s;
2840 s = copy_string(NULL, get_project_description());
2841 s = concat_strings(s, $2);
2842 xfree($2);
2843 s = concat_strings(s, "\n");
2844 set_project_description(s);
2845 xfree(s);
2846 }
2847 | CLEAR DESCRIPTION {
2848 set_project_description(NULL);
2849 }
2850
2851 | LEGEND onoff {
2852 if (!is_valid_gno(whichgraph)) {
2853 yyerror("No valid graph selected");
2854 return 1;
2855 }
2856 g[whichgraph].l.active = $2;
2857 }
2858 | LEGEND LOCTYPE worldview {
2859 if (!is_valid_gno(whichgraph)) {
2860 yyerror("No valid graph selected");
2861 return 1;
2862 }
2863 g[whichgraph].l.loctype = $3;
2864 }
2865 | LEGEND VGAP nexpr {
2866 if (!is_valid_gno(whichgraph)) {
2867 yyerror("No valid graph selected");
2868 return 1;
2869 }
2870 g[whichgraph].l.vgap = $3;
2871 }
2872 | LEGEND HGAP nexpr {
2873 if (!is_valid_gno(whichgraph)) {
2874 yyerror("No valid graph selected");
2875 return 1;
2876 }
2877 g[whichgraph].l.hgap = $3;
2878 }
2879 | LEGEND LENGTH nexpr {
2880 if (!is_valid_gno(whichgraph)) {
2881 yyerror("No valid graph selected");
2882 return 1;
2883 }
2884 g[whichgraph].l.len = $3;
2885 }
2886 | LEGEND INVERT onoff {
2887 if (!is_valid_gno(whichgraph)) {
2888 yyerror("No valid graph selected");
2889 return 1;
2890 }
2891 g[whichgraph].l.invert = $3;
2892 }
2893 | LEGEND BOX FILL color_select {
2894 if (!is_valid_gno(whichgraph)) {
2895 yyerror("No valid graph selected");
2896 return 1;
2897 }
2898 g[whichgraph].l.boxfillpen.color = $4;
2899 }
2900 | LEGEND BOX FILL pattern_select {
2901 if (!is_valid_gno(whichgraph)) {
2902 yyerror("No valid graph selected");
2903 return 1;
2904 }
2905 g[whichgraph].l.boxfillpen.pattern = $4;
2906 }
2907 | LEGEND BOX color_select {
2908 if (!is_valid_gno(whichgraph)) {
2909 yyerror("No valid graph selected");
2910 return 1;
2911 }
2912 g[whichgraph].l.boxpen.color = $3;
2913 }
2914 | LEGEND BOX pattern_select {
2915 if (!is_valid_gno(whichgraph)) {
2916 yyerror("No valid graph selected");
2917 return 1;
2918 }
2919 g[whichgraph].l.boxpen.pattern = $3;
2920 }
2921 | LEGEND BOX lines_select {
2922 if (!is_valid_gno(whichgraph)) {
2923 yyerror("No valid graph selected");
2924 return 1;
2925 }
2926 g[whichgraph].l.boxlines = $3;
2927 }
2928 | LEGEND BOX linew_select {
2929 if (!is_valid_gno(whichgraph)) {
2930 yyerror("No valid graph selected");
2931 return 1;
2932 }
2933 g[whichgraph].l.boxlinew = $3;
2934 }
2935 | LEGEND expr ',' expr {
2936 if (!is_valid_gno(whichgraph)) {
2937 yyerror("No valid graph selected");
2938 return 1;
2939 }
2940 g[whichgraph].l.legx = $2;
2941 g[whichgraph].l.legy = $4;
2942 }
2943 | LEGEND CHAR SIZE expr {
2944 if (!is_valid_gno(whichgraph)) {
2945 yyerror("No valid graph selected");
2946 return 1;
2947 }
2948 g[whichgraph].l.charsize = $4;
2949 }
2950 | LEGEND font_select {
2951 if (!is_valid_gno(whichgraph)) {
2952 yyerror("No valid graph selected");
2953 return 1;
2954 }
2955 g[whichgraph].l.font = $2;
2956 }
2957 | LEGEND color_select {
2958 if (!is_valid_gno(whichgraph)) {
2959 yyerror("No valid graph selected");
2960 return 1;
2961 }
2962 g[whichgraph].l.color = $2;
2963 }
2964
2965 | FRAMEP onoff {
2966 if (!is_valid_gno(whichgraph)) {
2967 yyerror("No valid graph selected");
2968 return 1;
2969 }
2970 g[whichgraph].f.pen.pattern = $2;
2971 }
2972 | FRAMEP TYPE nexpr {
2973 if (!is_valid_gno(whichgraph)) {
2974 yyerror("No valid graph selected");
2975 return 1;
2976 }
2977 g[whichgraph].f.type = $3;
2978 }
2979 | FRAMEP lines_select {
2980 if (!is_valid_gno(whichgraph)) {
2981 yyerror("No valid graph selected");
2982 return 1;
2983 }
2984 g[whichgraph].f.lines = $2;
2985 }
2986 | FRAMEP linew_select {
2987 if (!is_valid_gno(whichgraph)) {
2988 yyerror("No valid graph selected");
2989 return 1;
2990 }
2991 g[whichgraph].f.linew = $2;
2992 }
2993 | FRAMEP color_select {
2994 if (!is_valid_gno(whichgraph)) {
2995 yyerror("No valid graph selected");
2996 return 1;
2997 }
2998 g[whichgraph].f.pen.color = $2;
2999 }
3000 | FRAMEP pattern_select {
3001 if (!is_valid_gno(whichgraph)) {
3002 yyerror("No valid graph selected");
3003 return 1;
3004 }
3005 g[whichgraph].f.pen.pattern = $2;
3006 }
3007 | FRAMEP BACKGROUND color_select
3008 {
3009 if (!is_valid_gno(whichgraph)) {
3010 yyerror("No valid graph selected");
3011 return 1;
3012 }
3013 g[whichgraph].f.fillpen.color = $3;
3014 }
3015 | FRAMEP BACKGROUND pattern_select
3016 {
3017 if (!is_valid_gno(whichgraph)) {
3018 yyerror("No valid graph selected");
3019 return 1;
3020 }
3021 g[whichgraph].f.fillpen.pattern = $3;
3022 }
3023
3024 | selectgraph onoff {
3025 set_graph_hidden($1, !$2);
3026 }
3027 | selectgraph HIDDEN onoff {
3028 set_graph_hidden($1, $3);
3029 }
3030 | selectgraph TYPE graphtype {
3031 set_graph_type($1, $3);
3032 }
3033 | selectgraph STACKED onoff {
3034 set_graph_stacked($1, $3);
3035 }
3036
3037 | selectgraph BAR HGAP expr {
3038 set_graph_bargap($1, $4);
3039 }
3040
3041 | selectgraph FIXEDPOINT onoff {
3042 g[$1].locator.pointset = $3;
3043 }
3044 | selectgraph FIXEDPOINT FORMAT formatchoice formatchoice {
3045 g[$1].locator.fx = $4;
3046 g[$1].locator.fy = $5;
3047 }
3048 | selectgraph FIXEDPOINT PREC expr ',' expr {
3049 g[$1].locator.px = $4;
3050 g[$1].locator.py = $6;
3051 }
3052 | selectgraph FIXEDPOINT XY expr ',' expr {
3053 g[$1].locator.dsx = $4;
3054 g[$1].locator.dsy = $6;
3055 }
3056 | selectgraph FIXEDPOINT TYPE nexpr {
3057 g[$1].locator.pt_type = $4;
3058 }
3059
3060 | TYPE xytype {
3061 curtype = $2;
3062 }
3063
3064 /* I/O filters */
3065 | DEFINE filtertype sexpr filtermethod sexpr {
3066 if (add_io_filter($2, $4, $5, $3) != 0) {
3067 yyerror("Failed adding i/o filter");
3068 }
3069 xfree($3);
3070 xfree($5);
3071 }
3072 | CLEAR filtertype {
3073 clear_io_filters($2);
3074 }
3075
3076 | SOURCE sourcetype {
3077 cursource = $2;
3078 }
3079 | FORMAT formatchoice {
3080 readxformat = $2;
3081 }
3082 | FIT nonlfitopts { }
3083 | FITPARM CONSTRAINTS onoff {
3084 nonl_parms[$1].constr = $3;
3085 }
3086 ;
3087
3088 actions:
3089 REDRAW {
3090 drawgraph();
3091 }
3092 | UPDATEALL {
3093 #ifndef NONE_GUI
3094 if (inwin) {
3095 update_all();
3096 }
3097 #endif
3098 }
3099 | CD sexpr {
3100 set_workingdir($2);
3101 xfree($2);
3102 }
3103 | ECHO sexpr {
3104 echomsg($2);
3105 xfree($2);
3106 }
3107 | ECHO expr {
3108 char buf[32];
3109 set_locale_num(TRUE);
3110 sprintf(buf, "%g", $2);
3111 set_locale_num(FALSE);
3112 echomsg(buf);
3113 }
3114 | CLOSE {
3115 close_input = copy_string(close_input, "");
3116 }
3117 | CLOSE sexpr {
3118 close_input = copy_string(close_input, $2);
3119 }
3120 | EXIT {
3121 exit(0);
3122 }
3123 | EXIT '(' iexpr ')' {
3124 exit($3);
3125 }
3126 | PRINT {
3127 if (!safe_mode) {
3128 do_hardcopy();
3129 } else {
3130 yyerror("File modifications are disabled in safe mode");
3131 }
3132 }
3133 | PRINT TO DEVICE {
3134 set_ptofile(FALSE);
3135 }
3136 | PRINT TO sexpr {
3137 set_ptofile(TRUE);
3138 strcpy(print_file, $3);
3139 xfree($3);
3140 }
3141 | PAGE direction {
3142 switch ($2) {
3143 case UP:
3144 graph_scroll(GSCROLL_UP);
3145 break;
3146 case DOWN:
3147 graph_scroll(GSCROLL_DOWN);
3148 break;
3149 case RIGHT:
3150 graph_scroll(GSCROLL_RIGHT);
3151 break;
3152 case LEFT:
3153 graph_scroll(GSCROLL_LEFT);
3154 break;
3155 case IN:
3156 graph_zoom(GZOOM_SHRINK);
3157 break;
3158 case OUT:
3159 graph_zoom(GZOOM_EXPAND);
3160 break;
3161 }
3162 }
3163 | SLEEP expr {
3164 if ($2 > 0) {
3165 msleep_wrap((unsigned int) (1000 * $2));
3166 }
3167 }
3168 | HELP sexpr {
3169 #ifndef NONE_GUI
3170 if (inwin) {
3171 HelpCB($2);
3172 }
3173 xfree($2);
3174 #endif
3175 }
3176 | HELP {
3177 #ifndef NONE_GUI
3178 if (inwin) {
3179 HelpCB("doc/UsersGuide.html");
3180 }
3181 #endif
3182 }
3183 | GETP sexpr {
3184 gotparams = TRUE;
3185 strcpy(paramfile, $2);
3186 xfree($2);
3187 }
3188 | PUTP sexpr {
3189 if (!safe_mode) {
3190 FILE *pp = grace_openw($2);
3191 if (pp != NULL) {
3192 putparms(whichgraph, pp, 0);
3193 grace_close(pp);
3194 }
3195 } else {
3196 yyerror("File modifications are disabled in safe mode");
3197 }
3198 xfree($2);
3199 }
3200 | selectset HIDDEN onoff {
3201 set_set_hidden($1->gno, $1->setno, $3);
3202 }
3203 | selectset LENGTH nexpr {
3204 setlength($1->gno, $1->setno, $3);
3205 }
3206 | VEC_D LENGTH nexpr {
3207 realloc_vrbl($1, $3);
3208 }
3209 | selectset POINT expr ',' expr {
3210 add_point($1->gno, $1->setno, $3, $5);
3211 }
3212
3213 | selectset DROP nexpr ',' nexpr {
3214 int start = $3 - index_shift;
3215 int stop = $5 - index_shift;
3216 droppoints($1->gno, $1->setno, start, stop);
3217 }
3218 | SORT selectset sorton sortdir {
3219 if (is_set_active($2->gno, $2->setno)) {
3220 sortset($2->gno, $2->setno, $3, $4 == ASCENDING ? 0 : 1);
3221 }
3222 }
3223 | COPY selectset TO selectset {
3224 do_copyset($2->gno, $2->setno, $4->gno, $4->setno);
3225 }
3226 | APPEND selectset TO selectset {
3227 if ($2->gno != $4->gno) {
3228 errmsg("Can't append sets from different graphs");
3229 } else {
3230 int sets[2];
3231 sets[0] = $4->setno;
3232 sets[1] = $2->setno;
3233 join_sets($2->gno, sets, 2);
3234 }
3235 }
3236 | REVERSE selectset {
3237 reverse_set($2->gno, $2->setno);
3238 }
3239 | SPLIT selectset nexpr {
3240 do_splitsets($2->gno, $2->setno, $3);
3241 }
3242 | MOVE selectset TO selectset {
3243 do_moveset($2->gno, $2->setno, $4->gno, $4->setno);
3244 }
3245 | SWAP selectset AND selectset {
3246 do_swapset($2->gno, $2->setno, $4->gno, $4->setno);
3247 }
3248 | KILL selectset {
3249 killset($2->gno, $2->setno);
3250 }
3251 | KILL selectset SAVEALL {
3252 killsetdata($2->gno, $2->setno);
3253 setcomment($2->gno, $2->setno, "");
3254 }
3255 | KILL selectgraph {
3256 kill_graph($2);
3257 }
3258 | KILL REGNUM {
3259 kill_region($2);
3260 }
3261 | FLUSH {
3262 wipeout();
3263 }
3264 | ARRANGE '(' nexpr ',' nexpr ',' expr ',' expr ',' expr ')' {
3265 arrange_graphs_simple($3, $5, 0, FALSE, $7, $9, $11);
3266 }
3267 | ARRANGE '(' nexpr ',' nexpr ',' expr ',' expr ',' expr ',' onoff ',' onoff ',' onoff ')' {
3268 int order = ($13 * GA_ORDER_HV_INV) |
3269 ($15 * GA_ORDER_H_INV ) |
3270 ($17 * GA_ORDER_V_INV );
3271 arrange_graphs_simple($3, $5, order, FALSE, $7, $9, $11);
3272 }
3273 | ARRANGE '(' nexpr ',' nexpr ',' expr ',' expr ',' expr ',' onoff ',' onoff ',' onoff ',' onoff ')' {
3274 int order = ($13 * GA_ORDER_HV_INV) |
3275 ($15 * GA_ORDER_H_INV ) |
3276 ($17 * GA_ORDER_V_INV );
3277 arrange_graphs_simple($3, $5, order, $19, $7, $9, $11);
3278 }
3279 | NONLFIT '(' selectset ',' nexpr ')' {
3280 gotnlfit = TRUE;
3281 nlfit_gno = $3->gno;
3282 nlfit_setno = $3->setno;
3283 nlfit_nsteps = $5;
3284 nlfit_warray = NULL;
3285 }
3286 | NONLFIT '(' selectset ',' vexpr ',' nexpr ')' {
3287 if (getsetlength($3->gno, $3->setno) != $5->length) {
3288 errmsg("Data and weight arrays are of different lengths");
3289 return 1;
3290 } else {
3291 gotnlfit = TRUE;
3292 nlfit_gno = $3->gno;
3293 nlfit_setno = $3->setno;
3294 nlfit_nsteps = $7;
3295 nlfit_warray = copy_data_column($5->data, $5->length);
3296 }
3297 }
3298 | REGRESS '(' selectset ',' nexpr ')' {
3299 do_regress($3->gno, $3->setno, $5, 0, -1, 0, -1);
3300 }
3301 | runtype '(' selectset ',' nexpr ')' {
3302 do_runavg($3->gno, $3->setno, $5, $1, -1, 0);
3303 }
3304 | ffttype '(' selectset ',' nexpr ')' {
3305 do_fourier_command($3->gno, $3->setno, $1, $5);
3306 }
3307 | ffttype '(' selectset ',' fourierdata ',' windowtype ','
3308 fourierloadx ',' fourierloady ')' {
3309 switch ($1) {
3310 case FFT_DFT:
3311 do_fourier($3->gno, $3->setno, 0, $11, $9, 0, $5, $7);
3312 break;
3313 case FFT_INVDFT :
3314 do_fourier($3->gno, $3->setno, 0, $11, $9, 1, $5, $7);
3315 break;
3316 case FFT_FFT:
3317 do_fourier($3->gno, $3->setno, 1, $11, $9, 0, $5, $7);
3318 break;
3319 case FFT_INVFFT :
3320 do_fourier($3->gno, $3->setno, 1, $11, $9, 1, $5, $7);
3321 break;
3322 default:
3323 errmsg("Internal error");
3324 break;
3325 }
3326 }
3327 | INTERPOLATE '(' selectset ',' vexpr ',' interpmethod ',' onoff ')' {
3328 do_interp($3->gno, $3->setno, get_cg(), SET_SELECT_NEXT,
3329 $5->data, $5->length, $7, $9);
3330 }
3331 | HISTOGRAM '(' selectset ',' vexpr ',' onoff ',' onoff ')' {
3332 do_histo($3->gno, $3->setno, get_cg(), SET_SELECT_NEXT,
3333 $5->data, $5->length - 1, $7, $9);
3334 }
3335 | DIFFERENCE '(' selectset ',' nexpr ')' {
3336 do_differ($3->gno, $3->setno, $5);
3337 }
3338 | INTEGRATE '(' selectset ')' {
3339 do_int($3->gno, $3->setno, 0);
3340 }
3341 | XCOR '(' selectset ',' selectset ',' nexpr ',' onoff ')' {
3342 do_xcor($3->gno, $3->setno, $5->gno, $5->setno, $7, $9);
3343 }
3344 | LINCONV '(' selectset ',' selectset ')' {
3345 do_linearc($3->gno, $3->setno, $5->gno, $5->setno);
3346 }
3347 | RESTRICT '(' selectset ',' vexpr ')' {
3348 int len = getsetlength($3->gno, $3->setno);
3349 if (len != $5->length) {
3350 errmsg("Filter expression is of a wrong length");
3351 } else {
3352 char *rarray;
3353 rarray = xmalloc(len*SIZEOF_CHAR);
3354 if (rarray) {
3355 int i;
3356 for (i = 0; i < len; i++) {
3357 rarray[i] = CAST_DBL_TO_BOOL($5->data[i]);
3358 }
3359 filter_set($3->gno, $3->setno, rarray);
3360 xfree(rarray);
3361 }
3362 }
3363 }
3364 | RESTRICT '(' selectset ',' REGNUM ',' onoff ')' {
3365 int rtype;
3366 char *rarray;
3367
3368 rtype = RESTRICT_REG0 + $5;
3369
3370 if (get_restriction_array($3->gno, $3->setno,
3371 rtype, $7, &rarray) != RETURN_SUCCESS) {
3372 errmsg("Error in region evaluation");
3373 return 1;
3374 } else {
3375 filter_set($3->gno, $3->setno, rarray);
3376 xfree(rarray);
3377 }
3378 }
3379 | AUTOSCALE {
3380 if (autoscale_graph(whichgraph, AUTOSCALE_XY) != RETURN_SUCCESS) {
3381 errmsg("Can't autoscale (no active sets?)");
3382 }
3383 }
3384 | AUTOSCALE XAXES {
3385 if (autoscale_graph(whichgraph, AUTOSCALE_X) != RETURN_SUCCESS) {
3386 errmsg("Can't autoscale (no active sets?)");
3387 }
3388 }
3389 | AUTOSCALE YAXES {
3390 if (autoscale_graph(whichgraph, AUTOSCALE_Y) != RETURN_SUCCESS) {
3391 errmsg("Can't autoscale (no active sets?)");
3392 }
3393 }
3394 | AUTOSCALE selectset {
3395 autoscale_byset($2->gno, $2->setno, AUTOSCALE_XY);
3396 }
3397 | AUTOTICKS {
3398 autotick_axis(whichgraph, ALL_AXES);
3399 }
3400 | FOCUS selectgraph {
3401 int gno = $2;
3402 if (is_graph_hidden(gno) == FALSE) {
3403 select_graph(gno);
3404 } else {
3405 errmsg("Graph is not active");
3406 }
3407 }
3408 | READ sexpr {
3409 gotread = TRUE;
3410 strcpy(readfile, $2);
3411 xfree($2);
3412 }
3413 | READ BATCH sexpr {
3414 strcpy(batchfile, $3);
3415 xfree($3);
3416 }
3417 | READ BLOCK sexpr {
3418 getdata(whichgraph, $3, SOURCE_DISK, LOAD_BLOCK);
3419 xfree($3);
3420 }
3421 | READ BLOCK sourcetype sexpr {
3422 getdata(whichgraph, $4, $3, LOAD_BLOCK);
3423 xfree($4);
3424 }
3425 | BLOCK xytype sexpr {
3426 int nc, *cols, scol;
3427 if (field_string_to_cols($3, &nc, &cols, &scol) != RETURN_SUCCESS) {
3428 errmsg("Erroneous field specifications");
3429 xfree($3);
3430 return 1;
3431 } else {
3432 xfree($3);
3433 create_set_fromblock(whichgraph, NEW_SET,
3434 $2, nc, cols, scol, autoscale_onread);
3435 xfree(cols);
3436 }
3437 }
3438 | KILL BLOCK {
3439 set_blockdata(NULL);
3440 }
3441 | READ xytype sexpr {
3442 gotread = TRUE;
3443 curtype = $2;
3444 strcpy(readfile, $3);
3445 xfree($3);
3446 }
3447 | READ xytype sourcetype sexpr {
3448 gotread = TRUE;
3449 strcpy(readfile, $4);
3450 curtype = $2;
3451 cursource = $3;
3452 xfree($4);
3453 }
3454 | READ NXY sexpr {
3455 getdata(whichgraph, $3, SOURCE_DISK, LOAD_NXY);
3456 xfree($3);
3457 }
3458 | READ NXY sourcetype sexpr {
3459 getdata(whichgraph, $4, $3, LOAD_NXY);
3460 xfree($4);
3461 }
3462 | WRITE selectset {
3463 if (!safe_mode) {
3464 outputset($2->gno, $2->setno, "stdout", NULL);
3465 } else {
3466 yyerror("File modifications are disabled in safe mode");
3467 }
3468 }
3469 | WRITE selectset FORMAT sexpr {
3470 if (!safe_mode) {
3471 outputset($2->gno, $2->setno, "stdout", $4);
3472 } else {
3473 yyerror("File modifications are disabled in safe mode");
3474 }
3475 xfree($4);
3476 }
3477 | WRITE selectset FILEP sexpr {
3478 if (!safe_mode) {
3479 outputset($2->gno, $2->setno, $4, NULL);
3480 } else {
3481 yyerror("File modifications are disabled in safe mode");
3482 }
3483 xfree($4);
3484 }
3485 | WRITE selectset FILEP sexpr FORMAT sexpr {
3486 if (!safe_mode) {
3487 outputset($2->gno, $2->setno, $4, $6);
3488 } else {
3489 yyerror("File modifications are disabled in safe mode");
3490 }
3491 xfree($4);
3492 xfree($6);
3493 }
3494 | SAVEALL sexpr {
3495 if (!safe_mode) {
3496 save_project($2);
3497 } else {
3498 yyerror("File modifications are disabled in safe mode");
3499 }
3500 xfree($2);
3501 }
3502 | LOAD sexpr {
3503 load_project($2);
3504 xfree($2);
3505 }
3506 | NEW {
3507 new_project(NULL);
3508 }
3509 | NEW FROM sexpr {
3510 new_project($3);
3511 xfree($3);
3512 }
3513 | PUSH {
3514 push_world();
3515 }
3516 | POP {
3517 pop_world();
3518 }
3519 | CYCLE {
3520 cycle_world_stack();
3521 }
3522 | STACK nexpr {
3523 if ($2 > 0)
3524 show_world_stack($2 - 1);
3525 }
3526 | CLEAR STACK {
3527 clear_world_stack();
3528 }
3529 | CLEAR BOX {
3530 do_clear_boxes();
3531 }
3532 | CLEAR ELLIPSE {
3533 do_clear_ellipses();
3534 }
3535 | CLEAR LINE {
3536 do_clear_lines();
3537 }
3538 | CLEAR STRING {
3539 do_clear_text();
3540 }
3541 ;
3542
3543
3544 options:
3545 PAGE LAYOUT pagelayout {
3546 #ifndef NONE_GUI
3547 set_pagelayout($3);
3548 #endif
3549 }
3550 | AUTO REDRAW onoff {
3551 auto_redraw = $3;
3552 }
3553 | FOCUS onoff {
3554 draw_focus_flag = $2;
3555 }
3556 | FOCUS SET {
3557 focus_policy = FOCUS_SET;
3558 }
3559 | FOCUS FOLLOWS {
3560 focus_policy = FOCUS_FOLLOWS;
3561 }
3562 | FOCUS CLICK {
3563 focus_policy = FOCUS_CLICK;
3564 }
3565 ;
3566
3567
3568 set_setprop:
3569 setprop {}
3570 | setprop_obs {}
3571 ;
3572
3573 setprop:
3574 selectset onoff {
3575 set_set_hidden($1->gno, $1->setno, !$2);
3576 }
3577 | selectset TYPE xytype {
3578 set_dataset_type($1->gno, $1->setno, $3);
3579 }
3580
3581 | selectset SYMBOL nexpr {
3582 g[$1->gno].p[$1->setno].sym = $3;
3583 }
3584 | selectset SYMBOL color_select {
3585 g[$1->gno].p[$1->setno].sympen.color = $3;
3586 }
3587 | selectset SYMBOL pattern_select {
3588 g[$1->gno].p[$1->setno].sympen.pattern = $3;
3589 }
3590 | selectset SYMBOL linew_select {
3591 g[$1->gno].p[$1->setno].symlinew = $3;
3592 }
3593 | selectset SYMBOL lines_select {
3594 g[$1->gno].p[$1->setno].symlines = $3;
3595 }
3596 | selectset SYMBOL FILL color_select {
3597 g[$1->gno].p[$1->setno].symfillpen.color = $4;
3598 }
3599 | selectset SYMBOL FILL pattern_select {
3600 g[$1->gno].p[$1->setno].symfillpen.pattern = $4;
3601 }
3602 | selectset SYMBOL SIZE expr {
3603 g[$1->gno].p[$1->setno].symsize = $4;
3604 }
3605 | selectset SYMBOL CHAR nexpr {
3606 g[$1->gno].p[$1->setno].symchar = $4;
3607 }
3608 | selectset SYMBOL CHAR font_select {
3609 g[$1->gno].p[$1->setno].charfont = $4;
3610 }
3611 | selectset SYMBOL SKIP nexpr {
3612 g[$1->gno].p[$1->setno].symskip = $4;
3613 }
3614
3615 | selectset LINE TYPE nexpr
3616 {
3617 g[$1->gno].p[$1->setno].linet = $4;
3618 }
3619 | selectset LINE lines_select
3620 {
3621 g[$1->gno].p[$1->setno].lines = $3;
3622 }
3623 | selectset LINE linew_select
3624 {
3625 g[$1->gno].p[$1->setno].linew = $3;
3626 }
3627 | selectset LINE color_select
3628 {
3629 g[$1->gno].p[$1->setno].linepen.color = $3;
3630 }
3631 | selectset LINE pattern_select
3632 {
3633 g[$1->gno].p[$1->setno].linepen.pattern = $3;
3634 }
3635
3636 | selectset FILL TYPE nexpr
3637 {
3638 g[$1->gno].p[$1->setno].filltype = $4;
3639 }
3640 | selectset FILL RULE nexpr
3641 {
3642 g[$1->gno].p[$1->setno].fillrule = $4;
3643 }
3644 | selectset FILL color_select
3645 {
3646 int prop = $3;
3647
3648 if (get_project_version() <= 40102 && get_project_version() >= 30000) {
3649 switch (filltype_obs) {
3650 case COLOR:
3651 break;
3652 case PATTERN:
3653 prop = 1;
3654 break;
3655 default: /* NONE */
3656 prop = 0;
3657 break;
3658 }
3659 }
3660 g[$1->gno].p[$1->setno].setfillpen.color = prop;
3661 }
3662 | selectset FILL pattern_select
3663 {
3664 int prop = $3;
3665
3666 if (get_project_version() <= 40102) {
3667 switch (filltype_obs) {
3668 case COLOR:
3669 prop = 1;
3670 break;
3671 case PATTERN:
3672 break;
3673 default: /* NONE */
3674 prop = 0;
3675 break;
3676 }
3677 }
3678 g[$1->gno].p[$1->setno].setfillpen.pattern = prop;
3679 }
3680
3681
3682 | selectset BASELINE onoff
3683 {
3684 g[$1->gno].p[$1->setno].baseline = $3;
3685 }
3686 | selectset BASELINE TYPE nexpr
3687 {
3688 g[$1->gno].p[$1->setno].baseline_type = $4;
3689 }
3690
3691 | selectset DROPLINE onoff
3692 {
3693 g[$1->gno].p[$1->setno].dropline = $3;
3694 }
3695
3696 | selectset AVALUE onoff
3697 {
3698 g[$1->gno].p[$1->setno].avalue.active = $3;
3699 }
3700 | selectset AVALUE TYPE nexpr
3701 {
3702 g[$1->gno].p[$1->setno].avalue.type = $4;
3703 }
3704 | selectset AVALUE CHAR SIZE expr
3705 {
3706 g[$1->gno].p[$1->setno].avalue.size = $5;
3707 }
3708 | selectset AVALUE font_select
3709 {
3710 g[$1->gno].p[$1->setno].avalue.font = $3;
3711 }
3712 | selectset AVALUE color_select
3713 {
3714 g[$1->gno].p[$1->setno].avalue.color = $3;
3715 }
3716 | selectset AVALUE ROT nexpr
3717 {
3718 g[$1->gno].p[$1->setno].avalue.angle = $4;
3719 }
3720 | selectset AVALUE FORMAT formatchoice
3721 {
3722 g[$1->gno].p[$1->setno].avalue.format = $4;
3723 }
3724 | selectset AVALUE PREC nexpr
3725 {
3726 g[$1->gno].p[$1->setno].avalue.prec = $4;
3727 }
3728 | selectset AVALUE OFFSET expr ',' expr {
3729 g[$1->gno].p[$1->setno].avalue.offset.x = $4;
3730 g[$1->gno].p[$1->setno].avalue.offset.y = $6;
3731 }
3732 | selectset AVALUE PREPEND sexpr
3733 {
3734 strcpy(g[$1->gno].p[$1->setno].avalue.prestr, $4);
3735 xfree($4);
3736 }
3737 | selectset AVALUE APPEND sexpr
3738 {
3739 strcpy(g[$1->gno].p[$1->setno].avalue.appstr, $4);
3740 xfree($4);
3741 }
3742
3743 | selectset ERRORBAR onoff {
3744 g[$1->gno].p[$1->setno].errbar.active = $3;
3745 }
3746 | selectset ERRORBAR opchoice_sel {
3747 g[$1->gno].p[$1->setno].errbar.ptype = $3;
3748 }
3749 | selectset ERRORBAR color_select {
3750 g[$1->gno].p[$1->setno].errbar.pen.color = $3;
3751 }
3752 | selectset ERRORBAR pattern_select {
3753 g[$1->gno].p[$1->setno].errbar.pen.pattern = $3;
3754 }
3755 | selectset ERRORBAR SIZE expr {
3756 g[$1->gno].p[$1->setno].errbar.barsize = $4;
3757 }
3758 | selectset ERRORBAR linew_select {
3759 g[$1->gno].p[$1->setno].errbar.linew = $3;
3760 }
3761 | selectset ERRORBAR lines_select {
3762 g[$1->gno].p[$1->setno].errbar.lines = $3;
3763 }
3764 | selectset ERRORBAR RISER linew_select {
3765 g[$1->gno].p[$1->setno].errbar.riser_linew = $4;
3766 }
3767 | selectset ERRORBAR RISER lines_select {
3768 g[$1->gno].p[$1->setno].errbar.riser_lines = $4;
3769 }
3770 | selectset ERRORBAR RISER CLIP onoff {
3771 g[$1->gno].p[$1->setno].errbar.arrow_clip = $5;
3772 }
3773 | selectset ERRORBAR RISER CLIP LENGTH expr {
3774 g[$1->gno].p[$1->setno].errbar.cliplen = $6;
3775 }
3776
3777 | selectset COMMENT sexpr {
3778 strncpy(g[$1->gno].p[$1->setno].comments, $3, MAX_STRING_LENGTH - 1);
3779 xfree($3);
3780 }
3781
3782 | selectset LEGEND sexpr {
3783 strncpy(g[$1->gno].p[$1->setno].lstr, $3, MAX_STRING_LENGTH - 1);
3784 xfree($3);
3785 }
3786 ;
3787
3788
3789 axisfeature:
3790 onoff {
3791 if (!is_valid_axis(whichgraph, naxis)) {
3792 yyerror("No valid axis selected");
3793 return 1;
3794 }
3795 g[whichgraph].t[naxis]->active = $1;
3796 }
3797 | TYPE ZERO onoff {
3798 if (!is_valid_axis(whichgraph, naxis)) {
3799 yyerror("No valid axis selected");
3800 return 1;
3801 }
3802 g[whichgraph].t[naxis]->zero = $3;
3803 }
3804 | TICKP tickattr {}
3805 | TICKP tickattr_obs {}
3806 | TICKLABEL ticklabelattr {}
3807 | TICKLABEL ticklabelattr_obs {}
3808 | LABEL axislabeldesc {}
3809 | LABEL axislabeldesc_obs {}
3810 | BAR axisbardesc {}
3811 | OFFSET expr ',' expr {
3812 if (!is_valid_axis(whichgraph, naxis)) {
3813 yyerror("No valid axis selected");
3814 return 1;
3815 }
3816 g[whichgraph].t[naxis]->offsx = $2;
3817 g[whichgraph].t[naxis]->offsy = $4;
3818 }
3819 ;
3820
3821 tickattr:
3822 onoff {
3823 if (!is_valid_axis(whichgraph, naxis)) {
3824 yyerror("No valid axis selected");
3825 return 1;
3826 }
3827 g[whichgraph].t[naxis]->t_flag = $1;
3828 }
3829 | MAJOR expr {
3830 if (!is_valid_axis(whichgraph, naxis)) {
3831 yyerror("No valid axis selected");
3832 return 1;
3833 }
3834 g[whichgraph].t[naxis]->tmajor = $2;
3835 }
3836 | MINOR TICKSP nexpr {
3837 if (!is_valid_axis(whichgraph, naxis)) {
3838 yyerror("No valid axis selected");
3839 return 1;
3840 }
3841 g[whichgraph].t[naxis]->nminor = $3;
3842 }
3843 | PLACE ROUNDED onoff {
3844 if (!is_valid_axis(whichgraph, naxis)) {
3845 yyerror("No valid axis selected");
3846 return 1;
3847 }
3848 g[whichgraph].t[naxis]->t_round = $3;
3849 }
3850
3851 | OFFSETX expr {
3852 if (!is_valid_axis(whichgraph, naxis)) {
3853 yyerror("No valid axis selected");
3854 return 1;
3855 }
3856 g[whichgraph].t[naxis]->offsx = $2;
3857 }
3858 | OFFSETY expr {
3859 if (!is_valid_axis(whichgraph, naxis)) {
3860 yyerror("No valid axis selected");
3861 return 1;
3862 }
3863 g[whichgraph].t[naxis]->offsy = $2;
3864 }
3865 | DEFAULT nexpr {
3866 if (!is_valid_axis(whichgraph, naxis)) {
3867 yyerror("No valid axis selected");
3868 return 1;
3869 }
3870 g[whichgraph].t[naxis]->t_autonum = $2;
3871 }
3872 | inoutchoice {
3873 if (!is_valid_axis(whichgraph, naxis)) {
3874 yyerror("No valid axis selected");
3875 return 1;
3876 }
3877 g[whichgraph].t[naxis]->t_inout = $1;
3878 }
3879 | MAJOR SIZE expr {
3880 if (!is_valid_axis(whichgraph, naxis)) {
3881 yyerror("No valid axis selected");
3882 return 1;
3883 }
3884 g[whichgraph].t[naxis]->props.size = $3;
3885 }
3886 | MINOR SIZE expr {
3887 if (!is_valid_axis(whichgraph, naxis)) {
3888 yyerror("No valid axis selected");
3889 return 1;
3890 }
3891 g[whichgraph].t[naxis]->mprops.size = $3;
3892 }
3893 | color_select {
3894 if (!is_valid_axis(whichgraph, naxis)) {
3895 yyerror("No valid axis selected");
3896 return 1;
3897 }
3898 g[whichgraph].t[naxis]->props.color = g[whichgraph].t[naxis]->mprops.color = $1;
3899 }
3900 | MAJOR color_select {
3901 if (!is_valid_axis(whichgraph, naxis)) {
3902 yyerror("No valid axis selected");
3903 return 1;
3904 }
3905 g[whichgraph].t[naxis]->props.color = $2;
3906 }
3907 | MINOR color_select {
3908 if (!is_valid_axis(whichgraph, naxis)) {
3909 yyerror("No valid axis selected");
3910 return 1;
3911 }
3912 g[whichgraph].t[naxis]->mprops.color = $2;
3913 }
3914 | linew_select {
3915 if (!is_valid_axis(whichgraph, naxis)) {
3916 yyerror("No valid axis selected");
3917 return 1;
3918 }
3919 g[whichgraph].t[naxis]->props.linew = g[whichgraph].t[naxis]->mprops.linew = $1;
3920 }
3921 | MAJOR linew_select {
3922 if (!is_valid_axis(whichgraph, naxis)) {
3923 yyerror("No valid axis selected");
3924 return 1;
3925 }
3926 g[whichgraph].t[naxis]->props.linew = $2;
3927 }
3928 | MINOR linew_select {
3929 if (!is_valid_axis(whichgraph, naxis)) {
3930 yyerror("No valid axis selected");
3931 return 1;
3932 }
3933 g[whichgraph].t[naxis]->mprops.linew = $2;
3934 }
3935 | MAJOR lines_select {
3936 if (!is_valid_axis(whichgraph, naxis)) {
3937 yyerror("No valid axis selected");
3938 return 1;
3939 }
3940 g[whichgraph].t[naxis]->props.lines = $2;
3941 }
3942 | MINOR lines_select {
3943 if (!is_valid_axis(whichgraph, naxis)) {
3944 yyerror("No valid axis selected");
3945 return 1;
3946 }
3947 g[whichgraph].t[naxis]->mprops.lines = $2;
3948 }
3949 | MAJOR GRID onoff {
3950 if (!is_valid_axis(whichgraph, naxis)) {
3951 yyerror("No valid axis selected");
3952 return 1;
3953 }
3954 g[whichgraph].t[naxis]->props.gridflag = $3;
3955 }
3956 | MINOR GRID onoff {
3957 if (!is_valid_axis(whichgraph, naxis)) {
3958 yyerror("No valid axis selected");
3959 return 1;
3960 }
3961 g[whichgraph].t[naxis]->mprops.gridflag = $3;
3962 }
3963 | opchoice_sel {
3964 if (!is_valid_axis(whichgraph, naxis)) {
3965 yyerror("No valid axis selected");
3966 return 1;
3967 }
3968 g[whichgraph].t[naxis]->t_op = $1;
3969 }
3970 | SPEC TYPE tickspectype {
3971 if (!is_valid_axis(whichgraph, naxis)) {
3972 yyerror("No valid axis selected");
3973 return 1;
3974 }
3975 g[whichgraph].t[naxis]->t_spec = $3;
3976 }
3977 | SPEC nexpr {
3978 if (!is_valid_axis(whichgraph, naxis)) {
3979 yyerror("No valid axis selected");
3980 return 1;
3981 }
3982 g[whichgraph].t[naxis]->nticks = $2;
3983 }
3984 | MAJOR nexpr ',' expr {
3985 if (!is_valid_axis(whichgraph, naxis)) {
3986 yyerror("No valid axis selected");
3987 return 1;
3988 }
3989 g[whichgraph].t[naxis]->tloc[$2].wtpos = $4;
3990 g[whichgraph].t[naxis]->tloc[$2].type = TICK_TYPE_MAJOR;
3991 }
3992 | MINOR nexpr ',' expr {
3993 if (!is_valid_axis(whichgraph, naxis)) {
3994 yyerror("No valid axis selected");
3995 return 1;
3996 }
3997 g[whichgraph].t[naxis]->tloc[$2].wtpos = $4;
3998 g[whichgraph].t[naxis]->tloc[$2].type = TICK_TYPE_MINOR;
3999 }
4000 ;
4001
4002 ticklabelattr:
4003 onoff {
4004 if (!is_valid_axis(whichgraph, naxis)) {
4005 yyerror("No valid axis selected");
4006 return 1;
4007 }
4008 g[whichgraph].t[naxis]->tl_flag = $1;
4009 }
4010 | PREC nexpr {
4011 if (!is_valid_axis(whichgraph, naxis)) {
4012 yyerror("No valid axis selected");
4013 return 1;
4014 }
4015 g[whichgraph].t[naxis]->tl_prec = $2;
4016 }
4017 | FORMAT formatchoice {
4018 if (!is_valid_axis(whichgraph, naxis)) {
4019 yyerror("No valid axis selected");
4020 return 1;
4021 }
4022 g[whichgraph].t[naxis]->tl_format = $2;
4023 }
4024 | FORMAT expr {
4025 if (!is_valid_axis(whichgraph, naxis)) {
4026 yyerror("No valid axis selected");
4027 return 1;
4028 }
4029 g[whichgraph].t[naxis]->tl_format = $2;
4030 }
4031 | APPEND sexpr {
4032 if (!is_valid_axis(whichgraph, naxis)) {
4033 yyerror("No valid axis selected");
4034 return 1;
4035 }
4036 strcpy(g[whichgraph].t[naxis]->tl_appstr, $2);
4037 xfree($2);
4038 }
4039 | PREPEND sexpr {
4040 if (!is_valid_axis(whichgraph, naxis)) {
4041 yyerror("No valid axis selected");
4042 return 1;
4043 }
4044 strcpy(g[whichgraph].t[naxis]->tl_prestr, $2);
4045 xfree($2);
4046 }
4047 | ANGLE nexpr {
4048 if (!is_valid_axis(whichgraph, naxis)) {
4049 yyerror("No valid axis selected");
4050 return 1;
4051 }
4052 g[whichgraph].t[naxis]->tl_angle = $2;
4053 }
4054 | SKIP nexpr {
4055 if (!is_valid_axis(whichgraph, naxis)) {
4056 yyerror("No valid axis selected");
4057 return 1;
4058 }
4059 g[whichgraph].t[naxis]->tl_skip = $2;
4060 }
4061 | STAGGER nexpr {
4062 if (!is_valid_axis(whichgraph, naxis)) {
4063 yyerror("No valid axis selected");
4064 return 1;
4065 }
4066 g[whichgraph].t[naxis]->tl_staggered = $2;
4067 }
4068 | opchoice_sel {
4069 if (!is_valid_axis(whichgraph, naxis)) {
4070 yyerror("No valid axis selected");
4071 return 1;
4072 }
4073 g[whichgraph].t[naxis]->tl_op = $1;
4074 }
4075 | FORMULA sexpr {
4076 if (!is_valid_axis(whichgraph, naxis)) {
4077 yyerror("No valid axis selected");
4078 return 1;
4079 }
4080 g[whichgraph].t[naxis]->tl_formula =
4081 copy_string(g[whichgraph].t[naxis]->tl_formula, $2);
4082 xfree($2);
4083 }
4084 | START expr {
4085 if (!is_valid_axis(whichgraph, naxis)) {
4086 yyerror("No valid axis selected");
4087 return 1;
4088 }
4089 g[whichgraph].t[naxis]->tl_start = $2;
4090 }
4091 | STOP expr {
4092 if (!is_valid_axis(whichgraph, naxis)) {
4093 yyerror("No valid axis selected");
4094 return 1;
4095 }
4096 g[whichgraph].t[naxis]->tl_stop = $2;
4097 }
4098 | START TYPE SPEC {
4099 if (!is_valid_axis(whichgraph, naxis)) {
4100 yyerror("No valid axis selected");
4101 return 1;
4102 }
4103 g[whichgraph].t[naxis]->tl_starttype = TYPE_SPEC;
4104 }
4105 | START TYPE AUTO {
4106 if (!is_valid_axis(whichgraph, naxis)) {
4107 yyerror("No valid axis selected");
4108 return 1;
4109 }
4110 g[whichgraph].t[naxis]->tl_starttype = TYPE_AUTO;
4111 }
4112 | STOP TYPE SPEC {
4113 if (!is_valid_axis(whichgraph, naxis)) {
4114 yyerror("No valid axis selected");
4115 return 1;
4116 }
4117 g[whichgraph].t[naxis]->tl_stoptype = TYPE_SPEC;
4118 }
4119 | STOP TYPE AUTO {
4120 if (!is_valid_axis(whichgraph, naxis)) {
4121 yyerror("No valid axis selected");
4122 return 1;
4123 }
4124 g[whichgraph].t[naxis]->tl_stoptype = TYPE_AUTO;
4125 }
4126 | CHAR SIZE expr {
4127 if (!is_valid_axis(whichgraph, naxis)) {
4128 yyerror("No valid axis selected");
4129 return 1;
4130 }
4131 g[whichgraph].t[naxis]->tl_charsize = $3;
4132 }
4133 | font_select {
4134 if (!is_valid_axis(whichgraph, naxis)) {
4135 yyerror("No valid axis selected");
4136 return 1;
4137 }
4138 g[whichgraph].t[naxis]->tl_font = $1;
4139 }
4140 | color_select {
4141 if (!is_valid_axis(whichgraph, naxis)) {
4142 yyerror("No valid axis selected");
4143 return 1;
4144 }
4145 g[whichgraph].t[naxis]->tl_color = $1;
4146 }
4147 | nexpr ',' sexpr {
4148 if (!is_valid_axis(whichgraph, naxis)) {
4149 yyerror("No valid axis selected");
4150 xfree($3);
4151 return 1;
4152 }
4153 if ($1 >= MAX_TICKS) {
4154 yyerror("Number of ticks exceeds maximum");
4155 xfree($3);
4156 return 1;
4157 }
4158 g[whichgraph].t[naxis]->tloc[$1].label =
4159 copy_string(g[whichgraph].t[naxis]->tloc[$1].label, $3);
4160 xfree($3);
4161 }
4162 | OFFSET AUTO {
4163 if (!is_valid_axis(whichgraph, naxis)) {
4164 yyerror("No valid axis selected");
4165 return 1;
4166 }
4167 g[whichgraph].t[naxis]->tl_gaptype = TYPE_AUTO;
4168 }
4169 | OFFSET SPEC {
4170 if (!is_valid_axis(whichgraph, naxis)) {
4171 yyerror("No valid axis selected");
4172 return 1;
4173 }
4174 g[whichgraph].t[naxis]->tl_gaptype = TYPE_SPEC;
4175 }
4176 | OFFSET expr ',' expr {
4177 if (!is_valid_axis(whichgraph, naxis)) {
4178 yyerror("No valid axis selected");
4179 return 1;
4180 }
4181 g[whichgraph].t[naxis]->tl_gap.x = $2;
4182 g[whichgraph].t[naxis]->tl_gap.y = $4;
4183 }
4184 ;
4185
4186 axislabeldesc:
4187 sexpr {
4188 if (!is_valid_axis(whichgraph, naxis)) {
4189 yyerror("No valid axis selected");
4190 return 1;
4191 }
4192 set_plotstr_string(&g[whichgraph].t[naxis]->label, $1);
4193 xfree($1);
4194 }
4195 | LAYOUT PERP {
4196 if (!is_valid_axis(whichgraph, naxis)) {
4197 yyerror("No valid axis selected");
4198 return 1;
4199 }
4200 g[whichgraph].t[naxis]->label_layout = LAYOUT_PERPENDICULAR;
4201 }
4202 | LAYOUT PARA {
4203 if (!is_valid_axis(whichgraph, naxis)) {
4204 yyerror("No valid axis selected");
4205 return 1;
4206 }
4207 g[whichgraph].t[naxis]->label_layout = LAYOUT_PARALLEL;
4208 }
4209 | PLACE AUTO {
4210 if (!is_valid_axis(whichgraph, naxis)) {
4211 yyerror("No valid axis selected");
4212 return 1;
4213 }
4214 g[whichgraph].t[naxis]->label_place = TYPE_AUTO;
4215 }
4216 | PLACE SPEC {
4217 if (!is_valid_axis(whichgraph, naxis)) {
4218 yyerror("No valid axis selected");
4219 return 1;
4220 }
4221 g[whichgraph].t[naxis]->label_place = TYPE_SPEC;
4222 }
4223 | PLACE expr ',' expr {
4224 if (!is_valid_axis(whichgraph, naxis)) {
4225 yyerror("No valid axis selected");
4226 return 1;
4227 }
4228 g[whichgraph].t[naxis]->label.x = $2;
4229 g[whichgraph].t[naxis]->label.y = $4;
4230 }
4231 | JUST justchoice {
4232 if (!is_valid_axis(whichgraph, naxis)) {
4233 yyerror("No valid axis selected");
4234 return 1;
4235 }
4236 g[whichgraph].t[naxis]->label.just = $2;
4237 }
4238 | CHAR SIZE expr {
4239 if (!is_valid_axis(whichgraph, naxis)) {
4240 yyerror("No valid axis selected");
4241 return 1;
4242 }
4243 g[whichgraph].t[naxis]->label.charsize = $3;
4244 }
4245 | font_select {
4246 if (!is_valid_axis(whichgraph, naxis)) {
4247 yyerror("No valid axis selected");
4248 return 1;
4249 }
4250 g[whichgraph].t[naxis]->label.font = $1;
4251 }
4252 | color_select {
4253 if (!is_valid_axis(whichgraph, naxis)) {
4254 yyerror("No valid axis selected");
4255 return 1;
4256 }
4257 g[whichgraph].t[naxis]->label.color = $1;
4258 }
4259 | opchoice_sel {
4260 if (!is_valid_axis(whichgraph, naxis)) {
4261 yyerror("No valid axis selected");
4262 return 1;
4263 }
4264 g[whichgraph].t[naxis]->label_op = $1;
4265 }
4266 ;
4267
4268 axisbardesc:
4269 onoff {
4270 if (!is_valid_axis(whichgraph, naxis)) {
4271 yyerror("No valid axis selected");
4272 return 1;
4273 }
4274 g[whichgraph].t[naxis]->t_drawbar = $1;
4275 }
4276 | color_select {
4277 if (!is_valid_axis(whichgraph, naxis)) {
4278 yyerror("No valid axis selected");
4279 return 1;
4280 }
4281 g[whichgraph].t[naxis]->t_drawbarcolor = $1;
4282 }
4283 | lines_select {
4284 if (!is_valid_axis(whichgraph, naxis)) {
4285 yyerror("No valid axis selected");
4286 return 1;
4287 }
4288 g[whichgraph].t[naxis]->t_drawbarlines = $1;
4289 }
4290 | linew_select {
4291 if (!is_valid_axis(whichgraph, naxis)) {
4292 yyerror("No valid axis selected");
4293 return 1;
4294 }
4295 g[whichgraph].t[naxis]->t_drawbarlinew = $1;
4296 }
4297 ;
4298
4299 nonlfitopts:
4300 TITLE sexpr {
4301 nonl_opts.title = copy_string(nonl_opts.title, $2);
4302 xfree($2);
4303 }
4304 | FORMULA sexpr {
4305 nonl_opts.formula = copy_string(nonl_opts.formula, $2);
4306 xfree($2);
4307 }
4308 | WITH nexpr PARAMETERS {
4309 nonl_opts.parnum = $2;
4310 }
4311 | PREC expr {
4312 nonl_opts.tolerance = $2;
4313 }
4314 ;
4315
4316 selectgraph:
4317 GRAPHNO
4318 {
4319 $$ = $1;
4320 }
4321 | GRAPH indx
4322 {
4323 $$ = $2;
4324 }
4325 ;
4326
4327 selectset:
4328 selectgraph '.' SETNUM
4329 {
4330 int gno = $1, setno = $3;
4331 if (allocate_set(gno, setno) == RETURN_SUCCESS) {
4332 $$ = &trgt_pool[tgtn];
4333 $$->gno = gno;
4334 $$->setno = setno;
4335 tgtn++;
4336 } else {
4337 errmsg("Can't allocate referred set");
4338 return 1;
4339 }
4340 }
4341 | selectgraph '.' SET indx
4342 {
4343 int gno = $1, setno = $4;
4344 if (allocate_set(gno, setno) == RETURN_SUCCESS) {
4345 $$ = &trgt_pool[tgtn];
4346 $$->gno = gno;
4347 $$->setno = setno;
4348 tgtn++;
4349 } else {
4350 errmsg("Can't allocate referred set");
4351 return 1;
4352 }
4353 }
4354 | SETNUM
4355 {
4356 int gno = whichgraph, setno = $1;
4357 if (allocate_set(gno, setno) == RETURN_SUCCESS) {
4358 $$ = &trgt_pool[tgtn];
4359 $$->gno = gno;
4360 $$->setno = setno;
4361 tgtn++;
4362 } else {
4363 errmsg("Can't allocate referred set");
4364 return 1;
4365 }
4366 }
4367 | SET indx
4368 {
4369 int gno = whichgraph, setno = $2;
4370 if (allocate_set(gno, setno) == RETURN_SUCCESS) {
4371 $$ = &trgt_pool[tgtn];
4372 $$->gno = gno;
4373 $$->setno = setno;
4374 tgtn++;
4375 } else {
4376 errmsg("Can't allocate referred set");
4377 return 1;
4378 }
4379 }
4380 ;
4381
4382 setaxis:
4383 axis axisfeature {}
4384 | selectgraph axis axisfeature {}
4385 ;
4386
4387 axis:
4388 XAXIS { naxis = X_AXIS; }
4389 | YAXIS { naxis = Y_AXIS; }
4390 | ALTXAXIS { naxis = ZX_AXIS; }
4391 | ALTYAXIS { naxis = ZY_AXIS; }
4392 ;
4393
4394 proctype:
4395 KEY_CONST { $$ = CONSTANT; }
4396 | KEY_UNIT { $$ = UCONSTANT; }
4397 | KEY_FUNC_I { $$ = FUNC_I; }
4398 | KEY_FUNC_D { $$ = FUNC_D; }
4399 | KEY_FUNC_ND { $$ = FUNC_ND; }
4400 | KEY_FUNC_NN { $$ = FUNC_NN; }
4401 | KEY_FUNC_DD { $$ = FUNC_DD; }
4402 | KEY_FUNC_NND { $$ = FUNC_NND; }
4403 | KEY_FUNC_PPD { $$ = FUNC_PPD; }
4404 | KEY_FUNC_PPPD { $$ = FUNC_PPPD; }
4405 | KEY_FUNC_PPPPD { $$ = FUNC_PPPPD; }
4406 | KEY_FUNC_PPPPPD { $$ = FUNC_PPPPPD; }
4407 ;
4408
4409 tickspectype:
4410 NONE { $$ = TICKS_SPEC_NONE; }
4411 | TICKSP { $$ = TICKS_SPEC_MARKS; }
4412 | BOTH { $$ = TICKS_SPEC_BOTH; }
4413 ;
4414
4415 filtertype:
4416 IFILTER { $$ = FILTER_INPUT; }
4417 | OFILTER { $$ = FILTER_OUTPUT; }
4418 ;
4419
4420 filtermethod:
4421 MAGIC { $$ = FILTER_MAGIC; }
4422 | PATTERN { $$ = FILTER_PATTERN; }
4423 ;
4424
4425 xytype:
4426 XY { $$ = SET_XY; }
4427 | BAR { $$ = SET_BAR; }
4428 | BARDY { $$ = SET_BARDY; }
4429 | BARDYDY { $$ = SET_BARDYDY; }
4430 | XYZ { $$ = SET_XYZ; }
4431 | XYDX { $$ = SET_XYDX; }
4432 | XYDY { $$ = SET_XYDY; }
4433 | XYDXDX { $$ = SET_XYDXDX; }
4434 | XYDYDY { $$ = SET_XYDYDY; }
4435 | XYDXDY { $$ = SET_XYDXDY; }
4436 | XYDXDXDYDY { $$ = SET_XYDXDXDYDY; }
4437 | XYHILO { $$ = SET_XYHILO; }
4438 | XYR { $$ = SET_XYR; }
4439 | XYSIZE { $$ = SET_XYSIZE; }
4440 | XYCOLOR { $$ = SET_XYCOLOR; }
4441 | XYCOLPAT { $$ = SET_XYCOLPAT; }
4442 | XYVMAP { $$ = SET_XYVMAP; }
4443 | XYBOXPLOT { $$ = SET_BOXPLOT; }
4444 | XYSTRING { $$ = SET_XY; }
4445 ;
4446
4447 graphtype:
4448 XY { $$ = GRAPH_XY; }
4449 | CHART { $$ = GRAPH_CHART; }
4450 | POLAR { $$ = GRAPH_POLAR; }
4451 | SMITH { $$ = GRAPH_SMITH; }
4452 | FIXED { $$ = GRAPH_FIXED; }
4453 | PIE { $$ = GRAPH_PIE; }
4454 ;
4455
4456 pagelayout:
4457 FREE { $$ = PAGE_FREE; }
4458 | FIXED { $$ = PAGE_FIXED; }
4459 ;
4460
4461 pageorient:
4462 LANDSCAPE { $$ = PAGE_ORIENT_LANDSCAPE; }
4463 | PORTRAIT { $$ = PAGE_ORIENT_PORTRAIT; }
4464 ;
4465
4466 regiontype:
4467 ABOVE { $$ = REGION_ABOVE; }
4468 | BELOW { $$ = REGION_BELOW; }
4469 | LEFT { $$ = REGION_TOLEFT; }
4470 | RIGHT { $$ = REGION_TORIGHT; }
4471 | POLYI { $$ = REGION_POLYI; }
4472 | POLYO { $$ = REGION_POLYO; }
4473 | HORIZI { $$ = REGION_HORIZI; }
4474 | VERTI { $$ = REGION_VERTI; }
4475 | HORIZO { $$ = REGION_HORIZO; }
4476 | VERTO { $$ = REGION_VERTO; }
4477 ;
4478
4479 scaletype: NORMAL { $$ = SCALE_NORMAL; }
4480 | LOGARITHMIC { $$ = SCALE_LOG; }
4481 | RECIPROCAL { $$ = SCALE_REC; }
4482 | LOGIT { $$ = SCALE_LOGIT; }
4483 ;
4484
4485 onoff: ON { $$ = TRUE; }
4486 | OFF { $$ = FALSE; }
4487 ;
4488
4489 runtype: RUNAVG { $$ = RUN_AVG; }
4490 | RUNSTD { $$ = RUN_STD; }
4491 | RUNMED { $$ = RUN_MED; }
4492 | RUNMAX { $$ = RUN_MAX; }
4493 | RUNMIN { $$ = RUN_MIN; }
4494 ;
4495
4496 sourcetype:
4497 DISK { $$ = SOURCE_DISK; }
4498 | PIPE {
4499 if (!safe_mode) {
4500 $$ = SOURCE_PIPE;
4501 } else {
4502 yyerror("Pipe inputs are disabled in safe mode");
4503 $$ = SOURCE_DISK;
4504 }
4505 }
4506 ;
4507
4508 justchoice: RIGHT { $$ = JUST_RIGHT; }
4509 | LEFT { $$ = JUST_LEFT; }
4510 | CENTER { $$ = JUST_CENTER; }
4511 ;
4512
4513 inoutchoice: IN { $$ = TICKS_IN; }
4514 | OUT { $$ = TICKS_OUT; }
4515 | BOTH { $$ = TICKS_BOTH; }
4516 ;
4517
4518 formatchoice: DECIMAL { $$ = FORMAT_DECIMAL; }
4519 | EXPONENTIAL { $$ = FORMAT_EXPONENTIAL; }
4520 | GENERAL { $$ = FORMAT_GENERAL; }
4521 | SCIENTIFIC { $$ = FORMAT_SCIENTIFIC; }
4522 | ENGINEERING { $$ = FORMAT_ENGINEERING; }
4523 | COMPUTING { $$ = FORMAT_COMPUTING; }
4524 | POWER { $$ = FORMAT_POWER; }
4525 | DDMMYY { $$ = FORMAT_DDMMYY; }
4526 | MMDDYY { $$ = FORMAT_MMDDYY; }
4527 | YYMMDD { $$ = FORMAT_YYMMDD; }
4528 | MMYY { $$ = FORMAT_MMYY; }
4529 | MMDD { $$ = FORMAT_MMDD; }
4530 | MONTHDAY { $$ = FORMAT_MONTHDAY; }
4531 | DAYMONTH { $$ = FORMAT_DAYMONTH; }
4532 | MONTHS { $$ = FORMAT_MONTHS; }
4533 | MONTHSY { $$ = FORMAT_MONTHSY; }
4534 | MONTHL { $$ = FORMAT_MONTHL; }
4535 | DAYOFWEEKS { $$ = FORMAT_DAYOFWEEKS; }
4536 | DAYOFWEEKL { $$ = FORMAT_DAYOFWEEKL; }
4537 | DAYOFYEAR { $$ = FORMAT_DAYOFYEAR; }
4538 | HMS { $$ = FORMAT_HMS; }
4539 | MMDDHMS { $$ = FORMAT_MMDDHMS; }
4540 | MMDDYYHMS { $$ = FORMAT_MMDDYYHMS; }
4541 | YYMMDDHMS { $$ = FORMAT_YYMMDDHMS; }
4542 | DEGREESLON { $$ = FORMAT_DEGREESLON; }
4543 | DEGREESMMLON { $$ = FORMAT_DEGREESMMLON; }
4544 | DEGREESMMSSLON { $$ = FORMAT_DEGREESMMSSLON; }
4545 | MMSSLON { $$ = FORMAT_MMSSLON; }
4546 | DEGREESLAT { $$ = FORMAT_DEGREESLAT; }
4547 | DEGREESMMLAT { $$ = FORMAT_DEGREESMMLAT; }
4548 | DEGREESMMSSLAT { $$ = FORMAT_DEGREESMMSSLAT; }
4549 | MMSSLAT { $$ = FORMAT_MMSSLAT; }
4550 ;
4551
4552 signchoice: NORMAL { $$ = SIGN_NORMAL; }
4553 | ABSOLUTE { $$ = SIGN_ABSOLUTE; }
4554 | NEGATE { $$ = SIGN_NEGATE; }
4555 ;
4556
4557 direction: UP { $$ = UP; }
4558 | DOWN { $$ = DOWN; }
4559 | RIGHT { $$ = RIGHT; }
4560 | LEFT { $$ = LEFT; }
4561 | IN { $$ = IN; }
4562 | OUT { $$ = OUT; }
4563 ;
4564
4565 worldview: WORLD { $$ = COORD_WORLD; }
4566 | VIEW { $$ = COORD_VIEW; }
4567 ;
4568
4569 datacolumn: X_TOK { $$ = DATA_X; }
4570 | Y_TOK { $$ = DATA_Y; }
4571 | X0 { $$ = DATA_X; }
4572 | Y0 { $$ = DATA_Y; }
4573 | Y1 { $$ = DATA_Y1; }
4574 | Y2 { $$ = DATA_Y2; }
4575 | Y3 { $$ = DATA_Y3; }
4576 | Y4 { $$ = DATA_Y4; }
4577 ;
4578
4579 sortdir: ASCENDING { $$ = ASCENDING; }
4580 | DESCENDING { $$ = DESCENDING; }
4581 ;
4582
4583 sorton: X_TOK { $$ = DATA_X; }
4584 | Y_TOK { $$ = DATA_Y; }
4585 ;
4586
4587 ffttype: DFT { $$ = FFT_DFT; }
4588 | FFT { $$ = FFT_FFT; }
4589 | INVDFT { $$ = FFT_INVDFT; }
4590 | INVFFT { $$ = FFT_INVFFT; }
4591 ;
4592
4593 fourierdata:
4594 REAL {$$=0;}
4595 | COMPLEX {$$=1;}
4596 ;
4597
4598 fourierloadx:
4599 INDEX {$$=0;}
4600 | FREQUENCY {$$=1;}
4601 | PERIOD {$$=2;}
4602 ;
4603
4604 fourierloady:
4605 MAGNITUDE {$$=0;}
4606 | PHASE {$$=1;}
4607 | COEFFICIENTS {$$=2;}
4608 ;
4609
4610 windowtype:
4611 NONE {$$=0;}
4612 | TRIANGULAR {$$=1;}
4613 | HANNING {$$=2;}
4614 | WELCH {$$=3;}
4615 | HAMMING {$$=4;}
4616 | BLACKMAN {$$=5;}
4617 | PARZEN {$$=6;}
4618 ;
4619
4620 interpmethod:
4621 LINEAR { $$ = INTERP_LINEAR; }
4622 | SPLINE { $$ = INTERP_SPLINE; }
4623 | ASPLINE { $$ = INTERP_ASPLINE; }
4624 ;
4625
4626 stattype: MINP { $$ = MINP; }
4627 | MAXP { $$ = MAXP; }
4628 | AVG { $$ = AVG; }
4629 | SD { $$ = SD; }
4630 | SUM { $$ = SUM; }
4631 | IMIN { $$ = IMIN; }
4632 | IMAX { $$ = IMAX; }
4633 ;
4634
4635 font_select:
4636 FONTP nexpr
4637 {
4638 $$ = get_mapped_font($2);
4639 }
4640 | FONTP sexpr
4641 {
4642 $$ = get_font_by_name($2);
4643 xfree($2);
4644 }
4645 ;
4646
4647 lines_select:
4648 LINESTYLE nexpr
4649 {
4650 int lines = $2;
4651 if (lines >= 0 && lines < number_of_linestyles()) {
4652 $$ = lines;
4653 } else {
4654 errmsg("invalid linestyle");
4655 $$ = 1;
4656 }
4657 }
4658 ;
4659
4660 pattern_select:
4661 PATTERN nexpr
4662 {
4663 int patno = $2;
4664 if (patno >= 0 && patno < number_of_patterns()) {
4665 $$ = patno;
4666 } else {
4667 errmsg("invalid pattern number");
4668 $$ = 1;
4669 }
4670 }
4671 ;
4672
4673 color_select:
4674 COLOR nexpr
4675 {
4676 int c = $2;
4677 if (c >= 0 && c < number_of_colors()) {
4678 $$ = c;
4679 } else {
4680 errmsg("Invalid color ID");
4681 $$ = 1;
4682 }
4683 }
4684 | COLOR sexpr
4685 {
4686 int c = get_color_by_name($2);
4687 if (c == BAD_COLOR) {
4688 errmsg("Invalid color name");
4689 c = 1;
4690 }
4691 xfree($2);
4692 $$ = c;
4693 }
4694 | COLOR '(' nexpr ',' nexpr ',' nexpr ')'
4695 {
4696 int c;
4697 CMap_entry cmap;
4698 cmap.rgb.red = $3;
4699 cmap.rgb.green = $5;
4700 cmap.rgb.blue = $7;
4701 cmap.ctype = COLOR_MAIN;
4702 cmap.cname = NULL;
4703 c = add_color(cmap);
4704 if (c == BAD_COLOR) {
4705 errmsg("Can't allocate requested color");
4706 c = 1;
4707 }
4708 $$ = c;
4709 }
4710 ;
4711
4712 linew_select:
4713 LINEWIDTH expr
4714 {
4715 double linew;
4716 linew = $2;
4717 if (linew < 0.0) {
4718 yyerror("Negative linewidth");
4719 linew = 0.0;
4720 } else if (linew > MAX_LINEWIDTH) {
4721 yyerror("Linewidth too large");
4722 linew = MAX_LINEWIDTH;
4723 }
4724 $$ = linew;
4725 }
4726 ;
4727
4728 opchoice_sel: PLACE opchoice
4729 {
4730 $$ = $2;
4731 }
4732 ;
4733
4734 opchoice: NORMAL { $$ = PLACEMENT_NORMAL; }
4735 | OPPOSITE { $$ = PLACEMENT_OPPOSITE; }
4736 | BOTH { $$ = PLACEMENT_BOTH; }
4737 ;
4738
4739
4740 parmset_obs:
4741 PAGE LAYOUT pageorient
4742 {
4743 int wpp, hpp;
4744 if ($3 == PAGE_ORIENT_LANDSCAPE) {
4745 wpp = 792;
4746 hpp = 612;
4747 } else {
4748 wpp = 612;
4749 hpp = 792;
4750 }
4751 set_page_dimensions(wpp, hpp, FALSE);
4752 }
4753 | PAGE SIZE NUMBER NUMBER {
4754 set_page_dimensions((int) $3, (int) $4, FALSE);
4755 }
4756 | PAGE nexpr {
4757 scroll_proc($2);
4758 }
4759 | PAGE INOUT nexpr {
4760 scrollinout_proc($3);
4761 }
4762
4763 | DEFAULT FONTP SOURCE expr {
4764 }
4765
4766 | STACK WORLD expr ',' expr ',' expr ',' expr TICKP expr ',' expr ',' expr ',' expr
4767 {
4768 add_world(whichgraph, $3, $5, $7, $9);
4769 }
4770
4771 | BOX FILL colpat_obs {filltype_obs = $3;}
4772
4773 | ELLIPSE FILL colpat_obs {filltype_obs = $3;}
4774
4775 | STRING linew_select { }
4776
4777 | TIMESTAMP linew_select { }
4778
4779 | TITLE linew_select { }
4780 | SUBTITLE linew_select { }
4781
4782 | LEGEND BOX onoff {
4783 if (!is_valid_gno(whichgraph)) {
4784 yyerror("No valid graph selected");
4785 return 1;
4786 }
4787 if ($3 == FALSE && get_project_version() <= 40102) {
4788 g[whichgraph].l.boxpen.pattern = 0;
4789 }
4790 }
4791 | LEGEND X1 expr {
4792 if (!is_valid_gno(whichgraph)) {
4793 yyerror("No valid graph selected");
4794 return 1;
4795 }
4796 g[whichgraph].l.legx = $3;
4797 }
4798 | LEGEND Y1 expr {
4799 if (!is_valid_gno(whichgraph)) {
4800 yyerror("No valid graph selected");
4801 return 1;
4802 }
4803 g[whichgraph].l.legy = $3;
4804 }
4805 | LEGEND STRING nexpr sexpr {
4806 if (is_valid_setno(whichgraph, $3)) {
4807 strncpy(g[whichgraph].p[$3].lstr, $4, MAX_STRING_LENGTH - 1);
4808 } else {
4809 yyerror("Unallocated set");
4810 }
4811 xfree($4);
4812 }
4813 | LEGEND BOX FILL onoff { }
4814 | LEGEND BOX FILL WITH colpat_obs {filltype_obs = $5;}
4815 | LEGEND lines_select { }
4816 | LEGEND linew_select { }
4817
4818 | selectgraph LABEL onoff { }
4819
4820 | selectgraph TYPE LOGX {
4821 g[$1].type = GRAPH_XY;
4822 g[$1].xscale = SCALE_LOG;
4823 }
4824 | selectgraph TYPE LOGY {
4825 g[$1].type = GRAPH_XY;
4826 g[$1].yscale = SCALE_LOG;
4827 }
4828 | selectgraph TYPE LOGXY
4829 {
4830 g[$1].type = GRAPH_XY;
4831 g[$1].xscale = SCALE_LOG;
4832 g[$1].yscale = SCALE_LOG;
4833 }
4834 | selectgraph TYPE BAR
4835 {
4836 g[$1].type = GRAPH_CHART;
4837 g[$1].xyflip = FALSE;
4838 g[$1].stacked = FALSE;
4839 }
4840 | selectgraph TYPE HBAR
4841 {
4842 g[$1].type = GRAPH_CHART;
4843 g[$1].xyflip = TRUE;
4844 }
4845 | selectgraph TYPE STACKEDBAR
4846 {
4847 g[$1].type = GRAPH_CHART;
4848 g[$1].stacked = TRUE;
4849 }
4850 | selectgraph TYPE STACKEDHBAR
4851 {
4852 g[$1].type = GRAPH_CHART;
4853 g[$1].stacked = TRUE;
4854 g[$1].xyflip = TRUE;
4855 }
4856
4857 | WORLD XMIN expr {
4858 if (!is_valid_gno(whichgraph)) {
4859 yyerror("No valid graph selected");
4860 return 1;
4861 }
4862 g[whichgraph].w.xg1 = $3;
4863 }
4864 | WORLD XMAX expr {
4865 if (!is_valid_gno(whichgraph)) {
4866 yyerror("No valid graph selected");
4867 return 1;
4868 }
4869 g[whichgraph].w.xg2 = $3;
4870 }
4871 | WORLD YMIN expr {
4872 if (!is_valid_gno(whichgraph)) {
4873 yyerror("No valid graph selected");
4874 return 1;
4875 }
4876 g[whichgraph].w.yg1 = $3;
4877 }
4878 | WORLD YMAX expr {
4879 if (!is_valid_gno(whichgraph)) {
4880 yyerror("No valid graph selected");
4881 return 1;
4882 }
4883 g[whichgraph].w.yg2 = $3;
4884 }
4885
4886 | VIEW XMIN expr {
4887 if (!is_valid_gno(whichgraph)) {
4888 yyerror("No valid graph selected");
4889 return 1;
4890 }
4891 g[whichgraph].v.xv1 = $3;
4892 }
4893 | VIEW XMAX expr {
4894 if (!is_valid_gno(whichgraph)) {
4895 yyerror("No valid graph selected");
4896 return 1;
4897 }
4898 g[whichgraph].v.xv2 = $3;
4899 }
4900 | VIEW YMIN expr {
4901 if (!is_valid_gno(whichgraph)) {
4902 yyerror("No valid graph selected");
4903 return 1;
4904 }
4905 g[whichgraph].v.yv1 = $3;
4906 }
4907 | VIEW YMAX expr {
4908 if (!is_valid_gno(whichgraph)) {
4909 yyerror("No valid graph selected");
4910 return 1;
4911 }
4912 g[whichgraph].v.yv2 = $3;
4913 }
4914
4915 | LEGEND LAYOUT expr {
4916 }
4917
4918 | FRAMEP FILL onoff {
4919 if (!is_valid_gno(whichgraph)) {
4920 yyerror("No valid graph selected");
4921 return 1;
4922 }
4923 g[whichgraph].f.fillpen.pattern = $3;
4924 }
4925
4926 | selectgraph AUTOSCALE TYPE AUTO {
4927 }
4928 | selectgraph AUTOSCALE TYPE SPEC {
4929 }
4930
4931 | LINE ARROW SIZE expr {
4932 line_asize = 2.0*$4;
4933 }
4934
4935 | HARDCOPY DEVICE expr { }
4936 | PS LINEWIDTH BEGIN expr { }
4937 | PS LINEWIDTH INCREMENT expr { }
4938 | PS linew_select { }
4939 ;
4940
4941
4942 axislabeldesc_obs:
4943 linew_select { }
4944 | opchoice_sel_obs {
4945 if (!is_valid_axis(whichgraph, naxis)) {
4946 yyerror("No valid axis selected");
4947 return 1;
4948 }
4949 g[whichgraph].t[naxis]->label_op = $1;
4950 }
4951 ;
4952
4953 setprop_obs:
4954 selectset SYMBOL FILL nexpr {
4955 switch ($4){
4956 case 0:
4957 g[$1->gno].p[$1->setno].symfillpen.pattern = 0;
4958 break;
4959 case 1:
4960 g[$1->gno].p[$1->setno].symfillpen.pattern = 1;
4961 break;
4962 case 2:
4963 g[$1->gno].p[$1->setno].symfillpen.pattern = 1;
4964 g[$1->gno].p[$1->setno].symfillpen.color = getbgcolor();
4965 break;
4966 }
4967 }
4968 | selectset SKIP nexpr
4969 {
4970 g[$1->gno].p[$1->setno].symskip = $3;
4971 }
4972 | selectset FILL nexpr
4973 {
4974 switch ($3) {
4975 case 0:
4976 g[$1->gno].p[$1->setno].filltype = SETFILL_NONE;
4977 break;
4978 case 1:
4979 g[$1->gno].p[$1->setno].filltype = SETFILL_POLYGON;
4980 break;
4981 case 2:
4982 g[$1->gno].p[$1->setno].filltype = SETFILL_BASELINE;
4983 g[$1->gno].p[$1->setno].baseline_type = BASELINE_TYPE_0;
4984 break;
4985 case 6:
4986 g[$1->gno].p[$1->setno].filltype = SETFILL_BASELINE;
4987 g[$1->gno].p[$1->setno].baseline_type = BASELINE_TYPE_GMIN;
4988 break;
4989 case 7:
4990 g[$1->gno].p[$1->setno].filltype = SETFILL_BASELINE;
4991 g[$1->gno].p[$1->setno].baseline_type = BASELINE_TYPE_GMAX;
4992 break;
4993 }
4994 }
4995 | selectset ERRORBAR TYPE opchoice_obs {
4996 g[$1->gno].p[$1->setno].errbar.ptype = $4;
4997 }
4998 /*
4999 * | selectset SYMBOL COLOR '-' N_NUMBER {
5000 * g[$1->gno].p[$1->setno].sympen.color = -1;
5001 * }
5002 */
5003 | selectset SYMBOL CENTER onoff { }
5004 | selectset lines_select {
5005 g[$1->gno].p[$1->setno].lines = $2;
5006 }
5007 | selectset linew_select {
5008 g[$1->gno].p[$1->setno].linew = $2;
5009 }
5010 | selectset color_select {
5011 g[$1->gno].p[$1->setno].linepen.color = $2;
5012 }
5013 | selectset FILL WITH colpat_obs {filltype_obs = $4;}
5014 | selectset XYZ expr ',' expr { }
5015 | selectset ERRORBAR LENGTH expr {
5016 g[$1->gno].p[$1->setno].errbar.barsize = $4;
5017 }
5018 | selectset ERRORBAR RISER onoff { }
5019 ;
5020
5021
5022 tickattr_obs:
5023 MAJOR onoff {
5024 /* <= xmgr-4.1 */
5025 if (!is_valid_axis(whichgraph, naxis)) {
5026 yyerror("No valid axis selected");
5027 return 1;
5028 }
5029 g[whichgraph].t[naxis]->active = $2;
5030 }
5031 | MINOR onoff { }
5032 | ALT onoff { }
5033 | MINP NUMBER { }
5034 | MAXP NUMBER { }
5035 | LOG onoff { }
5036 | TYPE AUTO {
5037 if (!is_valid_axis(whichgraph, naxis)) {
5038 yyerror("No valid axis selected");
5039 return 1;
5040 }
5041 g[whichgraph].t[naxis]->t_spec = TICKS_SPEC_NONE;
5042 }
5043 | TYPE SPEC {
5044 if (!is_valid_axis(whichgraph, naxis)) {
5045 yyerror("No valid axis selected");
5046 return 1;
5047 }
5048 if (g[whichgraph].t[naxis]->t_spec != TICKS_SPEC_BOTH) {
5049 g[whichgraph].t[naxis]->t_spec = TICKS_SPEC_MARKS;
5050 }
5051 }
5052 | MINOR expr {
5053 if (!is_valid_axis(whichgraph, naxis)) {
5054 yyerror("No valid axis selected");
5055 return 1;
5056 }
5057 if ($2 != 0.0) {
5058 g[whichgraph].t[naxis]->nminor =
5059 (int) rint(g[whichgraph].t[naxis]->tmajor / $2 - 1);
5060 } else {
5061 g[whichgraph].t[naxis]->nminor = 0;
5062 }
5063 }
5064 | SIZE expr {
5065 if (!is_valid_axis(whichgraph, naxis)) {
5066 yyerror("No valid axis selected");
5067 return 1;
5068 }
5069 g[whichgraph].t[naxis]->props.size = $2;
5070 }
5071 | nexpr ',' expr {
5072 if (!is_valid_axis(whichgraph, naxis)) {
5073 yyerror("No valid axis selected");
5074 return 1;
5075 }
5076 g[whichgraph].t[naxis]->tloc[$1].wtpos = $3;
5077 g[whichgraph].t[naxis]->tloc[$1].type = TICK_TYPE_MAJOR;
5078 }
5079 | opchoice_sel_obs {
5080 if (!is_valid_axis(whichgraph, naxis)) {
5081 yyerror("No valid axis selected");
5082 return 1;
5083 }
5084 g[whichgraph].t[naxis]->t_op = $1;
5085 }
5086 ;
5087
5088 ticklabelattr_obs:
5089 linew_select { }
5090 | TYPE AUTO {
5091 if (!is_valid_axis(whichgraph, naxis)) {
5092 yyerror("No valid axis selected");
5093 return 1;
5094 }
5095 if (g[whichgraph].t[naxis]->t_spec == TICKS_SPEC_BOTH) {
5096 g[whichgraph].t[naxis]->t_spec = TICKS_SPEC_MARKS;
5097 }
5098 }
5099 | TYPE SPEC {
5100 if (!is_valid_axis(whichgraph, naxis)) {
5101 yyerror("No valid axis selected");
5102 return 1;
5103 }
5104 g[whichgraph].t[naxis]->t_spec = TICKS_SPEC_BOTH;
5105 }
5106 | LAYOUT SPEC { }
5107
5108 | LAYOUT HORIZONTAL {
5109 if (!is_valid_axis(whichgraph, naxis)) {
5110 yyerror("No valid axis selected");
5111 return 1;
5112 }
5113 g[whichgraph].t[naxis]->tl_angle = 0;
5114 }
5115 | LAYOUT VERTICAL {
5116 if (!is_valid_axis(whichgraph, naxis)) {
5117 yyerror("No valid axis selected");
5118 return 1;
5119 }
5120 g[whichgraph].t[naxis]->tl_angle = 90;
5121 }
5122 | PLACE ON TICKSP { }
5123 | PLACE BETWEEN TICKSP { }
5124 | opchoice_sel_obs {
5125 if (!is_valid_axis(whichgraph, naxis)) {
5126 yyerror("No valid axis selected");
5127 return 1;
5128 }
5129 g[whichgraph].t[naxis]->tl_op = $1;
5130 }
5131 | SIGN signchoice {
5132 if (!is_valid_axis(whichgraph, naxis)) {
5133 yyerror("No valid axis selected");
5134 return 1;
5135 }
5136 switch($2) {
5137 case SIGN_NEGATE:
5138 g[whichgraph].t[naxis]->tl_formula =
5139 copy_string(g[whichgraph].t[naxis]->tl_formula, "-$t");
5140 break;
5141 case SIGN_ABSOLUTE:
5142 g[whichgraph].t[naxis]->tl_formula =
5143 copy_string(g[whichgraph].t[naxis]->tl_formula, "abs($t)");
5144 break;
5145 default:
5146 g[whichgraph].t[naxis]->tl_formula =
5147 copy_string(g[whichgraph].t[naxis]->tl_formula, NULL);
5148 break;
5149 }
5150 }
5151 ;
5152
5153 colpat_obs: NONE
5154 | COLOR
5155 | PATTERN
5156 ;
5157
5158 opchoice_sel_obs: OP opchoice_obs
5159 {
5160 $$ = $2;
5161 }
5162 ;
5163
5164 opchoice_obs: TOP { $$ = PLACEMENT_OPPOSITE; }
5165 | BOTTOM { $$ = PLACEMENT_NORMAL; }
5166 | LEFT { $$ = PLACEMENT_NORMAL; }
5167 | RIGHT { $$ = PLACEMENT_OPPOSITE; }
5168 | BOTH { $$ = PLACEMENT_BOTH; }
5169 ;
5170
5171 %%
5172
5173 /* list of intrinsic functions and keywords */
5174 symtab_entry ikey[] = {
5175 {"A0", FITPARM, NULL},
5176 {"A0MAX", FITPMAX, NULL},
5177 {"A0MIN", FITPMIN, NULL},
5178 {"A1", FITPARM, NULL},
5179 {"A1MAX", FITPMAX, NULL},
5180 {"A1MIN", FITPMIN, NULL},
5181 {"A2", FITPARM, NULL},
5182 {"A2MAX", FITPMAX, NULL},
5183 {"A2MIN", FITPMIN, NULL},
5184 {"A3", FITPARM, NULL},
5185 {"A3MAX", FITPMAX, NULL},
5186 {"A3MIN", FITPMIN, NULL},
5187 {"A4", FITPARM, NULL},
5188 {"A4MAX", FITPMAX, NULL},
5189 {"A4MIN", FITPMIN, NULL},
5190 {"A5", FITPARM, NULL},
5191 {"A5MAX", FITPMAX, NULL},
5192 {"A5MIN", FITPMIN, NULL},
5193 {"A6", FITPARM, NULL},
5194 {"A6MAX", FITPMAX, NULL},
5195 {"A6MIN", FITPMIN, NULL},
5196 {"A7", FITPARM, NULL},
5197 {"A7MAX", FITPMAX, NULL},
5198 {"A7MIN", FITPMIN, NULL},
5199 {"A8", FITPARM, NULL},
5200 {"A8MAX", FITPMAX, NULL},
5201 {"A8MIN", FITPMIN, NULL},
5202 {"A9", FITPARM, NULL},
5203 {"A9MAX", FITPMAX, NULL},
5204 {"A9MIN", FITPMIN, NULL},
5205 {"ABOVE", ABOVE, NULL},
5206 {"ABS", FUNC_D, (void *) fabs},
5207 {"ABSOLUTE", ABSOLUTE, NULL},
5208 {"ACOS", FUNC_D, (void *) acos},
5209 {"ACOSH", FUNC_D, (void *) acosh},
5210 {"AI", FUNC_D, (void *) ai_wrap},
5211 {"ALIAS", ALIAS, NULL},
5212 {"ALT", ALT, NULL},
5213 {"ALTXAXIS", ALTXAXIS, NULL},
5214 {"ALTYAXIS", ALTYAXIS, NULL},
5215 {"AND", AND, NULL},
5216 {"ANGLE", ANGLE, NULL},
5217 {"ANTIALIASING", ANTIALIASING, NULL},
5218 {"APPEND", APPEND, NULL},
5219 {"ARRANGE", ARRANGE, NULL},
5220 {"ARROW", ARROW, NULL},
5221 {"ASCENDING", ASCENDING, NULL},
5222 {"ASIN", FUNC_D, (void *) asin},
5223 {"ASINH", FUNC_D, (void *) asinh},
5224 {"ASPLINE", ASPLINE, NULL},
5225 {"ATAN", FUNC_D, (void *) atan},
5226 {"ATAN2", FUNC_DD, (void *) atan2},
5227 {"ATANH", FUNC_D, (void *) atanh},
5228 {"AUTO", AUTO, NULL},
5229 {"AUTOSCALE", AUTOSCALE, NULL},
5230 {"AUTOTICKS", AUTOTICKS, NULL},
5231 {"AVALUE", AVALUE, NULL},
5232 {"AVG", AVG, NULL},
5233 {"BACKGROUND", BACKGROUND, NULL},
5234 {"BAR", BAR, NULL},
5235 {"BARDY", BARDY, NULL},
5236 {"BARDYDY", BARDYDY, NULL},
5237 {"BASELINE", BASELINE, NULL},
5238 {"BATCH", BATCH, NULL},
5239 {"BEGIN", BEGIN, NULL},
5240 {"BELOW", BELOW, NULL},
5241 {"BETA", FUNC_DD, (void *) beta},
5242 {"BETWEEN", BETWEEN, NULL},
5243 {"BI", FUNC_D, (void *) bi_wrap},
5244 {"BLACKMAN", BLACKMAN, NULL},
5245 {"BLOCK", BLOCK, NULL},
5246 {"BOTH", BOTH, NULL},
5247 {"BOTTOM", BOTTOM, NULL},
5248 {"BOX", BOX, NULL},
5249 {"CD", CD, NULL},
5250 {"CEIL", FUNC_D, (void *) ceil},
5251 {"CENTER", CENTER, NULL},
5252 {"CHAR", CHAR, NULL},
5253 {"CHART", CHART, NULL},
5254 {"CHDTR", FUNC_DD, (void *) chdtr},
5255 {"CHDTRC", FUNC_DD, (void *) chdtrc},
5256 {"CHDTRI", FUNC_DD, (void *) chdtri},
5257 {"CHI", FUNC_D, (void *) chi_wrap},
5258 {"CI", FUNC_D, (void *) ci_wrap},
5259 {"CLEAR", CLEAR, NULL},
5260 {"CLICK", CLICK, NULL},
5261 {"CLIP", CLIP, NULL},
5262 {"CLOSE", CLOSE, NULL},
5263 {"COEFFICIENTS", COEFFICIENTS, NULL},
5264 {"COLOR", COLOR, NULL},
5265 {"COMMENT", COMMENT, NULL},
5266 {"COMPLEX", COMPLEX, NULL},
5267 {"COMPUTING", COMPUTING, NULL},
5268 {"CONST", KEY_CONST, NULL},
5269 {"CONSTRAINTS", CONSTRAINTS, NULL},
5270 {"COPY", COPY, NULL},
5271 {"COS", FUNC_D, (void *) cos},
5272 {"COSH", FUNC_D, (void *) cosh},
5273 {"CYCLE", CYCLE, NULL},
5274 {"DATE", DATE, NULL},
5275 {"DAWSN", FUNC_D, (void *) dawsn},
5276 {"DAYMONTH", DAYMONTH, NULL},
5277 {"DAYOFWEEKL", DAYOFWEEKL, NULL},
5278 {"DAYOFWEEKS", DAYOFWEEKS, NULL},
5279 {"DAYOFYEAR", DAYOFYEAR, NULL},
5280 {"DDMMYY", DDMMYY, NULL},
5281 {"DECIMAL", DECIMAL, NULL},
5282 {"DEF", DEF, NULL},
5283 {"DEFAULT", DEFAULT, NULL},
5284 {"DEFINE", DEFINE, NULL},
5285 {"DEG", UCONSTANT, (void *) deg_uconst},
5286 {"DEGREESLAT", DEGREESLAT, NULL},
5287 {"DEGREESLON", DEGREESLON, NULL},
5288 {"DEGREESMMLAT", DEGREESMMLAT, NULL},
5289 {"DEGREESMMLON", DEGREESMMLON, NULL},
5290 {"DEGREESMMSSLAT", DEGREESMMSSLAT, NULL},
5291 {"DEGREESMMSSLON", DEGREESMMSSLON, NULL},
5292 {"DESCENDING", DESCENDING, NULL},
5293 {"DESCRIPTION", DESCRIPTION, NULL},
5294 {"DEVICE", DEVICE, NULL},
5295 {"DFT", DFT, NULL},
5296 {"DIFF", DIFFERENCE, NULL},
5297 {"DIFFERENCE", DIFFERENCE, NULL},
5298 {"DISK", DISK, NULL},
5299 {"DOWN", DOWN, NULL},
5300 {"DPI", DPI, NULL},
5301 {"DROP", DROP, NULL},
5302 {"DROPLINE", DROPLINE, NULL},
5303 {"ECHO", ECHO, NULL},
5304 {"ELLIE", FUNC_DD, (void *) ellie},
5305 {"ELLIK", FUNC_DD, (void *) ellik},
5306 {"ELLIPSE", ELLIPSE, NULL},
5307 {"ELLPE", FUNC_D, (void *) ellpe_wrap},
5308 {"ELLPK", FUNC_D, (void *) ellpk_wrap},
5309 {"ENGINEERING", ENGINEERING, NULL},
5310 {"EQ", EQ, NULL},
5311 {"ER", ERRORBAR, NULL},
5312 {"ERF", FUNC_D, (void *) erf},
5313 {"ERFC", FUNC_D, (void *) erfc},
5314 {"ERRORBAR", ERRORBAR, NULL},
5315 {"EXIT", EXIT, NULL},
5316 {"EXP", FUNC_D, (void *) exp},
5317 {"EXPN", FUNC_ND, (void *) expn},
5318 {"EXPONENTIAL", EXPONENTIAL, NULL},
5319 {"FAC", FUNC_I, (void *) fac},
5320 {"FALSE", OFF, NULL},
5321 {"FDTR", FUNC_NND, (void *) fdtr},
5322 {"FDTRC", FUNC_NND, (void *) fdtrc},
5323 {"FDTRI", FUNC_NND, (void *) fdtri},
5324 {"FFT", FFT, NULL},
5325 {"FILE", FILEP, NULL},
5326 {"FILL", FILL, NULL},
5327 {"FIT", FIT, NULL},
5328 {"FIXED", FIXED, NULL},
5329 {"FIXEDPOINT", FIXEDPOINT, NULL},
5330 {"FLOOR", FUNC_D, (void *) floor},
5331 {"FLUSH", FLUSH, NULL},
5332 {"FOCUS", FOCUS, NULL},
5333 {"FOLLOWS", FOLLOWS, NULL},
5334 {"FONT", FONTP, NULL},
5335 {"FORCE", FORCE, NULL},
5336 {"FORMAT", FORMAT, NULL},
5337 {"FORMULA", FORMULA, NULL},
5338 {"FRAME", FRAMEP, NULL},
5339 {"FREE", FREE, NULL},
5340 {"FREQUENCY", FREQUENCY, NULL},
5341 {"FRESNLC", FUNC_D, (void *) fresnlc_wrap},
5342 {"FRESNLS", FUNC_D, (void *) fresnls_wrap},
5343 {"FROM", FROM, NULL},
5344 {"F_OF_D", KEY_FUNC_D, NULL},
5345 {"F_OF_DD", KEY_FUNC_DD, NULL},
5346 {"F_OF_I", KEY_FUNC_I, NULL},
5347 {"F_OF_ND", KEY_FUNC_ND, NULL},
5348 {"F_OF_NN", KEY_FUNC_NN, NULL},
5349 {"F_OF_NND", KEY_FUNC_NND, NULL},
5350 {"F_OF_PPD", KEY_FUNC_PPD, NULL},
5351 {"F_OF_PPPD", KEY_FUNC_PPPD, NULL},
5352 {"F_OF_PPPPD", KEY_FUNC_PPPPD, NULL},
5353 {"F_OF_PPPPPD", KEY_FUNC_PPPPPD, NULL},
5354 {"GAMMA", FUNC_D, (void *) true_gamma},
5355 {"GDTR", FUNC_PPD, (void *) gdtr},
5356 {"GDTRC", FUNC_PPD, (void *) gdtrc},
5357 {"GE", GE, NULL},
5358 {"GENERAL", GENERAL, NULL},
5359 {"GETP", GETP, NULL},
5360 {"GRAPH", GRAPH, NULL},
5361 {"GRID", GRID, NULL},
5362 {"GT", GT, NULL},
5363 {"HAMMING", HAMMING, NULL},
5364 {"HANNING", HANNING, NULL},
5365 {"HARDCOPY", HARDCOPY, NULL},
5366 {"HBAR", HBAR, NULL},
5367 {"HELP", HELP, NULL},
5368 {"HGAP", HGAP, NULL},
5369 {"HIDDEN", HIDDEN, NULL},
5370 {"HISTOGRAM", HISTOGRAM, NULL},
5371 {"HMS", HMS, NULL},
5372 {"HORIZI", HORIZI, NULL},
5373 {"HORIZO", HORIZO, NULL},
5374 {"HORIZONTAL", HORIZONTAL, NULL},
5375 {"HYP2F1", FUNC_PPPD, (void *) hyp2f1},
5376 {"HYPERG", FUNC_PPD, (void *) hyperg},
5377 {"HYPOT", FUNC_DD, (void *) hypot},
5378 {"I0E", FUNC_D, (void *) i0e},
5379 {"I1E", FUNC_D, (void *) i1e},
5380 {"ID", ID, NULL},
5381 {"IFILTER", IFILTER, NULL},
5382 {"IGAM", FUNC_DD, (void *) igam},
5383 {"IGAMC", FUNC_DD, (void *) igamc},
5384 {"IGAMI", FUNC_DD, (void *) igami},
5385 {"IMAX", IMAX, NULL},
5386 {"IMIN", IMIN, NULL},
5387 {"IN", IN, NULL},
5388 {"INCBET", FUNC_PPD, (void *) incbet},
5389 {"INCBI", FUNC_PPD, (void *) incbi},
5390 {"INCREMENT", INCREMENT, NULL},
5391 {"INDEX", INDEX, NULL},
5392 {"INOUT", INOUT, NULL},
5393 {"INT", INT, NULL},
5394 {"INTEGRATE", INTEGRATE, NULL},
5395 {"INTERPOLATE", INTERPOLATE, NULL},
5396 {"INVDFT", INVDFT, NULL},
5397 {"INVERT", INVERT, NULL},
5398 {"INVFFT", INVFFT, NULL},
5399 {"IRAND", FUNC_I, (void *) irand_wrap},
5400 {"IV", FUNC_DD, (void *) iv_wrap},
5401 {"JUST", JUST, NULL},
5402 {"JV", FUNC_DD, (void *) jv_wrap},
5403 {"K0E", FUNC_D, (void *) k0e},
5404 {"K1E", FUNC_D, (void *) k1e},
5405 {"KILL", KILL, NULL},
5406 {"KN", FUNC_ND, (void *) kn_wrap},
5407 {"LABEL", LABEL, NULL},
5408 {"LANDSCAPE", LANDSCAPE, NULL},
5409 {"LAYOUT", LAYOUT, NULL},
5410 {"LBETA", FUNC_DD, (void *) lbeta},
5411 {"LE", LE, NULL},
5412 {"LEFT", LEFT, NULL},
5413 {"LEGEND", LEGEND, NULL},
5414 {"LENGTH", LENGTH, NULL},
5415 {"LGAMMA", FUNC_D, (void *) lgamma},
5416 {"LINCONV", LINCONV, NULL},
5417 {"LINE", LINE, NULL},
5418 {"LINEAR", LINEAR, NULL},
5419 {"LINESTYLE", LINESTYLE, NULL},
5420 {"LINEWIDTH", LINEWIDTH, NULL},
5421 {"LINK", LINK, NULL},
5422 {"LN", FUNC_D, (void *) log},
5423 {"LOAD", LOAD, NULL},
5424 {"LOCTYPE", LOCTYPE, NULL},
5425 {"LOG", LOG, NULL},
5426 {"LOG10", FUNC_D, (void *) log10},
5427 {"LOG2", FUNC_D, (void *) log2},
5428 {"LOGARITHMIC", LOGARITHMIC, NULL},
5429 {"LOGX", LOGX, NULL},
5430 {"LOGXY", LOGXY, NULL},
5431 {"LOGY", LOGY, NULL},
5432 {"LOGIT", LOGIT, NULL},
5433 {"LT", LT, NULL},
5434 {"MAGIC", MAGIC, NULL},
5435 {"MAGNITUDE", MAGNITUDE, NULL},
5436 {"MAJOR", MAJOR, NULL},
5437 {"MAP", MAP, NULL},
5438 {"MAX", MAXP, NULL},
5439 {"MAXOF", FUNC_DD, (void *) max_wrap},
5440 {"MESH", MESH, NULL},
5441 {"MIN", MINP, NULL},
5442 {"MINOF", FUNC_DD, (void *) min_wrap},
5443 {"MINOR", MINOR, NULL},
5444 {"MMDD", MMDD, NULL},
5445 {"MMDDHMS", MMDDHMS, NULL},
5446 {"MMDDYY", MMDDYY, NULL},
5447 {"MMDDYYHMS", MMDDYYHMS, NULL},
5448 {"MMSSLAT", MMSSLAT, NULL},
5449 {"MMSSLON", MMSSLON, NULL},
5450 {"MMYY", MMYY, NULL},
5451 {"MOD", FUNC_DD, (void *) fmod},
5452 {"MONTHDAY", MONTHDAY, NULL},
5453 {"MONTHL", MONTHL, NULL},
5454 {"MONTHS", MONTHS, NULL},
5455 {"MONTHSY", MONTHSY, NULL},
5456 {"MOVE", MOVE, NULL},
5457 {"NDTR", FUNC_D, (void *) ndtr},
5458 {"NDTRI", FUNC_D, (void *) ndtri},
5459 {"NE", NE, NULL},
5460 {"NEGATE", NEGATE, NULL},
5461 {"NEW", NEW, NULL},
5462 {"NONE", NONE, NULL},
5463 {"NONLFIT", NONLFIT, NULL},
5464 {"NORM", FUNC_D, (void *) fx},
5465 {"NORMAL", NORMAL, NULL},
5466 {"NOT", NOT, NULL},
5467 {"NXY", NXY, NULL},
5468 {"OFF", OFF, NULL},
5469 {"OFFSET", OFFSET, NULL},
5470 {"OFFSETX", OFFSETX, NULL},
5471 {"OFFSETY", OFFSETY, NULL},
5472 {"OFILTER", OFILTER, NULL},
5473 {"ON", ON, NULL},
5474 {"ONREAD", ONREAD, NULL},
5475 {"OP", OP, NULL},
5476 {"OPPOSITE", OPPOSITE, NULL},
5477 {"OR", OR, NULL},
5478 {"OUT", OUT, NULL},
5479 {"PAGE", PAGE, NULL},
5480 {"PARA", PARA, NULL},
5481 {"PARAMETERS", PARAMETERS, NULL},
5482 {"PARZEN", PARZEN, NULL},
5483 {"PATTERN", PATTERN, NULL},
5484 {"PDTR", FUNC_ND, (void *) pdtr},
5485 {"PDTRC", FUNC_ND, (void *) pdtrc},
5486 {"PDTRI", FUNC_ND, (void *) pdtri},
5487 {"PERIOD", PERIOD, NULL},
5488 {"PERP", PERP, NULL},
5489 {"PHASE", PHASE, NULL},
5490 {"PI", CONSTANT, (void *) pi_const},
5491 {"PIE", PIE, NULL},
5492 {"PIPE", PIPE, NULL},
5493 {"PLACE", PLACE, NULL},
5494 {"POINT", POINT, NULL},
5495 {"POLAR", POLAR, NULL},
5496 {"POLYI", POLYI, NULL},
5497 {"POLYO", POLYO, NULL},
5498 {"POP", POP, NULL},
5499 {"PORTRAIT", PORTRAIT, NULL},
5500 {"POWER", POWER, NULL},
5501 {"PREC", PREC, NULL},
5502 {"PREPEND", PREPEND, NULL},
5503 {"PRINT", PRINT, NULL},
5504 {"PS", PS, NULL},
5505 {"PSI", FUNC_D, (void *) psi},
5506 {"PUSH", PUSH, NULL},
5507 {"PUTP", PUTP, NULL},
5508 {"RAD", UCONSTANT, (void *) rad_uconst},
5509 {"RAND", RAND, NULL},
5510 {"READ", READ, NULL},
5511 {"REAL", REAL, NULL},
5512 {"RECIPROCAL", RECIPROCAL, NULL},
5513 {"REDRAW", REDRAW, NULL},
5514 {"REFERENCE", REFERENCE, NULL},
5515 {"REGRESS", REGRESS, NULL},
5516 {"RESIZE", RESIZE, NULL},
5517 {"RESTRICT", RESTRICT, NULL},
5518 {"REVERSE", REVERSE, NULL},
5519 {"RGAMMA", FUNC_D, (void *) rgamma},
5520 {"RIGHT", RIGHT, NULL},
5521 {"RINT", FUNC_D, (void *) rint},
5522 {"RISER", RISER, NULL},
5523 {"RNORM", FUNC_DD, (void *) rnorm},
5524 {"ROT", ROT, NULL},
5525 {"ROUNDED", ROUNDED, NULL},
5526 {"RSUM", RSUM, NULL},
5527 {"RULE", RULE, NULL},
5528 {"RUNAVG", RUNAVG, NULL},
5529 {"RUNMAX", RUNMAX, NULL},
5530 {"RUNMED", RUNMED, NULL},
5531 {"RUNMIN", RUNMIN, NULL},
5532 {"RUNSTD", RUNSTD, NULL},
5533 {"SAVEALL", SAVEALL, NULL},
5534 {"SCALE", SCALE, NULL},
5535 {"SCIENTIFIC", SCIENTIFIC, NULL},
5536 {"SCROLL", SCROLL, NULL},
5537 {"SD", SD, NULL},
5538 {"SET", SET, NULL},
5539 {"SFORMAT", SFORMAT, NULL},
5540 {"SGN", FUNC_D, (void *) sign_wrap},
5541 {"SHI", FUNC_D, (void *) shi_wrap},
5542 {"SI", FUNC_D, (void *) si_wrap},
5543 {"SIGN", SIGN, NULL},
5544 {"SIN", FUNC_D, (void *) sin},
5545 {"SINH", FUNC_D, (void *) sinh},
5546 {"SIZE", SIZE, NULL},
5547 {"SKIP", SKIP, NULL},
5548 {"SLEEP", SLEEP, NULL},
5549 {"SMITH", SMITH, NULL},
5550 {"SORT", SORT, NULL},
5551 {"SOURCE", SOURCE, NULL},
5552 {"SPEC", SPEC, NULL},
5553 {"SPENCE", FUNC_D, (void *) spence},
5554 {"SPLINE", SPLINE, NULL},
5555 {"SPLIT", SPLIT, NULL},
5556 {"SQR", FUNC_D, (void *) sqr_wrap},
5557 {"SQRT", FUNC_D, (void *) sqrt},
5558 {"STACK", STACK, NULL},
5559 {"STACKED", STACKED, NULL},
5560 {"STACKEDBAR", STACKEDBAR, NULL},
5561 {"STACKEDHBAR", STACKEDHBAR, NULL},
5562 {"STAGGER", STAGGER, NULL},
5563 {"START", START, NULL},
5564 {"STDTR", FUNC_ND, (void *) stdtr},
5565 {"STDTRI", FUNC_ND, (void *) stdtri},
5566 {"STOP", STOP, NULL},
5567 {"STRING", STRING, NULL},
5568 {"STRUVE", FUNC_DD, (void *) struve},
5569 {"SUBTITLE", SUBTITLE, NULL},
5570 {"SUM", SUM, NULL},
5571 {"SWAP", SWAP, NULL},
5572 {"SYMBOL", SYMBOL, NULL},
5573 {"TAN", FUNC_D, (void *) tan},
5574 {"TANH", FUNC_D, (void *) tanh},
5575 {"TARGET", TARGET, NULL},
5576 {"TICK", TICKP, NULL},
5577 {"TICKLABEL", TICKLABEL, NULL},
5578 {"TICKS", TICKSP, NULL},
5579 {"TIMER", TIMER, NULL},
5580 {"TIMESTAMP", TIMESTAMP, NULL},
5581 {"TITLE", TITLE, NULL},
5582 {"TO", TO, NULL},
5583 {"TOP", TOP, NULL},
5584 {"TRIANGULAR", TRIANGULAR, NULL},
5585 {"TRUE", ON, NULL},
5586 {"TYPE", TYPE, NULL},
5587 {"UNIT", KEY_UNIT, NULL},
5588 {"UP", UP, NULL},
5589 {"UPDATEALL", UPDATEALL, NULL},
5590 {"USE", USE, NULL},
5591 {"VERSION", VERSION, NULL},
5592 {"VERTI", VERTI, NULL},
5593 {"VERTICAL", VERTICAL, NULL},
5594 {"VERTO", VERTO, NULL},
5595 {"VGAP", VGAP, NULL},
5596 {"VIEW", VIEW, NULL},
5597 {"VOIGT", FUNC_PPD, (void *) voigt},
5598 {"VX1", VX1, NULL},
5599 {"VX2", VX2, NULL},
5600 {"VXMAX", VXMAX, NULL},
5601 {"VY1", VY1, NULL},
5602 {"VY2", VY2, NULL},
5603 {"VYMAX", VYMAX, NULL},
5604 {"WELCH", WELCH, NULL},
5605 {"WITH", WITH, NULL},
5606 {"WORLD", WORLD, NULL},
5607 {"WRAP", WRAP, NULL},
5608 {"WRITE", WRITE, NULL},
5609 {"WX1", WX1, NULL},
5610 {"WX2", WX2, NULL},
5611 {"WY1", WY1, NULL},
5612 {"WY2", WY2, NULL},
5613 {"X", X_TOK, NULL},
5614 {"X0", X0, NULL},
5615 {"X1", X1, NULL},
5616 {"XAXES", XAXES, NULL},
5617 {"XAXIS", XAXIS, NULL},
5618 {"XCOR", XCOR, NULL},
5619 {"XMAX", XMAX, NULL},
5620 {"XMIN", XMIN, NULL},
5621 {"XY", XY, NULL},
5622 {"XYAXES", XYAXES, NULL},
5623 {"XYBOXPLOT", XYBOXPLOT, NULL},
5624 {"XYCOLOR", XYCOLOR, NULL},
5625 {"XYCOLPAT", XYCOLPAT, NULL},
5626 {"XYDX", XYDX, NULL},
5627 {"XYDXDX", XYDXDX, NULL},
5628 {"XYDXDXDYDY", XYDXDXDYDY, NULL},
5629 {"XYDXDY", XYDXDY, NULL},
5630 {"XYDY", XYDY, NULL},
5631 {"XYDYDY", XYDYDY, NULL},
5632 {"XYHILO", XYHILO, NULL},
5633 {"XYR", XYR, NULL},
5634 {"XYSIZE", XYSIZE, NULL},
5635 {"XYSTRING", XYSTRING, NULL},
5636 {"XYVMAP", XYVMAP, NULL},
5637 {"XYZ", XYZ, NULL},
5638 {"Y", Y_TOK, NULL},
5639 {"Y0", Y0, NULL},
5640 {"Y1", Y1, NULL},
5641 {"Y2", Y2, NULL},
5642 {"Y3", Y3, NULL},
5643 {"Y4", Y4, NULL},
5644 {"YAXES", YAXES, NULL},
5645 {"YAXIS", YAXIS, NULL},
5646 {"YEAR", YEAR, NULL},
5647 {"YMAX", YMAX, NULL},
5648 {"YMIN", YMIN, NULL},
5649 {"YV", FUNC_DD, (void *) yv_wrap},
5650 {"YYMMDD", YYMMDD, NULL},
5651 {"YYMMDDHMS", YYMMDDHMS, NULL},
5652 {"ZERO", ZERO, NULL},
5653 {"ZEROXAXIS", ALTXAXIS, NULL},
5654 {"ZEROYAXIS", ALTYAXIS, NULL},
5655 {"ZETA", FUNC_DD, (void *) zeta},
5656 {"ZETAC", FUNC_D, (void *) zetac},
5657 {"ZNORM", ZNORM, NULL}
5658 };
5659
5660 static int maxfunc = sizeof(ikey) / sizeof(symtab_entry);
5661
get_parser_gno(void)5662 int get_parser_gno(void)
5663 {
5664 return whichgraph;
5665 }
5666
set_parser_gno(int gno)5667 int set_parser_gno(int gno)
5668 {
5669 if (is_valid_gno(gno) == TRUE) {
5670 whichgraph = gno;
5671 return RETURN_SUCCESS;
5672 } else {
5673 return RETURN_FAILURE;
5674 }
5675 }
5676
get_parser_setno(void)5677 int get_parser_setno(void)
5678 {
5679 return whichset;
5680 }
5681
set_parser_setno(int gno,int setno)5682 int set_parser_setno(int gno, int setno)
5683 {
5684 if (is_valid_setno(gno, setno) == TRUE) {
5685 whichgraph = gno;
5686 whichset = setno;
5687 /* those will usually be overridden except when evaluating
5688 a _standalone_ vexpr */
5689 vasgn_gno = gno;
5690 vasgn_setno = setno;
5691 return RETURN_SUCCESS;
5692 } else {
5693 return RETURN_FAILURE;
5694 }
5695 }
5696
realloc_vrbl(grarr * vrbl,int len)5697 void realloc_vrbl(grarr *vrbl, int len)
5698 {
5699 double *a;
5700 int i, oldlen;
5701
5702 if (vrbl->type != GRARR_VEC) {
5703 errmsg("Internal error");
5704 return;
5705 }
5706 oldlen = vrbl->length;
5707 if (oldlen == len) {
5708 return;
5709 } else {
5710 a = xrealloc(vrbl->data, len*SIZEOF_DOUBLE);
5711 if (a != NULL || len == 0) {
5712 vrbl->data = a;
5713 vrbl->length = len;
5714 for (i = oldlen; i < len; i++) {
5715 vrbl->data[i] = 0.0;
5716 }
5717 } else {
5718 errmsg("Malloc failed in realloc_vrbl()");
5719 }
5720 }
5721 }
5722
5723
5724 #define PARSER_TYPE_VOID 0
5725 #define PARSER_TYPE_EXPR 1
5726 #define PARSER_TYPE_VEXPR 2
5727
parser(char * s,int type)5728 static int parser(char *s, int type)
5729 {
5730 char *seekpos;
5731 int i;
5732
5733 if (s == NULL || s[0] == '\0') {
5734 if (type == PARSER_TYPE_VOID) {
5735 /* don't consider an empty string as error for generic parser */
5736 return RETURN_SUCCESS;
5737 } else {
5738 return RETURN_FAILURE;
5739 }
5740 }
5741
5742 strncpy(f_string, s, MAX_PARS_STRING_LENGTH - 2);
5743 f_string[MAX_PARS_STRING_LENGTH - 2] = '\0';
5744 strcat(f_string, " ");
5745
5746 seekpos = f_string;
5747
5748 while ((seekpos - f_string < MAX_PARS_STRING_LENGTH - 1) && (*seekpos == ' ' || *seekpos == '\t')) {
5749 seekpos++;
5750 }
5751 if (*seekpos == '\n' || *seekpos == '#') {
5752 if (type == PARSER_TYPE_VOID) {
5753 /* don't consider an empty string as error for generic parser */
5754 return RETURN_SUCCESS;
5755 } else {
5756 return RETURN_FAILURE;
5757 }
5758 }
5759
5760 lowtoupper(f_string);
5761
5762 pos = 0;
5763 interr = 0;
5764 expr_parsed = FALSE;
5765 vexpr_parsed = FALSE;
5766
5767 yyparse();
5768
5769 /* free temp. arrays; for a vector expression keep the last one
5770 * (which is none but v_result), given there have been no errors
5771 * and it's what we've been asked for
5772 */
5773 if (vexpr_parsed && !interr && type == PARSER_TYPE_VEXPR) {
5774 for (i = 0; i < fcnt - 1; i++) {
5775 free_tmpvrbl(&(freelist[i]));
5776 }
5777 } else {
5778 for (i = 0; i < fcnt; i++) {
5779 free_tmpvrbl(&(freelist[i]));
5780 }
5781 }
5782 fcnt = 0;
5783
5784 tgtn = 0;
5785
5786 if ((type == PARSER_TYPE_VEXPR && !vexpr_parsed) ||
5787 (type == PARSER_TYPE_EXPR && !expr_parsed)) {
5788 return RETURN_FAILURE;
5789 } else {
5790 return (interr ? RETURN_FAILURE:RETURN_SUCCESS);
5791 }
5792 }
5793
s_scanner(char * s,double * res)5794 int s_scanner(char *s, double *res)
5795 {
5796 int retval = parser(s, PARSER_TYPE_EXPR);
5797 *res = s_result;
5798 return retval;
5799 }
5800
v_scanner(char * s,int * reslen,double ** vres)5801 int v_scanner(char *s, int *reslen, double **vres)
5802 {
5803 int retval = parser(s, PARSER_TYPE_VEXPR);
5804 if (retval != RETURN_SUCCESS) {
5805 return RETURN_FAILURE;
5806 } else {
5807 *reslen = v_result->length;
5808 if (v_result->type == GRARR_TMP) {
5809 *vres = v_result->data;
5810 v_result->length = 0;
5811 v_result->data = NULL;
5812 } else {
5813 *vres = copy_data_column(v_result->data, v_result->length);
5814 }
5815 return RETURN_SUCCESS;
5816 }
5817 }
5818
scanner(char * s)5819 int scanner(char *s)
5820 {
5821 int retval = parser(s, PARSER_TYPE_VOID);
5822 if (retval != RETURN_SUCCESS) {
5823 return RETURN_FAILURE;
5824 }
5825
5826 if (gotparams) {
5827 gotparams = FALSE;
5828 getparms(paramfile);
5829 }
5830
5831 if (gotread) {
5832 gotread = FALSE;
5833 getdata(whichgraph, readfile, cursource, LOAD_SINGLE);
5834 }
5835
5836 if (gotnlfit) {
5837 gotnlfit = FALSE;
5838 do_nonlfit(nlfit_gno, nlfit_setno, nlfit_warray, NULL, nlfit_nsteps);
5839 XCFREE(nlfit_warray);
5840 }
5841 return retval;
5842 }
5843
free_tmpvrbl(grarr * vrbl)5844 static void free_tmpvrbl(grarr *vrbl)
5845 {
5846 if (vrbl->type == GRARR_TMP) {
5847 vrbl->length = 0;
5848 XCFREE(vrbl->data);
5849 }
5850 }
5851
copy_vrbl(grarr * dest,grarr * src)5852 static void copy_vrbl(grarr *dest, grarr *src)
5853 {
5854 dest->type = src->type;
5855 dest->data = xmalloc(src->length*SIZEOF_DOUBLE);
5856 if (dest->data == NULL) {
5857 errmsg("Malloc failed in copy_vrbl()");
5858 } else {
5859 memcpy(dest->data, src->data, src->length*SIZEOF_DOUBLE);
5860 dest->length = src->length;
5861 }
5862 }
5863
get_parser_arr_by_name(char * const name)5864 grarr *get_parser_arr_by_name(char * const name)
5865 {
5866 int position;
5867 char *s;
5868
5869 s = copy_string(NULL, name);
5870 lowtoupper(s);
5871
5872 position = findf(key, s);
5873 xfree(s);
5874
5875 if (position >= 0) {
5876 if (key[position].type == KEY_VEC) {
5877 return (grarr *) key[position].data;
5878 }
5879 }
5880
5881 return NULL;
5882 }
5883
define_parser_arr(char * const name)5884 grarr *define_parser_arr(char * const name)
5885 {
5886 if (get_parser_arr_by_name(name) == NULL) {
5887 symtab_entry tmpkey;
5888 grarr *var;
5889
5890 var = xmalloc(sizeof(grarr));
5891 var->type = GRARR_VEC;
5892 var->length = 0;
5893 var->data = NULL;
5894
5895 tmpkey.s = name;
5896 tmpkey.type = KEY_VEC;
5897 tmpkey.data = (void *) var;
5898 if (addto_symtab(tmpkey) == RETURN_SUCCESS) {
5899 return var;
5900 } else {
5901 return NULL;
5902 }
5903 } else {
5904 return NULL;
5905 }
5906 }
5907
undefine_parser_var(void * ptr)5908 int undefine_parser_var(void *ptr)
5909 {
5910 int i;
5911
5912 for (i = 0; i < maxfunc; i++) {
5913 if (key[i].data == ptr) {
5914 xfree(key[i].s);
5915 maxfunc--;
5916 if (i != maxfunc) {
5917 memmove(&(key[i]), &(key[i + 1]), (maxfunc - i)*sizeof(symtab_entry));
5918 }
5919 key = xrealloc(key, maxfunc*sizeof(symtab_entry));
5920 return RETURN_SUCCESS;
5921 }
5922 }
5923 return RETURN_FAILURE;
5924 }
5925
find_set_bydata(double * data,target * tgt)5926 static int find_set_bydata(double *data, target *tgt)
5927 {
5928 int gno, setno, ncol;
5929
5930 if (data == NULL) {
5931 return RETURN_FAILURE;
5932 } else {
5933 for (gno = 0; gno < number_of_graphs(); gno++) {
5934 for (setno = 0; setno < number_of_sets(gno); setno++) {
5935 for (ncol = 0; ncol < MAX_SET_COLS; ncol++) {
5936 if (getcol(gno, setno, ncol) == data) {
5937 tgt->gno = gno;
5938 tgt->setno = setno;
5939 return RETURN_SUCCESS;
5940 }
5941 }
5942 }
5943 }
5944 }
5945 return RETURN_FAILURE;
5946 }
5947
findf(symtab_entry * keytable,char * s)5948 static int findf(symtab_entry *keytable, char *s)
5949 {
5950
5951 int low, high, mid;
5952
5953 low = 0;
5954 high = maxfunc - 1;
5955 while (low <= high) {
5956 mid = (low + high) / 2;
5957 if (strcmp(s, keytable[mid].s) < 0) {
5958 high = mid - 1;
5959 } else {
5960 if (strcmp(s, keytable[mid].s) > 0) {
5961 low = mid + 1;
5962 } else {
5963 return (mid);
5964 }
5965 }
5966 }
5967 return (-1);
5968 }
5969
compare_keys(const void * a,const void * b)5970 static int compare_keys (const void *a, const void *b)
5971 {
5972 return (int) strcmp (((const symtab_entry*)a)->s,
5973 ((const symtab_entry*)b)->s);
5974 }
5975
5976 /* add new entry to the symbol table */
addto_symtab(symtab_entry newkey)5977 int addto_symtab(symtab_entry newkey)
5978 {
5979 int position;
5980 char *s;
5981
5982 s = copy_string(NULL, newkey.s);
5983 lowtoupper(s);
5984 if ((position = findf(key, s)) < 0) {
5985 if ((key = (symtab_entry *) xrealloc(key, (maxfunc + 1)*sizeof(symtab_entry))) != NULL) {
5986 key[maxfunc].type = newkey.type;
5987 key[maxfunc].data = newkey.data;
5988 key[maxfunc].s = s;
5989 maxfunc++;
5990 qsort(key, maxfunc, sizeof(symtab_entry), compare_keys);
5991 return RETURN_SUCCESS;
5992 } else {
5993 xfree(s);
5994 return RETURN_FAILURE;
5995 }
5996 } else if (alias_force == TRUE) { /* already exists but alias_force enabled */
5997 key[position].type = newkey.type;
5998 key[position].data = newkey.data;
5999 return RETURN_SUCCESS;
6000 } else {
6001 xfree(s);
6002 return RETURN_FAILURE;
6003 }
6004 }
6005
6006 /* initialize symbol table */
init_symtab(void)6007 void init_symtab(void)
6008 {
6009 int i;
6010
6011 if ((key = (symtab_entry *) xmalloc(maxfunc*sizeof(symtab_entry))) != NULL) {
6012 memcpy (key, ikey, maxfunc*sizeof(symtab_entry));
6013 for (i = 0; i < maxfunc; i++) {
6014 key[i].s = xmalloc(strlen(ikey[i].s) + 1);
6015 strcpy(key[i].s, ikey[i].s);
6016 }
6017 qsort(key, maxfunc, sizeof(symtab_entry), compare_keys);
6018 return;
6019 } else {
6020 key = ikey;
6021 return;
6022 }
6023 }
6024
getcharstr(void)6025 static int getcharstr(void)
6026 {
6027 if (pos >= strlen(f_string))
6028 return EOF;
6029 return (f_string[pos++]);
6030 }
6031
ungetchstr(void)6032 static void ungetchstr(void)
6033 {
6034 if (pos > 0)
6035 pos--;
6036 }
6037
yylex(void)6038 static int yylex(void)
6039 {
6040 int c, i;
6041 int found;
6042 char sbuf[MAX_PARS_STRING_LENGTH + 40];
6043
6044 while ((c = getcharstr()) == ' ' || c == '\t');
6045 if (c == EOF) {
6046 return (0);
6047 }
6048 if (c == '"') {
6049 i = 0;
6050 while ((c = getcharstr()) != '"' && c != EOF) {
6051 if (c == '\\') {
6052 int ctmp;
6053 ctmp = getcharstr();
6054 if (ctmp != '"') {
6055 ungetchstr();
6056 }
6057 else {
6058 c = ctmp;
6059 }
6060 }
6061 sbuf[i] = c;
6062 i++;
6063 }
6064 if (c == EOF) {
6065 yyerror("Nonterminating string");
6066 return 0;
6067 }
6068 sbuf[i] = '\0';
6069 yylval.sval = copy_string(NULL, sbuf);
6070 return CHRSTR;
6071 }
6072 if (c == '.' || isdigit(c)) {
6073 double d;
6074 int i, gotdot = 0;
6075
6076 i = 0;
6077 while (c == '.' || isdigit(c)) {
6078 if (c == '.') {
6079 if (gotdot) {
6080 yyerror("Reading number, too many dots");
6081 return 0;
6082 } else {
6083 gotdot = 1;
6084 }
6085 }
6086 sbuf[i++] = c;
6087 c = getcharstr();
6088 }
6089 if (c == 'E' || c == 'e') {
6090 sbuf[i++] = c;
6091 c = getcharstr();
6092 if (c == '+' || c == '-') {
6093 sbuf[i++] = c;
6094 c = getcharstr();
6095 }
6096 while (isdigit(c)) {
6097 sbuf[i++] = c;
6098 c = getcharstr();
6099 }
6100 }
6101 if (gotdot && i == 1) {
6102 ungetchstr();
6103 return '.';
6104 }
6105 sbuf[i] = '\0';
6106 ungetchstr();
6107 sscanf(sbuf, "%lf", &d);
6108 yylval.dval = d;
6109 return NUMBER;
6110 }
6111 /* graphs, sets, regions resp. */
6112 if (c == 'G' || c == 'S' || c == 'R') {
6113 int i = 0, ctmp = c, gn, sn, rn;
6114 c = getcharstr();
6115 while (isdigit(c) || c == '$' || c == '_') {
6116 sbuf[i++] = c;
6117 c = getcharstr();
6118 }
6119 if (i == 0) {
6120 c = ctmp;
6121 ungetchstr();
6122 } else {
6123 ungetchstr();
6124 if (ctmp == 'G') {
6125 sbuf[i] = '\0';
6126 if (i == 1 && sbuf[0] == '_') {
6127 gn = get_recent_gno();
6128 } else if (i == 1 && sbuf[0] == '$') {
6129 gn = whichgraph;
6130 } else {
6131 gn = atoi(sbuf);
6132 }
6133 if (is_valid_gno(gn) || graph_allocate(gn) == RETURN_SUCCESS) {
6134 yylval.ival = gn;
6135 return GRAPHNO;
6136 }
6137 } else if (ctmp == 'S') {
6138 sbuf[i] = '\0';
6139 if (i == 1 && sbuf[0] == '_') {
6140 sn = get_recent_setno();
6141 } else if (i == 1 && sbuf[0] == '$') {
6142 sn = whichset;
6143 } else {
6144 sn = atoi(sbuf);
6145 }
6146 yylval.ival = sn;
6147 return SETNUM;
6148 } else if (ctmp == 'R') {
6149 sbuf[i] = '\0';
6150 rn = atoi(sbuf);
6151 if (rn >= 0 && rn < MAXREGION) {
6152 yylval.ival = rn;
6153 return REGNUM;
6154 } else {
6155 errmsg("Invalid region number");
6156 }
6157 }
6158 }
6159 }
6160 if (isalpha(c) || c == '$') {
6161 char *p = sbuf;
6162
6163 do {
6164 *p++ = c;
6165 } while ((c = getcharstr()) != EOF && (isalpha(c) || isdigit(c) ||
6166 c == '_' || c == '$'));
6167 ungetchstr();
6168 *p = '\0';
6169 #ifdef DEBUG
6170 if (get_debuglevel() == 2) {
6171 printf("->%s<-\n", sbuf);
6172 }
6173 #endif
6174 found = -1;
6175 if ((found = findf(key, sbuf)) >= 0) {
6176 if (key[found].type == FITPARM) {
6177 int index = sbuf[1] - '0';
6178 yylval.ival = index;
6179 return FITPARM;
6180 }
6181 else if (key[found].type == FITPMAX) {
6182 int index = sbuf[1] - '0';
6183 yylval.ival = index;
6184 return FITPMAX;
6185 }
6186 else if (key[found].type == FITPMIN) {
6187 int index = sbuf[1] - '0';
6188 yylval.ival = index;
6189 return FITPMIN;
6190 }
6191
6192 else if (key[found].type == KEY_VAR) {
6193 yylval.dptr = (double *) key[found].data;
6194 return VAR_D;
6195 }
6196 else if (key[found].type == KEY_VEC) {
6197 yylval.vrbl = (grarr *) key[found].data;
6198 return VEC_D;
6199 }
6200
6201 else if (key[found].type == FUNC_I) {
6202 yylval.ival = found;
6203 return FUNC_I;
6204 }
6205 else if (key[found].type == CONSTANT) {
6206 yylval.ival = found;
6207 return CONSTANT;
6208 }
6209 else if (key[found].type == UCONSTANT) {
6210 yylval.ival = found;
6211 return UCONSTANT;
6212 }
6213 else if (key[found].type == FUNC_D) {
6214 yylval.ival = found;
6215 return FUNC_D;
6216 }
6217 else if (key[found].type == FUNC_ND) {
6218 yylval.ival = found;
6219 return FUNC_ND;
6220 }
6221 else if (key[found].type == FUNC_DD) {
6222 yylval.ival = found;
6223 return FUNC_DD;
6224 }
6225 else if (key[found].type == FUNC_NND) {
6226 yylval.ival = found;
6227 return FUNC_NND;
6228 }
6229 else if (key[found].type == FUNC_PPD) {
6230 yylval.ival = found;
6231 return FUNC_PPD;
6232 }
6233 else if (key[found].type == FUNC_PPPD) {
6234 yylval.ival = found;
6235 return FUNC_PPPD;
6236 }
6237 else if (key[found].type == FUNC_PPPPD) {
6238 yylval.ival = found;
6239 return FUNC_PPPPD;
6240 }
6241 else if (key[found].type == FUNC_PPPPPD) {
6242 yylval.ival = found;
6243 return FUNC_PPPPPD;
6244 }
6245 else {
6246 yylval.ival = key[found].type;
6247 return key[found].type;
6248 }
6249 } else {
6250 yylval.sval = copy_string(NULL, sbuf);
6251 return NEW_TOKEN;
6252 }
6253 }
6254 switch (c) {
6255 case '>':
6256 return follow('=', GE, GT);
6257 case '<':
6258 return follow('=', LE, LT);
6259 case '=':
6260 return follow('=', EQ, '=');
6261 case '!':
6262 return follow('=', NE, NOT);
6263 case '|':
6264 return follow('|', OR, '|');
6265 case '&':
6266 return follow('&', AND, '&');
6267 case '\n':
6268 return '\n';
6269 default:
6270 return c;
6271 }
6272 }
6273
follow(int expect,int ifyes,int ifno)6274 static int follow(int expect, int ifyes, int ifno)
6275 {
6276 int c = getcharstr();
6277
6278 if (c == expect) {
6279 return ifyes;
6280 }
6281 ungetchstr();
6282 return ifno;
6283 }
6284
yyerror(char * s)6285 static void yyerror(char *s)
6286 {
6287 char *buf;
6288
6289 buf = copy_string(NULL, s);
6290 buf = concat_strings(buf, ": ");
6291 buf = concat_strings(buf, f_string);
6292 errmsg(buf);
6293 xfree(buf);
6294 interr = 1;
6295 }
6296