diff options
-rw-r--r-- | Modules/stropmodule.c | 21 | ||||
-rw-r--r-- | Objects/stringobject.c | 73 |
2 files changed, 54 insertions, 40 deletions
diff --git a/Modules/stropmodule.c b/Modules/stropmodule.c index b92cb01..253c4ec 100644 --- a/Modules/stropmodule.c +++ b/Modules/stropmodule.c @@ -982,7 +982,7 @@ strop_translate(PyObject *self, PyObject *args) MEM, the function returns -1. */ static int -mymemfind(char *mem, int len, char *pat, int pat_len) +mymemfind(const char *mem, int len, const char *pat, int pat_len) { register int ii; @@ -1007,7 +1007,7 @@ mymemfind(char *mem, int len, char *pat, int pat_len) mem=11111 and pat==11 also return 2. */ static int -mymemcnt(char *mem, int len, char *pat, int pat_len) +mymemcnt(const char *mem, int len, const char *pat, int pat_len) { register int offset = 0; int nfound = 0; @@ -1043,10 +1043,11 @@ mymemcnt(char *mem, int len, char *pat, int pat_len) NULL if an error occurred. */ static char * -mymemreplace(char *str, int len, - char *pat, int pat_len, - char *sub, int sub_len, - int count, int *out_len) +mymemreplace(const char *str, int len, /* input string */ + const char *pat, int pat_len, /* pattern string to find */ + const char *sub, int sub_len, /* substitution string */ + int count, /* number of replacements */ + int *out_len) { char *out_s; char *new_s; @@ -1064,7 +1065,11 @@ mymemreplace(char *str, int len, new_len = len + nfound*(sub_len - pat_len); if (new_len == 0) { - out_s = ""; + /* Have to allocate something for the caller to free(). */ + out_s = (char *)PyMem_MALLOC(1); + if (out_s = NULL) + return NULL; + out_s[0] = '\0'; } else { assert(new_len > 0); @@ -1102,7 +1107,7 @@ mymemreplace(char *str, int len, return_same: *out_len = -1; - return str; + return (char *)str; /* cast away const */ } diff --git a/Objects/stringobject.c b/Objects/stringobject.c index 4c68972..ec909db 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -1546,7 +1546,7 @@ mymemreplace(const char *str, int len, /* input string */ const char *pat, int pat_len, /* pattern string to find */ const char *sub, int sub_len, /* substitution string */ int count, /* number of replacements */ - int *out_len) + int *out_len) { char *out_s; char *new_s; @@ -1557,47 +1557,56 @@ mymemreplace(const char *str, int len, /* input string */ /* find length of output string */ nfound = mymemcnt(str, len, pat, pat_len); - if (count < 0) - count = INT_MAX; - else if (nfound > count) - nfound = count; + if (count > 0) + nfound = nfound > count ? count : nfound; if (nfound == 0) goto return_same; + new_len = len + nfound*(sub_len - pat_len); + if (new_len == 0) { + /* Have to allocate something for the caller to free(). */ + out_s = (char *)PyMem_MALLOC(1); + if (out_s = NULL) + return NULL; + out_s[0] = '\0'; + } + else { + assert(new_len > 0); + new_s = (char *)PyMem_MALLOC(new_len); + if (new_s == NULL) + return NULL; + out_s = new_s; - new_s = (char *)PyMem_MALLOC(new_len); - if (new_s == NULL) return NULL; + while (len > 0) { + /* find index of next instance of pattern */ + offset = mymemfind(str, len, pat, pat_len); + if (offset == -1) + break; + /* copy non matching part of input string */ + memcpy(new_s, str, offset); + str += offset + pat_len; + len -= offset + pat_len; + + /* copy substitute into the output string */ + new_s += offset; + memcpy(new_s, sub, sub_len); + new_s += sub_len; + + /* note count==0 is effectively infinity */ + if (--count == 0) + break; + } + /* copy any remaining values into output string */ + if (len > 0) + memcpy(new_s, str, len); + } *out_len = new_len; - out_s = new_s; - - while (len > 0) { - /* find index of next instance of pattern */ - offset = mymemfind(str, len, pat, pat_len); - /* if not found, break out of loop */ - if (offset == -1) break; - - /* copy non matching part of input string */ - memcpy(new_s, str, offset); /* copy part of str before pat */ - str += offset + pat_len; /* move str past pattern */ - len -= offset + pat_len; /* reduce length of str remaining */ - - /* copy substitute into the output string */ - new_s += offset; /* move new_s to dest for sub string */ - memcpy(new_s, sub, sub_len); /* copy substring into new_s */ - new_s += sub_len; /* offset new_s past sub string */ - - /* break when we've done count replacements */ - if (--count == 0) break; - } - /* copy any remaining values into output string */ - if (len > 0) - memcpy(new_s, str, len); return out_s; return_same: *out_len = -1; - return (char*)str; /* have to cast away constness here */ + return (char *)str; /* cast away const */ } |