Home | History | Annotate | Line # | Download | only in csh
str.c revision 1.5
      1 /*-
      2  * Copyright (c) 1991, 1993
      3  *	The Regents of the University of California.  All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. All advertising materials mentioning features or use of this software
     14  *    must display the following acknowledgement:
     15  *	This product includes software developed by the University of
     16  *	California, Berkeley and its contributors.
     17  * 4. Neither the name of the University nor the names of its contributors
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     31  * SUCH DAMAGE.
     32  */
     33 
     34 #ifndef lint
     35 /*static char sccsid[] = "from: @(#)str.c	8.1 (Berkeley) 5/31/93";*/
     36 static char *rcsid = "$Id: str.c,v 1.5 1994/09/21 00:11:18 mycroft Exp $";
     37 #endif /* not lint */
     38 
     39 #define MALLOC_INCR	128
     40 
     41 /*
     42  * tc.str.c: Short string package
     43  *	     This has been a lesson of how to write buggy code!
     44  */
     45 
     46 #include <sys/types.h>
     47 #if __STDC__
     48 # include <stdarg.h>
     49 #else
     50 # include <varargs.h>
     51 #endif
     52 #include <vis.h>
     53 
     54 #include "csh.h"
     55 #include "extern.h"
     56 
     57 #ifdef SHORT_STRINGS
     58 
     59 Char  **
     60 blk2short(src)
     61     register char **src;
     62 {
     63     size_t     n;
     64     register Char **sdst, **dst;
     65 
     66     /*
     67      * Count
     68      */
     69     for (n = 0; src[n] != NULL; n++)
     70 	continue;
     71     sdst = dst = (Char **) xmalloc((size_t) ((n + 1) * sizeof(Char *)));
     72 
     73     for (; *src != NULL; src++)
     74 	*dst++ = SAVE(*src);
     75     *dst = NULL;
     76     return (sdst);
     77 }
     78 
     79 char  **
     80 short2blk(src)
     81     register Char **src;
     82 {
     83     size_t     n;
     84     register char **sdst, **dst;
     85 
     86     /*
     87      * Count
     88      */
     89     for (n = 0; src[n] != NULL; n++)
     90 	continue;
     91     sdst = dst = (char **) xmalloc((size_t) ((n + 1) * sizeof(char *)));
     92 
     93     for (; *src != NULL; src++)
     94 	*dst++ = strsave(short2str(*src));
     95     *dst = NULL;
     96     return (sdst);
     97 }
     98 
     99 Char   *
    100 str2short(src)
    101     register char *src;
    102 {
    103     static Char *sdst;
    104     static size_t dstsize = 0;
    105     register Char *dst, *edst;
    106 
    107     if (src == NULL)
    108 	return (NULL);
    109 
    110     if (sdst == (NULL)) {
    111 	dstsize = MALLOC_INCR;
    112 	sdst = (Char *) xmalloc((size_t) dstsize * sizeof(Char));
    113     }
    114 
    115     dst = sdst;
    116     edst = &dst[dstsize];
    117     while (*src) {
    118 	*dst++ = (Char) ((unsigned char) *src++);
    119 	if (dst == edst) {
    120 	    dstsize += MALLOC_INCR;
    121 	    sdst = (Char *) xrealloc((ptr_t) sdst,
    122 				     (size_t) dstsize * sizeof(Char));
    123 	    edst = &sdst[dstsize];
    124 	    dst = &edst[-MALLOC_INCR];
    125 	}
    126     }
    127     *dst = 0;
    128     return (sdst);
    129 }
    130 
    131 char   *
    132 short2str(src)
    133     register Char *src;
    134 {
    135     static char *sdst = NULL;
    136     static size_t dstsize = 0;
    137     register char *dst, *edst;
    138 
    139     if (src == NULL)
    140 	return (NULL);
    141 
    142     if (sdst == NULL) {
    143 	dstsize = MALLOC_INCR;
    144 	sdst = (char *) xmalloc((size_t) dstsize * sizeof(char));
    145     }
    146     dst = sdst;
    147     edst = &dst[dstsize];
    148     while (*src) {
    149 	*dst++ = (char) *src++;
    150 	if (dst == edst) {
    151 	    dstsize += MALLOC_INCR;
    152 	    sdst = (char *) xrealloc((ptr_t) sdst,
    153 				     (size_t) dstsize * sizeof(char));
    154 	    edst = &sdst[dstsize];
    155 	    dst = &edst[-MALLOC_INCR];
    156 	}
    157     }
    158     *dst = 0;
    159     return (sdst);
    160 }
    161 
    162 Char   *
    163 s_strcpy(dst, src)
    164     register Char *dst, *src;
    165 {
    166     register Char *sdst;
    167 
    168     sdst = dst;
    169     while ((*dst++ = *src++) != '\0')
    170 	continue;
    171     return (sdst);
    172 }
    173 
    174 Char   *
    175 s_strncpy(dst, src, n)
    176     register Char *dst, *src;
    177     register size_t n;
    178 {
    179     register Char *sdst;
    180 
    181     if (n == 0)
    182 	return(dst);
    183 
    184     sdst = dst;
    185     do
    186 	if ((*dst++ = *src++) == '\0') {
    187 	    while (--n != 0)
    188 		*dst++ = '\0';
    189 	    return(sdst);
    190 	}
    191     while (--n != 0);
    192     return (sdst);
    193 }
    194 
    195 Char   *
    196 s_strcat(dst, src)
    197     register Char *dst, *src;
    198 {
    199     register 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(dst, src, n)
    213     register Char *dst, *src;
    214     register size_t n;
    215 {
    216     register Char *sdst;
    217 
    218     if (n == 0)
    219 	return (dst);
    220 
    221     sdst = dst;
    222 
    223     while (*dst++)
    224 	continue;
    225     --dst;
    226 
    227     do
    228 	if ((*dst++ = *src++) == '\0')
    229 	    return(sdst);
    230     while (--n != 0)
    231 	continue;
    232 
    233     *dst = '\0';
    234     return (sdst);
    235 }
    236 
    237 #endif
    238 
    239 Char   *
    240 s_strchr(str, ch)
    241     register Char *str;
    242     int ch;
    243 {
    244     do
    245 	if (*str == ch)
    246 	    return (str);
    247     while (*str++);
    248     return (NULL);
    249 }
    250 
    251 Char   *
    252 s_strrchr(str, ch)
    253     register Char *str;
    254     int ch;
    255 {
    256     register Char *rstr;
    257 
    258     rstr = NULL;
    259     do
    260 	if (*str == ch)
    261 	    rstr = str;
    262     while (*str++);
    263     return (rstr);
    264 }
    265 
    266 size_t
    267 s_strlen(str)
    268     register Char *str;
    269 {
    270     register size_t n;
    271 
    272     for (n = 0; *str++; n++)
    273 	continue;
    274     return (n);
    275 }
    276 
    277 int
    278 s_strcmp(str1, str2)
    279     register Char *str1, *str2;
    280 {
    281     for (; *str1 && *str1 == *str2; str1++, str2++)
    282 	continue;
    283     /*
    284      * The following case analysis is necessary so that characters which look
    285      * negative collate low against normal characters but high against the
    286      * end-of-string NUL.
    287      */
    288     if (*str1 == '\0' && *str2 == '\0')
    289 	return (0);
    290     else if (*str1 == '\0')
    291 	return (-1);
    292     else if (*str2 == '\0')
    293 	return (1);
    294     else
    295 	return (*str1 - *str2);
    296 }
    297 
    298 int
    299 s_strncmp(str1, str2, n)
    300     register Char *str1, *str2;
    301     register size_t n;
    302 {
    303     if (n == 0)
    304 	return (0);
    305     do {
    306 	if (*str1 != *str2) {
    307 	    /*
    308 	     * The following case analysis is necessary so that characters
    309 	     * which look negative collate low against normal characters
    310 	     * but high against the end-of-string NUL.
    311 	     */
    312 	    if (*str1 == '\0')
    313 		return (-1);
    314 	    else if (*str2 == '\0')
    315 		return (1);
    316 	    else
    317 		return (*str1 - *str2);
    318 	    break;
    319 	}
    320         if (*str1 == '\0')
    321 	    return(0);
    322 	str1++, str2++;
    323     } while (--n != 0);
    324     return(0);
    325 }
    326 
    327 Char   *
    328 s_strsave(s)
    329     register Char *s;
    330 {
    331     Char   *n;
    332     register Char *p;
    333 
    334     if (s == 0)
    335 	s = STRNULL;
    336     for (p = s; *p++;)
    337 	continue;
    338     n = p = (Char *) xmalloc((size_t) ((p - s) * sizeof(Char)));
    339     while ((*p++ = *s++) != '\0')
    340 	continue;
    341     return (n);
    342 }
    343 
    344 Char   *
    345 s_strspl(cp, dp)
    346     Char   *cp, *dp;
    347 {
    348     Char   *ep;
    349     register Char *p, *q;
    350 
    351     if (!cp)
    352 	cp = STRNULL;
    353     if (!dp)
    354 	dp = STRNULL;
    355     for (p = cp; *p++;)
    356 	continue;
    357     for (q = dp; *q++;)
    358 	continue;
    359     ep = (Char *) xmalloc((size_t)
    360 			  (((p - cp) + (q - dp) - 1) * sizeof(Char)));
    361     for (p = ep, q = cp; (*p++ = *q++) != '\0';)
    362 	continue;
    363     for (p--, q = dp; (*p++ = *q++) != '\0';)
    364 	continue;
    365     return (ep);
    366 }
    367 
    368 Char   *
    369 s_strend(cp)
    370     register Char *cp;
    371 {
    372     if (!cp)
    373 	return (cp);
    374     while (*cp)
    375 	cp++;
    376     return (cp);
    377 }
    378 
    379 Char   *
    380 s_strstr(s, t)
    381     register Char *s, *t;
    382 {
    383     do {
    384 	register Char *ss = s;
    385 	register Char *tt = t;
    386 
    387 	do
    388 	    if (*tt == '\0')
    389 		return (s);
    390 	while (*ss++ == *tt++);
    391     } while (*s++ != '\0');
    392     return (NULL);
    393 }
    394 #endif				/* SHORT_STRINGS */
    395 
    396 char   *
    397 short2qstr(src)
    398     register Char *src;
    399 {
    400     static char *sdst = NULL;
    401     static size_t dstsize = 0;
    402     register char *dst, *edst;
    403 
    404     if (src == NULL)
    405 	return (NULL);
    406 
    407     if (sdst == NULL) {
    408 	dstsize = MALLOC_INCR;
    409 	sdst = (char *) xmalloc((size_t) dstsize * sizeof(char));
    410     }
    411     dst = sdst;
    412     edst = &dst[dstsize];
    413     while (*src) {
    414 	if (*src & QUOTE) {
    415 	    *dst++ = '\\';
    416 	    if (dst == edst) {
    417 		dstsize += MALLOC_INCR;
    418 		sdst = (char *) xrealloc((ptr_t) sdst,
    419 					 (size_t) dstsize * sizeof(char));
    420 		edst = &sdst[dstsize];
    421 		dst = &edst[-MALLOC_INCR];
    422 	    }
    423 	}
    424 	*dst++ = (char) *src++;
    425 	if (dst == edst) {
    426 	    dstsize += MALLOC_INCR;
    427 	    sdst = (char *) xrealloc((ptr_t) sdst,
    428 				     (size_t) dstsize * sizeof(char));
    429 	    edst = &sdst[dstsize];
    430 	    dst = &edst[-MALLOC_INCR];
    431 	}
    432     }
    433     *dst = 0;
    434     return (sdst);
    435 }
    436 
    437 /*
    438  * XXX: Should we worry about QUOTE'd chars?
    439  */
    440 char *
    441 vis_str(cp)
    442     Char *cp;
    443 {
    444     static char *sdst = NULL;
    445     static size_t dstsize = 0;
    446     size_t n;
    447     Char *dp;
    448 
    449     if (cp == NULL)
    450 	return (NULL);
    451 
    452     for (dp = cp; *dp++;)
    453 	continue;
    454     n = ((dp - cp) << 2) + 1; /* 4 times + NULL */
    455     if (dstsize < n) {
    456 	sdst = (char *) (dstsize ?
    457 			    xrealloc(sdst, (size_t) n * sizeof(char)) :
    458 			    xmalloc((size_t) n * sizeof(char)));
    459 	dstsize = n;
    460     }
    461     /*
    462      * XXX: When we are in AsciiOnly we want all characters >= 0200 to
    463      * be encoded, but currently there is no way in vis to do that.
    464      */
    465     (void) strvis(sdst, short2str(cp), VIS_NOSLASH);
    466     return (sdst);
    467 }
    468 
    469