From c5440c2b0fcd7f9e7960b7bad845ee83a2996565 Mon Sep 17 00:00:00 2001 From: schippes Date: Mon, 17 Aug 2020 01:08:13 +0200 Subject: [PATCH] make get_tok_value() and subst_tok() work well also with strings containing tokens with no value. --- src/scheduler.c | 20 +++++++++++++++++--- src/token.c | 29 +++++++++++++++++++---------- src/xschem.tcl | 8 ++++---- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/scheduler.c b/src/scheduler.c index 456d8a51..09e88fec 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1145,12 +1145,26 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } } - else if(!strcmp(argv[1],"gettok") ) + else if(!strcmp(argv[1],"subst_tok") ) + { + char *s=NULL; + my_strdup(894, &s, subst_token(argv[2], argv[3], strcmp(argv[4], "NULL") ? argv[4] : NULL)); + Tcl_SetResult(interp, s, TCL_VOLATILE); + my_free(1150, &s); + } + + else if(!strcmp(argv[1],"get_tok_size") ) + { + char s[30]; + my_snprintf(s, S(s), "%d", (int)get_tok_size); + Tcl_SetResult(interp, s, TCL_VOLATILE); + } + + else if(!strcmp(argv[1],"get_tok") ) { char *s=NULL; - Tcl_ResetResult(interp); my_strdup(648, &s, get_tok_value(argv[2], argv[3], 0)); - Tcl_AppendResult(interp, s, NULL); + Tcl_SetResult(interp, s, TCL_VOLATILE); my_free(649, &s); } else if(!strcmp(argv[1],"load_symbol") ) diff --git a/src/token.c b/src/token.c index f6a4f147..585c2d61 100644 --- a/src/token.c +++ b/src/token.c @@ -283,10 +283,6 @@ int set_different_token(char **s,char *new, char *old, int object, int n) my_new = new; dbg(1, "set_different_token(): *s=%s, new=%s, old=%s n=%d\n",*s, new, old, n); if(new==NULL) return 0; - sizetok=CADCHUNKALLOC; - token=my_malloc(427, sizetok); - sizeval=CADCHUNKALLOC; - value=my_malloc(429, sizeval); /* parse new string and add / change attributes that are missing / different from old */ while(1) { c=*my_new++; @@ -478,7 +474,7 @@ const char *get_tok_value(const char *s,const char *tok, int with_quotes) register int token_pos=0, value_pos=0; int quote=0; int escape=0; - int tok_size = 0; + int cmp = 1; if(s==NULL) { my_free(976, &result); @@ -508,6 +504,11 @@ const char *get_tok_value(const char *s,const char *tok, int with_quotes) if(!escape) quote=!quote; } if(state==XTOKEN) { + if(!cmp) { /* previous token matched search and was without value, return get_tok_size */ + result[0] = '\0'; + get_tok_value_size = 0; + return result; + } if(c=='"') { if((with_quotes & 1) || escape) token[token_pos++]=c; } @@ -521,15 +522,16 @@ const char *get_tok_value(const char *s,const char *tok, int with_quotes) else if( (c == '\\') && escape ) result[value_pos++]=c; /* 20170414 add escaped backslashes */ } else if(state==XENDTOK || state==XSEPARATOR) { if(token_pos) { - tok_size = token_pos; token[token_pos]='\0'; + if( !(cmp = strcmp(token,tok)) ) { + get_tok_size = token_pos; /* report back also token size, useful to check if requested token exists */ + } dbg(2, "get_tok_value(): token=%s\n", token); token_pos=0; } } else if(state==XEND) { result[value_pos]='\0'; - if( !strcmp(token,tok) ) { - get_tok_size = tok_size; /* report back also token size, useful to check if requested token exists */ + if( !cmp ) { get_tok_value_size = value_pos; /* return also size so to avoid using strlen 20180926 */ return result; } @@ -769,6 +771,7 @@ char *subst_token(const char *s, const char *tok, const char *new_val) int token_pos=0, result_pos=0, result_save_pos = 0; int quote=0; int done_subst=0; + int done_delete = 0; int escape=0; int cmptok = 1; @@ -776,7 +779,7 @@ char *subst_token(const char *s, const char *tok, const char *new_val) my_free(989, &result); return ""; } - dbg(1, "subst_token(%s, %s, %s)\n", s, tok, new_val); + dbg(0, "subst_token(%s, %s, %s)\n", s, tok, new_val); sizetok=CADCHUNKALLOC; token=my_malloc(451, sizetok); size=CADCHUNKALLOC; @@ -808,7 +811,8 @@ char *subst_token(const char *s, const char *tok, const char *new_val) result[result_pos++] = c; } else if(state==XSEPARATOR) { token[token_pos] = '\0'; - if(!(cmptok = strcmp(token,tok)) && !new_val) { + if(!(cmptok = strcmp(token,tok)) && !new_val && !done_delete) { + done_delete = 1; result_pos = result_save_pos; dbg(3, "subst_token(): result_pos=%d\n", result_pos); } else { @@ -843,6 +847,11 @@ char *subst_token(const char *s, const char *tok, const char *new_val) else result[result_pos++]=c; } else if(state==XENDTOK) { token[token_pos]='\0'; + if(!(strcmp(token,tok)) && !new_val && !done_delete) { + done_delete = 1; + result_pos = result_save_pos; + dbg(3, "subst_token(): result_pos=%d\n", result_pos); + } result[result_pos++] = c; } else if(state == XEND) { if(c=='\0' || !(result_save_pos == 0 && !cmptok && !new_val) ) result[result_pos++] = c; diff --git a/src/xschem.tcl b/src/xschem.tcl index d1725430..18f40499 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -2108,7 +2108,7 @@ proc edit_prop {txtlabel} { if {$selected_tok eq {} } { set retval $retval_orig } else { - set retval [xschem gettok $retval_orig $selected_tok] + set retval [xschem get_tok $retval_orig $selected_tok] regsub -all {\\?"} $retval {"} retval } .dialog.e1 delete 1.0 end @@ -2120,7 +2120,7 @@ proc edit_prop {txtlabel} { if {$selected_tok eq {} } { set retval $retval_orig } else { - set retval [xschem gettok $retval_orig $selected_tok] + set retval [xschem get_tok $retval_orig $selected_tok] regsub -all {\\?"} $retval {"} retval } .dialog.e1 delete 1.0 end @@ -2259,7 +2259,7 @@ proc text_line {txtlabel clear {preserve_disabled disabled} } { if {$selected_tok eq {} } { set retval $retval_orig } else { - set retval [xschem gettok $retval_orig $selected_tok] + set retval [xschem get_tok $retval_orig $selected_tok] regsub -all {\\?"} $retval {"} retval } .dialog.e1 delete 1.0 end @@ -2273,7 +2273,7 @@ proc text_line {txtlabel clear {preserve_disabled disabled} } { if {$selected_tok eq {} } { set retval $retval_orig } else { - set retval [xschem gettok $retval_orig $selected_tok] + set retval [xschem get_tok $retval_orig $selected_tok] regsub -all {\\?"} $retval {"} retval } .dialog.e1 delete 1.0 end