1 /*  Copyright (C) 1988-2005 by Brian Doty and the Institute
2                   of Global Environment and Society (IGES).
3 
4     See file COPYRIGHT for more information.   */
5 
6 #define RSIZ 600
7 /* One of these gets allocated for each record in the file */
8 
9 /* Record types:
10                   1 - statement
11                   2 - assignment
12                   3 - while
13                   4 - endwhile
14                   5 - continue
15                   6 - break
16                   7 - if
17                   8 - else
18                   9 - endif
19                   10 - return
20                   11 - function  */
21 
22 struct gsrecd {
23   struct gsrecd *forw;  /* Link list pointer */
24   struct gsrecd *refer; /* Position of end of code block */
25   struct gsfdef *pfdf;  /* Pointer to file def for this record */
26   char *pos;            /* Start of record */
27   char *epos;           /* Position of start of expression, if any */
28   int num;              /* Record number in file */
29   int type;             /* Record type */
30 };
31 
32 /* Following structure describes a file that has been read in
33    to become part of the running script.  */
34 
35 struct gsfdef {
36   struct gsfdef *forw;  /* Link list pointer */
37   struct gsrecd *precd; /* Record descriptor for start of this file */
38   char *name;           /* Text name of the file  */
39   char *file;           /* The contents of the file */
40 };
41 
42 /* Following structure is a member of a link list providing the
43    current value of a variable.    */
44 
45 struct gsvar {
46   struct gsvar *forw;      /* Forward pointer             */
47   char name[16];           /* Variable name               */
48   char *strng;             /* Value of variable           */
49 };
50 
51 /* Following structure is a member of a link list pointing to
52    all the functions contained within a file.  */
53 
54 struct gsfnc {
55   struct gsfnc *forw;      /* Forward pointer */
56   struct gsrecd *recd;     /* Record block for function   */
57   char name[16];           /* Name of function            */
58 };
59 
60 /* Following structure hold information on open files
61    accessed via the read/write/close user callable functions */
62 
63 struct gsiob {
64   struct gsiob *forw;      /* Forward pointer  */
65   FILE *file;              /* File pointer     */
66   char *name;              /* File name        */
67   int flag;                /* Status flag: 1-read 2-write  */
68 };
69 
70 /* Following structure holds global pointers needed by all the
71    gs routines, and anchors most global memory allocations */
72 
73 struct gscmn {
74   struct gsfdef *ffdef;    /* Head of input file link list */
75   struct gsfdef *lfdef;    /* Last in chain of input files */
76   struct gsrecd *frecd;    /* Head of record descriptor link list */
77   struct gsrecd *lrecd;    /* Last in record list list */
78   struct gsvar *fvar;      /* Head of variable linklist   */
79   struct gsfnc *ffnc;      /* Head of function list       */
80   struct gsiob *iob;       /* Head of file I/O list       */
81   struct gsvar *gvar;      /* Head of global var list     */
82   struct gsvar *farg;      /* Pointer to function arglist */
83   char *fname;             /* Pointer to user-entered file name   */
84   char *fprefix;           /* File name prefix for loading functions */
85   char *ppath;             /* Private path for gsf loads */
86   char *rres;              /* Pointer to function result  */
87   char *gsfnm;             /* Most recent file name read in */
88   int gsfflg;              /* Dynamic load script functions from files */
89   int rc;                  /* Exit value                  */
90 };
91 
92 /* Operator codes:  ordered by precedence
93 
94                     1: |   logical or
95                     2: &   logical and
96                     3: =   equality
97                     4: !=  not equal
98                     5: >   greater than
99                     6: >=  greater than or equal
100                     7: <   less than
101                     8: <=  less than or equal
102                     9: %   concatenation
103                    10: +   addition
104                    11: -   subtraction
105                    12: *   multiplication
106                    13: /   division
107                    14: !   unary not
108                    15: -   unary minus                        */
109 
110 char *opchars[13] = {"!=",">=","<=","|","&","=",">","<","%",
111        "+","-","*","/"};
112 int opvals[13] = {4,6,8,1,2,3,5,7,9,10,11,12,13};
113 int optyps[15] = {0,0,1,1,1,1,1,1,0,2,2,2,2,0,2};
114 int opmins[7] = {14,12,10,9,3,2,1};
115 int opmaxs[7] = {15,13,11,9,8,2,1};
116 
117 /* Stack to evaluate the expression.  The stack consists of an
118    doubly linked list of structures.                              */
119 
120 struct stck {
121   struct stck *pforw;               /* Forward Pointer  */
122   struct stck *pback;               /* Backwards Pointer */
123   int type;        /* Entry type: 0=oprnd,1=oprtr,2='(',3=')'        */
124   union tobj {
125     int op;                         /* Operator */
126     char *strng;                    /* Operand  */
127   } obj;
128 };
129 
130 /* Function prototypes */
131 
132 void gsfree (struct gscmn *);
133 struct gsrecd *gsrtyp (char **, int *, int *);
134 int gsblck (struct gsrecd *, struct gscmn *);
135 struct gsrecd *gsbkst (struct gsrecd *, struct gsrecd *,
136      struct gsrecd *, int *);
137 struct gsrecd *gsbkdo (struct gsrecd *, struct gsrecd *,
138      struct gsrecd *, int *);
139 struct gsrecd *gsbkif (struct gsrecd *, struct gsrecd *,
140      struct gsrecd *, int *);
141 int gsrunf (struct gsrecd *, struct gscmn *);
142 void gsfrev (struct gsvar *);
143 struct gsrecd *gsruns (struct gsrecd *, struct gscmn *, int *);
144 struct gsrecd *gsrund (struct gsrecd *, struct gscmn *, int *);
145 struct gsrecd *gsruni (struct gsrecd *, struct gscmn *, int *);
146 int gsstmn (struct gsrecd *, struct gscmn *);
147 int gsassn (struct gsrecd *, struct gscmn *);
148 char *gsexpr (char *, struct gscmn *);
149 struct stck *gseval (struct stck *);
150 char *gscnst (char **);
151 char *gsgopd (char **, struct gscmn *);
152 char *gsfunc (char *, char *, struct gscmn *);
153 char *gsfvar (char *, struct gscmn *);
154 int gsrvar (struct gscmn *, char *, char *);
155 void stkdmp (struct stck *);
156 void gsnum (char *, int *, int *, double *);
157 struct stck *gsoper (struct stck *);
158 
159 /* Functions for searching and reading script files */
160 
161 int gsgsfrd (struct gscmn *, int, char *);
162 FILE *gsonam (struct gscmn *, struct gsfdef *);
163 FILE *gsogsf(struct gscmn *, struct gsfdef *, char *);
164 char *gsstcp (char *);
165 int gsdelim (char);
166 char *gsstad (char *, char *);
167 
168 /* script functions */
169 
170 int gsfsub (struct gscmn *);
171 int gsfwrd (struct gscmn *);
172 int gsflin (struct gscmn *);
173 int gsfpwd (struct gscmn *);
174 int gsfrd (struct gscmn *);
175 int gsfwt (struct gscmn *);
176 int gsfcl (struct gscmn *);
177 int gsfval (struct gscmn *);
178 int gsfsln (struct gscmn *);
179 int gsflog (struct gscmn *, int);
180