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