From c1d229b917e2403fb8dfbc4869f83aade4b5676e Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Thu, 18 Aug 2022 10:21:14 +0200 Subject: [PATCH] better str_replace() implementation --- src/editprop.c | 73 +++++++++++++++++++++----------------------------- src/token.c | 1 - src/xinit.c | 1 + src/xschem.h | 2 +- 4 files changed, 32 insertions(+), 45 deletions(-) diff --git a/src/editprop.c b/src/editprop.c index 6cfaa380..755d29f0 100644 --- a/src/editprop.c +++ b/src/editprop.c @@ -1263,52 +1263,39 @@ void change_elem_order(void) } } -/* You must free the result if result is non-NULL. */ -char *str_replace(char *orig, char *rep, char *with) +char *str_replace(const char *s, const char *rep, const char *with) { - char *result; /* the return string */ - char *ins; /* the next insert point */ - char *tmp; /* varies */ - size_t len_rep; /* length of rep (the string to remove) */ - size_t len_with; /* length of with (the string to replace rep with) */ - size_t len_front; /* distance between rep and end of last rep */ - int count; /* number of replacements */ + static char *result = NULL; + static size_t size=0; + size_t result_pos = 0; + size_t rep_len; + size_t with_len; - /* sanity checks and initialization */ - if (!orig || !rep) - return NULL; - len_rep = strlen(rep); - if (len_rep == 0) - return NULL; /* empty rep causes infinite loop during count */ - if (!with) - with = ""; - len_with = strlen(with); - - /* count the number of replacements needed */ - ins = orig; - for (count = 0; (tmp = strstr(ins, rep)); ++count) { - ins = tmp + len_rep; + if(s==NULL || rep == NULL || with == NULL || rep[0] == '\0') { + my_free(1244, &result); + size = 0; + return NULL; + } + rep_len = strlen(rep); + with_len = strlen(with); + dbg(1, "str_replace(): %s, %s, %s\n", s, rep, with); + if( size == 0 ) { + size = CADCHUNKALLOC; + my_realloc(1245, &result, size); + } + while(*s) { + STR_ALLOC(&result, result_pos + with_len + 1, &size); + if(!strncmp(s, rep, rep_len)) { + my_strncpy(result + result_pos, with, with_len + 1); + result_pos += with_len; + s += rep_len; + } else { + result[result_pos++] = *s++; } - - tmp = result = my_malloc(1244, strlen(orig) + (len_with - len_rep) * count + 1); - - if (!result) - return NULL; - - /* first time through the loop, all the variable are set correctly */ - /* from here on, */ - /* tmp points to the end of the result string */ - /* ins points to the next occurrence of rep in orig */ - /* orig points to the remainder of orig after "end of rep" */ - while (count--) { - ins = strstr(orig, rep); - len_front = ins - orig; - tmp = strncpy(tmp, orig, len_front) + len_front; - tmp = strcpy(tmp, with) + len_with; - orig += len_front + len_rep; /* move to next "end of rep" */ - } - strcpy(tmp, orig); - return result; + } + result[result_pos] = '\0'; + dbg(1, "str_replace(): returning %s\n", result); + return result; } /* x=0 use tcl text widget x=1 use vim editor x=2 only view data */ diff --git a/src/token.c b/src/token.c index db4cb8e8..6dd35a04 100644 --- a/src/token.c +++ b/src/token.c @@ -133,7 +133,6 @@ const char *tcl_hook2(char **res) unescaped_res = str_replace(*res, "\\}", "}"); tclvareval("tclpropeval2 {", unescaped_res, "}" , NULL); my_strdup2(1286, &result, tclresult()); - my_free(1245, &unescaped_res); return result; } else { return *res; diff --git a/src/xinit.c b/src/xinit.c index f7bc7fd1..cdcdfb9a 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -648,6 +648,7 @@ static void delete_schematic_data(void) /* delete instances, wires, lines, rects, arcs, polys, texts, hash_inst, hash_wire, * inst & wire .node fields, instance name hash */ remove_symbols(); + str_replace(NULL, NULL, NULL); free_rawfile(0); free_xschem_data(); /* delete the xctx struct */ } diff --git a/src/xschem.h b/src/xschem.h index cfccaf94..f16ab503 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1374,7 +1374,7 @@ extern void hilight_parent_pins(void); extern void hilight_net_pin_mismatches(void); extern Node_hashentry **get_node_table_ptr(void); extern void change_elem_order(void); -extern char *str_replace(char *orig, char *rep, char *with); +extern char *str_replace(const char *s, const char *rep, const char *with); extern int set_different_token(char **s,const char *new, const char *old, int object, int n); extern void print_hilight_net(int show); extern void list_hilights(void);