strnsubst.c - sbase - suckless unix tools
 (HTM) git clone git://git.suckless.org/sbase
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) 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 }