VirtualBox

source: kBuild/trunk/src/kash/alias.c@ 3505

Last change on this file since 3505 was 3438, checked in by bird, 4 years ago

kash: Hammering on threaded mode.

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id
File size: 7.3 KB
Line 
1/* $NetBSD: alias.c,v 1.12 2003/08/07 09:05:29 agc Exp $ */
2
3/*-
4 * Copyright (c) 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Kenneth Almquist.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#if 0
36#ifndef lint
37static char sccsid[] = "@(#)alias.c 8.3 (Berkeley) 5/4/95";
38#else
39__RCSID("$NetBSD: alias.c,v 1.12 2003/08/07 09:05:29 agc Exp $");
40#endif /* not lint */
41#endif
42
43#include <stdlib.h>
44#include "shell.h"
45#include "input.h"
46#include "output.h"
47#include "error.h"
48#include "memalloc.h"
49#include "mystring.h"
50#include "alias.h"
51#include "options.h" /* XXX for argptr (should remove?) */
52#include "var.h"
53#include "shinstance.h"
54
55/*#define ATABSIZE 39
56
57struct alias *atab[ATABSIZE];*/
58
59STATIC void setalias(shinstance *, char *, char *);
60STATIC int unalias(shinstance *, char *);
61STATIC struct alias **hashalias(shinstance *, char *);
62
63#ifndef SH_FORKED_MODE
64void
65subshellinitalias(shinstance *psh, shinstance *inherit)
66{
67 unsigned i;
68 unsigned left = inherit->aliases;
69 if (left == 0)
70 return;
71 for (i = 0; i < K_ELEMENTS(inherit->atab); i++)
72 {
73 struct alias const *asrc = inherit->atab[i];
74 if (asrc)
75 {
76 struct alias **ppdst = &psh->atab[i];
77 do
78 {
79 if (*asrc->name)
80 {
81 struct alias *dst = (struct alias *)ckmalloc(psh, sizeof(*dst));
82 dst->name = savestr(psh, asrc->name);
83 dst->val = savestr(psh, asrc->val);
84 dst->flag = asrc->flag;
85 *ppdst = dst;
86 ppdst = &dst->next;
87 }
88 left--;
89 asrc = asrc->next;
90 } while (asrc);
91 *ppdst = NULL;
92 if (left == 0)
93 break;
94 }
95 }
96}
97#endif /* !SH_FORKED_MODE */
98
99STATIC
100void
101setalias(shinstance *psh, char *name, char *val)
102{
103 struct alias *ap, **app;
104
105 app = hashalias(psh, name);
106 for (ap = *app; ap; ap = ap->next) {
107 if (equal(name, ap->name)) {
108 INTOFF;
109 ckfree(psh, ap->val);
110 ap->val = savestr(psh, val);
111 INTON;
112 return;
113 }
114 }
115 /* not found */
116 INTOFF;
117 ap = ckmalloc(psh, sizeof (struct alias));
118 ap->name = savestr(psh, name);
119 /*
120 * XXX - HACK: in order that the parser will not finish reading the
121 * alias value off the input before processing the next alias, we
122 * dummy up an extra space at the end of the alias. This is a crock
123 * and should be re-thought. The idea (if you feel inclined to help)
124 * is to avoid alias recursions. The mechanism used is: when
125 * expanding an alias, the value of the alias is pushed back on the
126 * input as a string and a pointer to the alias is stored with the
127 * string. The alias is marked as being in use. When the input
128 * routine finishes reading the string, it markes the alias not
129 * in use. The problem is synchronization with the parser. Since
130 * it reads ahead, the alias is marked not in use before the
131 * resulting token(s) is next checked for further alias sub. The
132 * H A C K is that we add a little fluff after the alias value
133 * so that the string will not be exhausted. This is a good
134 * idea ------- ***NOT***
135 */
136#ifdef notyet
137 ap->val = savestr(psh, val);
138#else /* hack */
139 {
140 size_t len = strlen(val);
141 ap->val = ckmalloc(psh, len + 2);
142 memcpy(ap->val, val, len);
143 ap->val[len] = ' '; /* fluff */
144 ap->val[len+1] = '\0';
145 }
146#endif
147 ap->next = *app;
148 *app = ap;
149 psh->aliases++;
150 INTON;
151}
152
153STATIC int
154unalias(shinstance *psh, char *name)
155{
156 struct alias *ap, **app;
157
158 app = hashalias(psh, name);
159
160 for (ap = *app; ap; app = &(ap->next), ap = ap->next) {
161 if (equal(name, ap->name)) {
162 /*
163 * if the alias is currently in use (i.e. its
164 * buffer is being used by the input routine) we
165 * just null out the name instead of freeing it.
166 * We could clear it out later, but this situation
167 * is so rare that it hardly seems worth it.
168 */
169 if (ap->flag & ALIASINUSE)
170 *ap->name = '\0';
171 else {
172 INTOFF;
173 *app = ap->next;
174 ckfree(psh, ap->name);
175 ckfree(psh, ap->val);
176 ckfree(psh, ap);
177 psh->aliases--;
178 INTON;
179 }
180 return (0);
181 }
182 }
183
184 return (1);
185}
186
187#ifdef mkinit
188MKINIT void rmaliases(shinstance *psh);
189
190SHELLPROC {
191 rmaliases(psh);
192}
193#endif
194
195void
196rmaliases(shinstance *psh)
197{
198 struct alias *ap, *tmp;
199 int i;
200
201 INTOFF;
202 for (i = 0; i < ATABSIZE; i++) {
203 ap = psh->atab[i];
204 psh->atab[i] = NULL;
205 while (ap) {
206 ckfree(psh, ap->name);
207 ckfree(psh, ap->val);
208 tmp = ap;
209 ap = ap->next;
210 ckfree(psh, tmp);
211 }
212 }
213 INTON;
214}
215
216struct alias *
217lookupalias(shinstance *psh, char *name, int check)
218{
219 struct alias *ap = *hashalias(psh, name);
220
221 for (; ap; ap = ap->next) {
222 if (equal(name, ap->name)) {
223 if (check && (ap->flag & ALIASINUSE))
224 return (NULL);
225 return (ap);
226 }
227 }
228
229 return (NULL);
230}
231
232char *
233get_alias_text(shinstance *psh, char *name)
234{
235 struct alias *ap;
236
237 ap = lookupalias(psh, name, 0);
238 if (ap == NULL)
239 return NULL;
240 return ap->val;
241}
242
243/*
244 * TODO - sort output
245 */
246int
247aliascmd(shinstance *psh, int argc, char **argv)
248{
249 char *n, *v;
250 int ret = 0;
251 struct alias *ap;
252
253 if (argc == 1) {
254 int i;
255
256 for (i = 0; i < ATABSIZE; i++)
257 for (ap = psh->atab[i]; ap; ap = ap->next) {
258 if (*ap->name != '\0') {
259 out1fmt(psh, "alias %s=", ap->name);
260 print_quoted(psh, ap->val);
261 out1c(psh, '\n');
262 }
263 }
264 return (0);
265 }
266 while ((n = *++argv) != NULL) {
267 if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */
268 if ((ap = lookupalias(psh, n, 0)) == NULL) {
269 outfmt(psh->out2, "alias: %s not found\n", n);
270 ret = 1;
271 } else {
272 out1fmt(psh, "alias %s=", n);
273 print_quoted(psh, ap->val);
274 out1c(psh, '\n');
275 }
276 } else {
277 *v++ = '\0';
278 setalias(psh, n, v);
279 }
280 }
281
282 return (ret);
283}
284
285int
286unaliascmd(shinstance *psh, int argc, char **argv)
287{
288 int i;
289
290 while ((i = nextopt(psh, "a")) != '\0') {
291 if (i == 'a') {
292 rmaliases(psh);
293 return (0);
294 }
295 }
296 for (i = 0; *psh->argptr; psh->argptr++)
297 i = unalias(psh, *psh->argptr);
298
299 return (i);
300}
301
302STATIC struct alias **
303hashalias(shinstance *psh, char *p)
304{
305 unsigned int hashval;
306
307 hashval = *p << 4;
308 while (*p)
309 hashval+= *p++;
310 return &psh->atab[hashval % ATABSIZE];
311}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette