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