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 }