Home | History | Annotate | Line # | Download | only in csh
misc.c revision 1.1
      1 /*-
      2  * Copyright (c) 1980, 1991 The Regents of the University of California.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. All advertising materials mentioning features or use of this software
     14  *    must display the following acknowledgement:
     15  *	This product includes software developed by the University of
     16  *	California, Berkeley and its contributors.
     17  * 4. Neither the name of the University nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  */
     33 
     34 #ifndef lint
     35 static char sccsid[] = "@(#)misc.c	5.13 (Berkeley) 6/27/91";
     36 #endif /* not lint */
     37 
     38 #include <sys/param.h>
     39 #include <stdlib.h>
     40 #include <unistd.h>
     41 #if __STDC__
     42 # include <stdarg.h>
     43 #else
     44 # include <varargs.h>
     45 #endif
     46 
     47 #include "csh.h"
     48 #include "extern.h"
     49 
     50 static int	renum __P((int, int));
     51 
     52 int
     53 any(s, c)
     54     register char *s;
     55     register int c;
     56 {
     57     if (!s)
     58 	return (0);		/* Check for nil pointer */
     59     while (*s)
     60 	if (*s++ == c)
     61 	    return (1);
     62     return (0);
     63 }
     64 
     65 void
     66 setzero(cp, i)
     67     char   *cp;
     68     int     i;
     69 {
     70     if (i != 0)
     71 	do
     72 	    *cp++ = 0;
     73 	while (--i);
     74 }
     75 
     76 char   *
     77 strsave(s)
     78     register char *s;
     79 {
     80     char   *n;
     81     register char *p;
     82 
     83     if (s == NULL)
     84 	s = "";
     85     for (p = s; *p++;);
     86     n = p = (char *) xmalloc((size_t) ((p - s) * sizeof(char)));
     87     while (*p++ = *s++);
     88     return (n);
     89 }
     90 
     91 Char  **
     92 blkend(up)
     93     register Char **up;
     94 {
     95 
     96     while (*up)
     97 	up++;
     98     return (up);
     99 }
    100 
    101 
    102 void
    103 blkpr(av)
    104     register Char **av;
    105 {
    106 
    107     for (; *av; av++) {
    108 	xprintf("%s", short2str(*av));
    109 	if (av[1])
    110 	    xprintf(" ");
    111     }
    112 }
    113 
    114 int
    115 blklen(av)
    116     register Char **av;
    117 {
    118     register int i = 0;
    119 
    120     while (*av++)
    121 	i++;
    122     return (i);
    123 }
    124 
    125 Char  **
    126 blkcpy(oav, bv)
    127     Char  **oav;
    128     register Char **bv;
    129 {
    130     register Char **av = oav;
    131 
    132     while (*av++ = *bv++)
    133 	continue;
    134     return (oav);
    135 }
    136 
    137 Char  **
    138 blkcat(up, vp)
    139     Char  **up, **vp;
    140 {
    141 
    142     (void) blkcpy(blkend(up), vp);
    143     return (up);
    144 }
    145 
    146 void
    147 blkfree(av0)
    148     Char  **av0;
    149 {
    150     register Char **av = av0;
    151 
    152     if (!av0)
    153 	return;
    154     for (; *av; av++)
    155 	xfree((ptr_t) * av);
    156     xfree((ptr_t) av0);
    157 }
    158 
    159 Char  **
    160 saveblk(v)
    161     register Char **v;
    162 {
    163     register Char **newv =
    164     (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
    165     Char  **onewv = newv;
    166 
    167     while (*v)
    168 	*newv++ = Strsave(*v++);
    169     return (onewv);
    170 }
    171 
    172 #ifdef NOTUSED
    173 char   *
    174 strstr(s, t)
    175     register char *s, *t;
    176 {
    177     do {
    178 	register char *ss = s;
    179 	register char *tt = t;
    180 
    181 	do
    182 	    if (*tt == '\0')
    183 		return (s);
    184 	while (*ss++ == *tt++);
    185     } while (*s++ != '\0');
    186     return (NULL);
    187 }
    188 
    189 #endif /* NOTUSED */
    190 
    191 #ifndef SHORT_STRINGS
    192 char   *
    193 strspl(cp, dp)
    194     char   *cp, *dp;
    195 {
    196     char   *ep;
    197     register char *p, *q;
    198 
    199     if (!cp)
    200 	cp = "";
    201     if (!dp)
    202 	dp = "";
    203     for (p = cp; *p++;);
    204     for (q = dp; *q++;);
    205     ep = (char *) xmalloc((size_t) (((p - cp) + (q - dp) - 1) * sizeof(char)));
    206     for (p = ep, q = cp; *p++ = *q++;);
    207     for (p--, q = dp; *p++ = *q++;);
    208     return (ep);
    209 }
    210 
    211 #endif
    212 
    213 Char  **
    214 blkspl(up, vp)
    215     register Char **up, **vp;
    216 {
    217     register Char **wp =
    218     (Char **) xcalloc((size_t) (blklen(up) + blklen(vp) + 1),
    219 		      sizeof(Char **));
    220 
    221     (void) blkcpy(wp, up);
    222     return (blkcat(wp, vp));
    223 }
    224 
    225 Char
    226 lastchr(cp)
    227     register Char *cp;
    228 {
    229 
    230     if (!cp)
    231 	return (0);
    232     if (!*cp)
    233 	return (0);
    234     while (cp[1])
    235 	cp++;
    236     return (*cp);
    237 }
    238 
    239 /*
    240  * This routine is called after an error to close up
    241  * any units which may have been left open accidentally.
    242  */
    243 void
    244 closem()
    245 {
    246     register int f;
    247 
    248     for (f = 0; f < NOFILE; f++)
    249 	if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD &&
    250 	    f != FSHTTY)
    251 	    (void) close(f);
    252 }
    253 
    254 void
    255 donefds()
    256 {
    257 
    258     (void) close(0);
    259     (void) close(1);
    260     (void) close(2);
    261     didfds = 0;
    262 }
    263 
    264 /*
    265  * Move descriptor i to j.
    266  * If j is -1 then we just want to get i to a safe place,
    267  * i.e. to a unit > 2.  This also happens in dcopy.
    268  */
    269 int
    270 dmove(i, j)
    271     register int i, j;
    272 {
    273 
    274     if (i == j || i < 0)
    275 	return (i);
    276     if (j >= 0) {
    277 	(void) dup2(i, j);
    278 	if (j != i)
    279 	    (void) close(i);
    280 	return (j);
    281     }
    282     j = dcopy(i, j);
    283     if (j != i)
    284 	(void) close(i);
    285     return (j);
    286 }
    287 
    288 int
    289 dcopy(i, j)
    290     register int i, j;
    291 {
    292 
    293     if (i == j || i < 0 || j < 0 && i > 2)
    294 	return (i);
    295     if (j >= 0) {
    296 	(void) dup2(i, j);
    297 	return (j);
    298     }
    299     (void) close(j);
    300     return (renum(i, j));
    301 }
    302 
    303 static int
    304 renum(i, j)
    305     register int i, j;
    306 {
    307     register int k = dup(i);
    308 
    309     if (k < 0)
    310 	return (-1);
    311     if (j == -1 && k > 2)
    312 	return (k);
    313     if (k != j) {
    314 	j = renum(k, j);
    315 	(void) close(k);
    316 	return (j);
    317     }
    318     return (k);
    319 }
    320 
    321 /*
    322  * Left shift a command argument list, discarding
    323  * the first c arguments.  Used in "shift" commands
    324  * as well as by commands like "repeat".
    325  */
    326 void
    327 lshift(v, c)
    328     register Char **v;
    329     register int c;
    330 {
    331     register Char **u = v;
    332 
    333     while (*u && --c >= 0)
    334 	xfree((ptr_t) * u++);
    335     (void) blkcpy(v, u);
    336 }
    337 
    338 int
    339 number(cp)
    340     Char   *cp;
    341 {
    342     if (!cp)
    343 	return(0);
    344     if (*cp == '-') {
    345 	cp++;
    346 	if (!Isdigit(*cp))
    347 	    return (0);
    348 	cp++;
    349     }
    350     while (*cp && Isdigit(*cp))
    351 	cp++;
    352     return (*cp == 0);
    353 }
    354 
    355 Char  **
    356 copyblk(v)
    357     register Char **v;
    358 {
    359     Char  **nv = (Char **) xcalloc((size_t) (blklen(v) + 1), sizeof(Char **));
    360 
    361     return (blkcpy(nv, v));
    362 }
    363 
    364 #ifndef SHORT_STRINGS
    365 char   *
    366 strend(cp)
    367     register char *cp;
    368 {
    369     if (!cp)
    370 	return (cp);
    371     while (*cp)
    372 	cp++;
    373     return (cp);
    374 }
    375 
    376 #endif				/* SHORT_STRINGS */
    377 
    378 Char   *
    379 strip(cp)
    380     Char   *cp;
    381 {
    382     register Char *dp = cp;
    383 
    384     if (!cp)
    385 	return (cp);
    386     while (*dp++ &= TRIM)
    387 	continue;
    388     return (cp);
    389 }
    390 
    391 void
    392 udvar(name)
    393     Char   *name;
    394 {
    395 
    396     setname(short2str(name));
    397     stderror(ERR_NAME | ERR_UNDVAR);
    398 }
    399 
    400 int
    401 prefix(sub, str)
    402     register Char *sub, *str;
    403 {
    404 
    405     for (;;) {
    406 	if (*sub == 0)
    407 	    return (1);
    408 	if (*str == 0)
    409 	    return (0);
    410 	if (*sub++ != *str++)
    411 	    return (0);
    412     }
    413 }
    414