Split from git://repo.or.cz/quvi.git
[quvi-tool.git] / src / quvi / strepl.c
blob5d63538da94fd4db741d04ba6ec2c87d59c096fc
1 /*
2 * Copyright (C) 2009 Toni Gundogdu.
3 * Copyright (C) Laird Shaw.
5 * Public domain.
7 * http://creativeandcritical.net/sites/default/files/replacebench.c
8 */
11 * Changes to the original code:
12 * - This revision _releases_ the source string
13 * - Rename "replace_opt" -> "strepl"
14 * - Minor style changes
17 #include "config.h"
19 #include <stdlib.h>
20 #include <stddef.h>
21 #include <string.h>
23 char *strepl(const char *str, const char *old, const char *new)
25 size_t oldlen, count, retlen, newlen;
26 const char *p, *q;
27 char *ret, *r;
29 oldlen = strlen(old);
30 newlen = strlen(new);
32 if (oldlen != newlen)
34 for (count = 0, p = str; (q = strstr(p, old)) != 0; p = q + oldlen)
35 count++;
36 retlen = p - str + strlen(p) + count * (newlen - oldlen);
38 else
39 retlen = strlen(str);
41 if ((ret = malloc(retlen + 1)) == 0)
42 return 0;
44 for (r = ret, p = str; (q = strstr(p, old)) != 0; p = q + oldlen)
46 #ifdef HAVE_PTRDIFF_T
47 ptrdiff_t l = q - p;
48 #else
49 long l = q - p;
50 #endif
51 memcpy(r, p, l);
52 r += l;
53 memcpy(r, new, newlen);
54 r += newlen;
56 strcpy(r, p);
58 /* See the notes above. */
59 free((void *)str);
61 return (ret);
64 /* vim: set ts=2 sw=2 tw=72 expandtab: */