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