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