1: /* @(#)sh.misc.c 2.1 SCCS id keyword */ 2: /* Copyright (c) 1980 Regents of the University of California */ 3: #include "sh.h" 4: 5: /* 6: * C Shell 7: */ 8: 9: letter(c) 10: register char c; 11: { 12: 13: return (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c == '_'); 14: } 15: 16: digit(c) 17: register char c; 18: { 19: 20: return (c >= '0' && c <= '9'); 21: } 22: 23: alnum(c) 24: register char c; 25: { 26: return (letter(c) || digit(c)); 27: } 28: 29: any(c, s) 30: register int c; 31: register char *s; 32: { 33: 34: while (*s) 35: if (*s++ == c) 36: return(1); 37: return(0); 38: } 39: 40: char * 41: calloc(i, j) 42: register int i; 43: int j; 44: { 45: register char *cp, *dp; 46: #ifdef debug 47: static char *av[2] = {0, 0}; 48: #endif 49: 50: i *= j; 51: cp = (char *) malloc(i); 52: if (cp == 0) { 53: child++; 54: #ifndef debug 55: error("Out of memory"); 56: #else 57: showall(av); 58: printf("i=%d, j=%d: ", i/j, j); 59: printf("Out of memory\n"); 60: chdir("/usr/bill/cshcore"); 61: abort(); 62: #endif 63: } 64: dp = cp; 65: if (i > 0) 66: do 67: *dp++ = 0; 68: while (--i); 69: return (cp); 70: } 71: 72: cfree(p) 73: char *p; 74: { 75: 76: free(p); 77: } 78: 79: char ** 80: blkend(up) 81: register char **up; 82: { 83: 84: while (*up) 85: up++; 86: return (up); 87: } 88: 89: blkpr(av) 90: register int *av; 91: { 92: 93: for (; *av; av++) { 94: printf("%s", *av); 95: if (av[1]) 96: printf(" "); 97: } 98: } 99: 100: blklen(av) 101: register char **av; 102: { 103: register int i = 0; 104: 105: while (*av++) 106: i++; 107: return (i); 108: } 109: 110: char ** 111: blkcpy(oav, bv) 112: char **oav; 113: register char **bv; 114: { 115: register char **av = oav; 116: 117: while (*av++ = *bv++) 118: continue; 119: return (oav); 120: } 121: 122: char ** 123: blkcat(up, vp) 124: char **up, **vp; 125: { 126: 127: blkcpy(blkend(up), vp); 128: return (up); 129: } 130: 131: blkfree(av0) 132: char **av0; 133: { 134: register char **av = av0; 135: 136: while (*av) 137: xfree(*av++); 138: xfree(av0); 139: } 140: 141: char ** 142: saveblk(v) 143: register char **v; 144: { 145: register int len = blklen(v) + 1; 146: register char **newv = (char **) calloc(len, sizeof (char **)); 147: char **onewv = newv; 148: 149: while (*v) 150: *newv++ = savestr(*v++); 151: return (onewv); 152: } 153: 154: char * 155: strspl(cp, dp) 156: register char *cp, *dp; 157: { 158: register char *ep = calloc(1, strlen(cp) + strlen(dp) + 1); 159: 160: strcpy(ep, cp); 161: return (strcat(ep, dp)); 162: } 163: 164: char ** 165: blkspl(up, vp) 166: register char **up, **vp; 167: { 168: register char **wp = (char **) calloc(blklen(up) + blklen(vp) + 1, sizeof (char **)); 169: 170: blkcpy(wp, up); 171: return (blkcat(wp, vp)); 172: } 173: 174: lastchr(cp) 175: register char *cp; 176: { 177: 178: if (!*cp) 179: return (0); 180: while (cp[1]) 181: cp++; 182: return (*cp); 183: } 184: 185: /* 186: * This routine is called after an error to close up 187: * any units which may have been left open accidentally. 188: */ 189: closem() 190: { 191: register int f; 192: 193: for (f = 0; f < NOFILE; f++) 194: if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD) 195: close(f); 196: } 197: 198: /* 199: * Close files before executing a file. 200: * We could be MUCH more intelligent, since (on a version 7 system) 201: * we need only close files here during a source, the other 202: * shell fd's being in units 16-19 which are closed automatically! 203: */ 204: closech() 205: { 206: register int f; 207: 208: if (didcch) 209: return; 210: didcch = 1; 211: SHIN = 0; SHOUT = 1; SHDIAG = 2; OLDSTD = 0; 212: for (f = 3; f < NOFILE; f++) 213: close(f); 214: } 215: 216: donefds() 217: { 218: 219: close(0), close(1), close(2); 220: didfds = 0; 221: } 222: 223: /* 224: * Move descriptor i to j. 225: * If j is -1 then we just want to get i to a safe place, 226: * i.e. to a unit > 2. This also happens in dcopy. 227: */ 228: dmove(i, j) 229: register int i, j; 230: { 231: 232: if (i == j || i < 0) 233: return (i); 234: #ifdef V7 235: if (j >= 0) { 236: dup2(i, j); 237: return (j); 238: } else 239: #endif 240: j = dcopy(i, j); 241: if (j != i) 242: close(i); 243: return (j); 244: } 245: 246: dcopy(i, j) 247: register int i, j; 248: { 249: 250: if (i == j || i < 0 || j < 0 && i > 2) 251: return (i); 252: #ifdef V7 253: if (j >= 0) { 254: dup2(i, j); 255: return (j); 256: } 257: #endif 258: close(j); 259: return (renum(i, j)); 260: } 261: 262: renum(i, j) 263: register int i, j; 264: { 265: register int k = dup(i); 266: 267: if (k < 0) 268: return (-1); 269: if (j == -1 && k > 2) 270: return (k); 271: if (k != j) { 272: j = renum(k, j); 273: close(k); 274: return (j); 275: } 276: return (k); 277: } 278: 279: copy(to, from, size) 280: register char *to, *from; 281: register int size; 282: { 283: 284: if (size) 285: do 286: *to++ = *from++; 287: while (--size != 0); 288: } 289: 290: /* 291: * Left shift a command argument list, discarding 292: * the first c arguments. Used in "shift" commands 293: * as well as by commands like "repeat". 294: */ 295: lshift(v, c) 296: register char **v; 297: register int c; 298: { 299: register char **u = v; 300: 301: while (*u && --c >= 0) 302: xfree(*u++); 303: blkcpy(v, u); 304: } 305: 306: number(cp) 307: char *cp; 308: { 309: 310: if (*cp == '-') { 311: cp++; 312: if (!digit(*cp++)) 313: return (0); 314: } 315: while (*cp && digit(*cp)) 316: cp++; 317: return (*cp == 0); 318: } 319: 320: char ** 321: copyblk(v) 322: register char **v; 323: { 324: register char **nv = (char **) calloc(blklen(v) + 1, sizeof (char **)); 325: 326: return (blkcpy(nv, v)); 327: } 328: 329: char * 330: strend(cp) 331: register char *cp; 332: { 333: 334: while (*cp) 335: cp++; 336: return (cp); 337: } 338: 339: char * 340: strip(cp) 341: char *cp; 342: { 343: register char *dp = cp; 344: 345: while (*dp++ &= TRIM) 346: continue; 347: return (cp); 348: } 349: 350: udvar(name) 351: char *name; 352: { 353: 354: setname(name); 355: bferr("Undefined variable"); 356: }