diff --git a/doc/xschem_man/developer_info.html b/doc/xschem_man/developer_info.html
index dfbd5315..6c1c3c4c 100644
--- a/doc/xschem_man/developer_info.html
+++ b/doc/xschem_man/developer_info.html
@@ -1464,12 +1464,14 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
1 : select matching instances
-1 : unselect matching instances
'tok' set as:
+ <attr> : will search for 'val' in instance attribute 'attr'
propstring : will search for 'val' in the entire
*instance* attribute string.
+ txt_ptr : this is used to search only the txt_ptr string of text pbjects
cell::propstring : will search for 'val' in the entire
*symbol* attribute string.
cell::name : will search for 'val' in the symbol name
- cell::<attr> will search for 'val' in symbol attribute 'attr'
+ cell::<attr> : will search for 'val' in symbol attribute 'attr'
example: xschem search regex 0 cell::template GAIN=100
if 'no_match_case' is specified do not consider case sensitivity in search
if 'nodraw' is specified do not draw search result
diff --git a/src/hilight.c b/src/hilight.c
index 5eb5d7ff..966675c6 100644
--- a/src/hilight.c
+++ b/src/hilight.c
@@ -790,7 +790,13 @@ int search(const char *tok, const char *val, int sub, int sel, int match_case, i
#else
char *regexp_options = NULL;
#endif
+ int only_text_search = 0;
+ if(!tok) {
+ fprintf(errfp, "search(): warning: null tok key\n");
+ return TCL_ERROR;
+ }
+ if(!strcmp(tok, "txt_ptr")) only_text_search = 1;
if(!val) {
fprintf(errfp, "search(): warning: null val key\n");
return TCL_ERROR;
@@ -819,217 +825,223 @@ int search(const char *tok, const char *val, int sub, int sel, int match_case, i
}
has_token = 0;
prepare_netlist_structs(0);
- bus=bus_search(val); /* searching for a single bit in a bus, like val -> "DATA[13]" */
- for(i=0;iinstances; ++i) {
- if(!strcmp(tok,"cell::name")) {
- has_token = (xctx->inst[i].name != NULL) && xctx->inst[i].name[0];
- str = xctx->inst[i].name;
- } else if(!strcmp(tok,"cell::propstring")) {
- has_token = (str = (xctx->inst[i].ptr+ xctx->sym)->prop_ptr) ? 1 : 0;
- } else if(!strncmp(tok,"cell::", 6)) { /* cell::xxx looks for xxx in global symbol attributes */
- my_strdup(_ALLOC_ID_, &tmpname,get_tok_value(xctx->sym[xctx->inst[i].ptr].prop_ptr,tok+6,0));
- has_token = xctx->tok_size;
- if(tmpname) {
- str = tmpname;
+
+ if(!only_text_search) {
+ bus=bus_search(val); /* searching for a single bit in a bus, like val -> "DATA[13]" */
+ for(i=0;iinstances; ++i) {
+ if(!strcmp(tok,"cell::name")) {
+ has_token = (xctx->inst[i].name != NULL) && xctx->inst[i].name[0];
+ str = xctx->inst[i].name;
+ } else if(!strcmp(tok,"cell::propstring")) {
+ has_token = (str = (xctx->inst[i].ptr+ xctx->sym)->prop_ptr) ? 1 : 0;
+ } else if(!strncmp(tok,"cell::", 6)) { /* cell::xxx looks for xxx in global symbol attributes */
+ my_strdup(_ALLOC_ID_, &tmpname,get_tok_value(xctx->sym[xctx->inst[i].ptr].prop_ptr,tok+6,0));
+ has_token = xctx->tok_size;
+ if(tmpname) {
+ str = tmpname;
+ } else {
+ str = empty_string;
+ }
+ } else if(!strcmp(tok,"propstring")) {
+ has_token = (xctx->inst[i].prop_ptr != NULL) && xctx->inst[i].prop_ptr[0];
+ str = xctx->inst[i].prop_ptr;
} else {
- str = empty_string;
+ str = get_tok_value(xctx->inst[i].prop_ptr, tok,0);
+ has_token = xctx->tok_size;
}
- } else if(!strcmp(tok,"propstring")) {
- has_token = (xctx->inst[i].prop_ptr != NULL) && xctx->inst[i].prop_ptr[0];
- str = xctx->inst[i].prop_ptr;
- } else {
- str = get_tok_value(xctx->inst[i].prop_ptr, tok,0);
- has_token = xctx->tok_size;
- }
- dbg(1, "search(): inst=%d, tok=%s, val=%s \n", i,tok, str);
-
- if(bus && sub) {
- dbg(1, "search(): doing substr search on bus sig:%s inst=%d tok=%s val=%s\n", str,i,tok,val);
- str=expandlabel(str,&tmp);
- }
- if(str && has_token) {
- #ifdef __unix__
- if( (!sub && !regexec(&re, str,0 , NULL, 0) ) || /* 20071120 regex instead of strcmp */
- (sub && !bus && !comparefn(str, val)) || (sub && bus && substrfn(str,val)))
- #else
- if( (!sub && win_regexec(regexp_options, val, str)) ||
- (sub && !bus && !comparefn(str, val)) || (sub && bus && substrfn(str,val)))
- #endif
- {
- if(!sel) {
- type = (xctx->inst[i].ptr+ xctx->sym)->type;
- if( !strcmp(tok, "lab") && type && xctx->inst[i].node && IS_LABEL_SH_OR_PIN(type) ) {
- bus_hilight_hash_lookup(xctx->inst[i].node[0], col, XINSERT_NOREPLACE); /* sets xctx->hilight_nets=1; */
- } else {
- dbg(1, "search(): setting hilight flag on inst %d\n",i);
- /* xctx->hilight_nets=1; */ /* done in hilight_hash_lookup() */
- xctx->inst[i].color = col;
- inst_hilight_hash_lookup(i, col, XINSERT_NOREPLACE);
+ dbg(1, "search(): inst=%d, tok=%s, val=%s \n", i,tok, str);
+
+ if(bus && sub) {
+ dbg(1, "search(): doing substr search on bus sig:%s inst=%d tok=%s val=%s\n", str,i,tok,val);
+ str=expandlabel(str,&tmp);
+ }
+ if(str && has_token) {
+ #ifdef __unix__
+ if( (!sub && !regexec(&re, str,0 , NULL, 0) ) || /* 20071120 regex instead of strcmp */
+ (sub && !bus && !comparefn(str, val)) || (sub && bus && substrfn(str,val)))
+ #else
+ if( (!sub && win_regexec(regexp_options, val, str)) ||
+ (sub && !bus && !comparefn(str, val)) || (sub && bus && substrfn(str,val)))
+ #endif
+ {
+ if(!sel) {
+ type = (xctx->inst[i].ptr+ xctx->sym)->type;
+ if( !strcmp(tok, "lab") && type && xctx->inst[i].node && IS_LABEL_SH_OR_PIN(type) ) {
+ bus_hilight_hash_lookup(xctx->inst[i].node[0], col, XINSERT_NOREPLACE); /* sets xctx->hilight_nets=1; */
+ } else {
+ dbg(1, "search(): setting hilight flag on inst %d\n",i);
+ /* xctx->hilight_nets=1; */ /* done in hilight_hash_lookup() */
+ xctx->inst[i].color = col;
+ inst_hilight_hash_lookup(i, col, XINSERT_NOREPLACE);
+ }
}
- }
- if(sel==1) {
- xctx->inst[i].sel = SELECTED;
- set_first_sel(ELEMENT, i, 0);
- xctx->need_reb_sel_arr=1;
- }
- if(sel==-1) { /* 20171211 unselect */
- xctx->inst[i].sel = 0;
- xctx->need_reb_sel_arr=1;
- }
- found = 1;
- }
- }
- }
- for(i=0;iwires; ++i) {
- str = get_tok_value(xctx->wire[i].prop_ptr, tok,0);
- if(xctx->tok_size ) {
- #ifdef __unix__
- if( (!regexec(&re, str,0 , NULL, 0) && !sub ) || /* 20071120 regex instead of strcmp */
- ( !comparefn(str, val) && sub ) )
- #else
- if( (win_regexec(regexp_options, val, str) && !sub ) || /* 20071120 regex instead of strcmp */
- ( !comparefn(str, val) && sub ) )
-
- #endif
- {
- if(!sel) {
- bus_hilight_hash_lookup(xctx->wire[i].node, col, XINSERT_NOREPLACE); /* sets xctx->hilight_nets = 1 */
- }
- if(sel==1) {
- xctx->wire[i].sel = SELECTED;
- set_first_sel(WIRE, i, 0);
- xctx->need_reb_sel_arr=1;
- }
- if(sel==-1) {
- xctx->wire[i].sel = 0;
- xctx->need_reb_sel_arr=1;
- }
- found = 1;
- }
- else {
- dbg(2, "search(): not found wire=%d, tok=%s, val=%s search=%s\n", i,tok, str,val);
- }
- }
- }
- if(!sel && xctx->hilight_nets) propagate_hilights(1, 0, XINSERT_NOREPLACE);
- if(sel) for(c = 0; c < cadlayers; ++c) for(i=0;ilines[c]; ++i) {
- str = get_tok_value(xctx->line[c][i].prop_ptr, tok,0);
- if(xctx->tok_size) {
- #ifdef __unix__
- if( (!regexec(&re, str,0 , NULL, 0) && !sub ) ||
- ( !comparefn(str, val) && sub ))
- #else
- if( (win_regexec(regexp_options, val, str) && !sub ) ||
- ( !comparefn(str, val) && sub ))
- #endif
- {
- if(sel==1) {
- xctx->line[c][i].sel = SELECTED;
- set_first_sel(LINE, i, c);
- xctx->need_reb_sel_arr=1;
- }
- if(sel==-1) {
- xctx->line[c][i].sel = 0;
- xctx->need_reb_sel_arr=1;
- }
- found = 1;
- }
- else {
- dbg(2, "search(): not found line=%d col=%d, tok=%s, val=%s search=%s\n",
- i, c, tok, str, val);
- }
- }
- }
- if(sel) for(c = 0; c < cadlayers; ++c) for(i=0;irects[c]; ++i) {
- str = get_tok_value(xctx->rect[c][i].prop_ptr, tok,0);
- if(xctx->tok_size) {
- #ifdef __unix__
- if( (!regexec(&re, str,0 , NULL, 0) && !sub ) ||
- ( !comparefn(str, val) && sub ))
- #else
- if( (win_regexec(regexp_options, val, str) && !sub ) ||
- ( !comparefn(str, val) && sub ))
- #endif
- {
if(sel==1) {
- xctx->rect[c][i].sel = SELECTED;
- set_first_sel(xRECT, i, c);
+ xctx->inst[i].sel = SELECTED;
+ set_first_sel(ELEMENT, i, 0);
+ xctx->need_reb_sel_arr=1;
+ }
+ if(sel==-1) { /* 20171211 unselect */
+ xctx->inst[i].sel = 0;
+ xctx->need_reb_sel_arr=1;
+ }
+ found = 1;
+ }
+ }
+ }
+ for(i=0;iwires; ++i) {
+ str = get_tok_value(xctx->wire[i].prop_ptr, tok,0);
+ if(xctx->tok_size ) {
+ #ifdef __unix__
+ if( (!regexec(&re, str,0 , NULL, 0) && !sub ) || /* 20071120 regex instead of strcmp */
+ ( !comparefn(str, val) && sub ) )
+ #else
+ if( (win_regexec(regexp_options, val, str) && !sub ) || /* 20071120 regex instead of strcmp */
+ ( !comparefn(str, val) && sub ) )
+
+ #endif
+ {
+ if(!sel) {
+ bus_hilight_hash_lookup(xctx->wire[i].node, col, XINSERT_NOREPLACE); /* sets xctx->hilight_nets = 1 */
+ }
+ if(sel==1) {
+ xctx->wire[i].sel = SELECTED;
+ set_first_sel(WIRE, i, 0);
xctx->need_reb_sel_arr=1;
}
if(sel==-1) {
- xctx->rect[c][i].sel = 0;
+ xctx->wire[i].sel = 0;
xctx->need_reb_sel_arr=1;
}
found = 1;
- }
- else {
- dbg(2, "search(): not found rect=%d col=%d, tok=%s, val=%s search=%s\n",
- i, c, tok, str, val);
+ }
+ else {
+ dbg(2, "search(): not found wire=%d, tok=%s, val=%s search=%s\n", i,tok, str,val);
+ }
}
}
- }
-
- if(sel) for(c = 0; c < cadlayers; ++c) for(i=0;iarcs[c]; ++i) {
- str = get_tok_value(xctx->arc[c][i].prop_ptr, tok,0);
- if(xctx->tok_size) {
- #ifdef __unix__
- if( (!regexec(&re, str,0 , NULL, 0) && !sub ) ||
- ( !comparefn(str, val) && sub ))
- #else
- if( (win_regexec(regexp_options, val, str) && !sub ) ||
- ( !comparefn(str, val) && sub ))
- #endif
- {
+ if(!sel && xctx->hilight_nets) propagate_hilights(1, 0, XINSERT_NOREPLACE);
+ if(sel) for(c = 0; c < cadlayers; ++c) for(i=0;ilines[c]; ++i) {
+ str = get_tok_value(xctx->line[c][i].prop_ptr, tok,0);
+ if(xctx->tok_size) {
+ #ifdef __unix__
+ if( (!regexec(&re, str,0 , NULL, 0) && !sub ) ||
+ ( !comparefn(str, val) && sub ))
+ #else
+ if( (win_regexec(regexp_options, val, str) && !sub ) ||
+ ( !comparefn(str, val) && sub ))
+ #endif
+ {
if(sel==1) {
- xctx->arc[c][i].sel = SELECTED;
- set_first_sel(ARC, i, c);
+ xctx->line[c][i].sel = SELECTED;
+ set_first_sel(LINE, i, c);
xctx->need_reb_sel_arr=1;
}
if(sel==-1) {
- xctx->arc[c][i].sel = 0;
+ xctx->line[c][i].sel = 0;
xctx->need_reb_sel_arr=1;
}
found = 1;
- }
- else {
- dbg(2, "search(): not found arc=%d col=%d, tok=%s, val=%s search=%s\n",
- i, c, tok, str, val);
+ }
+ else {
+ dbg(2, "search(): not found line=%d col=%d, tok=%s, val=%s search=%s\n",
+ i, c, tok, str, val);
+ }
}
}
- }
-
- if(sel) for(c = 0; c < cadlayers; ++c) for(i=0;ipolygons[c]; ++i) {
- str = get_tok_value(xctx->poly[c][i].prop_ptr, tok,0);
- if(xctx->tok_size) {
- #ifdef __unix__
- if( (!regexec(&re, str,0 , NULL, 0) && !sub ) ||
- ( !comparefn(str, val) && sub ))
- #else
- if( (win_regexec(regexp_options, val, str) && !sub ) ||
- ( !comparefn(str, val) && sub ))
- #endif
- {
- if(sel==1) {
- xctx->poly[c][i].sel = SELECTED;
- set_first_sel(POLYGON, i, c);
- xctx->need_reb_sel_arr=1;
- }
- if(sel==-1) {
- xctx->poly[c][i].sel = 0;
- xctx->need_reb_sel_arr=1;
- }
- found = 1;
- }
- else {
- dbg(2, "search(): not found arc=%d col=%d, tok=%s, val=%s search=%s\n",
- i, c, tok, str, val);
+ if(sel) for(c = 0; c < cadlayers; ++c) for(i=0;irects[c]; ++i) {
+ str = get_tok_value(xctx->rect[c][i].prop_ptr, tok,0);
+ if(xctx->tok_size) {
+ #ifdef __unix__
+ if( (!regexec(&re, str,0 , NULL, 0) && !sub ) ||
+ ( !comparefn(str, val) && sub ))
+ #else
+ if( (win_regexec(regexp_options, val, str) && !sub ) ||
+ ( !comparefn(str, val) && sub ))
+ #endif
+ {
+ if(sel==1) {
+ xctx->rect[c][i].sel = SELECTED;
+ set_first_sel(xRECT, i, c);
+ xctx->need_reb_sel_arr=1;
+ }
+ if(sel==-1) {
+ xctx->rect[c][i].sel = 0;
+ xctx->need_reb_sel_arr=1;
+ }
+ found = 1;
+ }
+ else {
+ dbg(2, "search(): not found rect=%d col=%d, tok=%s, val=%s search=%s\n",
+ i, c, tok, str, val);
+ }
}
}
- }
-
+
+ if(sel) for(c = 0; c < cadlayers; ++c) for(i=0;iarcs[c]; ++i) {
+ str = get_tok_value(xctx->arc[c][i].prop_ptr, tok,0);
+ if(xctx->tok_size) {
+ #ifdef __unix__
+ if( (!regexec(&re, str,0 , NULL, 0) && !sub ) ||
+ ( !comparefn(str, val) && sub ))
+ #else
+ if( (win_regexec(regexp_options, val, str) && !sub ) ||
+ ( !comparefn(str, val) && sub ))
+ #endif
+ {
+ if(sel==1) {
+ xctx->arc[c][i].sel = SELECTED;
+ set_first_sel(ARC, i, c);
+ xctx->need_reb_sel_arr=1;
+ }
+ if(sel==-1) {
+ xctx->arc[c][i].sel = 0;
+ xctx->need_reb_sel_arr=1;
+ }
+ found = 1;
+ }
+ else {
+ dbg(2, "search(): not found arc=%d col=%d, tok=%s, val=%s search=%s\n",
+ i, c, tok, str, val);
+ }
+ }
+ }
+
+ if(sel) for(c = 0; c < cadlayers; ++c) for(i=0;ipolygons[c]; ++i) {
+ str = get_tok_value(xctx->poly[c][i].prop_ptr, tok,0);
+ if(xctx->tok_size) {
+ #ifdef __unix__
+ if( (!regexec(&re, str,0 , NULL, 0) && !sub ) ||
+ ( !comparefn(str, val) && sub ))
+ #else
+ if( (win_regexec(regexp_options, val, str) && !sub ) ||
+ ( !comparefn(str, val) && sub ))
+ #endif
+ {
+ if(sel==1) {
+ xctx->poly[c][i].sel = SELECTED;
+ set_first_sel(POLYGON, i, c);
+ xctx->need_reb_sel_arr=1;
+ }
+ if(sel==-1) {
+ xctx->poly[c][i].sel = 0;
+ xctx->need_reb_sel_arr=1;
+ }
+ found = 1;
+ }
+ else {
+ dbg(2, "search(): not found arc=%d col=%d, tok=%s, val=%s search=%s\n",
+ i, c, tok, str, val);
+ }
+ }
+ }
+ } /* if(!only_text_search) */
if(sel) for(i=0;itexts; ++i) {
- str = get_tok_value(xctx->text[i].prop_ptr, tok,0);
+ if(!strcmp(tok, "txt_ptr")) {
+ str = xctx->text[i].txt_ptr;
+ if(!str) continue;
+ xctx->tok_size = 1;
+ } else str = get_tok_value(xctx->text[i].prop_ptr, tok,0);
if(xctx->tok_size) {
#ifdef __unix__
if( (!regexec(&re, str,0 , NULL, 0) && !sub ) ||
@@ -1058,10 +1070,11 @@ int search(const char *tok, const char *val, int sub, int sel, int match_case, i
}
if(found) {
- if(tclgetboolvar("incr_hilight")) incr_hilight_color();
+ if(sel == 0 && tclgetboolvar("incr_hilight")) incr_hilight_color();
if(sel == -1) {
if(dr) draw();
}
+ else
if(sel) {
rebuild_selected_array(); /* sets or clears xctx->ui_state SELECTION flag */
if(dr) draw_selection(xctx->gc[SELLAYER], 0);
diff --git a/src/scheduler.c b/src/scheduler.c
index fdb80fbf..ae5def55 100644
--- a/src/scheduler.c
+++ b/src/scheduler.c
@@ -5173,12 +5173,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
* 1 : select matching instances
* -1 : unselect matching instances
* 'tok' set as:
+ : will search for 'val' in instance attribute 'attr'
* propstring : will search for 'val' in the entire
* *instance* attribute string.
+ * txt_ptr : this is used to search only the txt_ptr string of text pbjects
* cell::propstring : will search for 'val' in the entire
* *symbol* attribute string.
* cell::name : will search for 'val' in the symbol name
- * cell:: will search for 'val' in symbol attribute 'attr'
+ * cell:: : will search for 'val' in symbol attribute 'attr'
* example: xschem search regex 0 cell::template GAIN=100
* if 'no_match_case' is specified do not consider case sensitivity in search
* if 'nodraw' is specified do not draw search result