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