mirror of
https://github.com/moparisthebest/pacman
synced 2024-10-31 15:45:03 -04:00
rewrite strreplace
* just do one malloc call * p = realloc(p, new_size) was not good (see http://www.iso-9899.info/wiki/Why_not_realloc) * use more efficient strncpy instead of strncat Signed-off-by: Xavier Chantry <shiningxc@gmail.com> Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
cb1d4195bf
commit
43e16b373b
@ -335,48 +335,65 @@ char *strtrim(char *str)
|
||||
return(str);
|
||||
}
|
||||
|
||||
/* Helper function for strreplace */
|
||||
static void _strnadd(char **str, const char *append, unsigned int count)
|
||||
{
|
||||
if(*str) {
|
||||
*str = realloc(*str, strlen(*str) + count + 1);
|
||||
} else {
|
||||
*str = calloc(sizeof(char), count + 1);
|
||||
}
|
||||
|
||||
strncat(*str, append, count);
|
||||
}
|
||||
|
||||
/* Replace all occurances of 'needle' with 'replace' in 'str', returning
|
||||
* a new string (must be free'd) */
|
||||
char *strreplace(const char *str, const char *needle, const char *replace)
|
||||
{
|
||||
const char *p, *q;
|
||||
p = q = str;
|
||||
const char *p = NULL, *q = NULL;
|
||||
char *newstr = NULL, *newp = NULL;
|
||||
alpm_list_t *i = NULL, *list = NULL;
|
||||
size_t needlesz = strlen(needle), replacesz = strlen(replace);
|
||||
size_t newsz;
|
||||
|
||||
char *newstr = NULL;
|
||||
unsigned int needlesz = strlen(needle),
|
||||
replacesz = strlen(replace);
|
||||
|
||||
while (1) {
|
||||
q = strstr(p, needle);
|
||||
if(!q) { /* not found */
|
||||
if(*p) {
|
||||
/* add the rest of 'p' */
|
||||
_strnadd(&newstr, p, strlen(p));
|
||||
}
|
||||
break;
|
||||
} else { /* found match */
|
||||
if(q > p){
|
||||
/* add chars between this occurance and last occurance, if any */
|
||||
_strnadd(&newstr, p, q - p);
|
||||
}
|
||||
_strnadd(&newstr, replace, replacesz);
|
||||
p = q + needlesz;
|
||||
}
|
||||
if(!str) {
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
return newstr;
|
||||
p = str;
|
||||
q = strstr(p, needle);
|
||||
while(q) {
|
||||
list = alpm_list_add(list, (char *)q);
|
||||
p = q + needlesz;
|
||||
q = strstr(p, needle);
|
||||
}
|
||||
|
||||
/* no occurences of needle found */
|
||||
if(!list) {
|
||||
return(strdup(str));
|
||||
}
|
||||
/* size of new string = size of old string + "number of occurences of needle"
|
||||
* x "size difference between replace and needle" */
|
||||
newsz = strlen(str) + 1 +
|
||||
alpm_list_count(list) * (replacesz - needlesz);
|
||||
newstr = malloc(newsz);
|
||||
if(!newstr) {
|
||||
return(NULL);
|
||||
}
|
||||
*newstr = '\0';
|
||||
|
||||
p = str;
|
||||
newp = newstr;
|
||||
for(i = list; i; i = alpm_list_next(i)) {
|
||||
q = alpm_list_getdata(i);
|
||||
if(q > p){
|
||||
/* add chars between this occurence and last occurence, if any */
|
||||
strncpy(newp, p, q - p);
|
||||
newp += q - p;
|
||||
}
|
||||
strncpy(newp, replace, replacesz);
|
||||
newp += replacesz;
|
||||
p = q + needlesz;
|
||||
}
|
||||
alpm_list_free(list);
|
||||
|
||||
if(*p) {
|
||||
/* add the rest of 'p' */
|
||||
strcpy(newp, p);
|
||||
newp += strlen(p);
|
||||
}
|
||||
*newp = '\0';
|
||||
|
||||
return(newstr);
|
||||
}
|
||||
|
||||
/** Splits a string into a list of strings using the chosen character as
|
||||
|
Loading…
Reference in New Issue
Block a user