xref: /netbsd-src/bin/csh/misc.c (revision ae9172d6cd9432a6a1a56760d86b32c57a66c39c)
1 /*-
2  * Copyright (c) 1980, 1991, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by the University of
16  *	California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #ifndef lint
35 /*static char sccsid[] = "from: @(#)misc.c	8.1 (Berkeley) 5/31/93";*/
36 static char *rcsid = "$Id: misc.c,v 1.5 1994/09/21 00:11:03 mycroft Exp $";
37 #endif /* not lint */
38 
39 #include <sys/param.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #if __STDC__
43 # include <stdarg.h>
44 #else
45 # include <varargs.h>
46 #endif
47 
48 #include "csh.h"
49 #include "extern.h"
50 
51 static int	renum __P((int, int));
52 
53 int
54 any(s, c)
55     register char *s;
56     register int c;
57 {
58     if (!s)
59 	return (0);		/* Check for nil pointer */
60     while (*s)
61 	if (*s++ == c)
62 	    return (1);
63     return (0);
64 }
65 
66 void
67 setzero(cp, i)
68     char   *cp;
69     int     i;
70 {
71     if (i != 0)
72 	do
73 	    *cp++ = 0;
74 	while (--i);
75 }
76 
77 char   *
78 strsave(s)
79     register char *s;
80 {
81     char   *n;
82     register char *p;
83 
84     if (s == NULL)
85 	s = "";
86     for (p = s; *p++;)
87 	continue;
88     n = p = (char *) xmalloc((size_t) ((p - s) * sizeof(char)));
89     while ((*p++ = *s++) != '\0')
90 	continue;
91     return (n);
92 }
93 
94 Char  **
95 blkend(up)
96     register Char **up;
97 {
98 
99     while (*up)
100 	up++;
101     return (up);
102 }
103 
104 
105 void
106 blkpr(fp, av)
107     FILE *fp;
108     register Char **av;
109 {
110 
111     for (; *av; av++) {
112 	(void) fprintf(fp, "%s", vis_str(*av));
113 	if (av[1])
114 	    (void) fprintf(fp, " ");
115     }
116 }
117 
118 int
119 blklen(av)
120     register Char **av;
121 {
122     register int i = 0;
123 
124     while (*av++)
125 	i++;
126     return (i);
127 }
128 
129 Char  **
130 blkcpy(oav, bv)
131     Char  **oav;
132     register Char **bv;
133 {
134     register Char **av = oav;
135 
136     while ((*av++ = *bv++) != NULL)
137 	continue;
138     return (oav);
139 }
140 
141 Char  **
142 blkcat(up, vp)
143     Char  **up, **vp;
144 {
145 
146     (void) blkcpy(blkend(up), vp);
147     return (up);
148 }
149 
150 void
151 blkfree(av0)
152     Char  **av0;
153 {
154     register Char **av = av0;
155 
156     if (!av0)
157 	return;
158     for (; *av; av++)
159 	xfree((ptr_t) * av);
160     xfree((ptr_t) av0);
161 }
162 
163 Char  **
164 saveblk(v)
165     register Char **v;
166 {
167     register Char **newv =
168     (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
169     Char  **onewv = newv;
170 
171     while (*v)
172 	*newv++ = Strsave(*v++);
173     return (onewv);
174 }
175 
176 #ifdef NOTUSED
177 char   *
178 strstr(s, t)
179     register char *s, *t;
180 {
181     do {
182 	register char *ss = s;
183 	register char *tt = t;
184 
185 	do
186 	    if (*tt == '\0')
187 		return (s);
188 	while (*ss++ == *tt++);
189     } while (*s++ != '\0');
190     return (NULL);
191 }
192 
193 #endif /* NOTUSED */
194 
195 #ifndef SHORT_STRINGS
196 char   *
197 strspl(cp, dp)
198     char   *cp, *dp;
199 {
200     char   *ep;
201     register char *p, *q;
202 
203     if (!cp)
204 	cp = "";
205     if (!dp)
206 	dp = "";
207     for (p = cp; *p++;)
208 	continue;
209     for (q = dp; *q++;)
210 	continue;
211     ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char)));
212     for (p = ep, q = cp; *p++ = *q++;)
213 	continue;
214     for (p--, q = dp; *p++ = *q++;)
215 	continue;
216     return (ep);
217 }
218 
219 #endif
220 
221 Char  **
222 blkspl(up, vp)
223     register Char **up, **vp;
224 {
225     register Char **wp =
226     (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1),
227 		      sizeof(Char **));
228 
229     (void) blkcpy(wp, up);
230     return (blkcat(wp, vp));
231 }
232 
233 Char
234 lastchr(cp)
235     register Char *cp;
236 {
237 
238     if (!cp)
239 	return (0);
240     if (!*cp)
241 	return (0);
242     while (cp[1])
243 	cp++;
244     return (*cp);
245 }
246 
247 /*
248  * This routine is called after an error to close up
249  * any units which may have been left open accidentally.
250  */
251 void
252 closem()
253 {
254     register int f;
255 
256     for (f = 0; f < NOFILE; f++)
257 	if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD &&
258 	    f != FSHTTY)
259 	    (void) close(f);
260 }
261 
262 void
263 donefds()
264 {
265     (void) close(0);
266     (void) close(1);
267     (void) close(2);
268 
269     didfds = 0;
270 }
271 
272 /*
273  * Move descriptor i to j.
274  * If j is -1 then we just want to get i to a safe place,
275  * i.e. to a unit > 2.  This also happens in dcopy.
276  */
277 int
278 dmove(i, j)
279     register int i, j;
280 {
281 
282     if (i == j || i < 0)
283 	return (i);
284     if (j >= 0) {
285 	(void) dup2(i, j);
286 	if (j != i)
287 	    (void) close(i);
288 	return (j);
289     }
290     j = dcopy(i, j);
291     if (j != i)
292 	(void) close(i);
293     return (j);
294 }
295 
296 int
297 dcopy(i, j)
298     register int i, j;
299 {
300 
301     if (i == j || i < 0 || (j < 0 && i > 2))
302 	return (i);
303     if (j >= 0) {
304 	(void) dup2(i, j);
305 	return (j);
306     }
307     (void) close(j);
308     return (renum(i, j));
309 }
310 
311 static int
312 renum(i, j)
313     register int i, j;
314 {
315     register int k = dup(i);
316 
317     if (k < 0)
318 	return (-1);
319     if (j == -1 && k > 2)
320 	return (k);
321     if (k != j) {
322 	j = renum(k, j);
323 	(void) close(k);
324 	return (j);
325     }
326     return (k);
327 }
328 
329 /*
330  * Left shift a command argument list, discarding
331  * the first c arguments.  Used in "shift" commands
332  * as well as by commands like "repeat".
333  */
334 void
335 lshift(v, c)
336     register Char **v;
337     register int c;
338 {
339     register Char **u;
340 
341     for (u = v; *u && --c >= 0; u++)
342 	xfree((ptr_t) *u);
343     (void) blkcpy(v, u);
344 }
345 
346 int
347 number(cp)
348     Char   *cp;
349 {
350     if (!cp)
351 	return(0);
352     if (*cp == '-') {
353 	cp++;
354 	if (!Isdigit(*cp))
355 	    return (0);
356 	cp++;
357     }
358     while (*cp && Isdigit(*cp))
359 	cp++;
360     return (*cp == 0);
361 }
362 
363 Char  **
364 copyblk(v)
365     register Char **v;
366 {
367     Char  **nv = (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
368 
369     return (blkcpy(nv, v));
370 }
371 
372 #ifndef SHORT_STRINGS
373 char   *
374 strend(cp)
375     register char *cp;
376 {
377     if (!cp)
378 	return (cp);
379     while (*cp)
380 	cp++;
381     return (cp);
382 }
383 
384 #endif /* SHORT_STRINGS */
385 
386 Char   *
387 strip(cp)
388     Char   *cp;
389 {
390     register Char *dp = cp;
391 
392     if (!cp)
393 	return (cp);
394     while ((*dp++ &= TRIM) != '\0')
395 	continue;
396     return (cp);
397 }
398 
399 void
400 udvar(name)
401     Char   *name;
402 {
403 
404     setname(vis_str(name));
405     stderror(ERR_NAME | ERR_UNDVAR);
406 }
407 
408 int
409 prefix(sub, str)
410     register Char *sub, *str;
411 {
412 
413     for (;;) {
414 	if (*sub == 0)
415 	    return (1);
416 	if (*str == 0)
417 	    return (0);
418 	if (*sub++ != *str++)
419 	    return (0);
420     }
421 }
422