From fddd3f84fb36193ab15f0024b902e05d5e8ce2ea Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Sun, 21 Nov 2021 23:04:48 +0100 Subject: [PATCH] avoid force-saving changed schematic before doing netlist (use push/pop undo instead of load_schematic() to restore circuit after traversing hierarchy) --- src/callback.c | 4 +- src/in_memory_undo.c | 4 +- src/save.c | 20 ++++---- src/scheduler.c | 4 +- src/spice_netlist.c | 80 +++++++++++++---------------- src/tedax_netlist.c | 10 ++-- src/verilog_netlist.c | 21 ++++---- src/vhdl_netlist.c | 17 +++--- src/xschem.h | 2 +- xschem_library/examples/loading.sch | 3 +- 10 files changed, 78 insertions(+), 87 deletions(-) diff --git a/src/callback.c b/src/callback.c index 38add77c..ae2f8951 100644 --- a/src/callback.c +++ b/src/callback.c @@ -1135,14 +1135,14 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key, if(key=='u' && state==0) /* undo */ { if(xctx->semaphore >= 2) break; - pop_undo(0); + pop_undo(0, 1); /* 2nd parameter: set_modify_status */ draw(); break; } if(key=='U' && state==ShiftMask) /* redo */ { if(xctx->semaphore >= 2) break; - pop_undo(1); + pop_undo(1, 1); /* 2nd parameter: set_modify_status */ draw(); break; } diff --git a/src/in_memory_undo.c b/src/in_memory_undo.c index 7f80d6b3..6a4eab94 100644 --- a/src/in_memory_undo.c +++ b/src/in_memory_undo.c @@ -287,7 +287,7 @@ void push_undo(void) } -void pop_undo(int redo) +void pop_undo(int redo, int set_modify_status) { int slot, i, c; @@ -402,7 +402,7 @@ void pop_undo(int redo) } link_symbols_to_instances(-1); - set_modify(1); + if(set_modify_status) set_modify(1); xctx->prep_hash_inst=0; xctx->prep_hash_wires=0; xctx->prep_net_structs=0; diff --git a/src/save.c b/src/save.c index f2b0a08c..29a30adb 100644 --- a/src/save.c +++ b/src/save.c @@ -1076,10 +1076,12 @@ void load_schematic(int load_symbols, const char *filename, int reset_undo) /* 2 dbg(1, "load_schematic(): sch[currsch]=%s\n", xctx->sch[xctx->currsch]); if(!name[0]) return; - if(!stat(name, &buf)) { /* file exists */ - xctx->time_last_modify = buf.st_mtime; - } else { - xctx->time_last_modify = time(NULL); /* file does not exist, set mtime to current time */ + if(reset_undo) { + if(!stat(name, &buf)) { /* file exists */ + xctx->time_last_modify = buf.st_mtime; + } else { + xctx->time_last_modify = time(NULL); /* file does not exist, set mtime to current time */ + } } if( (fd=fopen(name,fopen_read_mode))== NULL) { fprintf(errfp, "load_schematic(): unable to open file: %s, filename=%s\n", @@ -1092,7 +1094,7 @@ void load_schematic(int load_symbols, const char *filename, int reset_undo) /* 2 dbg(1, "load_schematic(): reading file: %s\n", name); read_xschem_file(fd); fclose(fd); /* 20150326 moved before load symbols */ - set_modify(0); + if(reset_undo) set_modify(0); dbg(2, "load_schematic(): loaded file:wire=%d inst=%d\n",xctx->wires , xctx->instances); if(load_symbols) link_symbols_to_instances(-1); if(reset_undo) { @@ -1113,7 +1115,7 @@ void load_schematic(int load_symbols, const char *filename, int reset_undo) /* 2 } dbg(1, "load_schematic(): %s, returning\n", xctx->sch[xctx->currsch]); } else { - xctx->time_last_modify = time(NULL); /* no file given, set mtime to current time */ + if(reset_undo) xctx->time_last_modify = time(NULL); /* no file given, set mtime to current time */ clear_drawing(); for(i=0;;i++) { if(xctx->netlist_type == CAD_SYMBOL_ATTRS) { @@ -1127,7 +1129,7 @@ void load_schematic(int load_symbols, const char *filename, int reset_undo) /* 2 } my_snprintf(xctx->sch[xctx->currsch], S(xctx->sch[xctx->currsch]), "%s/%s", pwd_dir, name); my_strncpy(xctx->current_name, name, S(xctx->current_name)); - set_modify(0); + if(reset_undo) set_modify(0); } if(tclgetboolvar("autotrim_wires")) trim_wires(); update_conn_cues(0, 0); @@ -1228,7 +1230,7 @@ void push_undo(void) #endif } -void pop_undo(int redo) +void pop_undo(int redo, int set_modify_status) { FILE *fd; char diff_name[PATH_MAX+12]; @@ -1315,7 +1317,7 @@ void pop_undo(int redo) #endif dbg(2, "pop_undo(): loaded file:wire=%d inst=%d\n",xctx->wires , xctx->instances); link_symbols_to_instances(-1); - set_modify(1); + if(set_modify_status) set_modify(1); xctx->prep_hash_inst=0; xctx->prep_hash_wires=0; xctx->prep_net_structs=0; diff --git a/src/scheduler.c b/src/scheduler.c index 9a9d82e5..d98db8f5 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -1834,7 +1834,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else if(!strcmp(argv[1],"redo")) { cmd_found = 1; - pop_undo(1); + pop_undo(1, 1); /* 2nd param: set_modify_status */ Tcl_ResetResult(interp); } @@ -2423,7 +2423,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg if(!strcmp(argv[1],"undo")) { cmd_found = 1; - pop_undo(0); + pop_undo(0, 1); /* 2nd param: set_modify_status */ Tcl_ResetResult(interp); } diff --git a/src/spice_netlist.c b/src/spice_netlist.c index 4bf3bedb..9c2c269f 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -28,26 +28,23 @@ static struct hashentry *subckt_table[HASHSIZE]; /* safe even with multiple sche void hier_psprint(void) /* netlister driver */ { - int i, save_ok; + int i; char *subckt_name; - int spice_stop; char filename[PATH_MAX]; char *abs_path = NULL; const char *str_tmp; char *sch = NULL; if(!ps_draw(1)) return; /* prolog */ - if(xctx->modified) { - save_ok = save_schematic(xctx->sch[xctx->currsch]); - if(save_ok == -1) return; - } + push_undo(); free_hash(subckt_table); zoom_full(0, 0, 1, 0.97); ps_draw(2); /* page */ dbg(1,"--> %s\n", skip_dir( xctx->sch[xctx->currsch]) ); unselect_all(); remove_symbols(); /* 20161205 ensure all unused symbols purged before descending hierarchy */ - load_schematic(1, xctx->sch[xctx->currsch], 0); + link_symbols_to_instances(-1); + /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ my_strdup(1224, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]); my_strcat(1227, &xctx->sch_path[xctx->currsch+1], "->netlisting"); xctx->sch_path_hash[xctx->currsch+1] = 0; @@ -55,41 +52,39 @@ void hier_psprint(void) /* netlister driver */ subckt_name=NULL; for(i=0;isymbols;i++) { - if( strcmp(get_tok_value(xctx->sym[i].prop_ptr,"spice_ignore",0),"true")==0 ) continue; - if(!xctx->sym[i].type) continue; - my_strdup(1230, &abs_path, abs_sym_path(xctx->sym[i].name, "")); - if(strcmp(xctx->sym[i].type,"subcircuit")==0 && check_lib(2, abs_path)) - { - /* 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)); - if (str_hash_lookup(subckt_table, subckt_name, "", XLOOKUP)==NULL) - { - str_hash_lookup(subckt_table, subckt_name, "", XINSERT); - if(!strcmp( get_tok_value(xctx->sym[i].prop_ptr,"spice_stop",0),"true") ) - spice_stop=1; - else - spice_stop=0; - if((str_tmp = get_tok_value(xctx->sym[i].prop_ptr, "schematic",0 ))[0]) { - my_strdup2(1252, &sch, str_tmp); - my_strncpy(filename, abs_sym_path(sch, ""), S(filename)); - my_free(1253, &sch); - } else { - my_strncpy(filename, add_ext(abs_sym_path(xctx->sym[i].name, ""), ".sch"), S(filename)); - } - spice_stop ? load_schematic(0,filename, 0) : load_schematic(1,filename, 0); - zoom_full(0, 0, 1, 0.97); - ps_draw(2); /* page */ - dbg(1,"--> %s\n", skip_dir( xctx->sch[xctx->currsch]) ); - } - } - my_free(1231, &abs_path); + if( strcmp(get_tok_value(xctx->sym[i].prop_ptr,"spice_ignore",0),"true")==0 ) continue; + if(!xctx->sym[i].type) continue; + my_strdup(1230, &abs_path, abs_sym_path(xctx->sym[i].name, "")); + if(strcmp(xctx->sym[i].type,"subcircuit")==0 && check_lib(2, abs_path)) + { + /* 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)); + if (str_hash_lookup(subckt_table, subckt_name, "", XLOOKUP)==NULL) + { + str_hash_lookup(subckt_table, subckt_name, "", XINSERT); + if((str_tmp = get_tok_value(xctx->sym[i].prop_ptr, "schematic",0 ))[0]) { + my_strdup2(1252, &sch, str_tmp); + my_strncpy(filename, abs_sym_path(sch, ""), S(filename)); + my_free(1253, &sch); + } else { + my_strncpy(filename, add_ext(abs_sym_path(xctx->sym[i].name, ""), ".sch"), S(filename)); + } + /* 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 */ + dbg(1,"--> %s\n", skip_dir( xctx->sch[xctx->currsch]) ); + } + } + my_free(1231, &abs_path); } free_hash(subckt_table); my_free(1229, &subckt_name); my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch])); xctx->currsch--; unselect_all(); - load_schematic(1, xctx->sch[xctx->currsch], 0); + /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ + pop_undo(0, 0); ps_draw(4); /* trailer */ zoom_full(0, 0, 1, 0.97); draw(); @@ -105,7 +100,7 @@ void global_spice_netlist(int global) /* netlister driver */ const char *str_tmp; int multip; unsigned int *stored_flags; - int i, save_ok; + int i; char *type=NULL; char *place=NULL; char netl_filename[PATH_MAX]; /* overflow safe 20161122 */ @@ -118,12 +113,9 @@ void global_spice_netlist(int global) /* netlister driver */ split_f = tclgetboolvar("split_files"); top_sub = tclgetboolvar("top_subckt"); + push_undo(); xctx->netlist_unconn_cnt=0; /* unique count of unconnected pins while netlisting */ statusmsg("",2); /* clear infowindow */ - if(xctx->modified) { - save_ok = save_schematic(xctx->sch[xctx->currsch]); - if(save_ok == -1) return; - } free_hash(subckt_table); free_hash(model_table); record_global_node(2, NULL, NULL); /* delete list of global nodes */ @@ -272,7 +264,8 @@ void global_spice_netlist(int global) /* netlister driver */ int saved_hilight_nets = xctx->hilight_nets; unselect_all(); remove_symbols(); /* 20161205 ensure all unused symbols purged before descending hierarchy */ - load_schematic(1, xctx->sch[xctx->currsch], 0); + link_symbols_to_instances(-1); + /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ my_strdup(469, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]); my_strcat(481, &xctx->sch_path[xctx->currsch+1], "->netlisting"); @@ -311,7 +304,8 @@ void global_spice_netlist(int global) /* netlister driver */ xctx->currsch--; unselect_all(); /* remove_symbols(); */ - load_schematic(1, xctx->sch[xctx->currsch], 0); + /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ + pop_undo(0, 0); prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ /* symbol vs schematic pin check, we do it here since now we have ALL symbols loaded */ sym_vs_sch_pins(); diff --git a/src/tedax_netlist.c b/src/tedax_netlist.c index b46e5dd8..91e70b9e 100644 --- a/src/tedax_netlist.c +++ b/src/tedax_netlist.c @@ -26,17 +26,14 @@ void global_tedax_netlist(int global) /* netlister driver */ { FILE *fd; const char *str_tmp; - int i, save_ok; + int i; unsigned int *stored_flags; char netl_filename[PATH_MAX]; /* overflow safe 20161122 */ char tcl_cmd_netlist[PATH_MAX + 100]; /* 20081211 overflow safe 20161122 */ char cellname[PATH_MAX]; /* 20081211 overflow safe 20161122 */ char *abs_path = NULL; - if(xctx->modified) { - save_ok = save_schematic(xctx->sch[xctx->currsch]); - if(save_ok == -1) return; - } + push_undo(); statusmsg("",2); /* clear infowindow */ record_global_node(2, NULL, NULL); /* delete list of global nodes */ bus_char[0] = bus_char[1] = '\0'; @@ -115,7 +112,8 @@ void global_tedax_netlist(int global) /* netlister driver */ xctx->currsch--; unselect_all(); /* remove_symbols(); */ - load_schematic(1, xctx->sch[xctx->currsch], 0); + /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ + pop_undo(0, 0); prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ /* symbol vs schematic pin check, we do it here since now we have ALL symbols loaded */ diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index 963d9527..f0cac99a 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -31,7 +31,7 @@ void global_verilog_netlist(int global) /* netlister driver */ char *port_value = NULL; char *tmp_string=NULL; unsigned int *stored_flags; - int i, tmp, save_ok; + int i, tmp; char netl_filename[PATH_MAX]; /* overflow safe 20161122 */ char tcl_cmd_netlist[PATH_MAX + 100]; /* 20081203 overflow safe 20161122 */ char cellname[PATH_MAX]; /* 20081203 overflow safe 20161122 */ @@ -42,12 +42,9 @@ void global_verilog_netlist(int global) /* netlister driver */ int split_f; split_f = tclgetboolvar("split_files"); + push_undo(); xctx->netlist_unconn_cnt=0; /* unique count of unconnected pins while netlisting */ statusmsg("",2); /* clear infowindow */ - if(xctx->modified) { - save_ok = save_schematic(xctx->sch[xctx->currsch]); - if(save_ok == -1) return; - } free_hash(subckt_table); xctx->netlist_count=0; /* top sch properties used for library use declarations and type definitions */ @@ -95,12 +92,10 @@ void global_verilog_netlist(int global) /* netlister driver */ /* flush data structures (remove unused symbols) */ unselect_all(); remove_symbols(); /* removed 25122002, readded 04112003 */ - + link_symbols_to_instances(-1); + /* load_schematic(1,xctx->sch[xctx->currsch] ,0); */ dbg(1, "global_verilog_netlist(): sch[currsch]=%s\n", xctx->sch[xctx->currsch]); - load_schematic(1,xctx->sch[xctx->currsch] ,0); - - /* print top subckt port directions */ dbg(1, "global_verilog_netlist(): printing top level out pins\n"); tmp=0; @@ -286,8 +281,9 @@ void global_verilog_netlist(int global) /* netlister driver */ int saved_hilight_nets = xctx->hilight_nets; unselect_all(); remove_symbols(); /* 20161205 ensure all unused symbols purged before descending hierarchy */ - - load_schematic(1, xctx->sch[xctx->currsch], 0); + link_symbols_to_instances(-1); + /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ + my_strdup(487, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]); my_strcat(496, &xctx->sch_path[xctx->currsch+1], "->netlisting"); @@ -324,7 +320,8 @@ void global_verilog_netlist(int global) /* netlister driver */ xctx->currsch--; unselect_all(); /* remove_symbols(); */ - load_schematic(1,xctx->sch[xctx->currsch], 0); + /* load_schematic(1,xctx->sch[xctx->currsch], 0); */ + pop_undo(0, 0); prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ /* symbol vs schematic pin check, we do it here since now we have ALL symbols loaded */ sym_vs_sch_pins(); diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c index 66fe3149..7fb96881 100644 --- a/src/vhdl_netlist.c +++ b/src/vhdl_netlist.c @@ -31,7 +31,7 @@ void global_vhdl_netlist(int global) /* netlister driver */ char *dir_tmp = NULL; char *sig_type = NULL; char *port_value = NULL; - int i,j, tmp, save_ok; + int i,j, tmp; unsigned int *stored_flags; char netl_filename[PATH_MAX]; /* overflow safe 20161122 */ char tcl_cmd_netlist[PATH_MAX + 100]; /* 20081202 overflow safe 20161122 */ @@ -43,15 +43,12 @@ void global_vhdl_netlist(int global) /* netlister driver */ int split_f; split_f = tclgetboolvar("split_files"); + push_undo(); xctx->netlist_unconn_cnt=0; /* unique count of unconnected pins while netlisting */ statusmsg("",2); /* clear infowindow */ /* top sch properties used for library use declarations and type definitions */ /* to be printed before any entity declarations */ - if(xctx->modified) { - save_ok = save_schematic(xctx->sch[xctx->currsch]); - if(save_ok == -1) return; - } xctx->netlist_count=0; free_hash(subckt_table); my_snprintf(netl_filename, S(netl_filename), "%s/.%s_%d", @@ -116,7 +113,8 @@ void global_vhdl_netlist(int global) /* netlister driver */ /* flush data structures (remove unused symbols) */ unselect_all(); remove_symbols(); /* removed 25122002, readded 04112003.. this removes unused symbols */ - load_schematic(1, xctx->sch[xctx->currsch], 0); + link_symbols_to_instances(-1); + /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ /* 20071009 print top level generics if defined in symbol */ @@ -342,7 +340,8 @@ void global_vhdl_netlist(int global) /* netlister driver */ int saved_hilight_nets = xctx->hilight_nets; unselect_all(); remove_symbols(); /* 20161205 ensure all unused symbols purged before descending hierarchy */ - load_schematic(1, xctx->sch[xctx->currsch], 0); + link_symbols_to_instances(-1); + /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ my_strdup(502, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]); my_strcat(509, &xctx->sch_path[xctx->currsch+1], "->netlisting"); @@ -380,11 +379,11 @@ void global_vhdl_netlist(int global) /* netlister driver */ xctx->currsch--; unselect_all(); /* remove_symbols(); */ - load_schematic(1, xctx->sch[xctx->currsch], 0); + /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ + pop_undo(0, 0); prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ /* symbol vs schematic pin check, we do it here since now we have ALL symbols loaded */ sym_vs_sch_pins(); - if(!xctx->hilight_nets) xctx->hilight_nets = saved_hilight_nets; } /* restore hilight flags from errors found analyzing top level before descending hierarchy */ diff --git a/src/xschem.h b/src/xschem.h index d49ffd7a..ac47ec92 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1044,7 +1044,7 @@ extern int sym_vs_sch_pins(void); extern int match_symbol(const char name[]); extern int save_schematic(const char *); /* 20171020 added return value */ extern void push_undo(void); -extern void pop_undo(int redo); +extern void pop_undo(int redo, int set_modify_status); extern void delete_undo(void); extern void clear_undo(void); extern void load_schematic(int load_symbol, const char *abs_name, int reset_undo); diff --git a/xschem_library/examples/loading.sch b/xschem_library/examples/loading.sch index ae52deba..c558e90e 100644 --- a/xschem_library/examples/loading.sch +++ b/xschem_library/examples/loading.sch @@ -1,5 +1,6 @@ -v {xschem version=2.9.7 file_version=1.2} +v {xschem version=3.0.0 file_version=1.2 } G {} +K {} V {// test} S {* test} E {}