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 * $FreeBSD: src/usr.bin/xargs/strnsubst.c,v 1.5.2.1 2002/06/17 04:44:46 jmallett Exp $ 11 * $DragonFly: src/usr.bin/xargs/strnsubst.c,v 1.2 2003/06/17 04:29:34 dillon Exp $ 12 */ 13 14 #include <err.h> 15 #include <stdint.h> 16 #include <stdlib.h> 17 #include <string.h> 18 #include <unistd.h> 19 20 void strnsubst(char **, const char *, const char *, size_t); 21 22 /* 23 * Replaces str with a string consisting of str with match replaced with 24 * replstr as many times as can be done before the constructed string is 25 * maxsize bytes large. It does not free the string pointed to by str, it 26 * is up to the calling program to be sure that the original contents of 27 * str as well as the new contents are handled in an appropriate manner. 28 * If replstr is NULL, then that internally is changed to a nil-string, so 29 * that we can still pretend to do somewhat meaningful substitution. 30 * No value is returned. 31 */ 32 void 33 strnsubst(char **str, const char *match, const char *replstr, size_t maxsize) 34 { 35 char *s1, *s2, *this; 36 37 s1 = *str; 38 if (s1 == NULL) 39 return; 40 s2 = calloc(maxsize, 1); 41 if (s2 == NULL) 42 err(1, "calloc"); 43 44 if (replstr == NULL) 45 replstr = ""; 46 47 if (match == NULL || replstr == NULL || maxsize == strlen(s1)) { 48 strlcpy(s2, s1, maxsize); 49 goto done; 50 } 51 52 for (;;) { 53 this = strstr(s1, match); 54 if (this == NULL) 55 break; 56 if ((strlen(s2) + ((uintptr_t)this - (uintptr_t)s1) + 57 (strlen(replstr) - 1)) > maxsize && *replstr != '\0') { 58 strlcat(s2, s1, maxsize); 59 goto done; 60 } 61 strncat(s2, s1, (uintptr_t)this - (uintptr_t)s1); 62 strcat(s2, replstr); 63 s1 = this + strlen(match); 64 } 65 strcat(s2, s1); 66 done: 67 *str = s2; 68 return; 69 } 70 71 #ifdef TEST 72 #include <stdio.h> 73 74 int 75 main(void) 76 { 77 char *x, *y; 78 79 y = x = "{}{}{}"; 80 strnsubst(&x, "{}", "v ybir whyv! ", 12); 81 if (strcmp(x, "v ybir whyv! ") == 0) 82 printf("strnsubst() seems to work as expected.\n"); 83 printf("x: %s\ny: %s\n", x, y); 84 free(x); 85 return 0; 86 } 87 #endif 88