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