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