1*17511Sedward #ifndef lint 2*17511Sedward static char *sccsid = "@(#)misc.c 4.4 (Berkeley) 12/13/84"; 3*17511Sedward #endif 41300Sbill 51300Sbill #include "sh.h" 61300Sbill 71300Sbill /* 81300Sbill * C Shell 91300Sbill */ 101300Sbill 111300Sbill letter(c) 121300Sbill register char c; 131300Sbill { 141300Sbill 151300Sbill return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_'); 161300Sbill } 171300Sbill 181300Sbill digit(c) 191300Sbill register char c; 201300Sbill { 211300Sbill 221300Sbill return (c >= '0' && c <= '9'); 231300Sbill } 241300Sbill 251300Sbill alnum(c) 261300Sbill register char c; 271300Sbill { 281300Sbill return (letter(c) || digit(c)); 291300Sbill } 301300Sbill 311300Sbill any(c, s) 321300Sbill register int c; 331300Sbill register char *s; 341300Sbill { 351300Sbill 361300Sbill while (*s) 371300Sbill if (*s++ == c) 381300Sbill return(1); 391300Sbill return(0); 401300Sbill } 411300Sbill 42*17511Sedward onlyread(cp) 43*17511Sedward char *cp; 44*17511Sedward { 45*17511Sedward extern char end[]; 46*17511Sedward 47*17511Sedward return (cp < end); 48*17511Sedward } 49*17511Sedward 50*17511Sedward xfree(cp) 51*17511Sedward char *cp; 52*17511Sedward { 53*17511Sedward extern char end[]; 54*17511Sedward 55*17511Sedward if (cp >= end && cp < (char *) &cp) 56*17511Sedward free(cp); 57*17511Sedward } 58*17511Sedward 591300Sbill char * 60*17511Sedward savestr(s) 61*17511Sedward register char *s; 62*17511Sedward { 63*17511Sedward char *n; 64*17511Sedward register char *p; 65*17511Sedward 66*17511Sedward if (s == 0) 67*17511Sedward s = ""; 68*17511Sedward for (p = s; *p++;) 69*17511Sedward ; 70*17511Sedward n = p = xalloc((unsigned) (p - s)); 71*17511Sedward while (*p++ = *s++) 72*17511Sedward ; 73*17511Sedward return (n); 74*17511Sedward } 75*17511Sedward 76*17511Sedward char * 771300Sbill calloc(i, j) 781300Sbill register unsigned i; 791300Sbill unsigned j; 801300Sbill { 811300Sbill register char *cp, *dp; 821300Sbill 831300Sbill i *= j; 84*17511Sedward dp = cp = xalloc(i); 851300Sbill if (i != 0) 861300Sbill do 871300Sbill *dp++ = 0; 881300Sbill while (--i); 891300Sbill return (cp); 901300Sbill } 911300Sbill 92*17511Sedward nomem(i) 93*17511Sedward unsigned i; 94*17511Sedward { 95*17511Sedward #ifdef debug 96*17511Sedward static char *av[2] = {0, 0}; 97*17511Sedward #endif 98*17511Sedward 99*17511Sedward child++; 100*17511Sedward #ifndef debug 101*17511Sedward error("Out of memory"); 102*17511Sedward #ifdef lint 103*17511Sedward i = i; 104*17511Sedward #endif 105*17511Sedward #else 106*17511Sedward showall(av); 107*17511Sedward printf("i=%d: Out of memory\n", i); 108*17511Sedward chdir("/usr/bill/cshcore"); 109*17511Sedward abort(); 110*17511Sedward #endif 111*17511Sedward return 0; /* fool lint */ 112*17511Sedward } 113*17511Sedward 1141300Sbill char ** 1151300Sbill blkend(up) 1161300Sbill register char **up; 1171300Sbill { 1181300Sbill 1191300Sbill while (*up) 1201300Sbill up++; 1211300Sbill return (up); 1221300Sbill } 1231300Sbill 1241300Sbill blkpr(av) 1251300Sbill register char **av; 1261300Sbill { 1271300Sbill 1281300Sbill for (; *av; av++) { 1291300Sbill printf("%s", *av); 1301300Sbill if (av[1]) 1311300Sbill printf(" "); 1321300Sbill } 1331300Sbill } 1341300Sbill 1351300Sbill blklen(av) 1361300Sbill register char **av; 1371300Sbill { 1381300Sbill register int i = 0; 1391300Sbill 1401300Sbill while (*av++) 1411300Sbill i++; 1421300Sbill return (i); 1431300Sbill } 1441300Sbill 1451300Sbill char ** 1461300Sbill blkcpy(oav, bv) 1471300Sbill char **oav; 1481300Sbill register char **bv; 1491300Sbill { 1501300Sbill register char **av = oav; 1511300Sbill 1521300Sbill while (*av++ = *bv++) 1531300Sbill continue; 1541300Sbill return (oav); 1551300Sbill } 1561300Sbill 1571300Sbill char ** 1581300Sbill blkcat(up, vp) 1591300Sbill char **up, **vp; 1601300Sbill { 1611300Sbill 162*17511Sedward (void) blkcpy(blkend(up), vp); 1631300Sbill return (up); 1641300Sbill } 1651300Sbill 1661300Sbill blkfree(av0) 1671300Sbill char **av0; 1681300Sbill { 1691300Sbill register char **av = av0; 1701300Sbill 171*17511Sedward for (; *av; av++) 172*17511Sedward XFREE(*av) 173*17511Sedward XFREE((char *)av0) 1741300Sbill } 1751300Sbill 1761300Sbill char ** 1771300Sbill saveblk(v) 1781300Sbill register char **v; 1791300Sbill { 180*17511Sedward register char **newv = 181*17511Sedward (char **) calloc((unsigned) (blklen(v) + 1), sizeof (char **)); 1821300Sbill char **onewv = newv; 1831300Sbill 1841300Sbill while (*v) 1851300Sbill *newv++ = savestr(*v++); 1861300Sbill return (onewv); 1871300Sbill } 1881300Sbill 1891300Sbill char * 1901300Sbill strspl(cp, dp) 191*17511Sedward char *cp, *dp; 1921300Sbill { 193*17511Sedward char *ep; 194*17511Sedward register char *p, *q; 1951300Sbill 196*17511Sedward for (p = cp; *p++;) 197*17511Sedward ; 198*17511Sedward for (q = dp; *q++;) 199*17511Sedward ; 200*17511Sedward ep = xalloc((unsigned) ((p - cp) + (q - dp) - 1)); 201*17511Sedward for (p = ep, q = cp; *p++ = *q++;) 202*17511Sedward ; 203*17511Sedward for (p--, q = dp; *p++ = *q++;) 204*17511Sedward ; 2051300Sbill return (ep); 2061300Sbill } 2071300Sbill 2081300Sbill char ** 2091300Sbill blkspl(up, vp) 2101300Sbill register char **up, **vp; 2111300Sbill { 212*17511Sedward register char **wp = 213*17511Sedward (char **) calloc((unsigned) (blklen(up) + blklen(vp) + 1), 214*17511Sedward sizeof (char **)); 2151300Sbill 216*17511Sedward (void) blkcpy(wp, up); 2171300Sbill return (blkcat(wp, vp)); 2181300Sbill } 2191300Sbill 2201300Sbill lastchr(cp) 2211300Sbill register char *cp; 2221300Sbill { 2231300Sbill 2241300Sbill if (!*cp) 2251300Sbill return (0); 2261300Sbill while (cp[1]) 2271300Sbill cp++; 2281300Sbill return (*cp); 2291300Sbill } 2301300Sbill 2311300Sbill /* 2321300Sbill * This routine is called after an error to close up 2331300Sbill * any units which may have been left open accidentally. 2341300Sbill */ 2351300Sbill closem() 2361300Sbill { 2371300Sbill register int f; 2381300Sbill 2391300Sbill for (f = 0; f < NOFILE; f++) 2401300Sbill if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD && 2411300Sbill f != FSHTTY) 242*17511Sedward (void) close(f); 2431300Sbill } 2441300Sbill 2451300Sbill donefds() 2461300Sbill { 2471300Sbill 248*17511Sedward (void) close(0); 249*17511Sedward (void) close(1); 250*17511Sedward (void) close(2); 2511300Sbill didfds = 0; 2521300Sbill } 2531300Sbill 2541300Sbill /* 2551300Sbill * Move descriptor i to j. 2561300Sbill * If j is -1 then we just want to get i to a safe place, 2571300Sbill * i.e. to a unit > 2. This also happens in dcopy. 2581300Sbill */ 2591300Sbill dmove(i, j) 2601300Sbill register int i, j; 2611300Sbill { 2621300Sbill 2631300Sbill if (i == j || i < 0) 2641300Sbill return (i); 2651300Sbill if (j >= 0) { 266*17511Sedward (void) dup2(i, j); 2671300Sbill return (j); 268*17511Sedward } 269*17511Sedward j = dcopy(i, j); 2701300Sbill if (j != i) 271*17511Sedward (void) close(i); 2721300Sbill return (j); 2731300Sbill } 2741300Sbill 2751300Sbill dcopy(i, j) 2761300Sbill register int i, j; 2771300Sbill { 2781300Sbill 2791300Sbill if (i == j || i < 0 || j < 0 && i > 2) 2801300Sbill return (i); 2811300Sbill if (j >= 0) { 282*17511Sedward (void) dup2(i, j); 2831300Sbill return (j); 2841300Sbill } 285*17511Sedward (void) close(j); 2861300Sbill return (renum(i, j)); 2871300Sbill } 2881300Sbill 2891300Sbill renum(i, j) 2901300Sbill register int i, j; 2911300Sbill { 2921300Sbill register int k = dup(i); 2931300Sbill 2941300Sbill if (k < 0) 2951300Sbill return (-1); 2961300Sbill if (j == -1 && k > 2) 2971300Sbill return (k); 2981300Sbill if (k != j) { 2991300Sbill j = renum(k, j); 300*17511Sedward (void) close(k); 3011300Sbill return (j); 3021300Sbill } 3031300Sbill return (k); 3041300Sbill } 3051300Sbill 30616678Ssam #ifndef copy 3071300Sbill copy(to, from, size) 3081300Sbill register char *to, *from; 3091300Sbill register int size; 3101300Sbill { 3111300Sbill 3121300Sbill if (size) 3131300Sbill do 3141300Sbill *to++ = *from++; 3151300Sbill while (--size != 0); 3161300Sbill } 31716678Ssam #endif 3181300Sbill 3191300Sbill /* 3201300Sbill * Left shift a command argument list, discarding 3211300Sbill * the first c arguments. Used in "shift" commands 3221300Sbill * as well as by commands like "repeat". 3231300Sbill */ 3241300Sbill lshift(v, c) 3251300Sbill register char **v; 3261300Sbill register int c; 3271300Sbill { 3281300Sbill register char **u = v; 3291300Sbill 3301300Sbill while (*u && --c >= 0) 3311300Sbill xfree(*u++); 332*17511Sedward (void) blkcpy(v, u); 3331300Sbill } 3341300Sbill 3351300Sbill number(cp) 3361300Sbill char *cp; 3371300Sbill { 3381300Sbill 3391300Sbill if (*cp == '-') { 3401300Sbill cp++; 3411300Sbill if (!digit(*cp++)) 3421300Sbill return (0); 3431300Sbill } 3441300Sbill while (*cp && digit(*cp)) 3451300Sbill cp++; 3461300Sbill return (*cp == 0); 3471300Sbill } 3481300Sbill 3491300Sbill char ** 3501300Sbill copyblk(v) 3511300Sbill register char **v; 3521300Sbill { 353*17511Sedward register char **nv = 354*17511Sedward (char **) calloc((unsigned) (blklen(v) + 1), sizeof (char **)); 3551300Sbill 3561300Sbill return (blkcpy(nv, v)); 3571300Sbill } 3581300Sbill 3591300Sbill char * 3601300Sbill strend(cp) 3611300Sbill register char *cp; 3621300Sbill { 3631300Sbill 3641300Sbill while (*cp) 3651300Sbill cp++; 3661300Sbill return (cp); 3671300Sbill } 3681300Sbill 3691300Sbill char * 3701300Sbill strip(cp) 3711300Sbill char *cp; 3721300Sbill { 3731300Sbill register char *dp = cp; 3741300Sbill 3751300Sbill while (*dp++ &= TRIM) 3761300Sbill continue; 3771300Sbill return (cp); 3781300Sbill } 3791300Sbill 3801300Sbill udvar(name) 3811300Sbill char *name; 3821300Sbill { 3831300Sbill 3841300Sbill setname(name); 3851300Sbill bferr("Undefined variable"); 3861300Sbill } 3871300Sbill 3881300Sbill prefix(sub, str) 3891300Sbill register char *sub, *str; 3901300Sbill { 3911300Sbill 3921300Sbill for (;;) { 3931300Sbill if (*sub == 0) 3941300Sbill return (1); 3951300Sbill if (*str == 0) 3961300Sbill return (0); 3971300Sbill if (*sub++ != *str++) 3981300Sbill return (0); 3991300Sbill } 4001300Sbill } 401