diff --git a/src/scheduler.c b/src/scheduler.c index e5036ebd..2c79bc92 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1335,7 +1335,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg if(argc > 2) { my_strncpy(xctx->plotfile, argv[2], S(xctx->plotfile)); } - hier_psprint(); + hier_psprint(NULL, 1); Tcl_ResetResult(interp); } else if(!strcmp(argv[1], "hilight")) @@ -1616,6 +1616,15 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } } + else if(!strcmp(argv[1], "list_hierarchy")) + { + char *res = NULL; + Tcl_ResetResult(interp); + hier_psprint(&res, 2); + Tcl_SetResult(interp, res, TCL_VOLATILE); + my_free(1645, &res); + } + else if(!strcmp(argv[1], "list_hilights")) { const char *sep; diff --git a/src/spice_netlist.c b/src/spice_netlist.c index edde3544..8e3fa09b 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -24,7 +24,24 @@ static Str_hashtable model_table = {NULL, 0}; /* safe even with multiple schematics */ -void hier_psprint(void) /* netlister driver */ +static const char *hier_psprint_mtime(const char *file_name) +{ + static char date[200] = ""; + struct stat time_buf; + struct tm *tm; + if(!stat(file_name , &time_buf)) { + tm=localtime(&(time_buf.st_mtime) ); + strftime(date, sizeof(date), "%Y%m%d_%H%M%S", tm); + } + return date; +} + +/* + * what: + * 1 : ps/pdf print + * 2 : list hierarchy + */ +void hier_psprint(char **res, int what) /* netlister driver */ { int i; char *subckt_name; @@ -32,11 +49,17 @@ void hier_psprint(void) /* netlister driver */ char *abs_path = NULL; Str_hashtable subckt_table = {NULL, 0}; - if(!ps_draw(1)) return; /* prolog */ + if((what & 1) && !ps_draw(1)) return; /* prolog */ xctx->push_undo(); str_hash_init(&subckt_table, HASHSIZE); zoom_full(0, 0, 1, 0.97); - ps_draw(2); /* page */ + if(what & 1) ps_draw(2); /* page */ + if(what & 2) { /* print cellname */ + my_strcat(1637, res, hier_psprint_mtime(xctx->sch[xctx->currsch])); + my_strcat(1638, res, " {"); + my_strcat(1639, res, xctx->sch[xctx->currsch]); + my_strcat(1640, res, "}\n"); + } dbg(1,"--> %s\n", skip_dir( xctx->sch[xctx->currsch]) ); unselect_all(1); remove_symbols(); /* ensure all unused symbols purged before descending hierarchy */ @@ -50,10 +73,13 @@ void hier_psprint(void) /* netlister driver */ subckt_name=NULL; for(i=0;isymbols;i++) { + int flag; /* for printing we process also symbols that have *_ignore attribute */ if(!xctx->sym[i].type || !xctx->sym[i].name || !xctx->sym[i].name[0]) continue; /* can not descend into */ my_strdup2(1230, &abs_path, abs_sym_path(xctx->sym[i].name, "")); - if(strcmp(xctx->sym[i].type,"subcircuit")==0 && check_lib(2, abs_path)) + if(what & 1) flag = check_lib(2, abs_path); /* noprint_libs */ + else flag = check_lib(1, abs_path); /* xschem_libs */ + if(strcmp(xctx->sym[i].type,"subcircuit")==0 && flag) { /* xctx->sym can be SCH or SYM, use hash to avoid writing duplicate subckt */ my_strdup(1228, &subckt_name, get_cell(xctx->sym[i].name, 0)); @@ -64,7 +90,13 @@ void hier_psprint(void) /* netlister driver */ /* for printing we go down to bottom regardless of spice_stop attribute */ load_schematic(1,filename, 0); zoom_full(0, 0, 1, 0.97); - ps_draw(2); /* page */ + if(what & 1) ps_draw(2); /* page */ + if(what & 2) { /* print cellname */ + my_strcat(1641, res, hier_psprint_mtime(xctx->sch[xctx->currsch])); + my_strcat(1642, res, " {"); + my_strcat(1643, res, xctx->sch[xctx->currsch]); + my_strcat(1644, res, "}\n"); + } dbg(1,"--> %s\n", skip_dir( xctx->sch[xctx->currsch]) ); } } @@ -77,7 +109,7 @@ void hier_psprint(void) /* netlister driver */ unselect_all(1); xctx->pop_undo(0, 0); my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name)); - ps_draw(4); /* trailer */ + if(what & 1) ps_draw(4); /* trailer */ zoom_full(0, 0, 1, 0.97); draw(); } diff --git a/src/xschem.h b/src/xschem.h index 71077a0a..0bb7a9ed 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1236,7 +1236,7 @@ extern void store_poly(int pos, double *x, double *y, int points, extern void store_arc(int pos, double x, double y, double r, double a, double b, unsigned int rectcolor, unsigned short sel, char *prop_ptr); -extern void hier_psprint(void); +extern void hier_psprint(char **res, int what); extern void global_spice_netlist(int global); extern void global_tedax_netlist(int global); extern void global_vhdl_netlist(int global); diff --git a/src/xschem.tcl b/src/xschem.tcl index f362783f..4f91b08e 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -1255,6 +1255,15 @@ proc xschem_server {sock addr port} { fileevent $sock readable [list xschem_getdata $sock] } +proc list_hierarchy {} { + set s [xschem list_hierarchy] + set r {} + foreach {a b} [lsort -decreasing -dictionary -index 0 -stride 2 $s] { + append r $a { } $b \n + } + return $r +} + ## given a path (x1.x2.m4) descend into x1.x2 and return m4 whether m4 found or not proc descend_hierarchy {path {redraw 1}} { xschem set no_draw 1 @@ -6005,6 +6014,9 @@ tclcommand=\"xschem raw_read \$netlist_dir/[file tail [file rootname [xschem get xschem set format {} } } + $topwin.menubar.simulation.menu add command -label {Changelog from current hierarchy} -command { + viewdata [list_hierarchy] + } $topwin.menubar.simulation.menu add checkbutton -label "Use 'spiceprefix' attribute" -variable spiceprefix \ -command {xschem save; xschem reload}