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:
parent
f3abdf2eb8
commit
94d5c44599
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue