1 static char *sccsid = "@(#)misc.c 4.1 10/09/80"; 2 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 unsigned i; 43 unsigned 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 char **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((char *)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 strcat(ep, dp); 162 return (ep); 163 } 164 165 char ** 166 blkspl(up, vp) 167 register char **up, **vp; 168 { 169 register char **wp = (char **) calloc(blklen(up) + blklen(vp) + 1, sizeof (char **)); 170 171 blkcpy(wp, up); 172 return (blkcat(wp, vp)); 173 } 174 175 lastchr(cp) 176 register char *cp; 177 { 178 179 if (!*cp) 180 return (0); 181 while (cp[1]) 182 cp++; 183 return (*cp); 184 } 185 186 /* 187 * This routine is called after an error to close up 188 * any units which may have been left open accidentally. 189 */ 190 closem() 191 { 192 register int f; 193 194 for (f = 0; f < NOFILE; f++) 195 if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD && 196 f != FSHTTY) 197 close(f); 198 } 199 200 /* 201 * Close files before executing a file. 202 * We could be MUCH more intelligent, since (on a version 7 system) 203 * we need only close files here during a source, the other 204 * shell fd's being in units 16-19 which are closed automatically! 205 */ 206 closech() 207 { 208 register int f; 209 210 if (didcch) 211 return; 212 didcch = 1; 213 SHIN = 0; SHOUT = 1; SHDIAG = 2; OLDSTD = 0; 214 for (f = 3; f < NOFILE; f++) 215 close(f); 216 } 217 218 donefds() 219 { 220 221 close(0), close(1), close(2); 222 didfds = 0; 223 } 224 225 /* 226 * Move descriptor i to j. 227 * If j is -1 then we just want to get i to a safe place, 228 * i.e. to a unit > 2. This also happens in dcopy. 229 */ 230 dmove(i, j) 231 register int i, j; 232 { 233 234 if (i == j || i < 0) 235 return (i); 236 #ifdef V7 237 if (j >= 0) { 238 dup2(i, j); 239 return (j); 240 } else 241 #endif 242 j = dcopy(i, j); 243 if (j != i) 244 close(i); 245 return (j); 246 } 247 248 dcopy(i, j) 249 register int i, j; 250 { 251 252 if (i == j || i < 0 || j < 0 && i > 2) 253 return (i); 254 #ifdef V7 255 if (j >= 0) { 256 dup2(i, j); 257 return (j); 258 } 259 #endif 260 close(j); 261 return (renum(i, j)); 262 } 263 264 renum(i, j) 265 register int i, j; 266 { 267 register int k = dup(i); 268 269 if (k < 0) 270 return (-1); 271 if (j == -1 && k > 2) 272 return (k); 273 if (k != j) { 274 j = renum(k, j); 275 close(k); 276 return (j); 277 } 278 return (k); 279 } 280 281 copy(to, from, size) 282 register char *to, *from; 283 register int size; 284 { 285 286 if (size) 287 do 288 *to++ = *from++; 289 while (--size != 0); 290 } 291 292 /* 293 * Left shift a command argument list, discarding 294 * the first c arguments. Used in "shift" commands 295 * as well as by commands like "repeat". 296 */ 297 lshift(v, c) 298 register char **v; 299 register int c; 300 { 301 register char **u = v; 302 303 while (*u && --c >= 0) 304 xfree(*u++); 305 blkcpy(v, u); 306 } 307 308 number(cp) 309 char *cp; 310 { 311 312 if (*cp == '-') { 313 cp++; 314 if (!digit(*cp++)) 315 return (0); 316 } 317 while (*cp && digit(*cp)) 318 cp++; 319 return (*cp == 0); 320 } 321 322 char ** 323 copyblk(v) 324 register char **v; 325 { 326 register char **nv = (char **) calloc(blklen(v) + 1, sizeof (char **)); 327 328 return (blkcpy(nv, v)); 329 } 330 331 char * 332 strend(cp) 333 register char *cp; 334 { 335 336 while (*cp) 337 cp++; 338 return (cp); 339 } 340 341 char * 342 strip(cp) 343 char *cp; 344 { 345 register char *dp = cp; 346 347 while (*dp++ &= TRIM) 348 continue; 349 return (cp); 350 } 351 352 udvar(name) 353 char *name; 354 { 355 356 setname(name); 357 bferr("Undefined variable"); 358 } 359 360 prefix(sub, str) 361 register char *sub, *str; 362 { 363 364 for (;;) { 365 if (*sub == 0) 366 return (1); 367 if (*str == 0) 368 return (0); 369 if (*sub++ != *str++) 370 return (0); 371 } 372 } 373