Home | History | Annotate | Line # | Download | only in csh
str.c revision 1.11
      1 /* $NetBSD: str.c,v 1.11 2001/09/14 14:04:01 wiz Exp $ */
      2 
      3 /*-
      4  * Copyright (c) 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[] = "@(#)str.c	8.1 (Berkeley) 5/31/93";
     40 #else
     41 __RCSID("$NetBSD: str.c,v 1.11 2001/09/14 14:04:01 wiz Exp $");
     42 #endif
     43 #endif /* not lint */
     44 
     45 #define MALLOC_INCR 128
     46 
     47 /*
     48  * tc.str.c: Short string package
     49  *	     This has been a lesson of how to write buggy code!
     50  */
     51 
     52 #include <sys/types.h>
     53 
     54 #include <vis.h>
     55 
     56 #if __STDC__
     57 # include <stdarg.h>
     58 #else
     59 # include <varargs.h>
     60 #endif
     61 
     62 #include "csh.h"
     63 #include "extern.h"
     64 
     65 #ifdef SHORT_STRINGS
     66 
     67 Char **
     68 blk2short(char **src)
     69 {
     70     Char **dst, **sdst;
     71     size_t n;
     72 
     73     /*
     74      * Count
     75      */
     76     for (n = 0; src[n] != NULL; n++)
     77 	continue;
     78     sdst = dst = (Char **)xmalloc((size_t)((n + 1) * sizeof(Char *)));
     79 
     80     for (; *src != NULL; src++)
     81 	*dst++ = SAVE(*src);
     82     *dst = NULL;
     83     return (sdst);
     84 }
     85 
     86 char **
     87 short2blk(Char **src)
     88 {
     89     char **dst, **sdst;
     90     size_t n;
     91 
     92     /*
     93      * Count
     94      */
     95     for (n = 0; src[n] != NULL; n++)
     96 	continue;
     97     sdst = dst = (char **)xmalloc((size_t)((n + 1) * sizeof(char *)));
     98 
     99     for (; *src != NULL; src++)
    100 	*dst++ = strsave(short2str(*src));
    101     *dst = NULL;
    102     return (sdst);
    103 }
    104 
    105 Char *
    106 str2short(const char *src)
    107 {
    108     static Char *sdst;
    109     Char *dst, *edst;
    110     static size_t dstsize = 0;
    111 
    112     if (src == NULL)
    113 	return (NULL);
    114 
    115     if (sdst == (NULL)) {
    116 	dstsize = MALLOC_INCR;
    117 	sdst = (Char *)xmalloc((size_t)dstsize * sizeof(Char));
    118     }
    119 
    120     dst = sdst;
    121     edst = &dst[dstsize];
    122     while (*src) {
    123 	*dst++ = (Char) ((unsigned char) *src++);
    124 	if (dst == edst) {
    125 	    dstsize += MALLOC_INCR;
    126 	    sdst = (Char *)xrealloc((ptr_t)sdst,
    127 	        (size_t)dstsize * sizeof(Char));
    128 	    edst = &sdst[dstsize];
    129 	    dst = &edst[-MALLOC_INCR];
    130 	}
    131     }
    132     *dst = 0;
    133     return (sdst);
    134 }
    135 
    136 char *
    137 short2str(Char *src)
    138 {
    139     static char *sdst = NULL;
    140     static size_t dstsize = 0;
    141     char *dst, *edst;
    142 
    143     if (src == NULL)
    144 	return (NULL);
    145 
    146     if (sdst == NULL) {
    147 	dstsize = MALLOC_INCR;
    148 	sdst = (char *)xmalloc((size_t)dstsize * sizeof(char));
    149     }
    150     dst = sdst;
    151     edst = &dst[dstsize];
    152     while (*src) {
    153 	*dst++ = (char) *src++;
    154 	if (dst == edst) {
    155 	    dstsize += MALLOC_INCR;
    156 	    sdst = (char *)xrealloc((ptr_t)sdst,
    157 	        (size_t)dstsize * sizeof(char));
    158 	    edst = &sdst[dstsize];
    159 	    dst = &edst[-MALLOC_INCR];
    160 	}
    161     }
    162     *dst = 0;
    163     return (sdst);
    164 }
    165 
    166 Char *
    167 s_strcpy(Char *dst, Char *src)
    168 {
    169     Char *sdst;
    170 
    171     sdst = dst;
    172     while ((*dst++ = *src++) != '\0')
    173 	continue;
    174     return (sdst);
    175 }
    176 
    177 Char *
    178 s_strncpy(Char *dst, Char *src, size_t n)
    179 {
    180     Char *sdst;
    181 
    182     if (n == 0)
    183 	return(dst);
    184 
    185     sdst = dst;
    186     do
    187 	if ((*dst++ = *src++) == '\0') {
    188 	    while (--n != 0)
    189 		*dst++ = '\0';
    190 	    return(sdst);
    191 	}
    192     while (--n != 0);
    193     return (sdst);
    194 }
    195 
    196 Char *
    197 s_strcat(Char *dst, Char *src)
    198 {
    199     short *sdst;
    200 
    201     sdst = dst;
    202     while (*dst++)
    203 	continue;
    204     --dst;
    205     while ((*dst++ = *src++) != '\0')
    206 	continue;
    207     return (sdst);
    208 }
    209 
    210 #ifdef NOTUSED
    211 Char *
    212 s_strncat(Char *dst, Char *src, size_t n)
    213 {
    214     Char *sdst;
    215 
    216     if (n == 0)
    217 	return (dst);
    218 
    219     sdst = dst;
    220 
    221     while (*dst++)
    222 	continue;
    223     --dst;
    224 
    225     do
    226 	if ((*dst++ = *src++) == '\0')
    227 	    return(sdst);
    228     while (--n != 0)
    229 	continue;
    230 
    231     *dst = '\0';
    232     return (sdst);
    233 }
    234 
    235 #endif
    236 
    237 Char *
    238 s_strchr(Char *str, int ch)
    239 {
    240     do
    241 	if (*str == ch)
    242 	    return (str);
    243     while (*str++);
    244     return (NULL);
    245 }
    246 
    247 Char *
    248 s_strrchr(Char *str, int ch)
    249 {
    250     Char *rstr;
    251 
    252     rstr = NULL;
    253     do
    254 	if (*str == ch)
    255 	    rstr = str;
    256     while (*str++);
    257     return (rstr);
    258 }
    259 
    260 size_t
    261 s_strlen(Char *str)
    262 {
    263     size_t n;
    264 
    265     for (n = 0; *str++; n++)
    266 	continue;
    267     return (n);
    268 }
    269 
    270 int
    271 s_strcmp(Char *str1, Char *str2)
    272 {
    273     for (; *str1 && *str1 == *str2; str1++, str2++)
    274 	continue;
    275     /*
    276      * The following case analysis is necessary so that characters which look
    277      * negative collate low against normal characters but high against the
    278      * end-of-string NUL.
    279      */
    280     if (*str1 == '\0' && *str2 == '\0')
    281 	return (0);
    282     else if (*str1 == '\0')
    283 	return (-1);
    284     else if (*str2 == '\0')
    285 	return (1);
    286     else
    287 	return (*str1 - *str2);
    288 }
    289 
    290 int
    291 s_strncmp(Char *str1, Char *str2, size_t n)
    292 {
    293     if (n == 0)
    294 	return (0);
    295     do {
    296 	if (*str1 != *str2) {
    297 	    /*
    298 	     * The following case analysis is necessary so that characters
    299 	     * which look negative collate low against normal characters
    300 	     * but high against the end-of-string NUL.
    301 	     */
    302 	    if (*str1 == '\0')
    303 		return (-1);
    304 	    else if (*str2 == '\0')
    305 		return (1);
    306 	    else
    307 		return (*str1 - *str2);
    308 	}
    309         if (*str1 == '\0')
    310 	    return(0);
    311 	str1++, str2++;
    312     } while (--n != 0);
    313     return(0);
    314 }
    315 
    316 Char *
    317 s_strsave(Char *s)
    318 {
    319     Char *n, *p;
    320 
    321     if (s == 0)
    322 	s = STRNULL;
    323     for (p = s; *p++;)
    324 	continue;
    325     n = p = (Char *)xmalloc((size_t)((p - s) * sizeof(Char)));
    326     while ((*p++ = *s++) != '\0')
    327 	continue;
    328     return (n);
    329 }
    330 
    331 Char *
    332 s_strspl(Char *cp, Char *dp)
    333 {
    334     Char *ep, *p, *q;
    335 
    336     if (!cp)
    337 	cp = STRNULL;
    338     if (!dp)
    339 	dp = STRNULL;
    340     for (p = cp; *p++;)
    341 	continue;
    342     for (q = dp; *q++;)
    343 	continue;
    344     ep = (Char *)xmalloc((size_t)(((p - cp) + (q - dp) - 1) * sizeof(Char)));
    345     for (p = ep, q = cp; (*p++ = *q++) != '\0';)
    346 	continue;
    347     for (p--, q = dp; (*p++ = *q++) != '\0';)
    348 	continue;
    349     return (ep);
    350 }
    351 
    352 Char *
    353 s_strend(Char *cp)
    354 {
    355     if (!cp)
    356 	return (cp);
    357     while (*cp)
    358 	cp++;
    359     return (cp);
    360 }
    361 
    362 Char *
    363 s_strstr(Char *s, Char *t)
    364 {
    365     do {
    366 	Char *ss = s;
    367 	Char *tt = t;
    368 
    369 	do
    370 	    if (*tt == '\0')
    371 		return (s);
    372 	while (*ss++ == *tt++);
    373     } while (*s++ != '\0');
    374     return (NULL);
    375 }
    376 #endif				/* SHORT_STRINGS */
    377 
    378 char *
    379 short2qstr(Char *src)
    380 {
    381     static char *sdst = NULL;
    382     static size_t dstsize = 0;
    383     char *dst, *edst;
    384 
    385     if (src == NULL)
    386 	return (NULL);
    387 
    388     if (sdst == NULL) {
    389 	dstsize = MALLOC_INCR;
    390 	sdst = (char *)xmalloc((size_t)dstsize * sizeof(char));
    391     }
    392     dst = sdst;
    393     edst = &dst[dstsize];
    394     while (*src) {
    395 	if (*src & QUOTE) {
    396 	    *dst++ = '\\';
    397 	    if (dst == edst) {
    398 		dstsize += MALLOC_INCR;
    399 		sdst = (char *)xrealloc((ptr_t) sdst,
    400 		    (size_t)dstsize * sizeof(char));
    401 		edst = &sdst[dstsize];
    402 		dst = &edst[-MALLOC_INCR];
    403 	    }
    404 	}
    405 	*dst++ = (char) *src++;
    406 	if (dst == edst) {
    407 	    dstsize += MALLOC_INCR;
    408 	    sdst = (char *)xrealloc((ptr_t) sdst,
    409 	        (size_t)dstsize * sizeof(char));
    410 	    edst = &sdst[dstsize];
    411 	    dst = &edst[-MALLOC_INCR];
    412 	}
    413     }
    414     *dst = 0;
    415     return (sdst);
    416 }
    417 
    418 /*
    419  * XXX: Should we worry about QUOTE'd chars?
    420  */
    421 char *
    422 vis_str(Char *cp)
    423 {
    424     static char *sdst = NULL;
    425     static size_t dstsize = 0;
    426     Char *dp;
    427     size_t n;
    428 
    429     if (cp == NULL)
    430 	return (NULL);
    431 
    432     for (dp = cp; *dp++;)
    433 	continue;
    434     n = ((dp - cp) << 2) + 1; /* 4 times + NULL */
    435     if (dstsize < n) {
    436 	sdst = (char *) (dstsize ?
    437 	    xrealloc(sdst, (size_t)n * sizeof(char)) :
    438 	    xmalloc((size_t)n * sizeof(char)));
    439 	dstsize = n;
    440     }
    441     /*
    442      * XXX: When we are in AsciiOnly we want all characters >= 0200 to
    443      * be encoded, but currently there is no way in vis to do that.
    444      */
    445     (void)strvis(sdst, short2str(cp), VIS_NOSLASH);
    446     return (sdst);
    447 }
    448