149999Schristos /*-
2*60765Sbostic * Copyright (c) 1991, 1993
3*60765Sbostic * The Regents of the University of California. All rights reserved.
449999Schristos *
549999Schristos * %sccs.include.redist.c%
649999Schristos */
749999Schristos
849999Schristos #ifndef lint
9*60765Sbostic static char sccsid[] = "@(#)str.c 8.1 (Berkeley) 05/31/93";
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 **
blk2short(src)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 **
short2blk(src)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 *
str2short(src)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 *
short2str(src)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 *
s_strcpy(dst,src)13649999Schristos s_strcpy(dst, src)
13749999Schristos register Char *dst, *src;
13849999Schristos {
13949999Schristos register Char *sdst;
14049999Schristos
14149999Schristos sdst = dst;
14260237Schristos while ((*dst++ = *src++) != '\0')
14351437Sleres continue;
14449999Schristos return (sdst);
14549999Schristos }
14649999Schristos
14749999Schristos Char *
s_strncpy(dst,src,n)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 *
s_strcat(dst,src)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;
17860237Schristos while ((*dst++ = *src++) != '\0')
17951437Sleres continue;
18049999Schristos return (sdst);
18149999Schristos }
18249999Schristos
18349999Schristos #ifdef NOTUSED
18449999Schristos Char *
s_strncat(dst,src,n)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 *
s_strchr(str,ch)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 *
s_strrchr(str,ch)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
s_strlen(str)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
s_strcmp(str1,str2)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
s_strncmp(str1,str2,n)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 *
s_strsave(s)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)));
31260237Schristos while ((*p++ = *s++) != '\0')
31351437Sleres continue;
31449999Schristos return (n);
31549999Schristos }
31649999Schristos
31749999Schristos Char *
s_strspl(cp,dp)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)));
33460237Schristos for (p = ep, q = cp; (*p++ = *q++) != '\0';)
33551437Sleres continue;
33660237Schristos for (p--, q = dp; (*p++ = *q++) != '\0';)
33751437Sleres continue;
33849999Schristos return (ep);
33949999Schristos }
34049999Schristos
34149999Schristos Char *
s_strend(cp)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 *
s_strstr(s,t)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 *
short2qstr(src)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 *
vis_str(cp)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 }
43452369Schristos /*
43552369Schristos * XXX: When we are in AsciiOnly we want all characters >= 0200 to
43652369Schristos * be encoded, but currently there is no way in vis to do that.
43752369Schristos */
43852369Schristos (void) strvis(sdst, short2str(cp), VIS_NOSLASH);
43951589Schristos return (sdst);
44051589Schristos }
44151589Schristos
442