xref: /netbsd-src/bin/csh/str.c (revision 1ca5c1b28139779176bd5c13ad7c5f25c0bcd5f8)
1 /* $NetBSD: str.c,v 1.11 2001/09/14 14:04:01 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.11 2001/09/14 14:04:01 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 <vis.h>
55 
56 #if __STDC__
57 # include <stdarg.h>
58 #else
59 # include <varargs.h>
60 #endif
61 
62 #include "csh.h"
63 #include "extern.h"
64 
65 #ifdef SHORT_STRINGS
66 
67 Char **
68 blk2short(char **src)
69 {
70     Char **dst, **sdst;
71     size_t n;
72 
73     /*
74      * Count
75      */
76     for (n = 0; src[n] != NULL; n++)
77 	continue;
78     sdst = dst = (Char **)xmalloc((size_t)((n + 1) * sizeof(Char *)));
79 
80     for (; *src != NULL; src++)
81 	*dst++ = SAVE(*src);
82     *dst = NULL;
83     return (sdst);
84 }
85 
86 char **
87 short2blk(Char **src)
88 {
89     char **dst, **sdst;
90     size_t n;
91 
92     /*
93      * Count
94      */
95     for (n = 0; src[n] != NULL; n++)
96 	continue;
97     sdst = dst = (char **)xmalloc((size_t)((n + 1) * sizeof(char *)));
98 
99     for (; *src != NULL; src++)
100 	*dst++ = strsave(short2str(*src));
101     *dst = NULL;
102     return (sdst);
103 }
104 
105 Char *
106 str2short(const char *src)
107 {
108     static Char *sdst;
109     Char *dst, *edst;
110     static size_t dstsize = 0;
111 
112     if (src == NULL)
113 	return (NULL);
114 
115     if (sdst == (NULL)) {
116 	dstsize = MALLOC_INCR;
117 	sdst = (Char *)xmalloc((size_t)dstsize * sizeof(Char));
118     }
119 
120     dst = sdst;
121     edst = &dst[dstsize];
122     while (*src) {
123 	*dst++ = (Char) ((unsigned char) *src++);
124 	if (dst == edst) {
125 	    dstsize += MALLOC_INCR;
126 	    sdst = (Char *)xrealloc((ptr_t)sdst,
127 	        (size_t)dstsize * sizeof(Char));
128 	    edst = &sdst[dstsize];
129 	    dst = &edst[-MALLOC_INCR];
130 	}
131     }
132     *dst = 0;
133     return (sdst);
134 }
135 
136 char *
137 short2str(Char *src)
138 {
139     static char *sdst = NULL;
140     static size_t dstsize = 0;
141     char *dst, *edst;
142 
143     if (src == NULL)
144 	return (NULL);
145 
146     if (sdst == NULL) {
147 	dstsize = MALLOC_INCR;
148 	sdst = (char *)xmalloc((size_t)dstsize * sizeof(char));
149     }
150     dst = sdst;
151     edst = &dst[dstsize];
152     while (*src) {
153 	*dst++ = (char) *src++;
154 	if (dst == edst) {
155 	    dstsize += MALLOC_INCR;
156 	    sdst = (char *)xrealloc((ptr_t)sdst,
157 	        (size_t)dstsize * sizeof(char));
158 	    edst = &sdst[dstsize];
159 	    dst = &edst[-MALLOC_INCR];
160 	}
161     }
162     *dst = 0;
163     return (sdst);
164 }
165 
166 Char *
167 s_strcpy(Char *dst, Char *src)
168 {
169     Char *sdst;
170 
171     sdst = dst;
172     while ((*dst++ = *src++) != '\0')
173 	continue;
174     return (sdst);
175 }
176 
177 Char *
178 s_strncpy(Char *dst, Char *src, size_t n)
179 {
180     Char *sdst;
181 
182     if (n == 0)
183 	return(dst);
184 
185     sdst = dst;
186     do
187 	if ((*dst++ = *src++) == '\0') {
188 	    while (--n != 0)
189 		*dst++ = '\0';
190 	    return(sdst);
191 	}
192     while (--n != 0);
193     return (sdst);
194 }
195 
196 Char *
197 s_strcat(Char *dst, Char *src)
198 {
199     short *sdst;
200 
201     sdst = dst;
202     while (*dst++)
203 	continue;
204     --dst;
205     while ((*dst++ = *src++) != '\0')
206 	continue;
207     return (sdst);
208 }
209 
210 #ifdef NOTUSED
211 Char *
212 s_strncat(Char *dst, Char *src, size_t n)
213 {
214     Char *sdst;
215 
216     if (n == 0)
217 	return (dst);
218 
219     sdst = dst;
220 
221     while (*dst++)
222 	continue;
223     --dst;
224 
225     do
226 	if ((*dst++ = *src++) == '\0')
227 	    return(sdst);
228     while (--n != 0)
229 	continue;
230 
231     *dst = '\0';
232     return (sdst);
233 }
234 
235 #endif
236 
237 Char *
238 s_strchr(Char *str, int ch)
239 {
240     do
241 	if (*str == ch)
242 	    return (str);
243     while (*str++);
244     return (NULL);
245 }
246 
247 Char *
248 s_strrchr(Char *str, int ch)
249 {
250     Char *rstr;
251 
252     rstr = NULL;
253     do
254 	if (*str == ch)
255 	    rstr = str;
256     while (*str++);
257     return (rstr);
258 }
259 
260 size_t
261 s_strlen(Char *str)
262 {
263     size_t n;
264 
265     for (n = 0; *str++; n++)
266 	continue;
267     return (n);
268 }
269 
270 int
271 s_strcmp(Char *str1, Char *str2)
272 {
273     for (; *str1 && *str1 == *str2; str1++, str2++)
274 	continue;
275     /*
276      * The following case analysis is necessary so that characters which look
277      * negative collate low against normal characters but high against the
278      * end-of-string NUL.
279      */
280     if (*str1 == '\0' && *str2 == '\0')
281 	return (0);
282     else if (*str1 == '\0')
283 	return (-1);
284     else if (*str2 == '\0')
285 	return (1);
286     else
287 	return (*str1 - *str2);
288 }
289 
290 int
291 s_strncmp(Char *str1, Char *str2, size_t n)
292 {
293     if (n == 0)
294 	return (0);
295     do {
296 	if (*str1 != *str2) {
297 	    /*
298 	     * The following case analysis is necessary so that characters
299 	     * which look negative collate low against normal characters
300 	     * but high against the end-of-string NUL.
301 	     */
302 	    if (*str1 == '\0')
303 		return (-1);
304 	    else if (*str2 == '\0')
305 		return (1);
306 	    else
307 		return (*str1 - *str2);
308 	}
309         if (*str1 == '\0')
310 	    return(0);
311 	str1++, str2++;
312     } while (--n != 0);
313     return(0);
314 }
315 
316 Char *
317 s_strsave(Char *s)
318 {
319     Char *n, *p;
320 
321     if (s == 0)
322 	s = STRNULL;
323     for (p = s; *p++;)
324 	continue;
325     n = p = (Char *)xmalloc((size_t)((p - s) * sizeof(Char)));
326     while ((*p++ = *s++) != '\0')
327 	continue;
328     return (n);
329 }
330 
331 Char *
332 s_strspl(Char *cp, Char *dp)
333 {
334     Char *ep, *p, *q;
335 
336     if (!cp)
337 	cp = STRNULL;
338     if (!dp)
339 	dp = STRNULL;
340     for (p = cp; *p++;)
341 	continue;
342     for (q = dp; *q++;)
343 	continue;
344     ep = (Char *)xmalloc((size_t)(((p - cp) + (q - dp) - 1) * sizeof(Char)));
345     for (p = ep, q = cp; (*p++ = *q++) != '\0';)
346 	continue;
347     for (p--, q = dp; (*p++ = *q++) != '\0';)
348 	continue;
349     return (ep);
350 }
351 
352 Char *
353 s_strend(Char *cp)
354 {
355     if (!cp)
356 	return (cp);
357     while (*cp)
358 	cp++;
359     return (cp);
360 }
361 
362 Char *
363 s_strstr(Char *s, Char *t)
364 {
365     do {
366 	Char *ss = s;
367 	Char *tt = t;
368 
369 	do
370 	    if (*tt == '\0')
371 		return (s);
372 	while (*ss++ == *tt++);
373     } while (*s++ != '\0');
374     return (NULL);
375 }
376 #endif				/* SHORT_STRINGS */
377 
378 char *
379 short2qstr(Char *src)
380 {
381     static char *sdst = NULL;
382     static size_t dstsize = 0;
383     char *dst, *edst;
384 
385     if (src == NULL)
386 	return (NULL);
387 
388     if (sdst == NULL) {
389 	dstsize = MALLOC_INCR;
390 	sdst = (char *)xmalloc((size_t)dstsize * sizeof(char));
391     }
392     dst = sdst;
393     edst = &dst[dstsize];
394     while (*src) {
395 	if (*src & QUOTE) {
396 	    *dst++ = '\\';
397 	    if (dst == edst) {
398 		dstsize += MALLOC_INCR;
399 		sdst = (char *)xrealloc((ptr_t) sdst,
400 		    (size_t)dstsize * sizeof(char));
401 		edst = &sdst[dstsize];
402 		dst = &edst[-MALLOC_INCR];
403 	    }
404 	}
405 	*dst++ = (char) *src++;
406 	if (dst == edst) {
407 	    dstsize += MALLOC_INCR;
408 	    sdst = (char *)xrealloc((ptr_t) sdst,
409 	        (size_t)dstsize * sizeof(char));
410 	    edst = &sdst[dstsize];
411 	    dst = &edst[-MALLOC_INCR];
412 	}
413     }
414     *dst = 0;
415     return (sdst);
416 }
417 
418 /*
419  * XXX: Should we worry about QUOTE'd chars?
420  */
421 char *
422 vis_str(Char *cp)
423 {
424     static char *sdst = NULL;
425     static size_t dstsize = 0;
426     Char *dp;
427     size_t n;
428 
429     if (cp == NULL)
430 	return (NULL);
431 
432     for (dp = cp; *dp++;)
433 	continue;
434     n = ((dp - cp) << 2) + 1; /* 4 times + NULL */
435     if (dstsize < n) {
436 	sdst = (char *) (dstsize ?
437 	    xrealloc(sdst, (size_t)n * sizeof(char)) :
438 	    xmalloc((size_t)n * sizeof(char)));
439 	dstsize = n;
440     }
441     /*
442      * XXX: When we are in AsciiOnly we want all characters >= 0200 to
443      * be encoded, but currently there is no way in vis to do that.
444      */
445     (void)strvis(sdst, short2str(cp), VIS_NOSLASH);
446     return (sdst);
447 }
448