]> git.saurik.com Git - apple/shell_cmds.git/blame - sh/nodes.c.pat
shell_cmds-203.tar.gz
[apple/shell_cmds.git] / sh / nodes.c.pat
CommitLineData
71aad674
A
1/*-
2 * Copyright (c) 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Kenneth Almquist.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 4. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95
deb63bfb 33 * $FreeBSD: head/bin/sh/nodes.c.pat 291267 2015-11-24 22:47:19Z jilles $
71aad674
A
34 */
35
36#include <sys/param.h>
37#include <stdlib.h>
38#include <stddef.h>
39/*
40 * Routine for dealing with parsed shell commands.
41 */
42
43#include "shell.h"
44#include "nodes.h"
45#include "memalloc.h"
46#include "mystring.h"
47
48
deb63bfb
A
49struct nodesize {
50 int blocksize; /* size of structures in function */
51 int stringsize; /* size of strings in node */
52};
53
54struct nodecopystate {
55 pointer block; /* block to allocate function from */
56 char *string; /* block to allocate strings from */
57};
71aad674
A
58
59%SIZES
60
61
deb63bfb
A
62static void calcsize(union node *, struct nodesize *);
63static void sizenodelist(struct nodelist *, struct nodesize *);
64static union node *copynode(union node *, struct nodecopystate *);
65static struct nodelist *copynodelist(struct nodelist *, struct nodecopystate *);
66static char *nodesavestr(const char *, struct nodecopystate *);
71aad674
A
67
68
69struct funcdef {
70 unsigned int refcount;
71 union node n;
72};
73
74/*
75 * Make a copy of a parse tree.
76 */
77
78struct funcdef *
79copyfunc(union node *n)
80{
deb63bfb
A
81 struct nodesize sz;
82 struct nodecopystate st;
71aad674
A
83 struct funcdef *fn;
84
85 if (n == NULL)
86 return NULL;
deb63bfb
A
87 sz.blocksize = offsetof(struct funcdef, n);
88 sz.stringsize = 0;
89 calcsize(n, &sz);
90 fn = ckmalloc(sz.blocksize + sz.stringsize);
71aad674 91 fn->refcount = 1;
deb63bfb
A
92 st.block = (char *)fn + offsetof(struct funcdef, n);
93 st.string = (char *)fn + sz.blocksize;
94 copynode(n, &st);
71aad674
A
95 return fn;
96}
97
98
99union node *
100getfuncnode(struct funcdef *fn)
101{
102 return fn == NULL ? NULL : &fn->n;
103}
104
105
106static void
deb63bfb 107calcsize(union node *n, struct nodesize *result)
71aad674
A
108{
109 %CALCSIZE
110}
111
112
113
114static void
deb63bfb 115sizenodelist(struct nodelist *lp, struct nodesize *result)
71aad674
A
116{
117 while (lp) {
deb63bfb
A
118 result->blocksize += ALIGN(sizeof(struct nodelist));
119 calcsize(lp->n, result);
71aad674
A
120 lp = lp->next;
121 }
122}
123
124
125
126static union node *
deb63bfb 127copynode(union node *n, struct nodecopystate *state)
71aad674
A
128{
129 union node *new;
130
131 %COPY
132 return new;
133}
134
135
136static struct nodelist *
deb63bfb 137copynodelist(struct nodelist *lp, struct nodecopystate *state)
71aad674
A
138{
139 struct nodelist *start;
140 struct nodelist **lpp;
141
142 lpp = &start;
143 while (lp) {
deb63bfb
A
144 *lpp = state->block;
145 state->block = (char *)state->block +
146 ALIGN(sizeof(struct nodelist));
147 (*lpp)->n = copynode(lp->n, state);
71aad674
A
148 lp = lp->next;
149 lpp = &(*lpp)->next;
150 }
151 *lpp = NULL;
152 return start;
153}
154
155
156
157static char *
deb63bfb 158nodesavestr(const char *s, struct nodecopystate *state)
71aad674
A
159{
160 const char *p = s;
deb63bfb
A
161 char *q = state->string;
162 char *rtn = state->string;
71aad674
A
163
164 while ((*q++ = *p++) != '\0')
165 continue;
deb63bfb 166 state->string = q;
71aad674
A
167 return rtn;
168}
169
170
171void
172reffunc(struct funcdef *fn)
173{
174 if (fn)
175 fn->refcount++;
176}
177
178
179/*
180 * Decrement the reference count of a function definition, freeing it
181 * if it falls to 0.
182 */
183
184void
185unreffunc(struct funcdef *fn)
186{
187 if (fn) {
188 fn->refcount--;
189 if (fn->refcount > 0)
190 return;
191 ckfree(fn);
192 }
193}