strnsubst.c (1674B)
1 /* 2 * Copyright (c) 2002 J. Mallett. All rights reserved. 3 * You may do whatever you want with this file as long as 4 * the above copyright and this notice remain intact, along 5 * with the following statement: 6 * For the man who taught me vi, and who got too old, too young. 7 */ 8 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <string.h> 12 13 #include "../util.h" 14 15 /* 16 * Replaces str with a string consisting of str with match replaced with 17 * replstr as many times as can be done before the constructed string is 18 * maxsize bytes large. It does not free the string pointed to by str, it 19 * is up to the calling program to be sure that the original contents of 20 * str as well as the new contents are handled in an appropriate manner. 21 * If replstr is NULL, then that internally is changed to a nil-string, so 22 * that we can still pretend to do somewhat meaningful substitution. 23 * No value is returned. 24 */ 25 void 26 strnsubst(char **str, const char *match, const char *replstr, size_t maxsize) 27 { 28 char *s1, *s2, *this; 29 size_t matchlen, s2len; 30 int n; 31 32 if ((s1 = *str) == NULL) 33 return; 34 s2 = emalloc(maxsize); 35 36 if (replstr == NULL) 37 replstr = ""; 38 39 if (match == NULL || *match == '\0' || strlen(s1) >= maxsize) { 40 strlcpy(s2, s1, maxsize); 41 goto done; 42 } 43 44 *s2 = '\0'; 45 s2len = 0; 46 matchlen = strlen(match); 47 for (;;) { 48 if ((this = strstr(s1, match)) == NULL) 49 break; 50 n = snprintf(s2 + s2len, maxsize - s2len, "%.*s%s", 51 (int)(this - s1), s1, replstr); 52 if (n == -1 || n + s2len + strlen(this + matchlen) >= maxsize) 53 break; /* out of room */ 54 s2len += n; 55 s1 = this + matchlen; 56 } 57 strlcpy(s2 + s2len, s1, maxsize - s2len); 58 done: 59 *str = s2; 60 return; 61 }