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