diff --git a/src/callback.c b/src/callback.c index fb9b4ebf..03145ca6 100644 --- a/src/callback.c +++ b/src/callback.c @@ -635,7 +635,7 @@ static int waves_callback(int event, int mx, int my, KeySym key, int button, int char *saven, *nptr, *ntok, *node = NULL;; my_strdup2(1426, &node, get_tok_value(r->prop_ptr,"node",0)); nptr = node; - while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) { + while( (ntok = my_strtok_r(nptr, "\n\t ", "", &saven)) ) { nptr = NULL; j = get_raw_index(ntok); if(j >= 0) { diff --git a/src/draw.c b/src/draw.c index c6a80aa4..1e5db90b 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1659,8 +1659,8 @@ static SPICE_DATA **get_bus_idx_array(const char *ntok, int *n_bits) p = 0; my_strdup2(1402, &ntok_copy, ntok); ntok_ptr = ntok_copy; - my_strtok_r(ntok_ptr, ",", &ntok_savep); /*strip off bus name (1st field) */ - while( (bit_name = my_strtok_r(NULL, ",", &ntok_savep)) ) { + my_strtok_r(ntok_ptr, ",", "", &ntok_savep); /*strip off bus name (1st field) */ + while( (bit_name = my_strtok_r(NULL, ",", "", &ntok_savep)) ) { int idx; if( (idx = get_raw_index(bit_name)) != -1) { idx_arr[p] = xctx->graph_values[idx]; @@ -2279,9 +2279,9 @@ int edit_wave_attributes(int what, int i, Graph_ctx *gr) sptr = sweep; n_nodes = count_items(node, " \t\n"); /* process each node given in "node" attribute, get also associated color/sweep var if any */ - while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) { - ctok = my_strtok_r(cptr, " ", &savec); - stok = my_strtok_r(sptr, " ", &saves); + while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", &saven)) ) { + ctok = my_strtok_r(cptr, " ", "", &savec); + stok = my_strtok_r(sptr, " ", "", &saves); nptr = cptr = sptr = NULL; dbg(1, "ntok=%s ctok=%s\n", ntok, ctok? ctok: "NULL"); if(stok && stok[0]) { @@ -2347,7 +2347,7 @@ int edit_wave_attributes(int what, int i, Graph_ctx *gr) } } wcnt++; - } /* while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) */ + } /* while( (ntok = my_strtok_r(nptr, "\n\t ", "", &saven)) ) */ my_free(1494, &node); my_free(1495, &color); my_free(1496, &sweep); @@ -2399,14 +2399,14 @@ void draw_graph(int i, const int flags, Graph_ctx *gr) sptr = sweep; n_nodes = count_items(node, " \t\n"); /* process each node given in "node" attribute, get also associated color/sweep var if any*/ - while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) { + while( (ntok = my_strtok_r(nptr, "\n\t ", "\"", &saven)) ) { if(strstr(ntok, ",")) { my_strdup2(1452, &bus_msb, find_nth(ntok, ',', 2)); } - ctok = my_strtok_r(cptr, " ", &savec); - stok = my_strtok_r(sptr, " ", &saves); + ctok = my_strtok_r(cptr, " ", "", &savec); + stok = my_strtok_r(sptr, " ", "", &saves); nptr = cptr = sptr = NULL; - dbg(1, "ntok=%s ctok=%s\n", ntok, ctok? ctok: "NULL"); + dbg(0, "ntok=%s ctok=%s\n", ntok, ctok? ctok: "NULL"); if(ctok && ctok[0]) wave_color = atoi(ctok); if(wave_color < 0) wave_color = 4; if(wave_color >= cadlayers) wave_color = cadlayers - 1; @@ -2526,7 +2526,7 @@ void draw_graph(int i, const int flags, Graph_ctx *gr) } /* if( (idx = get_raw_index(bus_msb ? bus_msb : ntok)) != -1 ) */ wcnt++; if(bus_msb) my_free(1453, &bus_msb); - } /* while( (ntok = my_strtok_r(nptr, "\n\t ", &saven)) ) */ + } /* while( (ntok = my_strtok_r(nptr, "\n\t ", "", &saven)) ) */ my_free(1391, &node); my_free(1392, &color); my_free(1408, &sweep); diff --git a/src/editprop.c b/src/editprop.c index 43968e83..8730b446 100644 --- a/src/editprop.c +++ b/src/editprop.c @@ -47,7 +47,49 @@ int my_strncasecmp(const char *s1, const char *s2, size_t n) return tolower(*s1) - tolower(*s2); } -char *my_strtok_r(char *str, const char *delim, char **saveptr) +/* split a string into tokens like standard strtok_r, + * if quote string is not empty any character matching quote is considered a quoting + * character, removed from input and all characters before next quote are considered + * as part of the token. backslash can be used to enter literal quoting characters and + * literal backslashes. + * if quote is empty no backslash is removed from input and behavior is identical + * to strtok_r + */ +char *my_strtok_r(char *str, const char *delim, const char *quote, char **saveptr) +{ + char *tok; + int q = 0; /* quote */ + int e = 0; /* escape */ + int ne = 0; /* number of escapes / quoting chars to remove */ + if(str) { /* 1st call */ + *saveptr = str; + } + while(**saveptr && strchr(delim, **saveptr) ) { /* skip separators */ + ++(*saveptr); + } + tok = *saveptr; /* start of token */ + while(**saveptr && (e || q || !strchr(delim, **saveptr)) ) { /* look for sep. marking end of current token */ + if(ne) *(*saveptr - ne) = **saveptr; /* shift back eating escapes / quotes */ + if(!e && strchr(quote, **saveptr)) { + q = !q; + ne++; + } + if(quote[0] && !e && **saveptr == '\\') { /* if quote is empty string do not skip backslashes either */ + e = 1; + ne++; + } else e = 0; + ++(*saveptr); + } + if(**saveptr) { + **saveptr = '\0'; /* mark end of token */ + if(ne) *(*saveptr - ne) = **saveptr; /* shift back eating escapes / quotes */ + ++(*saveptr); /* if not at end of string advance one char for next iteration */ + } else if(ne) *(*saveptr - ne ) = **saveptr; /* shift back eating escapes / quotes */ + if(tok[0]) return tok; /* return token */ + else return NULL; /* no more tokens */ +} + +char *xmy_strtok_r(char *str, const char *delim, char **saveptr) { char *tok; if(str) { /* 1st call */ diff --git a/src/token.c b/src/token.c index 9496a6f3..181fe099 100644 --- a/src/token.c +++ b/src/token.c @@ -1943,8 +1943,8 @@ void print_tedax_element(FILE *fd, int inst) /* fprintf(errfp, "extra_pinnumber: |%s|\n", extra_pinnumber); */ /* fprintf(errfp, "extra: |%s|\n", extra); */ for(extra_ptr = extra, extra_pinnumber_ptr = extra_pinnumber; ; extra_ptr=NULL, extra_pinnumber_ptr=NULL) { - extra_pinnumber_token=my_strtok_r(extra_pinnumber_ptr, " ", &saveptr1); - extra_token=my_strtok_r(extra_ptr, " ", &saveptr2); + extra_pinnumber_token=my_strtok_r(extra_pinnumber_ptr, " ", "", &saveptr1); + extra_token=my_strtok_r(extra_ptr, " ", "", &saveptr2); if(!extra_token) break; /* fprintf(errfp, "extra_pinnumber_token: |%s|\n", extra_pinnumber_token); */ /* fprintf(errfp, "extra_token: |%s|\n", extra_token); */ diff --git a/src/xschem.h b/src/xschem.h index 1ac98e66..b17391bf 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1310,7 +1310,7 @@ extern int my_snprintf(char *str, int size, const char *fmt, ...); extern size_t my_strdup(int id, char **dest, const char *src); extern void my_strndup(int id, char **dest, const char *src, int n); extern size_t my_strdup2(int id, char **dest, const char *src); -extern char *my_strtok_r(char *str, const char *delim, char **saveptr); +extern char *my_strtok_r(char *str, const char *delim, const char *quote, char **saveptr); extern int my_strncpy(char *d, const char *s, int n); extern int my_strcasecmp(const char *s1, const char *s2); extern int my_strncasecmp(const char *s1, const char *s2, size_t n); diff --git a/src/xschem.tcl b/src/xschem.tcl index 59a17553..84127b24 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -659,7 +659,11 @@ proc sim_is_xyce {} { proc tolist {s} { set s [string trim $s] regsub -all {[\t\n ]+} $s { } s - return [split $s] + if { [string is list $s] } { + return $s + } else { + return [split $s] + } } proc set_sim_defaults {{reset {}}} { @@ -1501,7 +1505,7 @@ proc graph_update_nodelist {} { # tagging nodes in text widget: set col [xschem getprop rect 2 $graph_selected color] set col [string trim $col " \n"] - set tt [.graphdialog.center.right.text1 search -all -nolinestop -regexp -count cc {[^ \n]+} 1.0] + set tt [.graphdialog.center.right.text1 search -all -nolinestop -regexp -count cc {"[^"]+"|[^ \n]+} 1.0] ;#"4vim set n 0 if { [info exists cc] && ($tt ne {}) } { foreach t $tt c $cc { @@ -1538,7 +1542,7 @@ proc fill_graph_listbox {} { proc update_graph_node {node} { global graph_selected graph_update_nodelist - regsub -all {(["\\])} $node {\\\1} node_quoted ;#" editor is confused by the previous quote + regsub -all {(["\\])} $node {\\\1} node_quoted ;#"4vim xschem setprop rect 2 $graph_selected node $node_quoted fast xschem draw_graph $graph_selected }