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