1 /* @(#)strsubs.c 1.28 18/04/20 Copyright 1985-2018 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef lint
4 static UConst char sccsid[] =
5 "@(#)strsubs.c 1.28 18/04/20 Copyright 1985-2018 J. Schilling";
6 #endif
7 /*
8 * Useful string functions
9 *
10 * Copyright (c) 1985-2018 J. Schilling
11 */
12 /*
13 * The contents of this file are subject to the terms of the
14 * Common Development and Distribution License, Version 1.0 only
15 * (the "License"). You may not use this file except in compliance
16 * with the License.
17 *
18 * See the file CDDL.Schily.txt in this distribution for details.
19 * A copy of the CDDL is also available via the Internet at
20 * http://www.opensource.org/licenses/cddl1.txt
21 *
22 * When distributing Covered Code, include this CDDL HEADER in each
23 * file and include the License file CDDL.Schily.txt from this distribution.
24 */
25
26 #include <schily/stdio.h>
27 #include <schily/varargs.h>
28 #include <schily/utypes.h>
29 #include "bsh.h"
30 #include "strsubs.h"
31 #include <schily/string.h>
32 #include <schily/stdlib.h>
33 #include "ctype.h"
34
35 EXPORT char *makestr __PR((char *s));
36 EXPORT char *concat __PR((char *, ...));
37 EXPORT char *concatv __PR((char **s));
38 EXPORT int streql __PR((const char *s1, const char *s2));
39 EXPORT int streqln __PR((char *s1, char *s2, int n));
40 EXPORT char *strindex __PR((char *x, char *y));
41 EXPORT int strbeg __PR((char *x, char *y));
42 EXPORT int wordeql __PR((char *s1, char *s2));
43 EXPORT char *quote_string __PR((char *s, char *spec));
44 EXPORT char *pretty_string __PR((unsigned char *s));
45 EXPORT char *fbasename __PR((char *n));
46
47 EXPORT char *
makestr(s)48 makestr(s)
49 register char *s;
50 {
51 char *tmp;
52 register char *s1;
53
54 if ((tmp = malloc((size_t)strlen(s)+1)) == NULL) {
55 raisecond("makestr", (long)NULL);
56 return (0);
57 }
58 for (s1 = tmp; (*s1++ = *s++) != '\0'; );
59 return (tmp);
60 }
61
62 EXPORT char *
concatv(s)63 concatv(s)
64 char **s;
65 {
66 register char **argv;
67 char *ret;
68 register char *op;
69 register char *rp;
70 register int i;
71 register size_t len;
72 register int argc;
73
74 argv = s;
75 for (argc = 0; argv[argc]; argc++)
76 ;
77
78 for (i = 0, len = 0; i < argc; i++)
79 len += strlen(argv[i]);
80
81 if ((ret = rp = malloc(len + 1)) == NULL) {
82 raisecond("concat", (long)NULL);
83 return (NULL);
84 }
85
86 for (i = 0; i < argc; i++) {
87 for (op = argv[i]; (*rp = *op++) != '\0'; rp++)
88 ;
89 }
90 *rp = '\0';
91 return (ret);
92 }
93
94 #ifdef lint
95 /* VARARGS1 */
96 EXPORT char *
concat(args)97 concat(args)
98 char *args;
99 {
100 return (args);
101 }
102 #else
103 #ifdef PROTOTYPES
104 /* VARARGS1 */
105 EXPORT char *
concat(char * s,...)106 concat(char *s, ...)
107 #else
108 /* VARARGS1 */
109 EXPORT char *
110 concat(s, va_alist)
111 char *s;
112 va_dcl
113 #endif
114 {
115 va_list args;
116 char *ret;
117
118 register int i;
119 register size_t len;
120 register int argc;
121 register char *p;
122 register char *rp;
123
124 #ifdef PROTOTYPES
125 va_start(args, s);
126 #else
127 va_start(args);
128 #endif
129 p = s;
130 for (argc = 0, len = 0; p != NULL; argc++, p = va_arg(args, char *)) {
131 len += strlen(p);
132 }
133 va_end(args);
134
135 if ((ret = rp = malloc(len + 1)) == NULL) {
136 raisecond("concat", (long)NULL);
137 return (NULL);
138 }
139
140 #ifdef PROTOTYPES
141 va_start(args, s);
142 #else
143 va_start(args);
144 #endif
145
146 p = s;
147 for (i = 0; i < argc; i++, p = va_arg(args, char *)) {
148 for (; (*rp = *p++) != '\0'; rp++)
149 ;
150 }
151 *rp = '\0';
152 va_end(args);
153 return (ret);
154 }
155 #endif /* lint */
156
157 #ifdef used
158 /* not longer used */
159 EXPORT char *
find(c,s)160 find(c, s)
161 register char c;
162 register char *s;
163 {
164 do {
165 if (*s == c)
166 return (s);
167 } while (*s++ != '\0');
168 return (NULL);
169 }
170
171 EXPORT char *
rfind(c,s)172 rfind(c, s)
173 register char c;
174 register char *s;
175 {
176 register char *p = NULL;
177
178 do {
179 if (*s == c)
180 p = s;
181 } while (*s++ != '\0');
182 return (p);
183 }
184 #endif
185
186 EXPORT BOOL
streql(s1,s2)187 streql(s1, s2)
188 #ifdef __STDC__
189 const char *s1;
190 const char *s2;
191 #else
192 char *s1;
193 char *s2;
194 #endif
195 {
196 for (; *s1 == *s2; s1++, s2++)
197 if (*s1 == '\0')
198 return (TRUE);
199 return (FALSE);
200 }
201
202 /*
203 * Check if two strings equal to n chars
204 */
205 EXPORT BOOL
streqln(s1,s2,n)206 streqln(s1, s2, n)
207 register char *s1;
208 register char *s2;
209 register int n;
210 {
211 for (; n-- > 0; )
212 if (*s1++ != *s2++)
213 return (FALSE);
214 return (TRUE);
215 }
216
217 EXPORT char *
strindex(x,y)218 strindex(x, y)
219 char *x;
220 register char *y;
221 {
222 register char *a;
223 register char *b;
224
225 for (; *y != '\0'; y++) {
226 for (a = x, b = y; *a == *b++; ) {
227 if (*a++ == '\0')
228 return (y);
229 }
230 if (*a == '\0')
231 return (y);
232 }
233 return (NULL);
234 }
235
236 EXPORT BOOL
strbeg(x,y)237 strbeg(x, y)
238 char *x;
239 char *y;
240 {
241 return (strindex(x, y) == y);
242 }
243
244 EXPORT BOOL
wordeql(s1,s2)245 wordeql(s1, s2)
246 register char *s1;
247 register char *s2;
248 {
249 register int len = strlen(s2);
250
251 if (strlen(s1) < len)
252 return (FALSE);
253 if (s1[len] && !strchr(" \t\n\377", s1[len]))
254 return (FALSE);
255
256 return (streqln(s1, s2, len));
257 }
258
259
260 EXPORT char *
quote_string(s,spec)261 quote_string(s, spec)
262 register char *s;
263 register char *spec;
264 {
265 static char buf[16];
266 static char *str = 0;
267 register char *s1 = 0;
268 register int len;
269
270 if (str && str != buf)
271 free(str);
272 len = 2 * strlen(s) + 1;
273 if (len > sizeof (buf))
274 s1 = str = malloc(len);
275
276 if (s1 == 0) {
277 len = sizeof (buf);
278 s1 = str = buf;
279 }
280 while (*s && --len > 0) {
281 if (strchr(spec, *s)) {
282 *s1++ = '\\';
283 len--;
284 }
285 *s1++ = *s++;
286 }
287 *s1 = '\0';
288 return (str);
289 }
290
291 EXPORT char *
pretty_string(s)292 pretty_string(s)
293 register Uchar *s;
294 {
295 static Uchar buf[16];
296 static Uchar *str = 0;
297 register Uchar *s1 = 0;
298 register int len;
299
300 if (str && str != buf)
301 free(str);
302
303 len = 3 *(unsigned)strlen((char *)s) + 1;
304 if (len > sizeof (buf))
305 s1 = str = (Uchar *)malloc(len);
306
307 if (s1 == 0) {
308 len = sizeof (buf);
309 s1 = str = buf;
310 }
311 while (*s && --len > 0) {
312 if (isprint(*s)) {
313 *s1++ = *s++;
314 continue;
315 }
316 if (*s & 0x80) {
317 *s1++ = '~';
318 len--;
319 }
320 if (*s != 127 && *s & 0x60) {
321 *s1++ = *s++ & 0x7F;
322 } else {
323 *s1++ = '^';
324 *s1++ = (*s++ & 0x7F) ^ 0100;
325 len--;
326 }
327 }
328 *s1 = '\0';
329 return ((char *)str);
330 }
331
332 EXPORT char *
fbasename(n)333 fbasename(n)
334 register char *n;
335 {
336 register char *bn = n;
337
338 while (*n)
339 if (*n++ == '/')
340 bn = n;
341 return (bn);
342 }
343