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