[BACK]Return to strnsubst.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / xargs

Annotation of src/usr.bin/xargs/strnsubst.c, Revision 1.8

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