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