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