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