xschem change_sch_path command for changing the current path we are descended in; set_title parameter for xschem descend and xschem go_back (optimization for faster scripts). optimized utility procedure traversal.tcl. Catch glob pattern errors in proc setglob

This commit is contained in:
stefan schippers 2024-11-03 00:22:40 +01:00
parent f3abdf2eb8
commit 94d5c44599
7 changed files with 124 additions and 31 deletions

View File

@ -2143,8 +2143,50 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst, int fallback)
dbg(1, "get_sch_from_sym(): sym->name=%s, filename=%s\n", sym->name, filename);
}
int change_sch_path(int instnumber, int dr)
{
int level = xctx->currsch - 1;
char *instname = NULL;
char *expanded_instname = NULL;
int inst_mult;
char *path = NULL;
char *ptr;
size_t pathlen;
int res = 0;
if(level <= 0 ) return 0;
my_strdup2(_ALLOC_ID_, &instname, get_tok_value(xctx->hier_attr[level].prop_ptr, "name", 0));
my_strdup2(_ALLOC_ID_, &expanded_instname, expandlabel(instname, &inst_mult));
my_strdup2(_ALLOC_ID_, &path, xctx->sch_path[xctx->currsch]);
if(instnumber < 0 ) instnumber += inst_mult+1;
/* any invalid number->descend to leftmost inst */
if(instnumber <1 || instnumber > inst_mult) instnumber = 1;
pathlen = strlen(path);
if(pathlen == 0) goto end;
path[pathlen - 1] = '\0';
ptr = strrchr(path, '.');
if(!ptr) goto end;
*(ptr+1) = '\0';
my_free(_ALLOC_ID_, &xctx->sch_path[xctx->currsch]);
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch], path);
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch], find_nth(expanded_instname, ",", "", 0, instnumber));
my_strcat(_ALLOC_ID_, &xctx->sch_path[xctx->currsch], ".");
xctx->sch_path_hash[xctx->currsch] = 0;
xctx->sch_inst_number[level] = instnumber;
dbg(0, "instname=%s, path=%s\n", instname, path);
path[pathlen - 1] = '.';
res = 1;
if(dr && has_x) {
draw();
}
end:
my_free(_ALLOC_ID_, &instname);
my_free(_ALLOC_ID_, &path);
my_free(_ALLOC_ID_, &expanded_instname);
return res;
}
/* fallback = 1: if schematic=.. attr is set but file not existing descend into symbol base schematic */
int descend_schematic(int instnumber, int fallback, int alert)
int descend_schematic(int instnumber, int fallback, int alert, int set_title)
{
char *str = NULL;
char filename[PATH_MAX];
@ -2297,7 +2339,7 @@ int descend_schematic(int instnumber, int fallback, int alert)
dbg(1, "descend_schematic(): filename=%s\n", filename);
/* we are descending from a parent schematic downloaded from the web */
if(!tclgetboolvar("keep_symbols")) remove_symbols();
load_schematic(1, filename, 1, alert);
load_schematic(1, filename, set_title, alert);
if(xctx->hilight_nets) {
prepare_netlist_structs(0);
propagate_hilights(1, 0, XINSERT_NOREPLACE);
@ -2317,7 +2359,7 @@ int descend_schematic(int instnumber, int fallback, int alert)
return 1;
}
void go_back(int confirm) /* 20171006 add confirm */
void go_back(int confirm, int set_title) /* 20171006 add confirm */
{
int save_ok;
int from_embedded_sym;
@ -2363,7 +2405,7 @@ void go_back(int confirm) /* 20171006 add confirm */
/* by default) to parent schematic if going back from embedded symbol */
my_strncpy(filename, xctx->sch[xctx->currsch], S(filename));
load_schematic(1, filename, 1, 1);
load_schematic(1, filename, set_title, 1);
/* if we are returning from a symbol created from a generator don't set modified flag on parent
* as these symbols can not be edited / saved as embedded
* xctx->sch_inst_number[xctx->currsch + 1] == -1 --> we came from an inst with no embed flag set */

View File

@ -1727,13 +1727,13 @@ static void context_menu_action(double mx, double my)
edit_property(1);
break;
case 12:
descend_schematic(0, 1, 1);
descend_schematic(0, 1, 1, 1);
break;
case 13:
descend_symbol();
break;
case 14:
go_back(1);
go_back(1, 1);
break;
case 15: /* copy selection into clipboard */
rebuild_selected_array();
@ -2791,7 +2791,7 @@ int rstate; /* (reduced state, without ShiftMask) */
if(key=='e' && rstate == 0) /* descend to schematic */
{
if(xctx->semaphore >= 2) break;
descend_schematic(0, 1, 1);break;
descend_schematic(0, 1, 1, 1);break;
}
if(key=='e' && EQUAL_MODMASK) /* edit schematic in new window */
{
@ -2834,7 +2834,7 @@ int rstate; /* (reduced state, without ShiftMask) */
if( (key=='e' && rstate == ControlMask) || (key==XK_BackSpace)) /* back */
{
if(xctx->semaphore >= 2) break;
go_back(1);break;
go_back(1, 1);break;
}
if(key=='a' && rstate == 0) /* make symbol */

View File

@ -703,10 +703,10 @@ void *my_malloc(int id, size_t size)
void my_realloc(int id, void *ptr,size_t size)
{
void *a;
char old[100];
char old[100] = "";
void *tmp;
a = *(void **)ptr;
my_snprintf(old, S(old), "%p", a);
if(debug_var > 2) my_snprintf(old, S(old), "%p", a);
if(size == 0) {
free(*(void **)ptr);
dbg(3, "\nmy_free(%d,): my_realloc_freeing %p\n",id, *(void **)ptr);

View File

@ -454,6 +454,21 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
}
}
/* change_sch_path n <draw>
* if descended into a vector instance change inst number we are into to 'n',
* (same rules as 'descend' command) without going up and descending again
* if 'draw' string is given redraw screen */
else if(!strcmp(argv[1], "change_sch_path"))
{
int dr = 0;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(argc > 3 && !strcmp(argv[3], "draw")) dr = 1;
if(argc > 2) {
int n = atoi(argv[2]);
change_sch_path(n, dr);
}
}
/* check_symbols
* List all used symbols in current schematic and warn if some symbol is newer */
else if(!strcmp(argv[1], "check_symbols"))
@ -763,19 +778,27 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
delete_files();
}
/* descend [n]
/* descend [n] [notitle]
* Descend into selected component instance. Optional number 'n' specifies the
* instance number to descend into for vector instances (default: 0). */
* instance number to descend into for vector instances (default: 0).
* 0 or 1: leftmost instance, 2: second leftmost instance, ...
* -1: rightmost instance,-2: second rightmost instance, ...
* if string 'notitle' is given do not update window title (slow) */
else if(!strcmp(argv[1], "descend"))
{
int ret=0;
int set_title = 1;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(xctx->semaphore == 0) {
if(argc > 3 && !strcmp(argv[3], "notitle")) {
set_title = 0;
}
if(argc > 2) {
int n = atoi(argv[2]);
ret = descend_schematic(n, 0, 0);
ret = descend_schematic(n, 0, 0, set_title);
} else {
ret = descend_schematic(0, 0, 0);
ret = descend_schematic(0, 0, 0, set_title);
}
}
Tcl_SetResult(interp, dtoa(ret), TCL_VOLATILE);
@ -2019,12 +2042,17 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
#endif
}
/* go_back
* Go up one level (pop) in hierarchy */
/* go_back [notitle]
* Go up one level (pop) in hierarchy
* if string 'notitle' is given do not update window title (slow) */
else if(!strcmp(argv[1], "go_back"))
{
int set_title = 1;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if((xctx->semaphore == 0)) go_back(1);
if(argc > 2 && !strcmp(argv[2], "notitle")) {
set_title = 0;
}
if((xctx->semaphore == 0)) go_back(1, set_title);
Tcl_ResetResult(interp);
}
@ -5765,8 +5793,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else { cmd_found = 0;}
break;
case 'u': /*----------------------------------------------*/
/* undo
Undo last action */
/* undo [redo [set_modify]
Undo last action. Optional integers redo and set_modify are passed to pop_undo() */
if(!strcmp(argv[1], "undo"))
{
int redo = 0, set_modify = 1;

View File

@ -22,7 +22,7 @@
# This script traverses the hierarchy and prints all instances in design.
proc traversal {file} {
proc traversal {file {only_subckts {}}} {
if { $file eq {} || [file exists $file] } {
puts stderr "empty or existing file..."
return
@ -31,7 +31,7 @@ proc traversal {file} {
xschem set no_draw 1 ;# disable screen update
xschem set no_undo 1 ;# disable undo
set fd [open $file "w"]
hier_traversal $fd 0
hier_traversal $fd 0 $only_subckts
xschem set no_draw 0
xschem set no_undo 0
close $fd
@ -46,31 +46,48 @@ proc spaces {n} {
}
# recursive procedure
proc hier_traversal {fd {level 0}} {
proc hier_traversal {fd {level 0} only_subckts} {
global nolist_libs
set done_print 0
set schpath [xschem get sch_path]
set instances [xschem get instances]
set current_level [xschem get currsch]
for {set i 0} { $i < $instances} { incr i} {
set instname [xschem getprop instance $i name]
set symbol [xschem getprop instance $i cell::name]
set abs_symbol [abs_sym_path $symbol]
set type [xschem getprop symbol $symbol type]
if {$only_subckts && ($type ne {subcircuit})} { continue }
set skip 0
foreach j $nolist_libs {
if {[regexp $j $abs_symbol]} {
set skip 1
break
}
}
if {$skip} { continue }
puts $fd "[spaces $level]$schpath$instname symbol: $symbol, type: $type"
set done_print 1
if {$type eq {subcircuit}} {
set ninst [lindex [split [xschem expandlabel $instname] { }] 1]
for {set n 1} {$n <= $ninst} { incr n} {
# set dp 0
xschem select instance $i
# descending ninst times is extremely inefficient --FIXME--
xschem descend $n
# descending ninst times is extremely inefficient
set descended [xschem descend $n notitle]
# ensure previous descend was successful
if {[xschem get currsch] == $current_level + 1} {
if {$descended} {
incr level
hier_traversal $fd $level
xschem go_back
set dp [hier_traversal $fd $level $only_subckts]
xschem go_back notitle
incr level -1
}
if {!$dp} { break } ;# nothing printed so skip all other vector instances
}
}
}
return $done_print
}

View File

@ -1520,8 +1520,9 @@ extern void get_sch_from_sym(char *filename, xSymbol *sym, int inst, int fallbac
extern const char *get_sym_name(int inst, int ndir, int ext, int abs_path);
extern void toggle_ignore(void);
extern void get_additional_symbols(int what);
extern int descend_schematic(int instnumber, int fallback, int alert);
extern void go_back(int confirm);
extern int change_sch_path(int instnumber, int dr);
extern int descend_schematic(int instnumber, int fallback, int alert, int set_title);
extern void go_back(int confirm, int set_title);
extern void clear_schematic(int cancel, int symbol);
extern void view_unzoom(double z);
extern void view_zoom(double z);

View File

@ -3574,8 +3574,13 @@ proc setglob {dir} {
if {$OS == "Windows"} {
regsub {:} $file_dialog_globfilter {\:} file_dialog_globfilter
}
set file_dialog_files2 ${file_dialog_files2}\ [lsort [
glob -nocomplain -directory $dir -tails -type {f} $file_dialog_globfilter]]
if {![catch {glob -nocomplain -directory $dir -tails -type {f} $file_dialog_globfilter} res]} {
set flist $res
} else {
set flist [glob -nocomplain -directory $dir -tails -type {f} {*}]
}
set file_dialog_files2 ${file_dialog_files2}\ [lsort $flist]
}
}