xref: /netbsd-src/bin/csh/misc.c (revision 0b9f50897e9a9c6709320fafb4c3787fddcc0a45)
1 /*-
2  * Copyright (c) 1980, 1991 The Regents of the University of California.
3  * 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	5.13 (Berkeley) 6/27/91";*/
36 static char rcsid[] = "$Id: misc.c,v 1.4 1993/08/01 19:00:36 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     n = p = (char *) xmalloc((size_t) ((p - s) * sizeof(char)));
88     while (*p++ = *s++);
89     return (n);
90 }
91 
92 Char  **
93 blkend(up)
94     register Char **up;
95 {
96 
97     while (*up)
98 	up++;
99     return (up);
100 }
101 
102 
103 void
104 blkpr(av)
105     register Char **av;
106 {
107 
108     for (; *av; av++) {
109 	xprintf("%s", short2str(*av));
110 	if (av[1])
111 	    xprintf(" ");
112     }
113 }
114 
115 int
116 blklen(av)
117     register Char **av;
118 {
119     register int i = 0;
120 
121     while (*av++)
122 	i++;
123     return (i);
124 }
125 
126 Char  **
127 blkcpy(oav, bv)
128     Char  **oav;
129     register Char **bv;
130 {
131     register Char **av = oav;
132 
133     while (*av++ = *bv++)
134 	continue;
135     return (oav);
136 }
137 
138 Char  **
139 blkcat(up, vp)
140     Char  **up, **vp;
141 {
142 
143     (void) blkcpy(blkend(up), vp);
144     return (up);
145 }
146 
147 void
148 blkfree(av0)
149     Char  **av0;
150 {
151     register Char **av = av0;
152 
153     if (!av0)
154 	return;
155     for (; *av; av++)
156 	xfree((ptr_t) * av);
157     xfree((ptr_t) av0);
158 }
159 
160 Char  **
161 saveblk(v)
162     register Char **v;
163 {
164     register Char **newv =
165     (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
166     Char  **onewv = newv;
167 
168     while (*v)
169 	*newv++ = Strsave(*v++);
170     return (onewv);
171 }
172 
173 #ifdef NOTUSED
174 char   *
175 strstr(s, t)
176     register char *s, *t;
177 {
178     do {
179 	register char *ss = s;
180 	register char *tt = t;
181 
182 	do
183 	    if (*tt == '\0')
184 		return (s);
185 	while (*ss++ == *tt++);
186     } while (*s++ != '\0');
187     return (NULL);
188 }
189 
190 #endif /* NOTUSED */
191 
192 #ifndef SHORT_STRINGS
193 char   *
194 strspl(cp, dp)
195     char   *cp, *dp;
196 {
197     char   *ep;
198     register char *p, *q;
199 
200     if (!cp)
201 	cp = "";
202     if (!dp)
203 	dp = "";
204     for (p = cp; *p++;);
205     for (q = dp; *q++;);
206     ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char)));
207     for (p = ep, q = cp; *p++ = *q++;);
208     for (p--, q = dp; *p++ = *q++;);
209     return (ep);
210 }
211 
212 #endif
213 
214 Char  **
215 blkspl(up, vp)
216     register Char **up, **vp;
217 {
218     register Char **wp =
219     (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1),
220 		      sizeof(Char **));
221 
222     (void) blkcpy(wp, up);
223     return (blkcat(wp, vp));
224 }
225 
226 Char
227 lastchr(cp)
228     register Char *cp;
229 {
230 
231     if (!cp)
232 	return (0);
233     if (!*cp)
234 	return (0);
235     while (cp[1])
236 	cp++;
237     return (*cp);
238 }
239 
240 /*
241  * This routine is called after an error to close up
242  * any units which may have been left open accidentally.
243  */
244 void
245 closem()
246 {
247     register int f;
248 
249     for (f = 0; f < NOFILE; f++)
250 	if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD &&
251 	    f != FSHTTY)
252 	    (void) close(f);
253 }
254 
255 void
256 donefds()
257 {
258 
259     (void) close(0);
260     (void) close(1);
261     (void) close(2);
262     didfds = 0;
263 }
264 
265 /*
266  * Move descriptor i to j.
267  * If j is -1 then we just want to get i to a safe place,
268  * i.e. to a unit > 2.  This also happens in dcopy.
269  */
270 int
271 dmove(i, j)
272     register int i, j;
273 {
274 
275     if (i == j || i < 0)
276 	return (i);
277     if (j >= 0) {
278 	(void) dup2(i, j);
279 	if (j != i)
280 	    (void) close(i);
281 	return (j);
282     }
283     j = dcopy(i, j);
284     if (j != i)
285 	(void) close(i);
286     return (j);
287 }
288 
289 int
290 dcopy(i, j)
291     register int i, j;
292 {
293 
294     if (i == j || i < 0 || j < 0 && i > 2)
295 	return (i);
296     if (j >= 0) {
297 	(void) dup2(i, j);
298 	return (j);
299     }
300     (void) close(j);
301     return (renum(i, j));
302 }
303 
304 static int
305 renum(i, j)
306     register int i, j;
307 {
308     register int k = dup(i);
309 
310     if (k < 0)
311 	return (-1);
312     if (j == -1 && k > 2)
313 	return (k);
314     if (k != j) {
315 	j = renum(k, j);
316 	(void) close(k);
317 	return (j);
318     }
319     return (k);
320 }
321 
322 /*
323  * Left shift a command argument list, discarding
324  * the first c arguments.  Used in "shift" commands
325  * as well as by commands like "repeat".
326  */
327 void
328 lshift(v, c)
329     register Char **v;
330     register int c;
331 {
332     register Char **u = v;
333 
334     while (*u && --c >= 0)
335 	xfree((ptr_t) * u++);
336     (void) blkcpy(v, u);
337 }
338 
339 int
340 number(cp)
341     Char   *cp;
342 {
343     if (!cp)
344 	return(0);
345     if (*cp == '-') {
346 	cp++;
347 	if (!Isdigit(*cp))
348 	    return (0);
349 	cp++;
350     }
351     while (*cp && Isdigit(*cp))
352 	cp++;
353     return (*cp == 0);
354 }
355 
356 Char  **
357 copyblk(v)
358     register Char **v;
359 {
360     Char  **nv = (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
361 
362     return (blkcpy(nv, v));
363 }
364 
365 #ifndef SHORT_STRINGS
366 char   *
367 strend(cp)
368     register char *cp;
369 {
370     if (!cp)
371 	return (cp);
372     while (*cp)
373 	cp++;
374     return (cp);
375 }
376 
377 #endif				/* SHORT_STRINGS */
378 
379 Char   *
380 strip(cp)
381     Char   *cp;
382 {
383     register Char *dp = cp;
384 
385     if (!cp)
386 	return (cp);
387     while (*dp++ &= TRIM)
388 	continue;
389     return (cp);
390 }
391 
392 void
393 udvar(name)
394     Char   *name;
395 {
396 
397     setname(short2str(name));
398     stderror(ERR_NAME | ERR_UNDVAR);
399 }
400 
401 int
402 prefix(sub, str)
403     register Char *sub, *str;
404 {
405 
406     for (;;) {
407 	if (*sub == 0)
408 	    return (1);
409 	if (*str == 0)
410 	    return (0);
411 	if (*sub++ != *str++)
412 	    return (0);
413     }
414 }
415