sbase

suckless unix tools
git clone git://git.suckless.org/sbase
Log | Files | Refs | README | LICENSE

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 }