14b88c807SRodney W. Grimes/*- 24b88c807SRodney W. Grimes * Copyright (c) 1991, 1993 34b88c807SRodney W. Grimes * The Regents of the University of California. All rights reserved. 44b88c807SRodney W. Grimes * 54b88c807SRodney W. Grimes * This code is derived from software contributed to Berkeley by 64b88c807SRodney W. Grimes * Kenneth Almquist. 74b88c807SRodney W. Grimes * 84b88c807SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 94b88c807SRodney W. Grimes * modification, are permitted provided that the following conditions 104b88c807SRodney W. Grimes * are met: 114b88c807SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 124b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 134b88c807SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 144b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 154b88c807SRodney W. Grimes * documentation and/or other materials provided with the distribution. 16*fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 174b88c807SRodney W. Grimes * may be used to endorse or promote products derived from this software 184b88c807SRodney W. Grimes * without specific prior written permission. 194b88c807SRodney W. Grimes * 204b88c807SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 214b88c807SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 224b88c807SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 234b88c807SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 244b88c807SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 254b88c807SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 264b88c807SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 274b88c807SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 284b88c807SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 294b88c807SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 304b88c807SRodney W. Grimes * SUCH DAMAGE. 314b88c807SRodney W. Grimes */ 324b88c807SRodney W. Grimes 33caecb2f4SMarcel Moolenaar#include <sys/param.h> 34aa9caaf6SPeter Wemm#include <stdlib.h> 35eb33e843SJilles Tjoelker#include <stddef.h> 364b88c807SRodney W. Grimes/* 374b88c807SRodney W. Grimes * Routine for dealing with parsed shell commands. 384b88c807SRodney W. Grimes */ 394b88c807SRodney W. Grimes 404b88c807SRodney W. Grimes#include "shell.h" 414b88c807SRodney W. Grimes#include "nodes.h" 424b88c807SRodney W. Grimes#include "memalloc.h" 434b88c807SRodney W. Grimes#include "mystring.h" 444b88c807SRodney W. Grimes 454b88c807SRodney W. Grimes 46a83f6e1aSJilles Tjoelkerstruct nodesize { 47a83f6e1aSJilles Tjoelker int blocksize; /* size of structures in function */ 48a83f6e1aSJilles Tjoelker int stringsize; /* size of strings in node */ 49a83f6e1aSJilles Tjoelker}; 50a83f6e1aSJilles Tjoelker 51a83f6e1aSJilles Tjoelkerstruct nodecopystate { 52a83f6e1aSJilles Tjoelker pointer block; /* block to allocate function from */ 53a83f6e1aSJilles Tjoelker char *string; /* block to allocate strings from */ 54a83f6e1aSJilles Tjoelker}; 554b88c807SRodney W. Grimes 564b88c807SRodney W. Grimes%SIZES 574b88c807SRodney W. Grimes 584b88c807SRodney W. Grimes 59a83f6e1aSJilles Tjoelkerstatic void calcsize(union node *, struct nodesize *); 60a83f6e1aSJilles Tjoelkerstatic void sizenodelist(struct nodelist *, struct nodesize *); 61a83f6e1aSJilles Tjoelkerstatic union node *copynode(union node *, struct nodecopystate *); 62a83f6e1aSJilles Tjoelkerstatic struct nodelist *copynodelist(struct nodelist *, struct nodecopystate *); 63a83f6e1aSJilles Tjoelkerstatic char *nodesavestr(const char *, struct nodecopystate *); 644b88c807SRodney W. Grimes 654b88c807SRodney W. Grimes 66e16947f8SJilles Tjoelkerstruct funcdef { 67e16947f8SJilles Tjoelker unsigned int refcount; 68e16947f8SJilles Tjoelker union node n; 69e16947f8SJilles Tjoelker}; 704b88c807SRodney W. Grimes 714b88c807SRodney W. Grimes/* 724b88c807SRodney W. Grimes * Make a copy of a parse tree. 734b88c807SRodney W. Grimes */ 744b88c807SRodney W. Grimes 75eb33e843SJilles Tjoelkerstruct funcdef * 765134c3f7SWarner Loshcopyfunc(union node *n) 774b88c807SRodney W. Grimes{ 78a83f6e1aSJilles Tjoelker struct nodesize sz; 79a83f6e1aSJilles Tjoelker struct nodecopystate st; 80eb33e843SJilles Tjoelker struct funcdef *fn; 81eb33e843SJilles Tjoelker 824b88c807SRodney W. Grimes if (n == NULL) 834b88c807SRodney W. Grimes return NULL; 84a83f6e1aSJilles Tjoelker sz.blocksize = offsetof(struct funcdef, n); 85a83f6e1aSJilles Tjoelker sz.stringsize = 0; 86a83f6e1aSJilles Tjoelker calcsize(n, &sz); 87a83f6e1aSJilles Tjoelker fn = ckmalloc(sz.blocksize + sz.stringsize); 88eb33e843SJilles Tjoelker fn->refcount = 1; 89a83f6e1aSJilles Tjoelker st.block = (char *)fn + offsetof(struct funcdef, n); 90a83f6e1aSJilles Tjoelker st.string = (char *)fn + sz.blocksize; 91a83f6e1aSJilles Tjoelker copynode(n, &st); 92eb33e843SJilles Tjoelker return fn; 934b88c807SRodney W. Grimes} 944b88c807SRodney W. Grimes 954b88c807SRodney W. Grimes 96e16947f8SJilles Tjoelkerunion node * 97e16947f8SJilles Tjoelkergetfuncnode(struct funcdef *fn) 98e16947f8SJilles Tjoelker{ 99e16947f8SJilles Tjoelker return fn == NULL ? NULL : &fn->n; 100e16947f8SJilles Tjoelker} 101e16947f8SJilles Tjoelker 1024b88c807SRodney W. Grimes 10388328642SDavid E. O'Brienstatic void 104a83f6e1aSJilles Tjoelkercalcsize(union node *n, struct nodesize *result) 1054b88c807SRodney W. Grimes{ 1064b88c807SRodney W. Grimes %CALCSIZE 1074b88c807SRodney W. Grimes} 1084b88c807SRodney W. Grimes 1094b88c807SRodney W. Grimes 1104b88c807SRodney W. Grimes 11188328642SDavid E. O'Brienstatic void 112a83f6e1aSJilles Tjoelkersizenodelist(struct nodelist *lp, struct nodesize *result) 1134b88c807SRodney W. Grimes{ 1144b88c807SRodney W. Grimes while (lp) { 115a83f6e1aSJilles Tjoelker result->blocksize += ALIGN(sizeof(struct nodelist)); 116a83f6e1aSJilles Tjoelker calcsize(lp->n, result); 1174b88c807SRodney W. Grimes lp = lp->next; 1184b88c807SRodney W. Grimes } 1194b88c807SRodney W. Grimes} 1204b88c807SRodney W. Grimes 1214b88c807SRodney W. Grimes 1224b88c807SRodney W. Grimes 12388328642SDavid E. O'Brienstatic union node * 124a83f6e1aSJilles Tjoelkercopynode(union node *n, struct nodecopystate *state) 1254b88c807SRodney W. Grimes{ 1264b88c807SRodney W. Grimes union node *new; 1274b88c807SRodney W. Grimes 1284b88c807SRodney W. Grimes %COPY 1294b88c807SRodney W. Grimes return new; 1304b88c807SRodney W. Grimes} 1314b88c807SRodney W. Grimes 1324b88c807SRodney W. Grimes 13388328642SDavid E. O'Brienstatic struct nodelist * 134a83f6e1aSJilles Tjoelkercopynodelist(struct nodelist *lp, struct nodecopystate *state) 1354b88c807SRodney W. Grimes{ 1364b88c807SRodney W. Grimes struct nodelist *start; 1374b88c807SRodney W. Grimes struct nodelist **lpp; 1384b88c807SRodney W. Grimes 1394b88c807SRodney W. Grimes lpp = &start; 1404b88c807SRodney W. Grimes while (lp) { 141a83f6e1aSJilles Tjoelker *lpp = state->block; 142a83f6e1aSJilles Tjoelker state->block = (char *)state->block + 143a83f6e1aSJilles Tjoelker ALIGN(sizeof(struct nodelist)); 144a83f6e1aSJilles Tjoelker (*lpp)->n = copynode(lp->n, state); 1454b88c807SRodney W. Grimes lp = lp->next; 1464b88c807SRodney W. Grimes lpp = &(*lpp)->next; 1474b88c807SRodney W. Grimes } 1484b88c807SRodney W. Grimes *lpp = NULL; 1494b88c807SRodney W. Grimes return start; 1504b88c807SRodney W. Grimes} 1514b88c807SRodney W. Grimes 1524b88c807SRodney W. Grimes 1534b88c807SRodney W. Grimes 15488328642SDavid E. O'Brienstatic char * 155a83f6e1aSJilles Tjoelkernodesavestr(const char *s, struct nodecopystate *state) 1564b88c807SRodney W. Grimes{ 1577d919c16SJilles Tjoelker const char *p = s; 158a83f6e1aSJilles Tjoelker char *q = state->string; 159a83f6e1aSJilles Tjoelker char *rtn = state->string; 1604b88c807SRodney W. Grimes 161aa9caaf6SPeter Wemm while ((*q++ = *p++) != '\0') 162aa9caaf6SPeter Wemm continue; 163a83f6e1aSJilles Tjoelker state->string = q; 1644b88c807SRodney W. Grimes return rtn; 1654b88c807SRodney W. Grimes} 1664b88c807SRodney W. Grimes 1674b88c807SRodney W. Grimes 168eb33e843SJilles Tjoelkervoid 169eb33e843SJilles Tjoelkerreffunc(struct funcdef *fn) 170eb33e843SJilles Tjoelker{ 171e16947f8SJilles Tjoelker if (fn) 172eb33e843SJilles Tjoelker fn->refcount++; 173eb33e843SJilles Tjoelker} 174eb33e843SJilles Tjoelker 1754b88c807SRodney W. Grimes 1764b88c807SRodney W. Grimes/* 177eb33e843SJilles Tjoelker * Decrement the reference count of a function definition, freeing it 178eb33e843SJilles Tjoelker * if it falls to 0. 1794b88c807SRodney W. Grimes */ 1804b88c807SRodney W. Grimes 1814b88c807SRodney W. Grimesvoid 182eb33e843SJilles Tjoelkerunreffunc(struct funcdef *fn) 1834b88c807SRodney W. Grimes{ 184eb33e843SJilles Tjoelker if (fn) { 185eb33e843SJilles Tjoelker fn->refcount--; 186eb33e843SJilles Tjoelker if (fn->refcount > 0) 187eb33e843SJilles Tjoelker return; 188eb33e843SJilles Tjoelker ckfree(fn); 189eb33e843SJilles Tjoelker } 1904b88c807SRodney W. Grimes} 191