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