]> CyberLeo.Net >> Repos - FreeBSD/stable/10.git/blob - bin/sh/nodes.c.pat
Copy head (r256279) to stable/10 as part of the 10.0-RELEASE cycle.
[FreeBSD/stable/10.git] / bin / sh / nodes.c.pat
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
33  * $FreeBSD$
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
49 static int     funcblocksize;   /* size of structures in function */
50 static int     funcstringsize;  /* size of strings in node */
51 static pointer funcblock;       /* block to allocate function from */
52 static char   *funcstring;      /* block to allocate strings from */
53
54 %SIZES
55
56
57 static void calcsize(union node *);
58 static void sizenodelist(struct nodelist *);
59 static union node *copynode(union node *);
60 static struct nodelist *copynodelist(struct nodelist *);
61 static char *nodesavestr(const char *);
62
63
64 struct funcdef {
65         unsigned int refcount;
66         union node n;
67 };
68
69 /*
70  * Make a copy of a parse tree.
71  */
72
73 struct funcdef *
74 copyfunc(union node *n)
75 {
76         struct funcdef *fn;
77
78         if (n == NULL)
79                 return NULL;
80         funcblocksize = offsetof(struct funcdef, n);
81         funcstringsize = 0;
82         calcsize(n);
83         fn = ckmalloc(funcblocksize + funcstringsize);
84         fn->refcount = 1;
85         funcblock = (char *)fn + offsetof(struct funcdef, n);
86         funcstring = (char *)fn + funcblocksize;
87         copynode(n);
88         return fn;
89 }
90
91
92 union node *
93 getfuncnode(struct funcdef *fn)
94 {
95         return fn == NULL ? NULL : &fn->n;
96 }
97
98
99 static void
100 calcsize(union node *n)
101 {
102         %CALCSIZE
103 }
104
105
106
107 static void
108 sizenodelist(struct nodelist *lp)
109 {
110         while (lp) {
111                 funcblocksize += ALIGN(sizeof(struct nodelist));
112                 calcsize(lp->n);
113                 lp = lp->next;
114         }
115 }
116
117
118
119 static union node *
120 copynode(union node *n)
121 {
122         union node *new;
123
124         %COPY
125         return new;
126 }
127
128
129 static struct nodelist *
130 copynodelist(struct nodelist *lp)
131 {
132         struct nodelist *start;
133         struct nodelist **lpp;
134
135         lpp = &start;
136         while (lp) {
137                 *lpp = funcblock;
138                 funcblock = (char *)funcblock + ALIGN(sizeof(struct nodelist));
139                 (*lpp)->n = copynode(lp->n);
140                 lp = lp->next;
141                 lpp = &(*lpp)->next;
142         }
143         *lpp = NULL;
144         return start;
145 }
146
147
148
149 static char *
150 nodesavestr(const char *s)
151 {
152         const char *p = s;
153         char *q = funcstring;
154         char   *rtn = funcstring;
155
156         while ((*q++ = *p++) != '\0')
157                 continue;
158         funcstring = q;
159         return rtn;
160 }
161
162
163 void
164 reffunc(struct funcdef *fn)
165 {
166         if (fn)
167                 fn->refcount++;
168 }
169
170
171 /*
172  * Decrement the reference count of a function definition, freeing it
173  * if it falls to 0.
174  */
175
176 void
177 unreffunc(struct funcdef *fn)
178 {
179         if (fn) {
180                 fn->refcount--;
181                 if (fn->refcount > 0)
182                         return;
183                 ckfree(fn);
184         }
185 }