Annotation of src/usr.bin/xargs/strnsubst.c, Revision 1.8
1.8 ! jsg 1: /* $OpenBSD: strnsubst.c,v 1.7 2019/07/03 03:24:02 deraadt 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: #include <err.h>
13: #include <stdio.h>
14: #include <stdlib.h>
15: #include <string.h>
16: #include <unistd.h>
17:
18: void strnsubst(char **, const char *, const char *, size_t);
19:
20: /*
21: * Replaces str with a string consisting of str with match replaced with
22: * replstr as many times as can be done before the constructed string is
23: * maxsize bytes large. It does not free the string pointed to by str, it
24: * is up to the calling program to be sure that the original contents of
25: * str as well as the new contents are handled in an appropriate manner.
26: * If replstr is NULL, then that internally is changed to a nil-string, so
27: * that we can still pretend to do somewhat meaningful substitution.
28: * No value is returned.
29: */
30: void
31: strnsubst(char **str, const char *match, const char *replstr, size_t maxsize)
32: {
33: char *s1, *s2, *this;
1.6 tedu 34: size_t matchlen, s2len;
1.4 cloder 35: int n;
1.1 millert 36:
37: if ((s1 = *str) == NULL)
38: return;
39: if ((s2 = malloc(maxsize)) == NULL)
40: err(1, NULL);
41:
42: if (replstr == NULL)
43: replstr = "";
44:
45: if (match == NULL || *match == '\0' || strlen(s1) >= maxsize) {
46: strlcpy(s2, s1, maxsize);
47: goto done;
48: }
49:
50: *s2 = '\0';
51: s2len = 0;
52: matchlen = strlen(match);
53: for (;;) {
54: if ((this = strstr(s1, match)) == NULL)
55: break;
56: n = snprintf(s2 + s2len, maxsize - s2len, "%.*s%s",
57: (int)(this - s1), s1, replstr);
1.7 deraadt 58: if (n < 0 || n + s2len + strlen(this + matchlen) >= maxsize)
1.1 millert 59: break; /* out of room */
60: s2len += n;
61: s1 = this + matchlen;
62: }
63: strlcpy(s2 + s2len, s1, maxsize - s2len);
64: done:
65: *str = s2;
66: return;
67: }
68:
69: #ifdef TEST
70:
1.3 deraadt 71: int
1.1 millert 72: main(void)
73: {
74: char *x, *y, *z, *za;
75:
76: x = "{}%$";
77: strnsubst(&x, "%$", "{} enpury!", 255);
78: y = x;
79: strnsubst(&y, "}{}", "ybir", 255);
80: z = y;
81: strnsubst(&z, "{", "v ", 255);
82: za = z;
83: strnsubst(&z, NULL, za, 255);
84: if (strcmp(z, "v ybir enpury!") == 0)
85: printf("strnsubst() seems to work!\n");
86: else
87: printf("strnsubst() is broken.\n");
88: printf("%s\n", z);
89: free(x);
90: free(y);
91: free(z);
92: free(za);
93: return 0;
94: }
95: #endif