11556Srgrimes/*- 21556Srgrimes * Copyright (c) 1991, 1993 31556Srgrimes * The Regents of the University of California. All rights reserved. 41556Srgrimes * 51556Srgrimes * This code is derived from software contributed to Berkeley by 61556Srgrimes * Kenneth Almquist. 71556Srgrimes * 81556Srgrimes * Redistribution and use in source and binary forms, with or without 91556Srgrimes * modification, are permitted provided that the following conditions 101556Srgrimes * are met: 111556Srgrimes * 1. Redistributions of source code must retain the above copyright 121556Srgrimes * notice, this list of conditions and the following disclaimer. 131556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141556Srgrimes * notice, this list of conditions and the following disclaimer in the 151556Srgrimes * documentation and/or other materials provided with the distribution. 161556Srgrimes * 4. Neither the name of the University nor the names of its contributors 171556Srgrimes * may be used to endorse or promote products derived from this software 181556Srgrimes * without specific prior written permission. 191556Srgrimes * 201556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231556Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301556Srgrimes * SUCH DAMAGE. 311556Srgrimes * 3217987Speter * @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95 3350471Speter * $FreeBSD$ 341556Srgrimes */ 351556Srgrimes 36111422Smarcel#include <sys/param.h> 3717987Speter#include <stdlib.h> 38196483Sjilles#include <stddef.h> 391556Srgrimes/* 401556Srgrimes * Routine for dealing with parsed shell commands. 411556Srgrimes */ 421556Srgrimes 431556Srgrimes#include "shell.h" 441556Srgrimes#include "nodes.h" 451556Srgrimes#include "memalloc.h" 461556Srgrimes#include "mystring.h" 471556Srgrimes 481556Srgrimes 49213811Sobrienstatic int funcblocksize; /* size of structures in function */ 50213811Sobrienstatic int funcstringsize; /* size of strings in node */ 51213811Sobrienstatic pointer funcblock; /* block to allocate function from */ 52213811Sobrienstatic char *funcstring; /* block to allocate strings from */ 531556Srgrimes 541556Srgrimes%SIZES 551556Srgrimes 561556Srgrimes 57213811Sobrienstatic void calcsize(union node *); 58213811Sobrienstatic void sizenodelist(struct nodelist *); 59213811Sobrienstatic union node *copynode(union node *); 60213811Sobrienstatic struct nodelist *copynodelist(struct nodelist *); 61213811Sobrienstatic char *nodesavestr(char *); 621556Srgrimes 631556Srgrimes 64196634Sjillesstruct funcdef { 65196634Sjilles unsigned int refcount; 66196634Sjilles union node n; 67196634Sjilles}; 681556Srgrimes 691556Srgrimes/* 701556Srgrimes * Make a copy of a parse tree. 711556Srgrimes */ 721556Srgrimes 73196483Sjillesstruct funcdef * 7490111Simpcopyfunc(union node *n) 7517987Speter{ 76196483Sjilles struct funcdef *fn; 77196483Sjilles 7817987Speter if (n == NULL) 7917987Speter return NULL; 80196483Sjilles funcblocksize = offsetof(struct funcdef, n); 8117987Speter funcstringsize = 0; 8217987Speter calcsize(n); 83196483Sjilles fn = ckmalloc(funcblocksize + funcstringsize); 84196483Sjilles fn->refcount = 1; 85196483Sjilles funcblock = (char *)fn + offsetof(struct funcdef, n); 86196483Sjilles funcstring = (char *)fn + funcblocksize; 87196483Sjilles copynode(n); 88196483Sjilles return fn; 891556Srgrimes} 901556Srgrimes 911556Srgrimes 92196634Sjillesunion node * 93196634Sjillesgetfuncnode(struct funcdef *fn) 94196634Sjilles{ 95196634Sjilles return fn == NULL ? NULL : &fn->n; 96196634Sjilles} 971556Srgrimes 98196634Sjilles 99213811Sobrienstatic void 10090111Simpcalcsize(union node *n) 10117987Speter{ 10217987Speter %CALCSIZE 1031556Srgrimes} 1041556Srgrimes 1051556Srgrimes 1061556Srgrimes 107213811Sobrienstatic void 10890111Simpsizenodelist(struct nodelist *lp) 10917987Speter{ 11017987Speter while (lp) { 11117987Speter funcblocksize += ALIGN(sizeof(struct nodelist)); 11217987Speter calcsize(lp->n); 11317987Speter lp = lp->next; 11417987Speter } 1151556Srgrimes} 1161556Srgrimes 1171556Srgrimes 1181556Srgrimes 119213811Sobrienstatic union node * 12090111Simpcopynode(union node *n) 12117987Speter{ 12217987Speter union node *new; 1231556Srgrimes 12417987Speter %COPY 12517987Speter return new; 1261556Srgrimes} 1271556Srgrimes 1281556Srgrimes 129213811Sobrienstatic struct nodelist * 13090111Simpcopynodelist(struct nodelist *lp) 13117987Speter{ 13217987Speter struct nodelist *start; 13317987Speter struct nodelist **lpp; 1341556Srgrimes 13517987Speter lpp = &start; 13617987Speter while (lp) { 13717987Speter *lpp = funcblock; 13825226Ssteve funcblock = (char *)funcblock + ALIGN(sizeof(struct nodelist)); 13917987Speter (*lpp)->n = copynode(lp->n); 14017987Speter lp = lp->next; 14117987Speter lpp = &(*lpp)->next; 14217987Speter } 14317987Speter *lpp = NULL; 14417987Speter return start; 1451556Srgrimes} 1461556Srgrimes 1471556Srgrimes 1481556Srgrimes 149213811Sobrienstatic char * 15090111Simpnodesavestr(char *s) 15117987Speter{ 15225226Ssteve char *p = s; 15325226Ssteve char *q = funcstring; 15417987Speter char *rtn = funcstring; 1551556Srgrimes 15617987Speter while ((*q++ = *p++) != '\0') 15717987Speter continue; 15817987Speter funcstring = q; 15917987Speter return rtn; 1601556Srgrimes} 1611556Srgrimes 1621556Srgrimes 163196483Sjillesvoid 164196483Sjillesreffunc(struct funcdef *fn) 165196483Sjilles{ 166196634Sjilles if (fn) 167196634Sjilles fn->refcount++; 168196483Sjilles} 1691556Srgrimes 170196483Sjilles 1711556Srgrimes/* 172196483Sjilles * Decrement the reference count of a function definition, freeing it 173196483Sjilles * if it falls to 0. 1741556Srgrimes */ 1751556Srgrimes 1761556Srgrimesvoid 177196483Sjillesunreffunc(struct funcdef *fn) 17817987Speter{ 179196483Sjilles if (fn) { 180196483Sjilles fn->refcount--; 181196483Sjilles if (fn->refcount > 0) 182196483Sjilles return; 183196483Sjilles ckfree(fn); 184196483Sjilles } 1851556Srgrimes} 186