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