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