From 92bb16773c5ba914213a709c1037bc4a3fc7d532 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Tue, 28 Jan 2025 11:24:51 +0100 Subject: [PATCH] guard against trepassing max hierarchy level when descending, updates to cellview and traversal procs --- src/actions.c | 4 ++ src/save.c | 16 +++++--- src/xschem.h | 2 +- src/xschem.tcl | 109 ++++++++++++++++++++++++++----------------------- 4 files changed, 74 insertions(+), 57 deletions(-) diff --git a/src/actions.c b/src/actions.c index 5eecc23b..5601e43b 100644 --- a/src/actions.c +++ b/src/actions.c @@ -2262,6 +2262,10 @@ int descend_schematic(int instnumber, int fallback, int alert, int set_title) int save_ok = 0; int i, n = 0; + if(xctx->currsch + 1 >= CADMAXHIER) { + dbg(0, "descend_schematic(): max hierarchy depth reached: %d", CADMAXHIER); + return 0; + } rebuild_selected_array(); if(xctx->lastsel !=1 || xctx->sel_array[0].type!=ELEMENT) { dbg(1, "descend_schematic(): wrong selection\n"); diff --git a/src/save.c b/src/save.c index 8dad1292..c088b816 100644 --- a/src/save.c +++ b/src/save.c @@ -5087,7 +5087,7 @@ void create_sch_from_sym(void) my_free(_ALLOC_ID_, &generic_pin); } -void descend_symbol(void) +int descend_symbol(void) { char *str=NULL; FILE *fd; @@ -5095,8 +5095,13 @@ void descend_symbol(void) char name_embedded[PATH_MAX]; int n = 0; struct stat buf; + if(xctx->currsch + 1 >= CADMAXHIER) { + dbg(0, "descend_symbol(): max hierarchy depth reached: %d", CADMAXHIER); + return 0; + } + rebuild_selected_array(); - if(xctx->lastsel > 1) return; + if(xctx->lastsel > 1) return 0; if(xctx->lastsel==1 && xctx->sel_array[0].type==ELEMENT) { n =xctx->sel_array[0].n; if(xctx->modified) @@ -5111,14 +5116,14 @@ void descend_symbol(void) * 0 : file not saved due to errors or per user request */ if(ret == 0) clear_all_hilights(); - if(ret == -1) return; /* user cancel */ + if(ret == -1) return 0; /* user cancel */ } my_snprintf(name, S(name), "%s", translate(n, xctx->inst[n].name)); /* dont allow descend in the default missing symbol */ if((xctx->inst[n].ptr+ xctx->sym)->type && - !strcmp( (xctx->inst[n].ptr+ xctx->sym)->type,"missing")) return; + !strcmp( (xctx->inst[n].ptr+ xctx->sym)->type,"missing")) return 0; } - else return; + else return 0; /* build up current hierarchy path */ my_strdup(_ALLOC_ID_, &str, xctx->inst[n].instname); @@ -5200,6 +5205,7 @@ void descend_symbol(void) my_free(_ALLOC_ID_, &sympath); } zoom_full(1, 0, 1 + 2 * tclgetboolvar("zoom_full_center"), 0.97); + return 1; } /* 20111023 align selected object to current grid setting */ diff --git a/src/xschem.h b/src/xschem.h index c855fdd6..6743790a 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1484,7 +1484,7 @@ extern void remove_symbol(int i); extern void clear_drawing(void); extern int is_from_web(const char *f); extern int load_sym_def(const char name[], FILE *embed_fd); -extern void descend_symbol(void); +extern int descend_symbol(void); extern int place_symbol(int pos, const char *symbol_name, double x, double y, short rot, short flip, const char *inst_props, int draw_sym, int first_call, int to_push_undo); extern void place_net_label(int type); diff --git a/src/xschem.tcl b/src/xschem.tcl index 1321e560..5f5d3e8e 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -1877,7 +1877,6 @@ proc cellview { {derived_symbols {}} {upd 0} } { set symbg SeaGreen1 set missingbg IndianRed1 } - if {[info tclversion] >= 8.5} { set font {TkDefaultFont 10 bold} ;# Monospace } else { @@ -1885,7 +1884,6 @@ proc cellview { {derived_symbols {}} {upd 0} } { } if {!$upd} { - xschem reload_symbols ;# purge unused symbols xschem netlist -keep_symbols -noalert;# traverse the hierarchy and retain all encountered symbols puts "get netlist" @@ -1988,7 +1986,7 @@ proc cellview { {derived_symbols {}} {upd 0} } { if {$upd} {return} frame .cv.bottom - button .cv.bottom.update -text Update -command "cellview [list $derived_symbols] 1" + button .cv.bottom.update -text Update -command "cellview $derived_symbols 1" pack .cv.bottom.update -side left label .cv.bottom.status -text {STATUS LINE} pack .cv.bottom.status -fill x -expand yes @@ -2006,15 +2004,15 @@ proc cellview { {derived_symbols {}} {upd 0} } { ############ /cellview ############ traversal -proc traversal_setlabels {w parent_sch instname inst_sch sym_sch default_sch inst_spice_sym_def sym_spice_sym_def} { - global traversal_cnt dark_gui_colorscheme +proc traversal_setlabels {w parent_sch instname inst_sch sym_sch default_sch + inst_spice_sym_def sym_spice_sym_def} { + global traversal dark_gui_colorscheme set sf .trav.center.f.scrl - # puts "traversal_setlabels $w $parent_sch $inst_sch $instname" + # puts "traversal_setlabels: $w parent: |$parent_sch| inst: $instname def: $sym_sch $inst_sch --> [$w get]" # update schematic if {$parent_sch ne {}} { set current [xschem get current_name] - # puts "traversal_update_schematic: $w parent: $parent_sch $instname def: $sym_sch $inst_sch --> [$w get]" if { $inst_sch ne [$w get] } { puts "update attr" xschem load -undoreset -nodraw $parent_sch @@ -2028,11 +2026,6 @@ proc traversal_setlabels {w parent_sch instname inst_sch sym_sch default_sch ins set inst_sch [$w get] # puts "inst_sch set to: $inst_sch" xschem load -undoreset -nodraw $current - - bind $w " - traversal_setlabels $w [list $parent_sch] [list $instname] [list $inst_sch] [list $sym_sch] \ - [list $default_sch] [list $inst_spice_sym_def] [list $sym_spice_sym_def] - " } } # /update schematic @@ -2070,8 +2063,10 @@ proc traversal_setlabels {w parent_sch instname inst_sch sym_sch default_sch ins # This proc traverses the hierarchy and prints all instances in design. proc traversal {{only_subckts 1} {all_hierarchy 1}} { - global keep_symbols traversal_cnt - set traversal_cnt 0 + global traversal keep_symbols + set traversal(only_subckts) $only_subckts + set traversal(all_hierarchy) $all_hierarchy + set traversal(cnt) 0 set save_keep $keep_symbols set keep_symbols 1 xschem unselect_all @@ -2085,8 +2080,6 @@ proc traversal {{only_subckts 1} {all_hierarchy 1}} { } toplevel .trav - wm geometry .trav 1200x400 - frame .trav.top label .trav.top.inst -text {INSTANCE} -width 25 -bg grey60 -anchor w -padx 4 -font $font label .trav.top.sym -text {SYMBOL} -width 30 -bg grey60 -anchor w -padx 4 -font $font @@ -2114,12 +2107,24 @@ proc traversal {{only_subckts 1} {all_hierarchy 1}} { bind .trav.center.f {sframeyview .trav.center} bind .trav { sframeyview .trav.center scroll -0.1} bind .trav { sframeyview .trav.center scroll 0.1} - bind .trav {destroy .trav} + bind .trav " + set traversal(geom) \[winfo geometry .trav\] + destroy .trav + " + if {[info exists traversal(geom)]} { + wm geometry .trav $traversal(geom) + } else { + wm geometry .trav 1200x400 + } + update + set traversal(geom) [winfo geometry .trav] + return {} } # recursive procedure proc hier_traversal {{level 0} {only_subckts 0} {all_hierarchy 1}} { - global nolist_libs traversal_cnt retval + global nolist_libs traversal retval + if {[info tclversion] >= 8.5} { set font {TkDefaultFont 10 bold} ;# Monospace } else { @@ -2155,59 +2160,61 @@ proc hier_traversal {{level 0} {only_subckts 0} {all_hierarchy 1}} { } } if {$skip} { continue } - incr traversal_cnt + incr traversal(cnt) + set cnt $traversal(cnt) - # puts "building frame $sf.f$traversal_cnt" - frame $sf.f$traversal_cnt - pack $sf.f$traversal_cnt -side top -fill x - label $sf.f$traversal_cnt.i -text "[spaces $level 2]$schpath$instname" \ + # puts "building frame $sf.f$cnt" + frame $sf.f$cnt + pack $sf.f$cnt -side top -fill x + label $sf.f$cnt.i -text "[spaces $level 2]$instname" \ -width 25 -anchor w -padx 4 -borderwidth 1 \ -relief sunken -pady 1 -font $font - label $sf.f$traversal_cnt.l -text $symbol -width 30 -anchor w -padx 4 -borderwidth 1 \ + label $sf.f$cnt.l -text $symbol -width 30 -anchor w -padx 4 -borderwidth 1 \ -relief sunken -pady 1 -font $font - entry $sf.f$traversal_cnt.s -width 45 -borderwidth 1 -relief sunken -font $font - + entry $sf.f$cnt.s -width 45 -borderwidth 1 -relief sunken -font $font if {$type eq {subcircuit}} { if {$inst_spice_sym_def ne {}} { - $sf.f$traversal_cnt.s insert 0 "$sch_rootname defined in instance spice_sym_def" + $sf.f$cnt.s insert 0 "$sch_rootname defined in instance spice_sym_def" } elseif {$sym_spice_sym_def ne {}} { - $sf.f$traversal_cnt.s insert 0 "$sch_rootname defined in symbol spice_sym_def" + $sf.f$cnt.s insert 0 "$sch_rootname defined in symbol spice_sym_def" } else { - $sf.f$traversal_cnt.s insert 0 "$inst_sch" + $sf.f$cnt.s insert 0 "$inst_sch" } } - button $sf.f$traversal_cnt.bsym -text {Sym} -padx 4 -borderwidth 1 -pady 0 -font $font \ + button $sf.f$cnt.bsym -text {Sym} -padx 4 -borderwidth 1 -pady 0 -font $font \ -command " - xschem load_new_window \[$sf.f$traversal_cnt.l cget -text\] + xschem load_new_window \[$sf.f$cnt.l cget -text\] " - button $sf.f$traversal_cnt.bsch -text {Sch} -padx 4 -borderwidth 1 -pady 0 -font $font \ - -command " - if { [list $sym_spice_sym_def] eq {} && [list $inst_spice_sym_def] eq {}} { - xschem load_new_window \[$sf.f$traversal_cnt.s get\] - } elseif {[list $sym_spice_sym_def] ne {}} { - editdata [list $sym_spice_sym_def] {Symbol spice_sym_def attribute} - } else { - editdata [list $inst_spice_sym_def] {Instance spice_sym_def attribute} - }" - if { $sym_spice_sym_def eq {} && $inst_spice_sym_def eq {}} { - bind $sf.f$traversal_cnt.s " - traversal_setlabels %W [list $parent_sch] [list $instname] [list $inst_sch] [list $sym_sch] \ - [list $default_sch] [list $inst_spice_sym_def] [list $sym_spice_sym_def] + button $sf.f$cnt.bsch -text {Sch} -padx 4 -borderwidth 1 -pady 0 -font $font \ + -command " + if { [list $sym_spice_sym_def] eq {} && [list $inst_spice_sym_def] eq {}} { + xschem load_new_window \[$sf.f$cnt.s get\] + } elseif {[list $sym_spice_sym_def] ne {}} { + editdata [list $sym_spice_sym_def] {Symbol spice_sym_def attribute} + } else { + editdata [list $inst_spice_sym_def] {Instance spice_sym_def attribute} + }" + button $sf.f$cnt.upd -text Upd -padx 4 -borderwidth 1 -pady 0 -font $font \ + -command " + traversal_setlabels $sf.f$cnt.s [list $parent_sch] [list $instname] [list $inst_sch] \ + [list $sym_sch] [list $default_sch] [list $inst_spice_sym_def] [list $sym_spice_sym_def] + set traversal(geom) \[winfo geometry .trav\] + destroy .trav + traversal $traversal(only_subckts) $traversal(all_hierarchy) " - } - traversal_setlabels $sf.f$traversal_cnt.s {} $instname $inst_sch $sym_sch \ - $default_sch $inst_spice_sym_def $sym_spice_sym_def - pack $sf.f$traversal_cnt.i -side left -fill x -expand 1 - pack $sf.f$traversal_cnt.l $sf.f$traversal_cnt.s -side left -fill x - pack $sf.f$traversal_cnt.bsym $sf.f$traversal_cnt.bsch -side left + traversal_setlabels $sf.f$cnt.s $parent_sch $instname $inst_sch $sym_sch \ + $default_sch $inst_spice_sym_def $sym_spice_sym_def + pack $sf.f$cnt.i -side left -fill x -expand 1 + pack $sf.f$cnt.l $sf.f$cnt.s -side left -fill x + pack $sf.f$cnt.bsym $sf.f$cnt.bsch $sf.f$cnt.upd -side left set done_print 1 if {$type eq {subcircuit} && $all_hierarchy} { xschem select instance $i fast nodraw set descended [xschem descend 1 6] if {$descended} { incr level - set dp [hier_traversal $level $only_subckts] + set dp [hier_traversal $level $only_subckts 1] xschem go_back 1 incr level -1 }