nodes.c.pat revision 196483
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: head/bin/sh/nodes.c.pat 196483 2009-08-23 21:09:46Z jilles $
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
49117261SddsSTATIC int     funcblocksize;	/* size of structures in function */
50117261SddsSTATIC int     funcstringsize;	/* size of strings in node */
51117261SddsSTATIC pointer funcblock;	/* block to allocate function from */
52117261SddsSTATIC char   *funcstring;	/* block to allocate strings from */
531556Srgrimes
541556Srgrimes%SIZES
551556Srgrimes
561556Srgrimes
5790111SimpSTATIC void calcsize(union node *);
5890111SimpSTATIC void sizenodelist(struct nodelist *);
5990111SimpSTATIC union node *copynode(union node *);
6090111SimpSTATIC struct nodelist *copynodelist(struct nodelist *);
6190111SimpSTATIC char *nodesavestr(char *);
621556Srgrimes
631556Srgrimes
641556Srgrimes
651556Srgrimes/*
661556Srgrimes * Make a copy of a parse tree.
671556Srgrimes */
681556Srgrimes
69196483Sjillesstruct funcdef *
7090111Simpcopyfunc(union node *n)
7117987Speter{
72196483Sjilles	struct funcdef *fn;
73196483Sjilles
7417987Speter	if (n == NULL)
7517987Speter		return NULL;
76196483Sjilles	funcblocksize = offsetof(struct funcdef, n);
7717987Speter	funcstringsize = 0;
7817987Speter	calcsize(n);
79196483Sjilles	fn = ckmalloc(funcblocksize + funcstringsize);
80196483Sjilles	fn->refcount = 1;
81196483Sjilles	funcblock = (char *)fn + offsetof(struct funcdef, n);
82196483Sjilles	funcstring = (char *)fn + funcblocksize;
83196483Sjilles	copynode(n);
84196483Sjilles	return fn;
851556Srgrimes}
861556Srgrimes
871556Srgrimes
881556Srgrimes
891556SrgrimesSTATIC void
9090111Simpcalcsize(union node *n)
9117987Speter{
9217987Speter	%CALCSIZE
931556Srgrimes}
941556Srgrimes
951556Srgrimes
961556Srgrimes
971556SrgrimesSTATIC void
9890111Simpsizenodelist(struct nodelist *lp)
9917987Speter{
10017987Speter	while (lp) {
10117987Speter		funcblocksize += ALIGN(sizeof(struct nodelist));
10217987Speter		calcsize(lp->n);
10317987Speter		lp = lp->next;
10417987Speter	}
1051556Srgrimes}
1061556Srgrimes
1071556Srgrimes
1081556Srgrimes
1091556SrgrimesSTATIC union node *
11090111Simpcopynode(union node *n)
11117987Speter{
11217987Speter	union node *new;
1131556Srgrimes
11417987Speter	%COPY
11517987Speter	return new;
1161556Srgrimes}
1171556Srgrimes
1181556Srgrimes
1191556SrgrimesSTATIC struct nodelist *
12090111Simpcopynodelist(struct nodelist *lp)
12117987Speter{
12217987Speter	struct nodelist *start;
12317987Speter	struct nodelist **lpp;
1241556Srgrimes
12517987Speter	lpp = &start;
12617987Speter	while (lp) {
12717987Speter		*lpp = funcblock;
12825226Ssteve		funcblock = (char *)funcblock + ALIGN(sizeof(struct nodelist));
12917987Speter		(*lpp)->n = copynode(lp->n);
13017987Speter		lp = lp->next;
13117987Speter		lpp = &(*lpp)->next;
13217987Speter	}
13317987Speter	*lpp = NULL;
13417987Speter	return start;
1351556Srgrimes}
1361556Srgrimes
1371556Srgrimes
1381556Srgrimes
1391556SrgrimesSTATIC char *
14090111Simpnodesavestr(char *s)
14117987Speter{
14225226Ssteve	char *p = s;
14325226Ssteve	char *q = funcstring;
14417987Speter	char   *rtn = funcstring;
1451556Srgrimes
14617987Speter	while ((*q++ = *p++) != '\0')
14717987Speter		continue;
14817987Speter	funcstring = q;
14917987Speter	return rtn;
1501556Srgrimes}
1511556Srgrimes
1521556Srgrimes
153196483Sjillesvoid
154196483Sjillesreffunc(struct funcdef *fn)
155196483Sjilles{
156196483Sjilles	fn->refcount++;
157196483Sjilles}
1581556Srgrimes
159196483Sjilles
1601556Srgrimes/*
161196483Sjilles * Decrement the reference count of a function definition, freeing it
162196483Sjilles * if it falls to 0.
1631556Srgrimes */
1641556Srgrimes
1651556Srgrimesvoid
166196483Sjillesunreffunc(struct funcdef *fn)
16717987Speter{
168196483Sjilles	if (fn) {
169196483Sjilles		fn->refcount--;
170196483Sjilles		if (fn->refcount > 0)
171196483Sjilles			return;
172196483Sjilles		ckfree(fn);
173196483Sjilles	}
1741556Srgrimes}
175