tc.str.c revision 131962
155714Skris/* $Header: /src/pub/tcsh/tc.str.c,v 3.13 2004/02/21 20:34:25 christos Exp $ */
255714Skris/*
355714Skris * tc.str.c: Short string package
455714Skris * 	     This has been a lesson of how to write buggy code!
555714Skris */
655714Skris/*-
755714Skris * Copyright (c) 1980, 1991 The Regents of the University of California.
855714Skris * All rights reserved.
955714Skris *
1055714Skris * Redistribution and use in source and binary forms, with or without
1155714Skris * modification, are permitted provided that the following conditions
1255714Skris * are met:
1355714Skris * 1. Redistributions of source code must retain the above copyright
1455714Skris *    notice, this list of conditions and the following disclaimer.
1555714Skris * 2. Redistributions in binary form must reproduce the above copyright
1655714Skris *    notice, this list of conditions and the following disclaimer in the
1755714Skris *    documentation and/or other materials provided with the distribution.
1855714Skris * 3. Neither the name of the University nor the names of its contributors
1955714Skris *    may be used to endorse or promote products derived from this software
2055714Skris *    without specific prior written permission.
2155714Skris *
2255714Skris * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2355714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2455714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2555714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2655714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2755714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2855714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2955714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3055714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3155714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3255714Skris * SUCH DAMAGE.
3355714Skris */
3455714Skris#include "sh.h"
3555714Skris
3655714SkrisRCSID("$Id: tc.str.c,v 3.13 2004/02/21 20:34:25 christos Exp $")
3755714Skris
3855714Skris#define MALLOC_INCR	128
3955714Skris
4055714Skris#ifdef SHORT_STRINGS
4155714SkrisChar  **
4255714Skrisblk2short(src)
4355714Skris    register char **src;
4455714Skris{
4555714Skris    size_t     n;
4655714Skris    register Char **sdst, **dst;
4755714Skris
4855714Skris    /*
4955714Skris     * Count
5055714Skris     */
5155714Skris    for (n = 0; src[n] != NULL; n++)
5255714Skris	continue;
5355714Skris    sdst = dst = (Char **) xmalloc((size_t) ((n + 1) * sizeof(Char *)));
5455714Skris
5555714Skris    for (; *src != NULL; src++)
5655714Skris	*dst++ = SAVE(*src);
5755714Skris    *dst = NULL;
5855714Skris    return (sdst);
5955714Skris}
6055714Skris
6155714Skrischar  **
6255714Skrisshort2blk(src)
6355714Skris    register Char **src;
6455714Skris{
6555714Skris    size_t     n;
6655714Skris    register char **sdst, **dst;
6755714Skris
6855714Skris    /*
6955714Skris     * Count
7055714Skris     */
7155714Skris    for (n = 0; src[n] != NULL; n++)
7255714Skris	continue;
7355714Skris    sdst = dst = (char **) xmalloc((size_t) ((n + 1) * sizeof(char *)));
7455714Skris
7555714Skris    for (; *src != NULL; src++)
7655714Skris	*dst++ = strsave(short2str(*src));
7755714Skris    *dst = NULL;
7855714Skris    return (sdst);
7955714Skris}
8055714Skris
8155714SkrisChar   *
8255714Skrisstr2short(src)
8355714Skris    register const char *src;
84{
85    static Char *sdst;
86    static size_t dstsize = 0;
87    register Char *dst, *edst;
88
89    if (src == NULL)
90	return (NULL);
91
92    if (sdst == (NULL)) {
93	dstsize = MALLOC_INCR;
94	sdst = (Char *) xmalloc((size_t) (dstsize * sizeof(Char)));
95    }
96
97    dst = sdst;
98    edst = &dst[dstsize];
99    while ((unsigned char) *src) {
100	*dst++ = (Char) ((unsigned char) *src++);
101	if (dst == edst) {
102	    dstsize += MALLOC_INCR;
103	    sdst = (Char *) xrealloc((ptr_t) sdst,
104				     (size_t) (dstsize * sizeof(Char)));
105	    edst = &sdst[dstsize];
106	    dst = &edst[-MALLOC_INCR];
107	}
108    }
109    *dst = 0;
110    return (sdst);
111}
112
113char   *
114short2str(src)
115    register const Char *src;
116{
117    static char *sdst = NULL;
118    static size_t dstsize = 0;
119    register char *dst, *edst;
120
121    if (src == NULL)
122	return (NULL);
123
124    if (sdst == NULL) {
125	dstsize = MALLOC_INCR;
126	sdst = (char *) xmalloc((size_t) (dstsize * sizeof(char)));
127    }
128    dst = sdst;
129    edst = &dst[dstsize];
130    while (*src) {
131	*dst++ = (char) *src++;
132	if (dst == edst) {
133	    dstsize += MALLOC_INCR;
134	    sdst = (char *) xrealloc((ptr_t) sdst,
135				     (size_t) (dstsize * sizeof(char)));
136	    edst = &sdst[dstsize];
137	    dst = &edst[-MALLOC_INCR];
138	}
139    }
140    *dst = 0;
141    return (sdst);
142}
143
144Char   *
145s_strcpy(dst, src)
146    register Char *dst;
147    register const Char *src;
148{
149    register Char *sdst;
150
151    sdst = dst;
152    while ((*dst++ = *src++) != '\0')
153	continue;
154    return (sdst);
155}
156
157Char   *
158s_strncpy(dst, src, n)
159    register Char *dst;
160    register const Char *src;
161    register size_t n;
162{
163    register Char *sdst;
164
165    if (n == 0)
166	return(dst);
167
168    sdst = dst;
169    do
170	if ((*dst++ = *src++) == '\0') {
171	    while (--n != 0)
172		*dst++ = '\0';
173	    return(sdst);
174	}
175    while (--n != 0);
176    return (sdst);
177}
178
179Char   *
180s_strcat(dst, src)
181    register Char *dst;
182    register const Char *src;
183{
184    register short *sdst;
185
186    sdst = dst;
187    while (*dst++)
188	continue;
189    --dst;
190    while ((*dst++ = *src++) != '\0')
191	continue;
192    return (sdst);
193}
194
195#ifdef NOTUSED
196Char   *
197s_strncat(dst, src, n)
198    register Char *dst;
199    register const Char *src;
200    register size_t n;
201{
202    register Char *sdst;
203
204    if (n == 0)
205	return (dst);
206
207    sdst = dst;
208
209    while (*dst++)
210	continue;
211    --dst;
212
213    do
214	if ((*dst++ = *src++) == '\0')
215	    return(sdst);
216    while (--n != 0)
217	continue;
218
219    *dst = '\0';
220    return (sdst);
221}
222
223#endif
224
225Char   *
226s_strchr(str, ch)
227    register const Char *str;
228    int ch;
229{
230    do
231	if (*str == ch)
232	    return ((Char *) str);
233    while (*str++);
234    return (NULL);
235}
236
237Char   *
238s_strrchr(str, ch)
239    register const Char *str;
240    int ch;
241{
242    register const Char *rstr;
243
244    rstr = NULL;
245    do
246	if (*str == ch)
247	    rstr = str;
248    while (*str++);
249    return ((Char *) rstr);
250}
251
252size_t
253s_strlen(str)
254    register const Char *str;
255{
256    register size_t n;
257
258    for (n = 0; *str++; n++)
259	continue;
260    return (n);
261}
262
263int
264s_strcmp(str1, str2)
265    register const Char *str1, *str2;
266{
267    for (; *str1 && *str1 == *str2; str1++, str2++)
268	continue;
269    /*
270     * The following case analysis is necessary so that characters which look
271     * negative collate low against normal characters but high against the
272     * end-of-string NUL.
273     */
274    if (*str1 == '\0' && *str2 == '\0')
275	return (0);
276    else if (*str1 == '\0')
277	return (-1);
278    else if (*str2 == '\0')
279	return (1);
280    else
281	return (*str1 - *str2);
282}
283
284int
285s_strncmp(str1, str2, n)
286    register const Char *str1, *str2;
287    register size_t n;
288{
289    if (n == 0)
290	return (0);
291    do {
292	if (*str1 != *str2) {
293	    /*
294	     * The following case analysis is necessary so that characters
295	     * which look negative collate low against normal characters
296	     * but high against the end-of-string NUL.
297	     */
298	    if (*str1 == '\0')
299		return (-1);
300	    else if (*str2 == '\0')
301		return (1);
302	    else
303		return (*str1 - *str2);
304	}
305        if (*str1 == '\0')
306	    return(0);
307	str1++, str2++;
308    } while (--n != 0);
309    return(0);
310}
311
312int
313s_strcasecmp(str1, str2)
314    register const Char *str1, *str2;
315{
316    unsigned char c1, c2, l1 = 0, l2 = 0;
317    for (; *str1 && ((*str1 == *str2 && (l1 = l2 = 0) == 0) ||
318	((c1 = (unsigned char)*str1) == *str1 &&
319	 (c2 = (unsigned char)*str2) == *str2 &&
320	(l1 = tolower(c1)) == (l2 = tolower(c2)))); str1++, str2++)
321	continue;
322    /*
323     * The following case analysis is necessary so that characters which look
324     * negative collate low against normal characters but high against the
325     * end-of-string NUL.
326     */
327    if (*str1 == '\0' && *str2 == '\0')
328	return (0);
329    else if (*str1 == '\0')
330	return (-1);
331    else if (*str2 == '\0')
332	return (1);
333    else if (l1 == l2)	/* They are zero when they are equal */
334	return (*str1 - *str2);
335    else
336	return (l1 - l2);
337}
338
339Char   *
340s_strsave(s)
341    register const Char *s;
342{
343    Char   *n;
344    register Char *p;
345
346    if (s == 0)
347	s = STRNULL;
348    for (p = (Char *) s; *p++;)
349	continue;
350    n = p = (Char *) xmalloc((size_t)
351			     ((((const Char *) p) - s) * sizeof(Char)));
352    while ((*p++ = *s++) != '\0')
353	continue;
354    return (n);
355}
356
357Char   *
358s_strspl(cp, dp)
359    const Char   *cp, *dp;
360{
361    Char   *ep;
362    register Char *p, *q;
363
364    if (!cp)
365	cp = STRNULL;
366    if (!dp)
367	dp = STRNULL;
368    for (p = (Char *) cp; *p++;)
369	continue;
370    for (q = (Char *) dp; *q++;)
371	continue;
372    ep = (Char *) xmalloc((size_t)
373			  (((((const Char *) p) - cp) +
374			    (((const Char *) q) - dp) - 1) * sizeof(Char)));
375    for (p = ep, q = (Char*) cp; (*p++ = *q++) != '\0';)
376	continue;
377    for (p--, q = (Char *) dp; (*p++ = *q++) != '\0';)
378	continue;
379    return (ep);
380}
381
382Char   *
383s_strend(cp)
384    register const Char *cp;
385{
386    if (!cp)
387	return ((Char *) cp);
388    while (*cp)
389	cp++;
390    return ((Char *) cp);
391}
392
393Char   *
394s_strstr(s, t)
395    register const Char *s, *t;
396{
397    do {
398	register const Char *ss = s;
399	register const Char *tt = t;
400
401	do
402	    if (*tt == '\0')
403		return ((Char *) s);
404	while (*ss++ == *tt++);
405    } while (*s++ != '\0');
406    return (NULL);
407}
408
409#endif				/* SHORT_STRINGS */
410
411char   *
412short2qstr(src)
413    register const Char *src;
414{
415    static char *sdst = NULL;
416    static size_t dstsize = 0;
417    register char *dst, *edst;
418
419    if (src == NULL)
420	return (NULL);
421
422    if (sdst == NULL) {
423	dstsize = MALLOC_INCR;
424	sdst = (char *) xmalloc((size_t) (dstsize * sizeof(char)));
425    }
426    dst = sdst;
427    edst = &dst[dstsize];
428    while (*src) {
429	if (*src & QUOTE) {
430	    *dst++ = '\\';
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++ = (char) *src++;
440	if (dst == edst) {
441	    dstsize += MALLOC_INCR;
442	    sdst = (char *) xrealloc((ptr_t) sdst,
443				     (size_t) (dstsize * sizeof(char)));
444	    edst = &sdst[dstsize];
445	    dst = &edst[-MALLOC_INCR];
446	}
447    }
448    *dst = 0;
449    return (sdst);
450}
451