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