xref: /original-bsd/bin/csh/misc.c (revision ba762ddc)
1 /*-
2  * Copyright (c) 1980, 1991 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)misc.c	5.6 (Berkeley) 04/04/91";
10 #endif /* not lint */
11 
12 #include "sh.h"
13 
14 /*
15  * C Shell
16  */
17 
18 onlyread(cp)
19 	char *cp;
20 {
21 	extern char end[];
22 
23 	return (cp < end);
24 }
25 
26 xfree(cp)
27 	char *cp;
28 {
29 	extern char end[];
30 
31 	if (cp >= end && cp < (char *) &cp)
32 		free(cp);
33 }
34 
35 char *
36 savestr(s)
37 	register char *s;
38 {
39 	char *n;
40 	register char *p;
41 
42 	if (s == 0)
43 		s = "";
44 	for (p = s; *p++;)
45 		;
46 	n = p = xalloc((unsigned) (p - s));
47 	while (*p++ = *s++)
48 		;
49 	return (n);
50 }
51 
52 char *
53 calloc(i, j)
54 	register unsigned i;
55 	unsigned j;
56 {
57 	char *cp;
58 
59 	i *= j;
60 	cp = xalloc(i);
61 	bzero(cp, (int)i);
62 	return (cp);
63 }
64 
65 nomem(i)
66 	unsigned i;
67 {
68 #ifdef debug
69 	static char *av[2] = {0, 0};
70 #endif
71 
72 	child++;
73 #ifndef debug
74 	error("Out of memory");
75 #ifdef lint
76 	i = i;
77 #endif
78 #else
79 	showall(av);
80 	printf("i=%d: Out of memory\n", i);
81 	chdir("/usr/bill/cshcore");
82 	abort();
83 #endif
84 	return 0;		/* fool lint */
85 }
86 
87 char **
88 blkend(up)
89 	register char **up;
90 {
91 
92 	while (*up)
93 		up++;
94 	return (up);
95 }
96 
97 blkpr(av)
98 	register char **av;
99 {
100 
101 	for (; *av; av++) {
102 		printf("%s", *av);
103 		if (av[1])
104 			printf(" ");
105 	}
106 }
107 
108 blklen(av)
109 	register char **av;
110 {
111 	register int i = 0;
112 
113 	while (*av++)
114 		i++;
115 	return (i);
116 }
117 
118 char **
119 blkcpy(oav, bv)
120 	char **oav;
121 	register char **bv;
122 {
123 	register char **av = oav;
124 
125 	while (*av++ = *bv++)
126 		continue;
127 	return (oav);
128 }
129 
130 char **
131 blkcat(up, vp)
132 	char **up, **vp;
133 {
134 
135 	(void) blkcpy(blkend(up), vp);
136 	return (up);
137 }
138 
139 blkfree(av0)
140 	char **av0;
141 {
142 	register char **av = av0;
143 
144 	for (; *av; av++)
145 		XFREE(*av)
146 	XFREE((char *)av0)
147 }
148 
149 char **
150 saveblk(v)
151 	register char **v;
152 {
153 	register char **newv =
154 		(char **) calloc((unsigned) (blklen(v) + 1), sizeof (char **));
155 	char **onewv = newv;
156 
157 	while (*v)
158 		*newv++ = savestr(*v++);
159 	return (onewv);
160 }
161 
162 char *
163 strspl(cp, dp)
164 	char *cp, *dp;
165 {
166 	char *ep;
167 	register char *p, *q;
168 
169 	for (p = cp; *p++;)
170 		;
171 	for (q = dp; *q++;)
172 		;
173 	ep = xalloc((unsigned) ((p - cp) + (q - dp) - 1));
174 	for (p = ep, q = cp; *p++ = *q++;)
175 		;
176 	for (p--, q = dp; *p++ = *q++;)
177 		;
178 	return (ep);
179 }
180 
181 char **
182 blkspl(up, vp)
183 	register char **up, **vp;
184 {
185 	register char **wp =
186 		(char **) calloc((unsigned) (blklen(up) + blklen(vp) + 1),
187 			sizeof (char **));
188 
189 	(void) blkcpy(wp, up);
190 	return (blkcat(wp, vp));
191 }
192 
193 lastchr(cp)
194 	register char *cp;
195 {
196 
197 	if (!*cp)
198 		return (0);
199 	while (cp[1])
200 		cp++;
201 	return (*cp);
202 }
203 
204 /*
205  * This routine is called after an error to close up
206  * any units which may have been left open accidentally.
207  */
208 closem()
209 {
210 	register int f;
211 
212 	for (f = 0; f < NOFILE; f++)
213 		if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD &&
214 		    f != FSHTTY)
215 			(void) close(f);
216 }
217 
218 donefds()
219 {
220 
221 	(void) close(0);
222 	(void) close(1);
223 	(void) close(2);
224 	didfds = 0;
225 }
226 
227 /*
228  * Move descriptor i to j.
229  * If j is -1 then we just want to get i to a safe place,
230  * i.e. to a unit > 2.  This also happens in dcopy.
231  */
232 dmove(i, j)
233 	register int i, j;
234 {
235 
236 	if (i == j || i < 0)
237 		return (i);
238 	if (j >= 0) {
239 		(void) dup2(i, j);
240 		return (j);
241 	}
242 	j = dcopy(i, j);
243 	if (j != i)
244 		(void) close(i);
245 	return (j);
246 }
247 
248 dcopy(i, j)
249 	register int i, j;
250 {
251 
252 	if (i == j || i < 0 || j < 0 && i > 2)
253 		return (i);
254 	if (j >= 0) {
255 		(void) dup2(i, j);
256 		return (j);
257 	}
258 	(void) close(j);
259 	return (renum(i, j));
260 }
261 
262 renum(i, j)
263 	register int i, j;
264 {
265 	register int k = dup(i);
266 
267 	if (k < 0)
268 		return (-1);
269 	if (j == -1 && k > 2)
270 		return (k);
271 	if (k != j) {
272 		j = renum(k, j);
273 		(void) close(k);
274 		return (j);
275 	}
276 	return (k);
277 }
278 
279 /*
280  * Left shift a command argument list, discarding
281  * the first c arguments.  Used in "shift" commands
282  * as well as by commands like "repeat".
283  */
284 lshift(v, c)
285 	register char **v;
286 	register int c;
287 {
288 	register char **u = v;
289 
290 	while (*u && --c >= 0)
291 		xfree(*u++);
292 	(void) blkcpy(v, u);
293 }
294 
295 number(cp)
296 	char *cp;
297 {
298 
299 	if (*cp == '-') {
300 		cp++;
301 		if (!digit(*cp++))
302 			return (0);
303 	}
304 	while (*cp && digit(*cp))
305 		cp++;
306 	return (*cp == 0);
307 }
308 
309 char **
310 copyblk(v)
311 	register char **v;
312 {
313 	register char **nv =
314 		(char **) calloc((unsigned) (blklen(v) + 1), sizeof (char **));
315 
316 	return (blkcpy(nv, v));
317 }
318 
319 char *
320 strend(cp)
321 	register char *cp;
322 {
323 
324 	while (*cp)
325 		cp++;
326 	return (cp);
327 }
328 
329 char *
330 strip(cp)
331 	char *cp;
332 {
333 	register char *dp = cp;
334 
335 	while (*dp++ &= TRIM)
336 		continue;
337 	return (cp);
338 }
339 
340 udvar(name)
341 	char *name;
342 {
343 
344 	setname(name);
345 	bferr("Undefined variable");
346 }
347 
348 prefix(sub, str)
349 	register char *sub, *str;
350 {
351 
352 	for (;;) {
353 		if (*sub == 0)
354 			return (1);
355 		if (*str == 0)
356 			return (0);
357 		if (*sub++ != *str++)
358 			return (0);
359 	}
360 }
361