add case insensitive matching in xschem search function
This commit is contained in:
parent
83b1993c32
commit
3c73bb918b
|
|
@ -496,6 +496,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
|
||||
|
||||
|
||||
|
||||
<li><kbd> abort_operation</kbd></li><pre>
|
||||
Resets UI state, unselect all and abort any pending operation </pre>
|
||||
<li><kbd> add_symbol_pin</kbd></li><pre>
|
||||
|
|
@ -1042,7 +1043,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
If nothing selected open another window of the second
|
||||
schematic (issues a warning).
|
||||
if 'new_process' is given start a new xschem process </pre>
|
||||
<li><kbd> search regex|exact select tok val</kbd></li><pre>
|
||||
<li><kbd> search regex|exact select tok val [match_case]</kbd></li><pre>
|
||||
Search instances with attribute string containing 'tok'
|
||||
attribute and value 'val'
|
||||
search can be exact ('exact') or as a regular expression ('regex')
|
||||
|
|
@ -1057,7 +1058,11 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
*symbol* attribute string.
|
||||
cell::name : will search for 'val' in the symbol name
|
||||
cell::<attr> will search for 'val' in symbol attribute 'attr'
|
||||
example: xschem search regex 0 cell::template GAIN=100</pre>
|
||||
example: xschem search regex 0 cell::template GAIN=100
|
||||
match_case:
|
||||
1 : Match case
|
||||
0 : Do not match case
|
||||
If not given assume 1 (Match case)</pre>
|
||||
<li><kbd> select instance|wire|text id [clear]</kbd></li><pre>
|
||||
Select indicated instance or wire or text.
|
||||
For 'instance' 'id' can be the instance name or number
|
||||
|
|
@ -1254,6 +1259,7 @@ C {verilog_timescale.sym} 1050 -100 0 0 {name=s1 timestep="1ns" precision="1ns"
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,28 @@ int my_strcasecmp(const char *s1, const char *s2)
|
|||
return tolower(*s1) - tolower(*s2);
|
||||
}
|
||||
|
||||
char *my_strcasestr(const char *haystack, const char *needle)
|
||||
{
|
||||
const char *h, *n;
|
||||
int found = 0;
|
||||
if(needle[0] == '\0') return (char *)haystack;
|
||||
|
||||
for(h = haystack; *h; h++) {
|
||||
found = 1;
|
||||
for(n = needle; *n; n++) {
|
||||
const char *hh = h + (n - needle);
|
||||
dbg(1, "%c %c\n", *hh, *n);
|
||||
if(toupper(*hh) != toupper(*n)) {
|
||||
found = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found) return (char *)h;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int my_strncasecmp(const char *s1, const char *s2, size_t n)
|
||||
{
|
||||
if (n == 0) return 0;
|
||||
|
|
|
|||
|
|
@ -632,7 +632,7 @@ static int win_regexec(const char *options, const char *pattern, char *name)
|
|||
* 0 : regex search
|
||||
* 1 : exact search
|
||||
*/
|
||||
int search(const char *tok, const char *val, int sub, int sel)
|
||||
int search(const char *tok, const char *val, int sub, int sel, int match_case)
|
||||
{
|
||||
int save_draw;
|
||||
int i,c, col = 7,tmp,bus=0;
|
||||
|
|
@ -642,9 +642,14 @@ int search(const char *tok, const char *val, int sub, int sel)
|
|||
const char *empty_string = "";
|
||||
char *tmpname=NULL;
|
||||
int found = 0;
|
||||
#ifdef __unix__
|
||||
int(*comparefn)(const char *,const char *) = strcmp;
|
||||
char *(*substrfn)(const char *,const char *) = strstr;
|
||||
#ifdef __unix__
|
||||
int cflags = REG_NOSUB | REG_EXTENDED;
|
||||
regex_t re;
|
||||
#endif
|
||||
#else
|
||||
char *regexp_options = NULL;
|
||||
#endif
|
||||
|
||||
if(!val) {
|
||||
fprintf(errfp, "search(): warning: null val key\n");
|
||||
|
|
@ -652,13 +657,25 @@ int search(const char *tok, const char *val, int sub, int sel)
|
|||
}
|
||||
save_draw = xctx->draw_window;
|
||||
xctx->draw_window=1;
|
||||
#ifdef __unix__
|
||||
if(regcomp(&re, val , REG_NOSUB | REG_EXTENDED)) return TCL_ERROR;
|
||||
#endif
|
||||
/* replace strcmp and strstr with my_strcasecmp and my_strcasestr
|
||||
* if SPICE or VHDL (case insensitive) netlist mode is set */
|
||||
if(!match_case) {
|
||||
comparefn = my_strcasecmp;
|
||||
substrfn = my_strcasestr;
|
||||
}
|
||||
#ifdef __unix__
|
||||
if(!match_case) {
|
||||
cflags |= REG_ICASE; /* ignore case for Spice and VHDL (these are case insensitive netlists) */
|
||||
}
|
||||
if(regcomp(&re, val , cflags)) return TCL_ERROR;
|
||||
#else
|
||||
if(!match_case) {
|
||||
regexp_options = "-nocase";
|
||||
}
|
||||
#endif
|
||||
dbg(1, "search():val=%s\n", val);
|
||||
if(!sel) {
|
||||
col=xctx->hilight_color;
|
||||
if(tclgetboolvar("incr_hilight")) incr_hilight_color();
|
||||
}
|
||||
has_token = 0;
|
||||
prepare_netlist_structs(0);
|
||||
|
|
@ -693,11 +710,10 @@ int search(const char *tok, const char *val, int sub, int sel)
|
|||
if(str && has_token) {
|
||||
#ifdef __unix__
|
||||
if( (!sub && !regexec(&re, str,0 , NULL, 0) ) || /* 20071120 regex instead of strcmp */
|
||||
(sub && !strcmp(str, val) && !bus) || (sub && strstr(str,val) && bus))
|
||||
(sub && !bus && !comparefn(str, val)) || (sub && bus && substrfn(str,val)))
|
||||
#else
|
||||
|
||||
if( (!sub && win_regexec(NULL, val, str)) ||
|
||||
(sub && !strcmp(str, val) && !bus) || (sub && strstr(str,val) && bus))
|
||||
if( (!sub && win_regexec(regexp_options, val, str)) ||
|
||||
(sub && !bus && !comparefn(str, val)) || (sub && bus && substrfn(str,val)))
|
||||
#endif
|
||||
{
|
||||
if(!sel) {
|
||||
|
|
@ -728,10 +744,10 @@ int search(const char *tok, const char *val, int sub, int sel)
|
|||
if(xctx->tok_size ) {
|
||||
#ifdef __unix__
|
||||
if( (!regexec(&re, str,0 , NULL, 0) && !sub ) || /* 20071120 regex instead of strcmp */
|
||||
( !strcmp(str, val) && sub ) )
|
||||
( !comparefn(str, val) && sub ) )
|
||||
#else
|
||||
if( (win_regexec(NULL, val, str) && !sub ) || /* 20071120 regex instead of strcmp */
|
||||
( !strcmp(str, val) && sub ) )
|
||||
if( (win_regexec(regexp_options, val, str) && !sub ) || /* 20071120 regex instead of strcmp */
|
||||
( !comparefn(str, val) && sub ) )
|
||||
|
||||
#endif
|
||||
{
|
||||
|
|
@ -759,10 +775,10 @@ int search(const char *tok, const char *val, int sub, int sel)
|
|||
if(xctx->tok_size) {
|
||||
#ifdef __unix__
|
||||
if( (!regexec(&re, str,0 , NULL, 0) && !sub ) ||
|
||||
( !strcmp(str, val) && sub ))
|
||||
( !comparefn(str, val) && sub ))
|
||||
#else
|
||||
if( (win_regexec(NULL, val, str) && !sub ) ||
|
||||
( !strcmp(str, val) && sub ))
|
||||
if( (win_regexec(regexp_options, val, str) && !sub ) ||
|
||||
( !comparefn(str, val) && sub ))
|
||||
#endif
|
||||
{
|
||||
if(sel==1) {
|
||||
|
|
@ -786,10 +802,10 @@ int search(const char *tok, const char *val, int sub, int sel)
|
|||
if(xctx->tok_size) {
|
||||
#ifdef __unix__
|
||||
if( (!regexec(&re, str,0 , NULL, 0) && !sub ) ||
|
||||
( !strcmp(str, val) && sub ))
|
||||
( !comparefn(str, val) && sub ))
|
||||
#else
|
||||
if( (win_regexec(NULL, val, str) && !sub ) ||
|
||||
( !strcmp(str, val) && sub ))
|
||||
if( (win_regexec(regexp_options, val, str) && !sub ) ||
|
||||
( !comparefn(str, val) && sub ))
|
||||
#endif
|
||||
{
|
||||
if(sel==1) {
|
||||
|
|
@ -809,6 +825,7 @@ int search(const char *tok, const char *val, int sub, int sel)
|
|||
}
|
||||
}
|
||||
if(found) {
|
||||
if(tclgetboolvar("incr_hilight")) incr_hilight_color();
|
||||
if(sel == -1) {
|
||||
draw();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3154,7 +3154,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
Tcl_ResetResult(interp);
|
||||
}
|
||||
|
||||
/* search regex|exact select tok val
|
||||
/* search regex|exact select tok val [match_case]
|
||||
* Search instances with attribute string containing 'tok'
|
||||
* attribute and value 'val'
|
||||
* search can be exact ('exact') or as a regular expression ('regex')
|
||||
|
|
@ -3170,21 +3170,27 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
* cell::name : will search for 'val' in the symbol name
|
||||
* cell::<attr> will search for 'val' in symbol attribute 'attr'
|
||||
* example: xschem search regex 0 cell::template GAIN=100
|
||||
* match_case:
|
||||
* 1 : Match case
|
||||
* 0 : Do not match case
|
||||
* If not given assume 1 (Match case)
|
||||
*/
|
||||
else if(!strcmp(argv[1], "search") || !strcmp(argv[1], "searchmenu"))
|
||||
{
|
||||
/* 0 1 2 3 4 5 */
|
||||
/* select */
|
||||
/* xschem search regex|exact 0|1|-1 tok val */
|
||||
/* 0 1 2 3 4 5 6 */
|
||||
/* select */
|
||||
/* xschem search regex|exact 0|1|-1 tok val [match_case] */
|
||||
int select, r;
|
||||
int match_case = 1;
|
||||
if(argc > 6 && argv[6][0] == '0') match_case = 0;
|
||||
if(argc < 6) {
|
||||
Tcl_SetResult(interp, "xschem search requires 4 or 5 additional fields.", TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
if(argc > 5) {
|
||||
select = atoi(argv[3]);
|
||||
if(!strcmp(argv[2], "regex") ) r = search(argv[4],argv[5],0,select);
|
||||
else r = search(argv[4],argv[5],1,select);
|
||||
if(!strcmp(argv[2], "regex") ) r = search(argv[4],argv[5],0,select, match_case);
|
||||
else r = search(argv[4],argv[5],1,select, match_case);
|
||||
if(r == 0) {
|
||||
if(has_x && !strcmp(argv[1], "searchmenu"))
|
||||
tcleval("tk_messageBox -type ok -parent [xschem get topwindow] -message {Not found.}");
|
||||
|
|
@ -3855,8 +3861,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
|||
* testmode */
|
||||
else if(!strcmp(argv[1], "test"))
|
||||
{
|
||||
dbg(0, "sizeof Xschem_ctx=%d\n", sizeof(Xschem_ctx));
|
||||
/* swap_windows(); */
|
||||
/*
|
||||
* if(argc > 3) {
|
||||
* char *r = my_strcasestr(argv[2], argv[3]);
|
||||
* dbg(0, "%s\n", r ? r : "NULL");
|
||||
* }
|
||||
*/
|
||||
Tcl_ResetResult(interp);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1198,7 +1198,7 @@ extern Hilight_hashentry *bus_hilight_hash_lookup(const char *token, int value,
|
|||
/* wrapper function to hash highlighted instances, avoid clash with net names */
|
||||
extern Hilight_hashentry *inst_hilight_hash_lookup(int i, int value, int what);
|
||||
extern Hilight_hashentry *hilight_lookup(const char *token, int value, int what);
|
||||
extern int search(const char *tok, const char *val, int sub, int sel);
|
||||
extern int search(const char *tok, const char *val, int sub, int sel, int match_case);
|
||||
extern int process_options(int argc, char **argv);
|
||||
extern void calc_drawing_bbox(xRect *boundbox, int selected);
|
||||
extern int ps_draw(int what);
|
||||
|
|
@ -1457,6 +1457,7 @@ extern char *my_strtok_r(char *str, const char *delim, const char *quote, char *
|
|||
extern char **parse_cmd_string(const char *cmd, int *argc);
|
||||
extern int my_strncpy(char *d, const char *s, size_t n);
|
||||
extern int my_strcasecmp(const char *s1, const char *s2);
|
||||
extern char *my_strcasestr(const char *haystack, const char *needle);
|
||||
extern double mylog10(double x);
|
||||
extern double mylog(double x);
|
||||
extern int my_strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
|
|
|
|||
|
|
@ -1327,7 +1327,7 @@ proc descend_hierarchy {path {redraw 1}} {
|
|||
set inst $path
|
||||
regsub {\..*} $inst {} inst ;# take 1st path component: xlev1[3].xlev2.m3 -> xlev1[3]
|
||||
regsub {[^.]+\.} $path {} path ;# take remaining path: xlev1[3].xlev2.m3 -> xlev2.m3
|
||||
xschem search exact 1 name $inst
|
||||
xschem search exact 1 name $inst 1
|
||||
# handle vector instances: xlev1[3:0] -> xlev1[3],xlev1[2],xlev1[1],xlev1[0]
|
||||
# descend into the right one
|
||||
set inst_list [split [lindex [xschem expandlabel [lindex [xschem selected_set] 0 ] ] 0] {,}]
|
||||
|
|
@ -3600,7 +3600,7 @@ proc about {} {
|
|||
|
||||
proc property_search {} {
|
||||
global search_value search_found
|
||||
global search_exact
|
||||
global search_exact search_case
|
||||
global search_select
|
||||
global custom_token OS
|
||||
|
||||
|
|
@ -3631,22 +3631,24 @@ proc property_search {} {
|
|||
set custom_token [.dialog.custom.e get]
|
||||
if {$debug_var<=-1} { puts stderr "|$custom_token|" }
|
||||
if { $search_exact==1 } {
|
||||
set search_found [xschem searchmenu exact $search_select $custom_token $search_value]
|
||||
set search_found [xschem searchmenu exact $search_select $custom_token $search_value $search_case]
|
||||
} else {
|
||||
set search_found [xschem searchmenu regex $search_select $custom_token $search_value]
|
||||
set search_found [xschem searchmenu regex $search_select $custom_token $search_value $search_case]
|
||||
}
|
||||
destroy .dialog
|
||||
}
|
||||
button .dialog.but.cancel -text Cancel -command { set search_found 1; destroy .dialog }
|
||||
|
||||
# Window doesn't support regular expression, has to be exact match for now
|
||||
checkbutton .dialog.but.sub -text Exact_search -variable search_exact
|
||||
checkbutton .dialog.but.sub -text {Exact search} -variable search_exact
|
||||
checkbutton .dialog.but.case -text {Match case} -variable search_case
|
||||
radiobutton .dialog.but.nosel -text {Highlight} -variable search_select -value 0
|
||||
radiobutton .dialog.but.sel -text {Select} -variable search_select -value 1
|
||||
# 20171211 added unselect
|
||||
radiobutton .dialog.but.unsel -text {Unselect} -variable search_select -value -1
|
||||
pack .dialog.but.ok -anchor w -side left
|
||||
pack .dialog.but.sub -side left
|
||||
pack .dialog.but.case -side left
|
||||
pack .dialog.but.nosel -side left
|
||||
pack .dialog.but.sel -side left
|
||||
pack .dialog.but.unsel -side left
|
||||
|
|
@ -5493,7 +5495,7 @@ set tctx::global_list {
|
|||
netlist_type no_change_attrs nolist_libs noprint_libs old_selected_tok only_probes path pathlist
|
||||
persistent_command preserve_unchanged_attrs prev_symbol ps_colors ps_paper_size rainbow_colors
|
||||
rawfile_loaded rcode recentfile
|
||||
replace_key retval retval_orig rotated_text search_exact search_found search_schematic
|
||||
replace_key retval retval_orig rotated_text search_case search_exact search_found search_schematic
|
||||
search_select search_value selected_tok show_hidden_texts show_infowindow
|
||||
show_infowindow_after_netlist show_pin_net_names
|
||||
simconf_default_geometry simconf_vpos simulate_bg spiceprefix split_files svg_colors
|
||||
|
|
@ -6754,6 +6756,7 @@ set_ne XSCHEM_START_WINDOW {}
|
|||
set custom_token {lab}
|
||||
set search_value {}
|
||||
set search_exact 0
|
||||
set search_case 1
|
||||
|
||||
# 20171005
|
||||
set custom_label_prefix {}
|
||||
|
|
|
|||
Loading…
Reference in New Issue