xref: /freebsd/bin/sh/nodes.c.pat (revision 90aea514c6249118e880d75972d063362f4bf492)
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