[pacman-dev] [PATCH] rewrite strreplace

Dan McGee dpmcgee at gmail.com
Sun Sep 6 20:08:03 EDT 2009


On Sun, Sep 6, 2009 at 6:47 PM, Xavier Chantry<shiningxc at gmail.com> wrote:
> * 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 at gmail.com>
> ---
>  src/pacman/util.c |   75 +++++++++++++++++++++++++++++++----------------------
>  1 files changed, 44 insertions(+), 31 deletions(-)
>
> diff --git a/src/pacman/util.c b/src/pacman/util.c
> index 6af8229..d137460 100644
> --- a/src/pacman/util.c
> +++ b/src/pacman/util.c
> @@ -335,48 +335,61 @@ 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;
> -
> -       char *newstr = NULL;
> +       const char *p = NULL, *q = NULL;
> +       char *newstr = NULL, *newp = NULL;
> +       alpm_list_t *i = NULL, *list = NULL;
>        unsigned int needlesz = strlen(needle),
>                                                         replacesz = strlen(replace);
>
> -       while (1) {
> +       if(!str) {
> +               return(NULL);
> +       }
> +
> +       p = str;
> +       q = strstr(p, needle);
> +       while(q) {
> +               list = alpm_list_add(list, (char *)q);
> +               p = q + needlesz;
>                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(!list) {
> +               return(strdup(str));
> +       }
> +       newstr = malloc(strlen(str) + 1 +
> +                       alpm_list_count(list) * (replacesz - needlesz));
Maybe an explanation comment here? And there should be no way to trick
this up by having needlesize > replacesize, or the other way around
(replacesize > needlesize), since those are declared as unsigned?

> +       if(!newstr) {
> +               return(NULL);
> +       }
> +       *newstr = 0;
I'd prefer '\0' when setting a string pointer to a null character; I
think we try to do this in the rest of the code as well.

> +
> +       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 occurance and last occurance, if any */
Spelling, s/occurance/occurrence/

> +                       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;
Same as above.

>
> -       return newstr;
> +       return(newstr);
>  }
>
>  /** Splits a string into a list of strings using the chosen character as
> --
> 1.6.4.2


More information about the pacman-dev mailing list