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