8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / csh / sh.misc.c
blob52db0dc8ff994b082aa96d794d61da42fdd25275
1 /*
2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
9 /*
10 * Copyright (c) 1980 Regents of the University of California.
11 * All rights reserved. The Berkeley Software License Agreement
12 * specifies the terms and conditions for redistribution.
15 #pragma ident "%Z%%M% %I% %E% SMI"
17 #include "sh.h"
18 #include "sh.tconst.h"
19 #include <fcntl.h>
20 #include <unistd.h>
23 * C Shell
25 tchar **blkcat(tchar **, tchar **);
26 tchar **blkend(tchar **);
28 int
29 any(int c, tchar *s)
32 while (s && *s)
33 if (*s++ == c)
34 return (1);
35 return (0);
38 int
39 onlyread(tchar *cp)
41 extern char end[];
43 return ((char *)cp < end);
46 tchar *
47 savestr(tchar *s)
49 tchar *n;
50 tchar *p;
52 if (s == 0)
53 s = S_ /* "" */;
54 #ifndef m32
55 for (p = s; *p++; )
57 n = p = (tchar *)xalloc((unsigned)(p - s)*sizeof (tchar));
58 while (*p++ = *s++)
60 return (n);
61 #else
62 p = (tchar *) xalloc((strlen_(s) + 1)*sizeof (tchar));
63 strcpy_(p, s);
64 return (p);
65 #endif
68 static void *
69 nomem(size_t i)
71 #ifdef debug
72 static tchar *av[2] = {0, 0};
73 #endif
75 child++;
76 #ifndef debug
77 error("Out of memory");
78 #ifdef lint
79 i = i;
80 #endif
81 #else
82 showall(av);
83 printf("i=%d: Out of memory\n", i);
84 chdir("/usr/bill/cshcore");
85 abort();
86 #endif
87 return (0); /* fool lint */
90 tchar **
91 blkend(tchar **up)
94 while (*up)
95 up++;
96 return (up);
99 void
100 blkpr(tchar **av)
103 for (; *av; av++) {
104 printf("%t", *av);
105 if (av[1])
106 printf(" ");
111 blklen(tchar **av)
113 int i = 0;
115 while (*av++)
116 i++;
117 return (i);
120 tchar **
121 blkcpy(tchar **oav, tchar **bv)
123 tchar **av = oav;
125 while (*av++ = *bv++)
126 continue;
127 return (oav);
130 tchar **
131 blkcat(tchar **up, tchar **vp)
134 (void) blkcpy(blkend(up), vp);
135 return (up);
138 void
139 blkfree(tchar **av0)
141 tchar **av = av0;
143 for (; *av; av++)
144 xfree(*av);
145 xfree(av0);
148 tchar **
149 saveblk(tchar **v)
151 tchar **newv =
152 (tchar **)xcalloc((unsigned)(blklen(v) + 1),
153 sizeof (tchar **));
154 tchar **onewv = newv;
156 while (*v)
157 *newv++ = savestr(*v++);
158 return (onewv);
161 tchar *
162 strspl(tchar *cp, tchar *dp)
164 tchar *ep;
165 tchar *p, *q;
167 #ifndef m32
168 for (p = cp; *p++; )
170 for (q = dp; *q++; )
172 ep = (tchar *) xalloc((unsigned)(((p - cp) +
173 (q - dp) - 1))*sizeof (tchar));
174 for (p = ep, q = cp; *p++ = *q++; )
176 for (p--, q = dp; *p++ = *q++; )
178 #else
179 int len1 = strlen_(cp);
180 int len2 = strlen_(dp);
182 ep = (tchar *)xalloc((unsigned)(len1 + len2 + 1)*sizeof (tchar));
183 strcpy_(ep, cp);
184 strcat_(ep, dp);
185 #endif
186 return (ep);
189 tchar **
190 blkspl(tchar **up, tchar **vp)
192 tchar **wp =
193 (tchar **)xcalloc((unsigned)(blklen(up) + blklen(vp) + 1),
194 sizeof (tchar **));
196 (void) blkcpy(wp, up);
197 return (blkcat(wp, vp));
201 lastchr(tchar *cp)
204 if (!*cp)
205 return (0);
206 while (cp[1])
207 cp++;
208 return (*cp);
211 void
212 donefds(void)
214 (void) close(0);
215 (void) close(1);
216 (void) close(2);
219 * To avoid NIS+ functions to get hold of 0/1/2,
220 * use descriptor 0, and dup it to 1 and 2.
222 open("/dev/null", 0);
223 dup(0); dup(0);
224 didfds = 0;
228 * Move descriptor i to j.
229 * If j is -1 then we just want to get i to a safe place,
230 * i.e. to a unit > 2. This also happens in dcopy.
233 dmove(int i, int j)
235 int fd;
237 if (i == j || i < 0)
238 return (i);
239 if (j >= 0) {
240 fd = dup2(i, j);
241 if (fd != -1)
242 setfd(fd);
243 } else
244 j = dcopy(i, j);
245 if (j != i) {
246 (void) close(i);
247 unsetfd(i);
249 return (j);
253 dcopy(int i, int j)
256 int fd;
258 if (i == j || i < 0 || j < 0 && i > 2)
259 return (i);
260 if (j >= 0) {
261 fd = dup2(i, j);
262 if (fd != -1)
263 setfd(fd);
264 return (j);
266 (void) close(j);
267 unsetfd(j);
268 return (renum(i, j));
272 renum(int i, int j)
274 int k = dup(i);
276 if (k < 0)
277 return (-1);
278 if (j == -1 && k > 2) {
279 setfd(k);
280 return (k);
282 if (k != j) {
283 j = renum(k, j);
284 (void) close(k); /* no need ofr unsetfd() */
285 return (j);
287 return (k);
290 #ifndef copy
291 void
292 copy(tchar *to, tchar *from, int size)
295 if (size)
297 *to++ = *from++;
298 while (--size != 0);
300 #endif
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".
307 void
308 lshift(tchar **v, int c)
310 tchar **u = v;
312 while (*u && --c >= 0)
313 xfree((char *)*u++);
314 (void) blkcpy(v, u);
318 number(tchar *cp)
321 if (*cp == '-') {
322 cp++;
323 if (!digit(*cp++))
324 return (0);
326 while (*cp && digit(*cp))
327 cp++;
328 return (*cp == 0);
331 tchar **
332 copyblk(tchar **v)
334 tchar **nv =
335 (tchar **)xcalloc((unsigned)(blklen(v) + 1),
336 sizeof (tchar **));
338 return (blkcpy(nv, v));
341 tchar *
342 strend(tchar *cp)
345 while (*cp)
346 cp++;
347 return (cp);
350 tchar *
351 strip(tchar *cp)
353 tchar *dp = cp;
355 while (*dp++ &= TRIM)
356 continue;
357 return (cp);
360 void
361 udvar(tchar *name)
364 setname(name);
365 bferr("Undefined variable");
369 prefix(tchar *sub, tchar *str)
372 for (;;) {
373 if (*sub == 0)
374 return (1);
375 if (*str == 0)
376 return (0);
377 if (*sub++ != *str++)
378 return (0);
383 * blk*_ routines
386 char **
387 blkend_(char **up)
390 while (*up)
391 up++;
392 return (up);
396 blklen_(char **av)
398 int i = 0;
400 while (*av++)
401 i++;
402 return (i);
405 char **
406 blkcpy_(char **oav, char **bv)
408 char **av = oav;
410 while (*av++ = *bv++)
411 continue;
412 return (oav);
415 char **
416 blkcat_(char **up, char **vp)
419 (void) blkcpy_(blkend_(up), vp);
420 return (up);
423 char **
424 blkspl_(char **up, char **vp)
426 char **wp =
427 (char **)xcalloc((unsigned)(blklen_(up) + blklen_(vp) + 1),
428 sizeof (char **));
430 (void) blkcpy_(wp, up);
431 return (blkcat_(wp, vp));
435 * If stack address was passed to free(), we have no good way to see if
436 * they are really in the stack. Therefore, we record the bottom of heap,
437 * and filter out the address not within heap's top(end) and bottom
438 * (xalloc_bottom).
440 extern char end[];
441 static char *xalloc_bottom;
443 void *
444 xalloc(size_t size)
446 char *rptr, *bp;
448 if ((rptr = malloc(size)) == NULL)
449 return (nomem(size));
450 bp = rptr + size;
451 if (bp > xalloc_bottom)
452 xalloc_bottom = bp;
453 return (rptr);
456 void *
457 xrealloc(void *ptr, size_t size)
459 char *rptr = ptr, *bp;
461 if (ptr == NULL)
462 return (xalloc(size));
463 if (rptr < end) {
464 /* data area, but not in heap area. don't touch it */
465 oob:
466 if (size == 0)
467 return (NULL);
468 rptr = xalloc(size);
469 /* copy max size */
470 (void) memcpy(rptr, ptr, size);
471 return (rptr);
473 if (rptr < xalloc_bottom) {
474 /* address in the heap */
475 inb:
476 if (size == 0) {
477 free(ptr);
478 return (NULL);
480 if ((rptr = realloc(ptr, size)) == NULL)
481 return (nomem(size));
482 bp = rptr + size;
483 if (bp > xalloc_bottom)
484 xalloc_bottom = bp;
485 return (rptr);
487 #if defined(__sparc)
488 if (rptr > (char *)&rptr) {
489 /* in the stack frame */
490 goto oob;
492 #endif
494 * can be a memory block returned indirectly from
495 * library functions. update bottom, and check it again.
497 xalloc_bottom = sbrk(0);
498 if (rptr <= xalloc_bottom)
499 goto inb;
500 else
501 goto oob;
502 /*NOTREACHED*/
505 void
506 xfree(void *ptr)
508 char *rptr = ptr;
510 if (rptr < end) {
511 return;
513 if (rptr < xalloc_bottom) {
514 free(ptr);
515 return;
517 #if defined(__sparc)
518 if (rptr > (char *)&rptr) {
519 /* in the stack frame */
520 return;
522 #endif
523 xalloc_bottom = sbrk(0);
524 if (rptr <= xalloc_bottom) {
525 free(ptr);
529 void *
530 xcalloc(size_t i, size_t j)
532 char *cp;
534 i *= j;
535 cp = xalloc(i);
536 (void) memset(cp, '\0', i);
537 return (cp);