~ubuntu-branches/ubuntu/karmic/grace/karmic

« back to all changes in this revision

Viewing changes to src/pars.yacc

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2002-03-19 14:19:58 UTC
  • Revision ID: james.westby@ubuntu.com-20020319141958-5gxna6vo1ek3zjml
Tags: upstream-5.1.7
ImportĀ upstreamĀ versionĀ 5.1.7

Show diffs side-by-side

added added

removed removed

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