From b697ec448d2ea839eb93c73efeae18b6064d5e32 Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Sun, 13 Feb 2022 12:12:37 +0100 Subject: [PATCH] fix find_nth if multiple / leading separators are present --- src/scheduler.c | 9 ++++++++- src/token.c | 19 ++++++++++++------- src/xschem.h | 2 +- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/scheduler.c b/src/scheduler.c index 15a4a54f..ee1279ab 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -741,7 +741,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } else if(argv[1][0] == 'f') { - if(!strcmp(argv[1],"flip")) + if(!strcmp(argv[1],"find_nth")) + { + cmd_found = 1; + if(argc > 4) { + Tcl_SetResult(interp, find_nth(argv[2], argv[3], atoi(argv[4])), TCL_VOLATILE); + } + } + else if(!strcmp(argv[1],"flip")) { cmd_found = 1; if(! (xctx->ui_state & (STARTMOVE | STARTCOPY) ) ) { diff --git a/src/token.c b/src/token.c index 1ff0e3a1..a19b051e 100644 --- a/src/token.c +++ b/src/token.c @@ -2698,11 +2698,10 @@ int isonlydigit(const char *s) /* find nth occurrence of substring in str separated by sep. 1st substring is position 1 * find_nth("aaa,bbb,ccc,ddd", ',', 2) --> "bbb" */ -const char *find_nth(const char *str, char *sep, int n) +char *find_nth(const char *str, const char *sep, int n) { static char *result=NULL; /* safe to keep even with multiple schematic windows */ static int result_size = 0; /* safe to keep even with multiple schematic windows */ - static const char *empty=""; int i, len; char *ptr; int count; @@ -2710,7 +2709,7 @@ const char *find_nth(const char *str, char *sep, int n) if(!str) { my_free(1062, &result); result_size = 0; - return empty; + return NULL; } len = strlen(str) + 1; if(len > result_size) { @@ -2718,19 +2717,25 @@ const char *find_nth(const char *str, char *sep, int n) my_realloc(138, &result, result_size); } memcpy(result, str, len); - for(i=0, count=1, ptr=result; result[i] != 0; i++) { + i = 0; + while(result[i] && strchr(sep, result[i])) i++; /* strip off leading separators */ + ptr = result + i; + for(count=1; result[i] != 0; i++) { if(strchr(sep, result[i])) { result[i]=0; if(count==n) { return ptr; } - while(strchr(sep, result[++i])) ; - ptr=result+i; + while(result[++i] && strchr(sep, result[i])) ; + ptr = result + i; count++; } } if(count==n) return ptr; - else return empty; + else { + result[0] = '\0'; + return result; + } } /* substitute given tokens in a string with their corresponding values */ diff --git a/src/xschem.h b/src/xschem.h index 20eab625..f1f50c07 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1292,7 +1292,7 @@ extern void int_hash_free(Int_hashentry **table); extern Int_hashentry *int_hash_lookup(Int_hashentry **table, const char *token, const int value, int what); -extern const char *find_nth(const char *str, char *sep, int n); +extern char *find_nth(const char *str, const char *sep, int n); extern int isonlydigit(const char *s); extern const char *translate(int inst, const char* s); extern const char* translate2(Lcc *lcc, int level, char* s);