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