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