tc.str.c revision 100616
1/* $Header: /src/pub/tcsh/tc.str.c,v 3.10 2002/03/08 17:36:47 christos Exp $ */
2/*
3 * tc.str.c: Short string package
4 * 	     This has been a lesson of how to write buggy code!
5 */
6/*-
7 * Copyright (c) 1980, 1991 The Regents of the University of California.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 *    may be used to endorse or promote products derived from this software
20 *    without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34#include "sh.h"
35
36RCSID("$Id: tc.str.c,v 3.10 2002/03/08 17:36:47 christos Exp $")
37
38#define MALLOC_INCR	128
39
40#ifdef SHORT_STRINGS
41Char  **
42blk2short(src)
43    register char **src;
44{
45    size_t     n;
46    register Char **sdst, **dst;
47
48    /*
49     * Count
50     */
51    for (n = 0; src[n] != NULL; n++)
52	continue;
53    sdst = dst = (Char **) xmalloc((size_t) ((n + 1) * sizeof(Char *)));
54
55    for (; *src != NULL; src++)
56	*dst++ = SAVE(*src);
57    *dst = NULL;
58    return (sdst);
59}
60
61char  **
62short2blk(src)
63    register Char **src;
64{
65    size_t     n;
66    register char **sdst, **dst;
67
68    /*
69     * Count
70     */
71    for (n = 0; src[n] != NULL; n++)
72	continue;
73    sdst = dst = (char **) xmalloc((size_t) ((n + 1) * sizeof(char *)));
74
75    for (; *src != NULL; src++)
76	*dst++ = strsave(short2str(*src));
77    *dst = NULL;
78    return (sdst);
79}
80
81Char   *
82str2short(src)
83    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
312Char   *
313s_strsave(s)
314    register const Char *s;
315{
316    Char   *n;
317    register Char *p;
318
319    if (s == 0)
320	s = STRNULL;
321    for (p = (Char *) s; *p++;)
322	continue;
323    n = p = (Char *) xmalloc((size_t)
324			     ((((const Char *) p) - s) * sizeof(Char)));
325    while ((*p++ = *s++) != '\0')
326	continue;
327    return (n);
328}
329
330Char   *
331s_strspl(cp, dp)
332    const Char   *cp, *dp;
333{
334    Char   *ep;
335    register Char *p, *q;
336
337    if (!cp)
338	cp = STRNULL;
339    if (!dp)
340	dp = STRNULL;
341    for (p = (Char *) cp; *p++;)
342	continue;
343    for (q = (Char *) dp; *q++;)
344	continue;
345    ep = (Char *) xmalloc((size_t)
346			  (((((const Char *) p) - cp) +
347			    (((const Char *) q) - dp) - 1) * sizeof(Char)));
348    for (p = ep, q = (Char*) cp; (*p++ = *q++) != '\0';)
349	continue;
350    for (p--, q = (Char *) dp; (*p++ = *q++) != '\0';)
351	continue;
352    return (ep);
353}
354
355Char   *
356s_strend(cp)
357    register const Char *cp;
358{
359    if (!cp)
360	return ((Char *) cp);
361    while (*cp)
362	cp++;
363    return ((Char *) cp);
364}
365
366Char   *
367s_strstr(s, t)
368    register const Char *s, *t;
369{
370    do {
371	register const Char *ss = s;
372	register const Char *tt = t;
373
374	do
375	    if (*tt == '\0')
376		return ((Char *) s);
377	while (*ss++ == *tt++);
378    } while (*s++ != '\0');
379    return (NULL);
380}
381
382#endif				/* SHORT_STRINGS */
383
384char   *
385short2qstr(src)
386    register const Char *src;
387{
388    static char *sdst = NULL;
389    static size_t dstsize = 0;
390    register char *dst, *edst;
391
392    if (src == NULL)
393	return (NULL);
394
395    if (sdst == NULL) {
396	dstsize = MALLOC_INCR;
397	sdst = (char *) xmalloc((size_t) (dstsize * sizeof(char)));
398    }
399    dst = sdst;
400    edst = &dst[dstsize];
401    while (*src) {
402	if (*src & QUOTE) {
403	    *dst++ = '\\';
404	    if (dst == edst) {
405		dstsize += MALLOC_INCR;
406		sdst = (char *) xrealloc((ptr_t) sdst,
407					 (size_t) (dstsize * sizeof(char)));
408		edst = &sdst[dstsize];
409		dst = &edst[-MALLOC_INCR];
410	    }
411	}
412	*dst++ = (char) *src++;
413	if (dst == edst) {
414	    dstsize += MALLOC_INCR;
415	    sdst = (char *) xrealloc((ptr_t) sdst,
416				     (size_t) (dstsize * sizeof(char)));
417	    edst = &sdst[dstsize];
418	    dst = &edst[-MALLOC_INCR];
419	}
420    }
421    *dst = 0;
422    return (sdst);
423}
424