fix netlisting errors on schematics with embedded symbols. When purging unused symbols schematic was re-linked with library symbols instead of embedded symbols, leading to errors if the symbols differ. Fixed popping schematic from undo stack instead of calling link_symbols_to_instances()

This commit is contained in:
Stefan Frederik 2021-11-24 03:47:04 +01:00
parent 364c2f1f3a
commit e7aa7b9d04
7 changed files with 48 additions and 28 deletions

View File

@ -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; 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) void pop_undo(int redo, int set_modify_status)
{ {
int slot, i, c; int slot, i, c;
if(xctx->no_undo)return; if(xctx->no_undo)return;
if(redo) { if(redo == 1) {
if(xctx->cur_undo_ptr < xctx->head_undo_ptr) { if(xctx->cur_undo_ptr < xctx->head_undo_ptr) {
xctx->cur_undo_ptr++; xctx->cur_undo_ptr++;
} else { } else {
return; return;
} }
} else { /*redo=0 (undo) */ } else if(redo == 0) { /* undo */
if(xctx->cur_undo_ptr == xctx->tail_undo_ptr) return; if(xctx->cur_undo_ptr == xctx->tail_undo_ptr) return;
if(xctx->head_undo_ptr == xctx->cur_undo_ptr) { if(xctx->head_undo_ptr == xctx->cur_undo_ptr) {
push_undo(); 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 */ if(xctx->cur_undo_ptr<=0) return; /* check undo tail */
xctx->cur_undo_ptr--; 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; slot = xctx->cur_undo_ptr%MAX_UNDO;
clear_drawing(); clear_drawing();
@ -400,8 +411,8 @@ void pop_undo(int redo, int set_modify_status)
xctx->wire[i].node=NULL; xctx->wire[i].node=NULL;
my_strdup(222, &xctx->wire[i].prop_ptr, xctx->uslot[slot].wptr[i].prop_ptr); my_strdup(222, &xctx->wire[i].prop_ptr, xctx->uslot[slot].wptr[i].prop_ptr);
} }
link_symbols_to_instances(-1); link_symbols_to_instances(-1);
if(redo == 2) xctx->cur_undo_ptr++; /* restore undo stack pointer */
if(set_modify_status) set_modify(1); if(set_modify_status) set_modify(1);
xctx->prep_hash_inst=0; xctx->prep_hash_inst=0;
xctx->prep_hash_wires=0; xctx->prep_hash_wires=0;

View File

@ -1232,6 +1232,11 @@ void push_undo(void)
#endif #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) void pop_undo(int redo, int set_modify_status)
{ {
FILE *fd; FILE *fd;
@ -1242,8 +1247,8 @@ void pop_undo(int redo, int set_modify_status)
FILE *diff_fd; FILE *diff_fd;
#endif #endif
if(xctx->no_undo)return; if(xctx->no_undo) return;
if(redo) { if(redo == 1) {
if(xctx->cur_undo_ptr < xctx->head_undo_ptr) { 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", 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); 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 { } else {
return; return;
} }
} else { /*redo=0 (undo) */ } else if(redo == 0) { /* undo */
if(xctx->cur_undo_ptr == xctx->tail_undo_ptr) return; 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", 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); 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 */ if(xctx->cur_undo_ptr<=0) return; /* check undo tail */
xctx->cur_undo_ptr--; 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(); clear_drawing();
unselect_all(); unselect_all();
@ -1308,6 +1316,7 @@ void pop_undo(int redo, int set_modify_status)
} }
#endif #endif
read_xschem_file(fd); read_xschem_file(fd);
if(redo == 2) xctx->cur_undo_ptr++; /* restore undo stack pointer */
#if HAS_POPEN==1 #if HAS_POPEN==1
pclose(fd); /* 20150326 moved before load symbols */ 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_net_structs=0;
xctx->prep_hi_structs=0; xctx->prep_hi_structs=0;
update_conn_cues(0, 0); update_conn_cues(0, 0);
dbg(2, "pop_undo(): returning\n"); dbg(2, "pop_undo(): returning\n");
} }

View File

@ -2410,8 +2410,15 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(argv[1][0] == 'u') { else if(argv[1][0] == 'u') {
if(!strcmp(argv[1],"undo")) if(!strcmp(argv[1],"undo"))
{ {
int redo = 0, set_modify = 1;
cmd_found = 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); Tcl_ResetResult(interp);
} }

View File

@ -43,8 +43,8 @@ void hier_psprint(void) /* netlister driver */
dbg(1,"--> %s\n", skip_dir( xctx->sch[xctx->currsch]) ); dbg(1,"--> %s\n", skip_dir( xctx->sch[xctx->currsch]) );
unselect_all(); unselect_all();
remove_symbols(); /* ensure all unused symbols purged before descending hierarchy */ remove_symbols(); /* ensure all unused symbols purged before descending hierarchy */
link_symbols_to_instances(-1); pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */ /* link_symbols_to_instances(-1); */ /* done in pop_undo() */
my_strdup(1224, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]); my_strdup(1224, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]);
my_strcat(1227, &xctx->sch_path[xctx->currsch+1], "->netlisting"); my_strcat(1227, &xctx->sch_path[xctx->currsch+1], "->netlisting");
xctx->sch_path_hash[xctx->currsch+1] = 0; 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; int saved_hilight_nets = xctx->hilight_nets;
unselect_all(); unselect_all();
remove_symbols(); /* 20161205 ensure all unused symbols purged before descending hierarchy */ remove_symbols(); /* 20161205 ensure all unused symbols purged before descending hierarchy */
link_symbols_to_instances(-1); pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */ /* link_symbols_to_instances(-1); */ /* done in pop_undo() */
my_strdup(469, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]); my_strdup(469, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]);
my_strcat(481, &xctx->sch_path[xctx->currsch+1], "->netlisting"); my_strcat(481, &xctx->sch_path[xctx->currsch+1], "->netlisting");
xctx->sch_path_hash[xctx->currsch+1] = 0; xctx->sch_path_hash[xctx->currsch+1] = 0;

