Annotation of src/usr.bin/xargs/strnsubst.c, Revision 1.3
1.3 ! deraadt 1: /* $OpenBSD: strnsubst.c,v 1.2 2003/06/12 03:23:22 millert Exp $ */
1.1 millert 2: /* $FreeBSD: strnsubst.c,v 1.6 2002/06/22 12:58:42 jmallett Exp $ */
3:
4: /*
5: * Copyright (c) 2002 J. Mallett. All rights reserved.
6: * You may do whatever you want with this file as long as
7: * the above copyright and this notice remain intact, along
8: * with the following statement:
9: * For the man who taught me vi, and who got too old, too young.
10: */
11:
12: #ifndef lint
1.3 ! deraadt 13: static const char rcsid[] = "$OpenBSD: strnsubst.c,v 1.2 2003/06/12 03:23:22 millert Exp $";
1.1 millert 14: #endif /* not lint */
15:
16: #include <err.h>
17: #include <stdio.h>
18: #include <stdlib.h>
19: #include <string.h>
20: #include <unistd.h>
21:
22: void strnsubst(char **, const char *, const char *, size_t);
23:
24: /*
25: * Replaces str with a string consisting of str with match replaced with
26: * replstr as many times as can be done before the constructed string is
27: * maxsize bytes large. It does not free the string pointed to by str, it
28: * is up to the calling program to be sure that the original contents of
29: * str as well as the new contents are handled in an appropriate manner.
30: * If replstr is NULL, then that internally is changed to a nil-string, so
31: * that we can still pretend to do somewhat meaningful substitution.
32: * No value is returned.
33: */
34: void
35: strnsubst(char **str, const char *match, const char *replstr, size_t maxsize)
36: {
37: char *s1, *s2, *this;
38: size_t matchlen, repllen, s2len, n;
39:
40: if ((s1 = *str) == NULL)
41: return;
42: if ((s2 = malloc(maxsize)) == NULL)
43: err(1, NULL);
44:
45: if (replstr == NULL)
46: replstr = "";
47:
48: if (match == NULL || *match == '\0' || strlen(s1) >= maxsize) {
49: strlcpy(s2, s1, maxsize);
50: goto done;
51: }
52:
53: *s2 = '\0';
54: s2len = 0;
55: matchlen = strlen(match);
56: repllen = strlen(replstr);
57: for (;;) {
58: if ((this = strstr(s1, match)) == NULL)
59: break;
60: n = snprintf(s2 + s2len, maxsize - s2len, "%.*s%s",
61: (int)(this - s1), s1, replstr);
1.2 millert 62: if (n == -1 || n + s2len + strlen(this + matchlen) >= maxsize)
1.1 millert 63: break; /* out of room */
64: s2len += n;
65: s1 = this + matchlen;
66: }
67: strlcpy(s2 + s2len, s1, maxsize - s2len);
68: done:
69: *str = s2;
70: return;
71: }
72:
73: #ifdef TEST
74: #include <stdio.h>
75:
1.3 ! deraadt 76: int
1.1 millert 77: main(void)
78: {
79: char *x, *y, *z, *za;
80:
81: x = "{}%$";
82: strnsubst(&x, "%$", "{} enpury!", 255);
83: y = x;
84: strnsubst(&y, "}{}", "ybir", 255);
85: z = y;
86: strnsubst(&z, "{", "v ", 255);
87: za = z;
88: strnsubst(&z, NULL, za, 255);
89: if (strcmp(z, "v ybir enpury!") == 0)
90: printf("strnsubst() seems to work!\n");
91: else
92: printf("strnsubst() is broken.\n");
93: printf("%s\n", z);
94: free(x);
95: free(y);
96: free(z);
97: free(za);
98: return 0;
99: }
100: #endif