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