master xplshn/aruu / cmd / posix / awk / parse.c
  1/* ***************************************************************
  2 * copyright (c) lucent technologies 1997
  3 * all rights reserved
  4 *
  5 * permission to use, copy, modify, and distribute this software and
  6 * its documentation for any purpose and without fee is hereby
  7 * granted, provided that the above copyright notice appear in all
  8 * copies and that both that the copyright notice and this
  9 * permission notice and warranty disclaimer appear in supporting
 10 * documentation, and that the name lucent technologies or any of
 11 * its entities not be used in advertising or publicity pertaining
 12 * to distribution of the software without specific, written prior
 13 * permission
 14 *
 15 * LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 17 * IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
 18 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 20 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 21 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
 22 * THIS SOFTWARE
 23 * ************************************************************** */
 24
 25#define DEBUG
 26#include "awk.h"
 27#include "awkgram.tab.h"
 28#include <stdio.h>
 29#include <stdlib.h>
 30#include <string.h>
 31
 32Node *
 33nodealloc(size_t n)
 34{
 35  Node *x;
 36
 37  x = (Node *)malloc(sizeof(*x) + (n - 1) * sizeof(x));
 38  if (x == NULL)
 39    FATAL("out of space in nodealloc");
 40  x->nnext  = NULL;
 41  x->lineno = lineno;
 42  return (x);
 43}
 44
 45Node *
 46exptostat(Node *a)
 47{
 48  a->ntype = NSTAT;
 49  return (a);
 50}
 51
 52Node *
 53node1(int a, Node *b)
 54{
 55  Node *x;
 56
 57  x          = nodealloc(1);
 58  x->nobj    = a;
 59  x->narg[0] = b;
 60  return (x);
 61}
 62
 63Node *
 64node2(int a, Node *b, Node *c)
 65{
 66  Node *x;
 67
 68  x          = nodealloc(2);
 69  x->nobj    = a;
 70  x->narg[0] = b;
 71  x->narg[1] = c;
 72  return (x);
 73}
 74
 75Node *
 76node3(int a, Node *b, Node *c, Node *d)
 77{
 78  Node *x;
 79
 80  x          = nodealloc(3);
 81  x->nobj    = a;
 82  x->narg[0] = b;
 83  x->narg[1] = c;
 84  x->narg[2] = d;
 85  return (x);
 86}
 87
 88Node *
 89node4(int a, Node *b, Node *c, Node *d, Node *e)
 90{
 91  Node *x;
 92
 93  x          = nodealloc(4);
 94  x->nobj    = a;
 95  x->narg[0] = b;
 96  x->narg[1] = c;
 97  x->narg[2] = d;
 98  x->narg[3] = e;
 99  return (x);
100}
101
102Node *
103stat1(int a, Node *b)
104{
105  Node *x;
106
107  x        = node1(a, b);
108  x->ntype = NSTAT;
109  return (x);
110}
111
112Node *
113stat2(int a, Node *b, Node *c)
114{
115  Node *x;
116
117  x        = node2(a, b, c);
118  x->ntype = NSTAT;
119  return (x);
120}
121
122Node *
123stat3(int a, Node *b, Node *c, Node *d)
124{
125  Node *x;
126
127  x        = node3(a, b, c, d);
128  x->ntype = NSTAT;
129  return (x);
130}
131
132Node *
133stat4(int a, Node *b, Node *c, Node *d, Node *e)
134{
135  Node *x;
136
137  x        = node4(a, b, c, d, e);
138  x->ntype = NSTAT;
139  return (x);
140}
141
142Node *
143op1(int a, Node *b)
144{
145  Node *x;
146
147  x        = node1(a, b);
148  x->ntype = NEXPR;
149  return (x);
150}
151
152Node *
153op2(int a, Node *b, Node *c)
154{
155  Node *x;
156
157  x        = node2(a, b, c);
158  x->ntype = NEXPR;
159  return (x);
160}
161
162Node *
163op3(int a, Node *b, Node *c, Node *d)
164{
165  Node *x;
166
167  x        = node3(a, b, c, d);
168  x->ntype = NEXPR;
169  return (x);
170}
171
172Node *
173op4(int a, Node *b, Node *c, Node *d, Node *e)
174{
175  Node *x;
176
177  x        = node4(a, b, c, d, e);
178  x->ntype = NEXPR;
179  return (x);
180}
181
182Node *
183celltonode(Cell *a, int b)
184{
185  Node *x;
186
187  a->ctype = OCELL;
188  a->csub  = b;
189  x        = node1(0, (Node *)a);
190  x->ntype = NVALUE;
191  return (x);
192}
193
194Node *
195rectonode(void) /* make $0 into a node */
196{
197  extern Cell *literal0;
198  return op1(INDIRECT, celltonode(literal0, CUNK));
199}
200
201Node *
202makearr(Node *p)
203{
204  Cell *cp;
205
206  if (isvalue(p)) {
207    cp = (Cell *)(p->narg[0]);
208    if (isfcn(cp))
209      SYNTAX("%s is a function, not an array", cp->nval);
210    else if (!isarr(cp)) {
211      xfree(cp->sval);
212      cp->sval = (char *)makesymtab(NSYMTAB);
213      cp->tval = ARR;
214    }
215  }
216  return p;
217}
218
219#define PA2NUM 50      /* max number of pat,pat patterns allowed */
220int paircnt;           /* number of them in use */
221int pairstack[PA2NUM]; /* state of each pat,pat */
222
223Node *
224pa2stat(Node *a, Node *b, Node *c) /* pat, pat {...} */
225{
226  Node *x;
227
228  x = node4(PASTAT2, a, b, c, itonp(paircnt));
229  if (paircnt++ >= PA2NUM)
230    SYNTAX("limited to %d pat,pat statements", PA2NUM);
231  x->ntype = NSTAT;
232  return (x);
233}
234
235Node *
236linkum(Node *a, Node *b)
237{
238  Node *c;
239
240  if (errorflag) /* dont link things that are wrong */
241    return a;
242  if (a == NULL)
243    return (b);
244  else if (b == NULL)
245    return (a);
246  for (c = a; c->nnext != NULL; c = c->nnext)
247    ;
248  c->nnext = b;
249  return (a);
250}
251
252void
253defn(Cell *v, Node *vl, Node *st) /* turn on FCN bit in definition, */
254{                                 /* body of function, arglist */
255  Node *p;
256  int   n;
257
258  if (isarr(v)) {
259    SYNTAX("`%s' is an array name and a function name", v->nval);
260    return;
261  }
262  if (isarg(v->nval) != -1) {
263    SYNTAX("`%s' is both function name and argument name", v->nval);
264    return;
265  }
266
267  v->tval = FCN;
268  v->sval = (char *)st;
269  n       = 0; /* count arguments */
270  for (p = vl; p; p = p->nnext)
271    n++;
272  v->fval = n;
273  DPRINTF("defining func %s (%d args)\n", v->nval, n);
274}
275
276int
277isarg(const char *s) /* is s in argument list for current function? */
278{                    /* return -1 if not, otherwise arg # */
279  extern Node *arglist;
280  Node        *p = arglist;
281  int          n;
282
283  for (n = 0; p != NULL; p = p->nnext, n++)
284    if (strcmp(((Cell *)(p->narg[0]))->nval, s) == 0)
285      return n;
286  return -1;
287}
288
289int
290ptoi(void *p) /* convert pointer to integer */
291{
292  return (int)(long)p; /* swearing that p fits, of course */
293}
294
295Node *
296itonp(int i) /* and vice versa */
297{
298  return (Node *)(long)i;
299}