[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.4

1.4     ! cloder      1: /*     $OpenBSD: strnsubst.c,v 1.3 2005/11/01 04:52:58 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: #ifndef lint
1.4     ! cloder     13: static const char rcsid[] = "$OpenBSD: strnsubst.c,v 1.3 2005/11/01 04:52:58 deraadt Exp $";
1.1       millert    14: #endif /* not lint */
                     15:
                     16: #include <err.h>
                     17: #include <stdio.h>
                     18: #include <stdlib.h>
                     19: #include <string.h>
                     20: #include <unistd.h>
                     21:
                     22: void   strnsubst(char **, const char *, const char *, size_t);
                     23:
                     24: /*
                     25:  * Replaces str with a string consisting of str with match replaced with
                     26:  * replstr as many times as can be done before the constructed string is
                     27:  * maxsize bytes large.  It does not free the string pointed to by str, it
                     28:  * is up to the calling program to be sure that the original contents of
                     29:  * str as well as the new contents are handled in an appropriate manner.
                     30:  * If replstr is NULL, then that internally is changed to a nil-string, so
                     31:  * that we can still pretend to do somewhat meaningful substitution.
                     32:  * No value is returned.
                     33:  */
                     34: void
                     35: strnsubst(char **str, const char *match, const char *replstr, size_t maxsize)
                     36: {
                     37:        char *s1, *s2, *this;
1.4     ! cloder     38:        size_t matchlen, repllen, s2len;
        !            39:        int n;
1.1       millert    40:
                     41:        if ((s1 = *str) == NULL)
                     42:                return;
                     43:        if ((s2 = malloc(maxsize)) == NULL)
                     44:                err(1, NULL);
                     45:
                     46:        if (replstr == NULL)
                     47:                replstr = "";
                     48:
                     49:        if (match == NULL || *match == '\0' || strlen(s1) >= maxsize) {
                     50:                strlcpy(s2, s1, maxsize);
                     51:                goto done;
                     52:        }
                     53:
                     54:        *s2 = '\0';
                     55:        s2len = 0;
                     56:        matchlen = strlen(match);
                     57:        repllen = strlen(replstr);
                     58:        for (;;) {
                     59:                if ((this = strstr(s1, match)) == NULL)
                     60:                        break;
                     61:                n = snprintf(s2 + s2len, maxsize - s2len, "%.*s%s",
                     62:                    (int)(this - s1), s1, replstr);
1.2       millert    63:                if (n == -1 || n + s2len + strlen(this + matchlen) >= maxsize)
1.1       millert    64:                        break;                  /* out of room */
                     65:                s2len += n;
                     66:                s1 = this + matchlen;
                     67:        }
                     68:        strlcpy(s2 + s2len, s1, maxsize - s2len);
                     69: done:
                     70:        *str = s2;
                     71:        return;
                     72: }
                     73:
                     74: #ifdef TEST
                     75: #include <stdio.h>
                     76:
1.3       deraadt    77: int
1.1       millert    78: main(void)
                     79: {
                     80:        char *x, *y, *z, *za;
                     81:
                     82:        x = "{}%$";
                     83:        strnsubst(&x, "%$", "{} enpury!", 255);
                     84:        y = x;
                     85:        strnsubst(&y, "}{}", "ybir", 255);
                     86:        z = y;
                     87:        strnsubst(&z, "{", "v ", 255);
                     88:        za = z;
                     89:        strnsubst(&z, NULL, za, 255);
                     90:        if (strcmp(z, "v ybir enpury!") == 0)
                     91:                printf("strnsubst() seems to work!\n");
                     92:        else
                     93:                printf("strnsubst() is broken.\n");
                     94:        printf("%s\n", z);
                     95:        free(x);
                     96:        free(y);
                     97:        free(z);
                     98:        free(za);
                     99:        return 0;
                    100: }
                    101: #endif