strnsubst.c revision 95898
195080Sjmallett/* $xMach: strnsubst.c,v 1.3 2002/02/23 02:10:24 jmallett Exp $ */ 295080Sjmallett 395080Sjmallett/* 495080Sjmallett * Copyright (c) 2002 J. Mallett. All rights reserved. 595080Sjmallett * You may do whatever you want with this file as long as 695080Sjmallett * the above copyright and this notice remain intact, along 795080Sjmallett * with the following statement: 895080Sjmallett * For the man who taught me vi, and who got too old, too young. 995080Sjmallett */ 1095080Sjmallett 1195080Sjmallett#include <sys/cdefs.h> 1295080Sjmallett__FBSDID("$FreeBSD: head/usr.bin/xargs/strnsubst.c 95898 2002-05-02 02:06:03Z jmallett $"); 1395080Sjmallett 1495080Sjmallett#include <err.h> 1595080Sjmallett#include <stdlib.h> 1695080Sjmallett#include <string.h> 1795080Sjmallett#include <unistd.h> 1895080Sjmallett 1995080Sjmallettvoid strnsubst(char **, const char *, const char *, size_t); 2095080Sjmallett 2195080Sjmallett/* 2295080Sjmallett * Replaces str with a string consisting of str with match replaced with 2395080Sjmallett * replstr as many times as can be done before the constructed string is 2495080Sjmallett * maxsize bytes large. It does not free the string pointed to by str, it 2595080Sjmallett * is up to the calling program to be sure that the original contents of 2695080Sjmallett * str as well as the new contents are handled in an appropriate manner. 2795080Sjmallett * No value is returned. 2895080Sjmallett */ 2995080Sjmallettvoid 3095080Sjmallettstrnsubst(char **str, const char *match, const char *replstr, size_t maxsize) 3195080Sjmallett{ 3295080Sjmallett char *s1, *s2; 3395080Sjmallett 3495080Sjmallett s1 = *str; 3595080Sjmallett if (s1 == NULL) 3695080Sjmallett return; 3795080Sjmallett s2 = calloc(maxsize, 1); 3895080Sjmallett if (s2 == NULL) 3995080Sjmallett err(1, "calloc"); 4095080Sjmallett 4195898Sjmallett if (match == NULL || replstr == NULL || maxsize == strlen(*str)) { 4295898Sjmallett strlcpy(s2, s1, maxsize); 4395898Sjmallett goto done; 4495898Sjmallett } 4595898Sjmallett 4695080Sjmallett for (;;) { 4795080Sjmallett char *this; 4895080Sjmallett 4995080Sjmallett this = strstr(s1, match); 5095080Sjmallett if (this == NULL) 5195080Sjmallett break; 5295080Sjmallett if ((strlen(s2) + ((uintptr_t)this - (uintptr_t)s1) + 5395080Sjmallett (strlen(replstr) - 1)) > maxsize) { 5495080Sjmallett strlcat(s2, s1, maxsize); 5595080Sjmallett goto done; 5695080Sjmallett } 5795080Sjmallett strncat(s2, s1, (uintptr_t)this - (uintptr_t)s1); 5895080Sjmallett strcat(s2, replstr); 5995080Sjmallett s1 = this + strlen(match); 6095080Sjmallett } 6195080Sjmallett strcat(s2, s1); 6295080Sjmallettdone: 6395080Sjmallett *str = s2; 6495080Sjmallett return; 6595080Sjmallett} 6695080Sjmallett 6795080Sjmallett#ifdef TEST 6895080Sjmallett#include <stdio.h> 6995080Sjmallett 7095080Sjmallettint 7195080Sjmallettmain(void) 7295080Sjmallett{ 7395080Sjmallett char *x, *y; 7495080Sjmallett 7595080Sjmallett y = x = "{}{}{}"; 7695080Sjmallett strnsubst(&x, "{}", "v ybir whyv! ", 12); 7795080Sjmallett if (strcmp(x, "v ybir whyv! ") == 0) 7895080Sjmallett printf("strnsubst() seems to work as expected.\n"); 7995080Sjmallett printf("x: %s\ny: %s\n", x, y); 8095080Sjmallett free(x); 8195080Sjmallett return 0; 8295080Sjmallett} 8395080Sjmallett#endif 84