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