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