View File

@ -88,8 +88,8 @@ void global_tedax_netlist(int global) /* netlister driver */
int saved_hilight_nets = xctx->hilight_nets; int saved_hilight_nets = xctx->hilight_nets;
unselect_all(); unselect_all();
remove_symbols(); /* 20161205 ensure all unused symbols purged before descending hierarchy */ 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_strdup(482, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]);
my_strcat(485, &xctx->sch_path[xctx->currsch+1], "->netlisting"); my_strcat(485, &xctx->sch_path[xctx->currsch+1], "->netlisting");
xctx->sch_path_hash[xctx->currsch+1] = 0; xctx->sch_path_hash[xctx->currsch+1] = 0;

View File

@ -92,8 +92,8 @@ void global_verilog_netlist(int global) /* netlister driver */
/* flush data structures (remove unused symbols) */ /* flush data structures (remove unused symbols) */
unselect_all(); unselect_all();
remove_symbols(); /* removed 25122002, readded 04112003 */ remove_symbols(); /* removed 25122002, readded 04112003 */
link_symbols_to_instances(-1); pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */
/* load_schematic(1,xctx->sch[xctx->currsch] ,0); */ /* link_symbols_to_instances(-1); */ /* done in pop_undo() */
dbg(1, "global_verilog_netlist(): sch[currsch]=%s\n", xctx->sch[xctx->currsch]); dbg(1, "global_verilog_netlist(): sch[currsch]=%s\n", xctx->sch[xctx->currsch]);
/* print top subckt port directions */ /* print top subckt port directions */
@ -281,10 +281,8 @@ void global_verilog_netlist(int global) /* netlister driver */
int saved_hilight_nets = xctx->hilight_nets; int saved_hilight_nets = xctx->hilight_nets;
unselect_all(); unselect_all();
remove_symbols(); /* 20161205 ensure all unused symbols purged before descending hierarchy */ remove_symbols(); /* 20161205 ensure all unused symbols purged before descending hierarchy */
link_symbols_to_instances(-1); pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */ /* link_symbols_to_instances(-1); */ /* done in pop_undo() */
my_strdup(487, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]); my_strdup(487, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]);
my_strcat(496, &xctx->sch_path[xctx->currsch+1], "->netlisting"); my_strcat(496, &xctx->sch_path[xctx->currsch+1], "->netlisting");
xctx->sch_path_hash[xctx->currsch+1] = 0; xctx->sch_path_hash[xctx->currsch+1] = 0;

View File

@ -113,12 +113,10 @@ void global_vhdl_netlist(int global) /* netlister driver */
/* flush data structures (remove unused symbols) */ /* flush data structures (remove unused symbols) */
unselect_all(); unselect_all();
remove_symbols(); /* removed 25122002, readded 04112003.. this removes unused symbols */ remove_symbols(); /* removed 25122002, readded 04112003.. this removes unused symbols */
link_symbols_to_instances(-1); pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */ /* link_symbols_to_instances(-1); */ /* done in pop_undo() */
/* 20071009 print top level generics if defined in symbol */ /* 20071009 print top level generics if defined in symbol */
str_tmp = add_ext(xctx->sch[xctx->currsch], ".sym"); str_tmp = add_ext(xctx->sch[xctx->currsch], ".sym");
if(!stat(str_tmp, &buf)) { if(!stat(str_tmp, &buf)) {
load_sym_def(str_tmp, NULL ); 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; int saved_hilight_nets = xctx->hilight_nets;
unselect_all(); unselect_all();
remove_symbols(); /* 20161205 ensure all unused symbols purged before descending hierarchy */ remove_symbols(); /* 20161205 ensure all unused symbols purged before descending hierarchy */
link_symbols_to_instances(-1); pop_undo(2, 0); /* reload data without popping undo stack, this populates embedded symbols if any */
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */ /* link_symbols_to_instances(-1); */ /* done in pop_undo() */
my_strdup(502, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]); my_strdup(502, &xctx->sch_path[xctx->currsch+1], xctx->sch_path[xctx->currsch]);
my_strcat(509, &xctx->sch_path[xctx->currsch+1], "->netlisting"); my_strcat(509, &xctx->sch_path[xctx->currsch+1], "->netlisting");
xctx->sch_path_hash[xctx->currsch+1] = 0; xctx->sch_path_hash[xctx->currsch+1] = 0;