149999Schristos /*- 249999Schristos * Copyright (c) 1991 The Regents of the University of California. 349999Schristos * All rights reserved. 449999Schristos * 549999Schristos * %sccs.include.redist.c% 649999Schristos */ 749999Schristos 849999Schristos #ifndef lint 9*52369Schristos static char sccsid[] = "@(#)str.c 5.12 (Berkeley) 02/05/92"; 1049999Schristos #endif /* not lint */ 1149999Schristos 1250439Schristos #define MALLOC_INCR 128 1350439Schristos 1449999Schristos /* 1549999Schristos * tc.str.c: Short string package 1651437Sleres * This has been a lesson of how to write buggy code! 1749999Schristos */ 1849999Schristos 1951589Schristos #include <sys/types.h> 2050033Schristos #if __STDC__ 2150033Schristos # include <stdarg.h> 2250033Schristos #else 2350033Schristos # include <varargs.h> 2450033Schristos #endif 2551589Schristos #include <vis.h> 2650033Schristos 2750023Sbostic #include "csh.h" 2850023Sbostic #include "extern.h" 2949999Schristos 3050465Schristos #ifdef SHORT_STRINGS 3150465Schristos 3249999Schristos Char ** 3349999Schristos blk2short(src) 3449999Schristos register char **src; 3549999Schristos { 3650033Schristos size_t n; 3749999Schristos register Char **sdst, **dst; 3849999Schristos 3949999Schristos /* 4049999Schristos * Count 4149999Schristos */ 4251437Sleres for (n = 0; src[n] != NULL; n++) 4351437Sleres continue; 4449999Schristos sdst = dst = (Char **) xmalloc((size_t) ((n + 1) * sizeof(Char *))); 4549999Schristos 4650033Schristos for (; *src != NULL; src++) 4749999Schristos *dst++ = SAVE(*src); 4849999Schristos *dst = NULL; 4949999Schristos return (sdst); 5049999Schristos } 5149999Schristos 5249999Schristos char ** 5349999Schristos short2blk(src) 5449999Schristos register Char **src; 5549999Schristos { 5650033Schristos size_t n; 5749999Schristos register char **sdst, **dst; 5849999Schristos 5949999Schristos /* 6049999Schristos * Count 6149999Schristos */ 6251437Sleres for (n = 0; src[n] != NULL; n++) 6351437Sleres continue; 6449999Schristos sdst = dst = (char **) xmalloc((size_t) ((n + 1) * sizeof(char *))); 6549999Schristos 6650033Schristos for (; *src != NULL; src++) 6749999Schristos *dst++ = strsave(short2str(*src)); 6850033Schristos *dst = NULL; 6949999Schristos return (sdst); 7049999Schristos } 7149999Schristos 7249999Schristos Char * 7349999Schristos str2short(src) 7449999Schristos register char *src; 7549999Schristos { 7649999Schristos static Char *sdst; 7750033Schristos static size_t dstsize = 0; 7849999Schristos register Char *dst, *edst; 7949999Schristos 8050033Schristos if (src == NULL) 8150033Schristos return (NULL); 8249999Schristos 8350033Schristos if (sdst == (NULL)) { 8449999Schristos dstsize = MALLOC_INCR; 8549999Schristos sdst = (Char *) xmalloc((size_t) dstsize * sizeof(Char)); 8649999Schristos } 8749999Schristos 8849999Schristos dst = sdst; 8949999Schristos edst = &dst[dstsize]; 9049999Schristos while (*src) { 9149999Schristos *dst++ = (Char) ((unsigned char) *src++); 9249999Schristos if (dst == edst) { 9349999Schristos dstsize += MALLOC_INCR; 9449999Schristos sdst = (Char *) xrealloc((ptr_t) sdst, 9549999Schristos (size_t) dstsize * sizeof(Char)); 9649999Schristos edst = &sdst[dstsize]; 9749999Schristos dst = &edst[-MALLOC_INCR]; 9849999Schristos } 9949999Schristos } 10049999Schristos *dst = 0; 10149999Schristos return (sdst); 10249999Schristos } 10349999Schristos 10449999Schristos char * 10549999Schristos short2str(src) 10649999Schristos register Char *src; 10749999Schristos { 10850033Schristos static char *sdst = NULL; 10950033Schristos static size_t dstsize = 0; 11049999Schristos register char *dst, *edst; 11149999Schristos 11250033Schristos if (src == NULL) 11350033Schristos return (NULL); 11449999Schristos 11550033Schristos if (sdst == NULL) { 11649999Schristos dstsize = MALLOC_INCR; 11749999Schristos sdst = (char *) xmalloc((size_t) dstsize * sizeof(char)); 11849999Schristos } 11949999Schristos dst = sdst; 12049999Schristos edst = &dst[dstsize]; 12149999Schristos while (*src) { 12249999Schristos *dst++ = (char) *src++; 12349999Schristos if (dst == edst) { 12449999Schristos dstsize += MALLOC_INCR; 12549999Schristos sdst = (char *) xrealloc((ptr_t) sdst, 12649999Schristos (size_t) dstsize * sizeof(char)); 12749999Schristos edst = &sdst[dstsize]; 12849999Schristos dst = &edst[-MALLOC_INCR]; 12949999Schristos } 13049999Schristos } 13149999Schristos *dst = 0; 13249999Schristos return (sdst); 13349999Schristos } 13449999Schristos 13549999Schristos Char * 13649999Schristos s_strcpy(dst, src) 13749999Schristos register Char *dst, *src; 13849999Schristos { 13949999Schristos register Char *sdst; 14049999Schristos 14149999Schristos sdst = dst; 14251437Sleres while (*dst++ = *src++) 14351437Sleres continue; 14449999Schristos return (sdst); 14549999Schristos } 14649999Schristos 14749999Schristos Char * 14849999Schristos s_strncpy(dst, src, n) 14949999Schristos register Char *dst, *src; 15050033Schristos register size_t n; 15149999Schristos { 15249999Schristos register Char *sdst; 15349999Schristos 15450075Schristos if (n == 0) 15550075Schristos return(dst); 15650075Schristos 15749999Schristos sdst = dst; 15851437Sleres do 15950075Schristos if ((*dst++ = *src++) == '\0') { 16050162Schristos while (--n != 0) 16150075Schristos *dst++ = '\0'; 16250075Schristos return(sdst); 16350075Schristos } 16450075Schristos while (--n != 0); 16549999Schristos return (sdst); 16649999Schristos } 16749999Schristos 16849999Schristos Char * 16949999Schristos s_strcat(dst, src) 17049999Schristos register Char *dst, *src; 17149999Schristos { 17249999Schristos register short *sdst; 17349999Schristos 17449999Schristos sdst = dst; 17551437Sleres while (*dst++) 17651437Sleres continue; 17749999Schristos --dst; 17851437Sleres while (*dst++ = *src++) 17951437Sleres continue; 18049999Schristos return (sdst); 18149999Schristos } 18249999Schristos 18349999Schristos #ifdef NOTUSED 18449999Schristos Char * 18549999Schristos s_strncat(dst, src, n) 18649999Schristos register Char *dst, *src; 18750033Schristos register size_t n; 18849999Schristos { 18949999Schristos register Char *sdst; 19049999Schristos 19151437Sleres if (n == 0) 19250075Schristos return (dst); 19350075Schristos 19449999Schristos sdst = dst; 19550075Schristos 19651437Sleres while (*dst++) 19751437Sleres continue; 19849999Schristos --dst; 19950075Schristos 20051437Sleres do 20150075Schristos if ((*dst++ = *src++) == '\0') 20250075Schristos return(sdst); 20351437Sleres while (--n != 0) 20451437Sleres continue; 20550075Schristos 20650075Schristos *dst = '\0'; 20749999Schristos return (sdst); 20849999Schristos } 20949999Schristos 21049999Schristos #endif 21149999Schristos 21249999Schristos Char * 21349999Schristos s_strchr(str, ch) 21450033Schristos register Char *str; 21550033Schristos int ch; 21649999Schristos { 21749999Schristos do 21849999Schristos if (*str == ch) 21949999Schristos return (str); 22049999Schristos while (*str++); 22150033Schristos return (NULL); 22249999Schristos } 22349999Schristos 22449999Schristos Char * 22549999Schristos s_strrchr(str, ch) 22650033Schristos register Char *str; 22750033Schristos int ch; 22849999Schristos { 22949999Schristos register Char *rstr; 23049999Schristos 23150033Schristos rstr = NULL; 23249999Schristos do 23349999Schristos if (*str == ch) 23449999Schristos rstr = str; 23549999Schristos while (*str++); 23649999Schristos return (rstr); 23749999Schristos } 23849999Schristos 23950033Schristos size_t 24049999Schristos s_strlen(str) 24149999Schristos register Char *str; 24249999Schristos { 24350033Schristos register size_t n; 24449999Schristos 24551437Sleres for (n = 0; *str++; n++) 24651437Sleres continue; 24749999Schristos return (n); 24849999Schristos } 24949999Schristos 25049999Schristos int 25149999Schristos s_strcmp(str1, str2) 25249999Schristos register Char *str1, *str2; 25349999Schristos { 25451437Sleres for (; *str1 && *str1 == *str2; str1++, str2++) 25551437Sleres continue; 25649999Schristos /* 25749999Schristos * The following case analysis is necessary so that characters which look 25849999Schristos * negative collate low against normal characters but high against the 25949999Schristos * end-of-string NUL. 26049999Schristos */ 26149999Schristos if (*str1 == '\0' && *str2 == '\0') 26249999Schristos return (0); 26349999Schristos else if (*str1 == '\0') 26449999Schristos return (-1); 26549999Schristos else if (*str2 == '\0') 26649999Schristos return (1); 26749999Schristos else 26849999Schristos return (*str1 - *str2); 26949999Schristos } 27049999Schristos 27149999Schristos int 27249999Schristos s_strncmp(str1, str2, n) 27349999Schristos register Char *str1, *str2; 27450033Schristos register size_t n; 27549999Schristos { 27650075Schristos if (n == 0) 27749999Schristos return (0); 27850075Schristos do { 27950396Schristos if (*str1 != *str2) { 28050396Schristos /* 28151437Sleres * The following case analysis is necessary so that characters 28250396Schristos * which look negative collate low against normal characters 28350396Schristos * but high against the end-of-string NUL. 28450396Schristos */ 28550396Schristos if (*str1 == '\0') 28650396Schristos return (-1); 28750396Schristos else if (*str2 == '\0') 28850396Schristos return (1); 28950396Schristos else 29050396Schristos return (*str1 - *str2); 29150075Schristos break; 29250396Schristos } 29350396Schristos if (*str1 == '\0') 29450396Schristos return(0); 29550075Schristos str1++, str2++; 29650075Schristos } while (--n != 0); 29750075Schristos return(0); 29849999Schristos } 29949999Schristos 30049999Schristos Char * 30149999Schristos s_strsave(s) 30249999Schristos register Char *s; 30349999Schristos { 30449999Schristos Char *n; 30549999Schristos register Char *p; 30649999Schristos 30749999Schristos if (s == 0) 30849999Schristos s = STRNULL; 30951437Sleres for (p = s; *p++;) 31051437Sleres continue; 31149999Schristos n = p = (Char *) xmalloc((size_t) ((p - s) * sizeof(Char))); 31251437Sleres while (*p++ = *s++) 31351437Sleres continue; 31449999Schristos return (n); 31549999Schristos } 31649999Schristos 31749999Schristos Char * 31849999Schristos s_strspl(cp, dp) 31949999Schristos Char *cp, *dp; 32049999Schristos { 32149999Schristos Char *ep; 32249999Schristos register Char *p, *q; 32349999Schristos 32449999Schristos if (!cp) 32549999Schristos cp = STRNULL; 32649999Schristos if (!dp) 32749999Schristos dp = STRNULL; 32851437Sleres for (p = cp; *p++;) 32951437Sleres continue; 33051437Sleres for (q = dp; *q++;) 33151437Sleres continue; 33249999Schristos ep = (Char *) xmalloc((size_t) 33349999Schristos (((p - cp) + (q - dp) - 1) * sizeof(Char))); 33451437Sleres for (p = ep, q = cp; *p++ = *q++;) 33551437Sleres continue; 33651437Sleres for (p--, q = dp; *p++ = *q++;) 33751437Sleres continue; 33849999Schristos return (ep); 33949999Schristos } 34049999Schristos 34149999Schristos Char * 34249999Schristos s_strend(cp) 34349999Schristos register Char *cp; 34449999Schristos { 34549999Schristos if (!cp) 34649999Schristos return (cp); 34749999Schristos while (*cp) 34849999Schristos cp++; 34949999Schristos return (cp); 35049999Schristos } 35149999Schristos 35249999Schristos Char * 35349999Schristos s_strstr(s, t) 35449999Schristos register Char *s, *t; 35549999Schristos { 35649999Schristos do { 35749999Schristos register Char *ss = s; 35849999Schristos register Char *tt = t; 35949999Schristos 36049999Schristos do 36149999Schristos if (*tt == '\0') 36249999Schristos return (s); 36349999Schristos while (*ss++ == *tt++); 36449999Schristos } while (*s++ != '\0'); 36550033Schristos return (NULL); 36649999Schristos } 36750439Schristos #endif /* SHORT_STRINGS */ 36849999Schristos 36950439Schristos char * 37050439Schristos short2qstr(src) 37150439Schristos register Char *src; 37250439Schristos { 37350439Schristos static char *sdst = NULL; 37450439Schristos static size_t dstsize = 0; 37550439Schristos register char *dst, *edst; 37650439Schristos 37750439Schristos if (src == NULL) 37850439Schristos return (NULL); 37950439Schristos 38050439Schristos if (sdst == NULL) { 38150439Schristos dstsize = MALLOC_INCR; 38250439Schristos sdst = (char *) xmalloc((size_t) dstsize * sizeof(char)); 38350439Schristos } 38450439Schristos dst = sdst; 38550439Schristos edst = &dst[dstsize]; 38650439Schristos while (*src) { 38750439Schristos if (*src & QUOTE) { 38850439Schristos *dst++ = '\\'; 38950439Schristos if (dst == edst) { 39050439Schristos dstsize += MALLOC_INCR; 39150439Schristos sdst = (char *) xrealloc((ptr_t) sdst, 39250439Schristos (size_t) dstsize * sizeof(char)); 39350439Schristos edst = &sdst[dstsize]; 39450439Schristos dst = &edst[-MALLOC_INCR]; 39550439Schristos } 39650439Schristos } 39750439Schristos *dst++ = (char) *src++; 39850439Schristos if (dst == edst) { 39950439Schristos dstsize += MALLOC_INCR; 40050439Schristos sdst = (char *) xrealloc((ptr_t) sdst, 40150439Schristos (size_t) dstsize * sizeof(char)); 40250439Schristos edst = &sdst[dstsize]; 40350439Schristos dst = &edst[-MALLOC_INCR]; 40450439Schristos } 40550439Schristos } 40650439Schristos *dst = 0; 40750439Schristos return (sdst); 40850439Schristos } 40951589Schristos 41051589Schristos /* 41151589Schristos * XXX: Should we worry about QUOTE'd chars? 41251589Schristos */ 41351589Schristos char * 41451589Schristos vis_str(cp) 41551589Schristos Char *cp; 41651589Schristos { 41751589Schristos static char *sdst = NULL; 41851589Schristos static size_t dstsize = 0; 41951589Schristos size_t n; 42051589Schristos Char *dp; 42151589Schristos 42251589Schristos if (cp == NULL) 42351589Schristos return (NULL); 42451589Schristos 42551589Schristos for (dp = cp; *dp++;) 42651589Schristos continue; 42751589Schristos n = ((dp - cp) << 2) + 1; /* 4 times + NULL */ 42851589Schristos if (dstsize < n) { 42951589Schristos sdst = (char *) (dstsize ? 43051589Schristos xrealloc(sdst, (size_t) n * sizeof(char)) : 43151589Schristos xmalloc((size_t) n * sizeof(char))); 43251589Schristos dstsize = n; 43351589Schristos } 434*52369Schristos /* 435*52369Schristos * XXX: When we are in AsciiOnly we want all characters >= 0200 to 436*52369Schristos * be encoded, but currently there is no way in vis to do that. 437*52369Schristos */ 438*52369Schristos (void) strvis(sdst, short2str(cp), VIS_NOSLASH); 43951589Schristos return (sdst); 44051589Schristos } 44151589Schristos 442