diff --git a/src/in_memory_undo.c b/src/in_memory_undo.c index bed8182e..2f291f28 100644 --- a/src/in_memory_undo.c +++ b/src/in_memory_undo.c @@ -286,19 +286,27 @@ void push_undo(void) xctx->tail_undo_ptr = xctx->head_undo_ptr <= MAX_UNDO? 0: xctx->head_undo_ptr-MAX_UNDO; } +/* BUG: in_memory_undo does not save/restore embedded symbols, it just saves references to symbols + * if symbols are not found in library you get a schematic with missing symbols if you remove + * symbols and do an undo (this is done in netlist operations to purge unused syms */ +/* redo: + * 0: undo (with push current state for allowing following redo) + * 1: redo + * 2: read top data from undo stack without changing undo stack + */ void pop_undo(int redo, int set_modify_status) { int slot, i, c; if(xctx->no_undo)return; - if(redo) { + if(redo == 1) { if(xctx->cur_undo_ptr < xctx->head_undo_ptr) { xctx->cur_undo_ptr++; } else { return; } - } else { /*redo=0 (undo) */ + } else if(redo == 0) { /* undo */ if(xctx->cur_undo_ptr == xctx->tail_undo_ptr) return; if(xctx->head_undo_ptr == xctx->cur_undo_ptr) { push_undo(); @@ -307,6 +315,9 @@ void pop_undo(int redo, int set_modify_status) } if(xctx->cur_undo_ptr<=0) return; /* check undo tail */ xctx->cur_undo_ptr--; + } else { /* redo == 2, get data without changing undo stack */ + if(xctx->cur_undo_ptr<=0) return; /* check undo tail */ + xctx->cur_undo_ptr--; /* will be restored after building file name */ } slot = xctx->cur_undo_ptr%MAX_UNDO; clear_drawing(); @@ -400,8 +411,8 @@ void pop_undo(int redo, int set_modify_status) xctx->wire[i].node=NULL; my_strdup(222, &xctx->wire[i].prop_ptr, xctx->uslot[slot].wptr[i].prop_ptr); } - link_symbols_to_instances(-1); + if(redo == 2) xctx->cur_undo_ptr++; /* restore undo stack pointer */ if(set_modify_status) set_modify(1); xctx->prep_hash_inst=0; xctx->prep_hash_wires=0; diff --git a/src/save.c b/src/save.c index cf15ad19..c7e4fad2 100644 --- a/src/save.c +++ b/src/save.c @@ -1232,6 +1232,11 @@ void push_undo(void) #endif } +/* redo: + * 0: undo (with push current state for allowing following redo) + * 1: redo + * 2: read top data from undo stack without changing undo stack + */ void pop_undo(int redo, int set_modify_status) { FILE *fd; @@ -1242,8 +1247,8 @@ void pop_undo(int redo, int set_modify_status) FILE *diff_fd; #endif - if(xctx->no_undo)return; - if(redo) { + if(xctx->no_undo) return; + if(redo == 1) { if(xctx->cur_undo_ptr < xctx->head_undo_ptr) { dbg(1, "pop_undo(): redo; cur_undo_ptr=%d tail_undo_ptr=%d head_undo_ptr=%d\n", xctx->cur_undo_ptr, xctx->tail_undo_ptr, xctx->head_undo_ptr); @@ -1251,7 +1256,7 @@ void pop_undo(int redo, int set_modify_status) } else { return; } - } else { /*redo=0 (undo) */ + } else if(redo == 0) { /* undo */ if(xctx->cur_undo_ptr == xctx->tail_undo_ptr) return; dbg(1, "pop_undo(): undo; cur_undo_ptr=%d tail_undo_ptr=%d head_undo_ptr=%d\n", xctx->cur_undo_ptr, xctx->tail_undo_ptr, xctx->head_undo_ptr); @@ -1262,6 +1267,9 @@ void pop_undo(int redo, int set_modify_status) } if(xctx->cur_undo_ptr<=0) return; /* check undo tail */ xctx->cur_undo_ptr--; + } else { /* redo == 2, get data without changing undo stack */ + if(xctx->cur_undo_ptr<=0) return; /* check undo tail */ + xctx->cur_undo_ptr--; /* will be restored after building file name */ } clear_drawing(); unselect_all(); @@ -1308,6 +1316,7 @@ void pop_undo(int redo, int set_modify_status) } #endif read_xschem_file(fd); + if(redo == 2) xctx->cur_undo_ptr++; /* restore undo stack pointer */ #if HAS_POPEN==1 pclose(fd); /* 20150326 moved before load symbols */ @@ -1325,7 +1334,6 @@ void pop_undo(int redo, int set_modify_status) xctx->prep_net_structs=0; xctx->prep_hi_structs=0; update_conn_cues(0, 0); - dbg(2, "pop_undo(): returning\n"); } diff --git a/src/scheduler.c b/src/scheduler.c index 0636ec51..b00e1c2f 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -2410,8 +2410,15 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else if(argv[1][0] == 'u') { if(!strcmp(argv[1],"undo")) { + int redo = 0, set_modify = 1; cmd_found = 1; - pop_undo(0, 1); /* 2nd param: set_modify_status */ + if(argc > 2) { + redo = atoi(argv[2]); + } + if(argc > 3) { + set_modify = atoi(argv[3]); + } + pop_undo(redo, set_modify); /* 2nd param: set_modify_status */ Tcl_ResetResult(interp); } diff --git a/src/spice_netlist.c b/src/spice_netlist.c index 8d3a9f51..8d74d05e 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -43,8 +43,8 @@ void hier_psprint(void) /* netlister driver */ dbg(1,"--> %s\n", skip_dir( xctx->sch[xctx->currsch]) ); unselect_all(); remove_symbols(); /* ensure all unused symbols purged before descending hierarchy */ - link_symbols_to_instances(-1); - /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ + pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */ + /* link_symbols_to_instances(-1); */ /* done in pop_undo() */ 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; @@ -257,9 +257,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 */ - link_symbols_to_instances(-1); - /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ - + pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */ + /* link_symbols_to_instances(-1); */ /* done in pop_undo() */ my_strdup(469, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]); my_strcat(481, &xctx->sch_path[xctx->currsch+1], "->netlisting"); xctx->sch_path_hash[xctx->currsch+1] = 0; diff --git a/src/tedax_netlist.c b/src/tedax_netlist.c index dc46f47b..fbf32376 100644 --- a/src/tedax_netlist.c +++ b/src/tedax_netlist.c @@ -88,8 +88,8 @@ void global_tedax_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); - + pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */ + /* link_symbols_to_instances(-1); */ /* done in pop_undo() */ my_strdup(482, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]); my_strcat(485, &xctx->sch_path[xctx->currsch+1], "->netlisting"); xctx->sch_path_hash[xctx->currsch+1] = 0; diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index ef0c11e9..7085365d 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -92,8 +92,8 @@ 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); */ + pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */ + /* link_symbols_to_instances(-1); */ /* done in pop_undo() */ dbg(1, "global_verilog_netlist(): sch[currsch]=%s\n", xctx->sch[xctx->currsch]); /* print top subckt port directions */ @@ -281,10 +281,8 @@ 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 */ - link_symbols_to_instances(-1); - /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ - - + pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */ + /* link_symbols_to_instances(-1); */ /* done in pop_undo() */ my_strdup(487, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]); my_strcat(496, &xctx->sch_path[xctx->currsch+1], "->netlisting"); xctx->sch_path_hash[xctx->currsch+1] = 0; diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c index 578a0aca..470bb72f 100644 --- a/src/vhdl_netlist.c +++ b/src/vhdl_netlist.c @@ -113,12 +113,10 @@ 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 */ - link_symbols_to_instances(-1); - /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ - + pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */ + /* link_symbols_to_instances(-1); */ /* done in pop_undo() */ /* 20071009 print top level generics if defined in symbol */ - str_tmp = add_ext(xctx->sch[xctx->currsch], ".sym"); if(!stat(str_tmp, &buf)) { load_sym_def(str_tmp, NULL ); @@ -340,9 +338,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 */ - link_symbols_to_instances(-1); - /* load_schematic(1, xctx->sch[xctx->currsch], 0); */ - + pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */ + /* link_symbols_to_instances(-1); */ /* done in pop_undo() */ my_strdup(502, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]); my_strcat(509, &xctx->sch_path[xctx->currsch+1], "->netlisting"); xctx->sch_path_hash[xctx->currsch+1] = 0;