nodes.c.pat revision 196634
144743Smarkm/*- 244743Smarkm * Copyright (c) 1991, 1993 344743Smarkm * The Regents of the University of California. All rights reserved. 444743Smarkm * 544743Smarkm * This code is derived from software contributed to Berkeley by 644743Smarkm * Kenneth Almquist. 744743Smarkm * 856977Sshin * Redistribution and use in source and binary forms, with or without 956977Sshin * modification, are permitted provided that the following conditions 1044743Smarkm * are met: 1144743Smarkm * 1. Redistributions of source code must retain the above copyright 1244743Smarkm * notice, this list of conditions and the following disclaimer. 1344743Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1444743Smarkm * notice, this list of conditions and the following disclaimer in the 1544743Smarkm * documentation and/or other materials provided with the distribution. 1644743Smarkm * 4. Neither the name of the University nor the names of its contributors 1744743Smarkm * may be used to endorse or promote products derived from this software 1844743Smarkm * without specific prior written permission. 1944743Smarkm * 2044743Smarkm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2144743Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2244743Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2344743Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2444743Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2544743Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2644743Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2744743Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2844743Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2944743Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3044743Smarkm * SUCH DAMAGE. 3144743Smarkm * 3244743Smarkm * @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95 3344743Smarkm * $FreeBSD: head/bin/sh/nodes.c.pat 196634 2009-08-28 22:41:25Z jilles $ 3444743Smarkm */ 3544743Smarkm 3644743Smarkm#include <sys/param.h> 3744743Smarkm#include <stdlib.h> 3844743Smarkm#include <stddef.h> 3944743Smarkm/* 4044743Smarkm * Routine for dealing with parsed shell commands. 4144743Smarkm */ 4244743Smarkm 4344743Smarkm#include "shell.h" 4444743Smarkm#include "nodes.h" 4544743Smarkm#include "memalloc.h" 4644743Smarkm#include "mystring.h" 4744743Smarkm 4844743Smarkm 4944743SmarkmSTATIC int funcblocksize; /* size of structures in function */ 5044743SmarkmSTATIC int funcstringsize; /* size of strings in node */ 5144743SmarkmSTATIC pointer funcblock; /* block to allocate function from */ 5244743SmarkmSTATIC char *funcstring; /* block to allocate strings from */ 5344743Smarkm 5444743Smarkm%SIZES 5544743Smarkm 5644743Smarkm 5744743SmarkmSTATIC void calcsize(union node *); 5844743SmarkmSTATIC void sizenodelist(struct nodelist *); 5944743SmarkmSTATIC union node *copynode(union node *); 6044743SmarkmSTATIC struct nodelist *copynodelist(struct nodelist *); 6144743SmarkmSTATIC char *nodesavestr(char *); 6244743Smarkm 6344743Smarkm 6444743Smarkmstruct funcdef { 6544743Smarkm unsigned int refcount; 6644743Smarkm union node n; 6744743Smarkm}; 6844743Smarkm 6944743Smarkm/* 7044743Smarkm * Make a copy of a parse tree. 7144743Smarkm */ 7244743Smarkm 7344743Smarkmstruct funcdef * 7444743Smarkmcopyfunc(union node *n) 7544743Smarkm{ 7644743Smarkm struct funcdef *fn; 7744743Smarkm 7844743Smarkm if (n == NULL) 7944743Smarkm return NULL; 8044743Smarkm funcblocksize = offsetof(struct funcdef, n); 8144743Smarkm funcstringsize = 0; 8244743Smarkm calcsize(n); 8344743Smarkm fn = ckmalloc(funcblocksize + funcstringsize); 8444743Smarkm fn->refcount = 1; 8544743Smarkm funcblock = (char *)fn + offsetof(struct funcdef, n); 8644743Smarkm funcstring = (char *)fn + funcblocksize; 8744743Smarkm copynode(n); 8844743Smarkm return fn; 8944743Smarkm} 9044743Smarkm 9144743Smarkm 9244743Smarkmunion node * 9344743Smarkmgetfuncnode(struct funcdef *fn) 9444743Smarkm{ 9544743Smarkm return fn == NULL ? NULL : &fn->n; 9644743Smarkm} 9744743Smarkm 9844743Smarkm 9944743SmarkmSTATIC void 10044743Smarkmcalcsize(union node *n) 10144743Smarkm{ 10244743Smarkm %CALCSIZE 10344743Smarkm} 10444743Smarkm 10544743Smarkm 10644743Smarkm 10744743SmarkmSTATIC void 10844743Smarkmsizenodelist(struct nodelist *lp) 10944743Smarkm{ 11044743Smarkm while (lp) { 11144743Smarkm funcblocksize += ALIGN(sizeof(struct nodelist)); 11244743Smarkm calcsize(lp->n); 11344743Smarkm lp = lp->next; 11444743Smarkm } 11544743Smarkm} 11644743Smarkm 11744743Smarkm 11844743Smarkm 11944743SmarkmSTATIC union node * 12044743Smarkmcopynode(union node *n) 12144743Smarkm{ 12244743Smarkm union node *new; 12344743Smarkm 12444743Smarkm %COPY 12544743Smarkm return new; 12644743Smarkm} 12744743Smarkm 12844743Smarkm 12944743SmarkmSTATIC struct nodelist * 13044743Smarkmcopynodelist(struct nodelist *lp) 13144743Smarkm{ 13244743Smarkm struct nodelist *start; 13344743Smarkm struct nodelist **lpp; 13444743Smarkm 13544743Smarkm lpp = &start; 13644743Smarkm while (lp) { 13744743Smarkm *lpp = funcblock; 13844743Smarkm funcblock = (char *)funcblock + ALIGN(sizeof(struct nodelist)); 13944743Smarkm (*lpp)->n = copynode(lp->n); 14044743Smarkm lp = lp->next; 14144743Smarkm lpp = &(*lpp)->next; 14244743Smarkm } 14344743Smarkm *lpp = NULL; 14444743Smarkm return start; 14544743Smarkm} 14644743Smarkm 14744743Smarkm 14844743Smarkm 14944743SmarkmSTATIC char * 15044743Smarkmnodesavestr(char *s) 15144743Smarkm{ 15244743Smarkm char *p = s; 15344743Smarkm char *q = funcstring; 15444743Smarkm char *rtn = funcstring; 15544743Smarkm 15644743Smarkm while ((*q++ = *p++) != '\0') 15744743Smarkm continue; 15844743Smarkm funcstring = q; 15944743Smarkm return rtn; 16044743Smarkm} 16144743Smarkm 16244743Smarkm 16344743Smarkmvoid 16444743Smarkmreffunc(struct funcdef *fn) 16544743Smarkm{ 16644743Smarkm if (fn) 16744743Smarkm fn->refcount++; 16844743Smarkm} 16944743Smarkm 17044743Smarkm 17156977Sshin/* 17256977Sshin * Decrement the reference count of a function definition, freeing it 17356977Sshin * if it falls to 0. 17444743Smarkm */ 17556977Sshin 17644743Smarkmvoid 17744743Smarkmunreffunc(struct funcdef *fn) 17856977Sshin{ 17956977Sshin if (fn) { 18056977Sshin fn->refcount--; 18156977Sshin if (fn->refcount > 0) 18256977Sshin return; 18356977Sshin ckfree(fn); 18444743Smarkm } 18544743Smarkm} 18656977Sshin