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