1 /*- 2 * Copyright (c) 1980, 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)misc.c 5.19 (Berkeley) 05/22/93"; 10 #endif /* not lint */ 11 12 #include <sys/param.h> 13 #include <stdlib.h> 14 #include <unistd.h> 15 #if __STDC__ 16 # include <stdarg.h> 17 #else 18 # include <varargs.h> 19 #endif 20 21 #include "csh.h" 22 #include "extern.h" 23 24 static int renum __P((int, int)); 25 26 int 27 any(s, c) 28 register char *s; 29 register int c; 30 { 31 if (!s) 32 return (0); /* Check for nil pointer */ 33 while (*s) 34 if (*s++ == c) 35 return (1); 36 return (0); 37 } 38 39 void 40 setzero(cp, i) 41 char *cp; 42 int i; 43 { 44 if (i != 0) 45 do 46 *cp++ = 0; 47 while (--i); 48 } 49 50 char * 51 strsave(s) 52 register char *s; 53 { 54 char *n; 55 register char *p; 56 57 if (s == NULL) 58 s = ""; 59 for (p = s; *p++;) 60 continue; 61 n = p = (char *) xmalloc((size_t) ((p - s) * sizeof(char))); 62 while ((*p++ = *s++) != '\0') 63 continue; 64 return (n); 65 } 66 67 Char ** 68 blkend(up) 69 register Char **up; 70 { 71 72 while (*up) 73 up++; 74 return (up); 75 } 76 77 78 void 79 blkpr(fp, av) 80 FILE *fp; 81 register Char **av; 82 { 83 84 for (; *av; av++) { 85 (void) fprintf(fp, "%s", vis_str(*av)); 86 if (av[1]) 87 (void) fprintf(fp, " "); 88 } 89 } 90 91 int 92 blklen(av) 93 register Char **av; 94 { 95 register int i = 0; 96 97 while (*av++) 98 i++; 99 return (i); 100 } 101 102 Char ** 103 blkcpy(oav, bv) 104 Char **oav; 105 register Char **bv; 106 { 107 register Char **av = oav; 108 109 while ((*av++ = *bv++) != NULL) 110 continue; 111 return (oav); 112 } 113 114 Char ** 115 blkcat(up, vp) 116 Char **up, **vp; 117 { 118 119 (void) blkcpy(blkend(up), vp); 120 return (up); 121 } 122 123 void 124 blkfree(av0) 125 Char **av0; 126 { 127 register Char **av = av0; 128 129 if (!av0) 130 return; 131 for (; *av; av++) 132 xfree((ptr_t) * av); 133 xfree((ptr_t) av0); 134 } 135 136 Char ** 137 saveblk(v) 138 register Char **v; 139 { 140 register Char **newv = 141 (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 142 Char **onewv = newv; 143 144 while (*v) 145 *newv++ = Strsave(*v++); 146 return (onewv); 147 } 148 149 #ifdef NOTUSED 150 char * 151 strstr(s, t) 152 register char *s, *t; 153 { 154 do { 155 register char *ss = s; 156 register char *tt = t; 157 158 do 159 if (*tt == '\0') 160 return (s); 161 while (*ss++ == *tt++); 162 } while (*s++ != '\0'); 163 return (NULL); 164 } 165 166 #endif /* NOTUSED */ 167 168 #ifndef SHORT_STRINGS 169 char * 170 strspl(cp, dp) 171 char *cp, *dp; 172 { 173 char *ep; 174 register char *p, *q; 175 176 if (!cp) 177 cp = ""; 178 if (!dp) 179 dp = ""; 180 for (p = cp; *p++;) 181 continue; 182 for (q = dp; *q++;) 183 continue; 184 ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char))); 185 for (p = ep, q = cp; *p++ = *q++;) 186 continue; 187 for (p--, q = dp; *p++ = *q++;) 188 continue; 189 return (ep); 190 } 191 192 #endif 193 194 Char ** 195 blkspl(up, vp) 196 register Char **up, **vp; 197 { 198 register Char **wp = 199 (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1), 200 sizeof(Char **)); 201 202 (void) blkcpy(wp, up); 203 return (blkcat(wp, vp)); 204 } 205 206 Char 207 lastchr(cp) 208 register Char *cp; 209 { 210 211 if (!cp) 212 return (0); 213 if (!*cp) 214 return (0); 215 while (cp[1]) 216 cp++; 217 return (*cp); 218 } 219 220 /* 221 * This routine is called after an error to close up 222 * any units which may have been left open accidentally. 223 */ 224 void 225 closem() 226 { 227 register int f; 228 229 for (f = 0; f < NOFILE; f++) 230 if (f != SHIN && f != SHOUT && f != SHERR && f != OLDSTD && 231 f != FSHTTY) 232 (void) close(f); 233 } 234 235 void 236 donefds() 237 { 238 (void) close(0); 239 (void) close(1); 240 (void) close(2); 241 242 didfds = 0; 243 } 244 245 /* 246 * Move descriptor i to j. 247 * If j is -1 then we just want to get i to a safe place, 248 * i.e. to a unit > 2. This also happens in dcopy. 249 */ 250 int 251 dmove(i, j) 252 register int i, j; 253 { 254 255 if (i == j || i < 0) 256 return (i); 257 if (j >= 0) { 258 (void) dup2(i, j); 259 if (j != i) 260 (void) close(i); 261 return (j); 262 } 263 j = dcopy(i, j); 264 if (j != i) 265 (void) close(i); 266 return (j); 267 } 268 269 int 270 dcopy(i, j) 271 register int i, j; 272 { 273 274 if (i == j || i < 0 || (j < 0 && i > 2)) 275 return (i); 276 if (j >= 0) { 277 (void) dup2(i, j); 278 return (j); 279 } 280 (void) close(j); 281 return (renum(i, j)); 282 } 283 284 static int 285 renum(i, j) 286 register int i, j; 287 { 288 register int k = dup(i); 289 290 if (k < 0) 291 return (-1); 292 if (j == -1 && k > 2) 293 return (k); 294 if (k != j) { 295 j = renum(k, j); 296 (void) close(k); 297 return (j); 298 } 299 return (k); 300 } 301 302 /* 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". 306 */ 307 void 308 lshift(v, c) 309 register Char **v; 310 register int c; 311 { 312 register Char **u; 313 314 for (u = v; *u && --c >= 0; u++) 315 xfree((ptr_t) *u); 316 (void) blkcpy(v, u); 317 } 318 319 int 320 number(cp) 321 Char *cp; 322 { 323 if (!cp) 324 return(0); 325 if (*cp == '-') { 326 cp++; 327 if (!Isdigit(*cp)) 328 return (0); 329 cp++; 330 } 331 while (*cp && Isdigit(*cp)) 332 cp++; 333 return (*cp == 0); 334 } 335 336 Char ** 337 copyblk(v) 338 register Char **v; 339 { 340 Char **nv = (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **)); 341 342 return (blkcpy(nv, v)); 343 } 344 345 #ifndef SHORT_STRINGS 346 char * 347 strend(cp) 348 register char *cp; 349 { 350 if (!cp) 351 return (cp); 352 while (*cp) 353 cp++; 354 return (cp); 355 } 356 357 #endif /* SHORT_STRINGS */ 358 359 Char * 360 strip(cp) 361 Char *cp; 362 { 363 register Char *dp = cp; 364 365 if (!cp) 366 return (cp); 367 while ((*dp++ &= TRIM) != '\0') 368 continue; 369 return (cp); 370 } 371 372 void 373 udvar(name) 374 Char *name; 375 { 376 377 setname(vis_str(name)); 378 stderror(ERR_NAME | ERR_UNDVAR); 379 } 380 381 int 382 prefix(sub, str) 383 register Char *sub, *str; 384 { 385 386 for (;;) { 387 if (*sub == 0) 388 return (1); 389 if (*str == 0) 390 return (0); 391 if (*sub++ != *str++) 392 return (0); 393 } 394 } 395