147823Sbostic /*- 247823Sbostic * Copyright (c) 1980, 1991 The Regents of the University of California. 347823Sbostic * All rights reserved. 447823Sbostic * 547823Sbostic * %sccs.include.redist.c% 621938Sdist */ 721938Sdist 817511Sedward #ifndef lint 9*50233Schristos static char sccsid[] = "@(#)misc.c 5.13 (Berkeley) 06/27/91"; 1047823Sbostic #endif /* not lint */ 111300Sbill 1250028Sbostic #include <sys/param.h> 1350028Sbostic #include <stdlib.h> 1450028Sbostic #include <unistd.h> 1550033Schristos #if __STDC__ 1650033Schristos # include <stdarg.h> 1750033Schristos #else 1850033Schristos # include <varargs.h> 1950033Schristos #endif 2050033Schristos 2150023Sbostic #include "csh.h" 2250023Sbostic #include "extern.h" 231300Sbill 2450024Schristos static int renum __P((int, int)); 251300Sbill 2649992Sbostic int 2749992Sbostic any(s, c) 2849992Sbostic register char *s; 2949992Sbostic register int c; 3017511Sedward { 3149992Sbostic if (!s) 3249992Sbostic return (0); /* Check for nil pointer */ 3349992Sbostic while (*s) 3449992Sbostic if (*s++ == c) 3549992Sbostic return (1); 3649992Sbostic return (0); 3717511Sedward } 3817511Sedward 3949992Sbostic void 4049992Sbostic setzero(cp, i) 4149992Sbostic char *cp; 4249992Sbostic int i; 4317511Sedward { 4449992Sbostic if (i != 0) 4549992Sbostic do 4649992Sbostic *cp++ = 0; 4749992Sbostic while (--i); 4817511Sedward } 4917511Sedward 5049992Sbostic char * 5149992Sbostic strsave(s) 5249992Sbostic register char *s; 5317511Sedward { 5449992Sbostic char *n; 5549992Sbostic register char *p; 5617511Sedward 5750023Sbostic if (s == NULL) 5849992Sbostic s = ""; 5949992Sbostic for (p = s; *p++;); 6049992Sbostic n = p = (char *) xmalloc((size_t) ((p - s) * sizeof(char))); 6149992Sbostic while (*p++ = *s++); 6249992Sbostic return (n); 6317511Sedward } 6417511Sedward 6549992Sbostic Char ** 6649992Sbostic blkend(up) 6749992Sbostic register Char **up; 681300Sbill { 691300Sbill 7049992Sbostic while (*up) 7149992Sbostic up++; 7249992Sbostic return (up); 731300Sbill } 741300Sbill 7517511Sedward 7649992Sbostic void 771300Sbill blkpr(av) 7849992Sbostic register Char **av; 791300Sbill { 801300Sbill 8149992Sbostic for (; *av; av++) { 8249992Sbostic xprintf("%s", short2str(*av)); 8349992Sbostic if (av[1]) 8449992Sbostic xprintf(" "); 8549992Sbostic } 861300Sbill } 871300Sbill 8849992Sbostic int 891300Sbill blklen(av) 9049992Sbostic register Char **av; 911300Sbill { 9249992Sbostic register int i = 0; 931300Sbill 9449992Sbostic while (*av++) 9549992Sbostic i++; 9649992Sbostic return (i); 971300Sbill } 981300Sbill 9949992Sbostic Char ** 1001300Sbill blkcpy(oav, bv) 10149992Sbostic Char **oav; 10249992Sbostic register Char **bv; 1031300Sbill { 10449992Sbostic register Char **av = oav; 1051300Sbill 10649992Sbostic while (*av++ = *bv++) 10749992Sbostic continue; 10849992Sbostic return (oav); 1091300Sbill } 1101300Sbill 11149992Sbostic Char ** 1121300Sbill blkcat(up, vp) 11349992Sbostic Char **up, **vp; 1141300Sbill { 1151300Sbill 11649992Sbostic (void) blkcpy(blkend(up), vp); 11749992Sbostic return (up); 1181300Sbill } 1191300Sbill 12049992Sbostic void 1211300Sbill blkfree(av0) 12249992Sbostic Char **av0; 1231300Sbill { 12449992Sbostic register Char **av = av0; 1251300Sbill 12649992Sbostic if (!av0) 12749992Sbostic return; 12849992Sbostic for (; *av; av++) 12949992Sbostic xfree((ptr_t) * av); 13049992Sbostic xfree((ptr_t) av0); 1311300Sbill } 1321300Sbill 13349992Sbostic Char ** 1341300Sbill saveblk(v) 13549992Sbostic register Char **v; 1361300Sbill { 13749992Sbostic register Char **newv = 13849992Sbostic (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 13949992Sbostic Char **onewv = newv; 1401300Sbill 14149992Sbostic while (*v) 14249992Sbostic *newv++ = Strsave(*v++); 14349992Sbostic return (onewv); 1441300Sbill } 1451300Sbill 14650011Schristos #ifdef NOTUSED 14749992Sbostic char * 14849992Sbostic strstr(s, t) 14949992Sbostic register char *s, *t; 15049992Sbostic { 15149992Sbostic do { 15249992Sbostic register char *ss = s; 15349992Sbostic register char *tt = t; 15449992Sbostic 15549992Sbostic do 15649992Sbostic if (*tt == '\0') 15749992Sbostic return (s); 15849992Sbostic while (*ss++ == *tt++); 15949992Sbostic } while (*s++ != '\0'); 16050024Schristos return (NULL); 16149992Sbostic } 16249992Sbostic 16350011Schristos #endif /* NOTUSED */ 16449992Sbostic 16549992Sbostic #ifndef SHORT_STRINGS 16649992Sbostic char * 1671300Sbill strspl(cp, dp) 16849992Sbostic char *cp, *dp; 1691300Sbill { 17049992Sbostic char *ep; 17149992Sbostic register char *p, *q; 1721300Sbill 17349992Sbostic if (!cp) 17449992Sbostic cp = ""; 17549992Sbostic if (!dp) 17649992Sbostic dp = ""; 17749992Sbostic for (p = cp; *p++;); 17849992Sbostic for (q = dp; *q++;); 17949992Sbostic ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char))); 18049992Sbostic for (p = ep, q = cp; *p++ = *q++;); 18149992Sbostic for (p--, q = dp; *p++ = *q++;); 18249992Sbostic return (ep); 1831300Sbill } 1841300Sbill 18549992Sbostic #endif 18649992Sbostic 18749992Sbostic Char ** 1881300Sbill blkspl(up, vp) 18949992Sbostic register Char **up, **vp; 1901300Sbill { 19149992Sbostic register Char **wp = 19249992Sbostic (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1), 19349992Sbostic sizeof(Char **)); 1941300Sbill 19549992Sbostic (void) blkcpy(wp, up); 19649992Sbostic return (blkcat(wp, vp)); 1971300Sbill } 1981300Sbill 19949992Sbostic Char 2001300Sbill lastchr(cp) 20149992Sbostic register Char *cp; 2021300Sbill { 2031300Sbill 20449992Sbostic if (!cp) 20549992Sbostic return (0); 20649992Sbostic if (!*cp) 20749992Sbostic return (0); 20849992Sbostic while (cp[1]) 20949992Sbostic cp++; 21049992Sbostic return (*cp); 2111300Sbill } 2121300Sbill 2131300Sbill /* 2141300Sbill * This routine is called after an error to close up 2151300Sbill * any units which may have been left open accidentally. 2161300Sbill */ 21749992Sbostic void 2181300Sbill closem() 2191300Sbill { 22049992Sbostic register int f; 2211300Sbill 22249992Sbostic for (f = 0; f < NOFILE; f++) 22349992Sbostic if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD && 22449992Sbostic f != FSHTTY) 22549992Sbostic (void) close(f); 2261300Sbill } 2271300Sbill 22849992Sbostic void 2291300Sbill donefds() 2301300Sbill { 2311300Sbill 23249992Sbostic (void) close(0); 23349992Sbostic (void) close(1); 23449992Sbostic (void) close(2); 23549992Sbostic didfds = 0; 2361300Sbill } 2371300Sbill 2381300Sbill /* 2391300Sbill * Move descriptor i to j. 2401300Sbill * If j is -1 then we just want to get i to a safe place, 2411300Sbill * i.e. to a unit > 2. This also happens in dcopy. 2421300Sbill */ 24349992Sbostic int 2441300Sbill dmove(i, j) 24549992Sbostic register int i, j; 2461300Sbill { 2471300Sbill 24849992Sbostic if (i == j || i < 0) 24949992Sbostic return (i); 25049992Sbostic if (j >= 0) { 25149992Sbostic (void) dup2(i, j); 252*50233Schristos if (j != i) 253*50233Schristos (void) close(i); 2541300Sbill return (j); 25549992Sbostic } 25649992Sbostic j = dcopy(i, j); 25749992Sbostic if (j != i) 25849992Sbostic (void) close(i); 25949992Sbostic return (j); 2601300Sbill } 2611300Sbill 26249992Sbostic int 2631300Sbill dcopy(i, j) 26449992Sbostic register int i, j; 2651300Sbill { 2661300Sbill 26749992Sbostic if (i == j || i < 0 || j < 0 && i > 2) 26849992Sbostic return (i); 26949992Sbostic if (j >= 0) { 27049992Sbostic (void) dup2(i, j); 27149992Sbostic return (j); 27249992Sbostic } 27349992Sbostic (void) close(j); 27449992Sbostic return (renum(i, j)); 2751300Sbill } 2761300Sbill 27749992Sbostic static int 2781300Sbill renum(i, j) 27949992Sbostic register int i, j; 2801300Sbill { 28149992Sbostic register int k = dup(i); 2821300Sbill 28349992Sbostic if (k < 0) 28449992Sbostic return (-1); 28549992Sbostic if (j == -1 && k > 2) 2861300Sbill return (k); 28749992Sbostic if (k != j) { 28849992Sbostic j = renum(k, j); 28949992Sbostic (void) close(k); 29049992Sbostic return (j); 29149992Sbostic } 29249992Sbostic return (k); 2931300Sbill } 2941300Sbill 2951300Sbill /* 2961300Sbill * Left shift a command argument list, discarding 2971300Sbill * the first c arguments. Used in "shift" commands 2981300Sbill * as well as by commands like "repeat". 2991300Sbill */ 30049992Sbostic void 3011300Sbill lshift(v, c) 30249992Sbostic register Char **v; 30349992Sbostic register int c; 3041300Sbill { 30549992Sbostic register Char **u = v; 3061300Sbill 30749992Sbostic while (*u && --c >= 0) 30849992Sbostic xfree((ptr_t) * u++); 30949992Sbostic (void) blkcpy(v, u); 3101300Sbill } 3111300Sbill 31249992Sbostic int 3131300Sbill number(cp) 31449992Sbostic Char *cp; 3151300Sbill { 31649992Sbostic if (!cp) 31749992Sbostic return(0); 31849992Sbostic if (*cp == '-') { 31949992Sbostic cp++; 32049992Sbostic if (!Isdigit(*cp)) 32149992Sbostic return (0); 32249992Sbostic cp++; 32349992Sbostic } 32449992Sbostic while (*cp && Isdigit(*cp)) 32549992Sbostic cp++; 32649992Sbostic return (*cp == 0); 3271300Sbill } 3281300Sbill 32949992Sbostic Char ** 3301300Sbill copyblk(v) 33149992Sbostic register Char **v; 3321300Sbill { 33349992Sbostic Char **nv = (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 3341300Sbill 33549992Sbostic return (blkcpy(nv, v)); 3361300Sbill } 3371300Sbill 33849992Sbostic #ifndef SHORT_STRINGS 33949992Sbostic char * 3401300Sbill strend(cp) 34149992Sbostic register char *cp; 3421300Sbill { 34349992Sbostic if (!cp) 3441300Sbill return (cp); 34549992Sbostic while (*cp) 34649992Sbostic cp++; 34749992Sbostic return (cp); 3481300Sbill } 3491300Sbill 35049992Sbostic #endif /* SHORT_STRINGS */ 35149992Sbostic 35249992Sbostic Char * 3531300Sbill strip(cp) 35449992Sbostic Char *cp; 3551300Sbill { 35649992Sbostic register Char *dp = cp; 3571300Sbill 35849992Sbostic if (!cp) 3591300Sbill return (cp); 36049992Sbostic while (*dp++ &= TRIM) 36149992Sbostic continue; 36249992Sbostic return (cp); 3631300Sbill } 3641300Sbill 36549992Sbostic void 3661300Sbill udvar(name) 36749992Sbostic Char *name; 3681300Sbill { 3691300Sbill 37049992Sbostic setname(short2str(name)); 37149992Sbostic stderror(ERR_NAME | ERR_UNDVAR); 3721300Sbill } 3731300Sbill 37449992Sbostic int 3751300Sbill prefix(sub, str) 37649992Sbostic register Char *sub, *str; 3771300Sbill { 3781300Sbill 37949992Sbostic for (;;) { 38049992Sbostic if (*sub == 0) 38149992Sbostic return (1); 38249992Sbostic if (*str == 0) 38349992Sbostic return (0); 38449992Sbostic if (*sub++ != *str++) 38549992Sbostic return (0); 38649992Sbostic } 3871300Sbill } 388