nodes.c.pat revision 249235
1169695Skan/*- 2169695Skan * Copyright (c) 1991, 1993 3169695Skan * The Regents of the University of California. All rights reserved. 4169695Skan * 5169695Skan * This code is derived from software contributed to Berkeley by 6169695Skan * Kenneth Almquist. 7169695Skan * 8169695Skan * Redistribution and use in source and binary forms, with or without 9169695Skan * modification, are permitted provided that the following conditions 10169695Skan * are met: 11169695Skan * 1. Redistributions of source code must retain the above copyright 12169695Skan * notice, this list of conditions and the following disclaimer. 13169695Skan * 2. Redistributions in binary form must reproduce the above copyright 14169695Skan * notice, this list of conditions and the following disclaimer in the 15169695Skan * documentation and/or other materials provided with the distribution. 16169695Skan * 4. Neither the name of the University nor the names of its contributors 17169695Skan * may be used to endorse or promote products derived from this software 18169695Skan * without specific prior written permission. 19169695Skan * 20169695Skan * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21169695Skan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22169695Skan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23169695Skan * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24169695Skan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25169695Skan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26169695Skan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27169695Skan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28169695Skan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29169695Skan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30169695Skan * SUCH DAMAGE. 31169695Skan * 32169695Skan * @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95 33169695Skan * $FreeBSD: head/bin/sh/nodes.c.pat 249235 2013-04-07 16:28:36Z jilles $ 34169695Skan */ 35169695Skan 36169695Skan#include <sys/param.h> 37169695Skan#include <stdlib.h> 38169695Skan#include <stddef.h> 39169695Skan/* 40169695Skan * Routine for dealing with parsed shell commands. 41169695Skan */ 42169695Skan 43169695Skan#include "shell.h" 44169695Skan#include "nodes.h" 45169695Skan#include "memalloc.h" 46169695Skan#include "mystring.h" 47169695Skan 48169695Skan 49169695Skanstatic int funcblocksize; /* size of structures in function */ 50169695Skanstatic int funcstringsize; /* size of strings in node */ 51169695Skanstatic pointer funcblock; /* block to allocate function from */ 52169695Skanstatic char *funcstring; /* block to allocate strings from */ 53169695Skan 54169695Skan%SIZES 55169695Skan 56169695Skan 57169695Skanstatic void calcsize(union node *); 58169695Skanstatic void sizenodelist(struct nodelist *); 59169695Skanstatic union node *copynode(union node *); 60169695Skanstatic struct nodelist *copynodelist(struct nodelist *); 61169695Skanstatic char *nodesavestr(const char *); 62169695Skan 63169695Skan 64169695Skanstruct funcdef { 65169695Skan unsigned int refcount; 66169695Skan union node n; 67169695Skan}; 68169695Skan 69169695Skan/* 70169695Skan * Make a copy of a parse tree. 71169695Skan */ 72169695Skan 73169695Skanstruct funcdef * 74169695Skancopyfunc(union node *n) 75169695Skan{ 76169695Skan struct funcdef *fn; 77169695Skan 78169695Skan if (n == NULL) 79169695Skan return NULL; 80169695Skan funcblocksize = offsetof(struct funcdef, n); 81169695Skan funcstringsize = 0; 82169695Skan calcsize(n); 83169695Skan fn = ckmalloc(funcblocksize + funcstringsize); 84169695Skan fn->refcount = 1; 85169695Skan funcblock = (char *)fn + offsetof(struct funcdef, n); 86169695Skan funcstring = (char *)fn + funcblocksize; 87169695Skan copynode(n); 88169695Skan return fn; 89169695Skan} 90169695Skan 91169695Skan 92169695Skanunion node * 93169695Skangetfuncnode(struct funcdef *fn) 94169695Skan{ 95169695Skan return fn == NULL ? NULL : &fn->n; 96169695Skan} 97169695Skan 98169695Skan 99169695Skanstatic void 100169695Skancalcsize(union node *n) 101169695Skan{ 102169695Skan %CALCSIZE 103169695Skan} 104169695Skan 105169695Skan 106169695Skan 107169695Skanstatic void 108169695Skansizenodelist(struct nodelist *lp) 109169695Skan{ 110169695Skan while (lp) { 111169695Skan funcblocksize += ALIGN(sizeof(struct nodelist)); 112169695Skan calcsize(lp->n); 113169695Skan lp = lp->next; 114169695Skan } 115169695Skan} 116169695Skan 117169695Skan 118169695Skan 119169695Skanstatic union node * 120169695Skancopynode(union node *n) 121169695Skan{ 122169695Skan union node *new; 123169695Skan 124169695Skan %COPY 125169695Skan return new; 126169695Skan} 127169695Skan 128169695Skan 129169695Skanstatic struct nodelist * 130169695Skancopynodelist(struct nodelist *lp) 131169695Skan{ 132169695Skan struct nodelist *start; 133169695Skan struct nodelist **lpp; 134169695Skan 135169695Skan lpp = &start; 136169695Skan while (lp) { 137169695Skan *lpp = funcblock; 138169695Skan funcblock = (char *)funcblock + ALIGN(sizeof(struct nodelist)); 139169695Skan (*lpp)->n = copynode(lp->n); 140169695Skan lp = lp->next; 141169695Skan lpp = &(*lpp)->next; 142169695Skan } 143169695Skan *lpp = NULL; 144169695Skan return start; 145169695Skan} 146169695Skan 147169695Skan 148169695Skan 149169695Skanstatic char * 150169695Skannodesavestr(const char *s) 151169695Skan{ 152169695Skan const char *p = s; 153169695Skan char *q = funcstring; 154169695Skan char *rtn = funcstring; 155169695Skan 156169695Skan while ((*q++ = *p++) != '\0') 157169695Skan continue; 158169695Skan funcstring = q; 159169695Skan return rtn; 160169695Skan} 161169695Skan 162169695Skan 163169695Skanvoid 164169695Skanreffunc(struct funcdef *fn) 165169695Skan{ 166169695Skan if (fn) 167169695Skan fn->refcount++; 168169695Skan} 169169695Skan 170169695Skan 171169695Skan/* 172169695Skan * Decrement the reference count of a function definition, freeing it 173169695Skan * if it falls to 0. 174169695Skan */ 175169695Skan 176169695Skanvoid 177169695Skanunreffunc(struct funcdef *fn) 178169695Skan{ 179169695Skan if (fn) { 180169695Skan fn->refcount--; 181169695Skan if (fn->refcount > 0) 182169695Skan return; 183169695Skan ckfree(fn); 184169695Skan } 185169695Skan} 186169695Skan