fix data corruption when netlisting hierarchical symbols with *_stop attribute set, thanks to Joanne Low regression tests, add option in pop_undo() to avoid saving state (push_undo()) for redo.

This commit is contained in:
stefan schippers 2023-04-27 11:52:51 +02:00
parent 52f35e30c2
commit 0bb345f764
5 changed files with 19 additions and 13 deletions

View File

@ -1628,9 +1628,13 @@ static void save_inst(FILE *fd, int select_only)
embedded_saved = my_calloc(_ALLOC_ID_, xctx->symbols, sizeof(int)); embedded_saved = my_calloc(_ALLOC_ID_, xctx->symbols, sizeof(int));
for(i=0;i<xctx->instances; ++i) for(i=0;i<xctx->instances; ++i)
{ {
dbg(1, "save_inst() instance %d, name=%s\n", i, inst[i].name); int ptr = inst[i].ptr;
dbg(1, "save_inst() %s: instance %d, name=%s\n", xctx->current_name, i, inst[i].name);
if(ptr == -1) {
dbg(0, "save_inst(): WARNING: inst %d .ptr = -1 ... current_name=%s\n", i, xctx->current_name);
}
if (select_only && inst[i].sel != SELECTED) continue; if (select_only && inst[i].sel != SELECTED) continue;
xctx->sym[inst[i].ptr].flags &=~EMBEDDED; if(ptr >=0) xctx->sym[ptr].flags &=~EMBEDDED;
fputs("C ", fd); fputs("C ", fd);
if(oldversion) { if(oldversion) {
my_strdup2(_ALLOC_ID_, &tmp, add_ext(inst[i].name, ".sym")); my_strdup2(_ALLOC_ID_, &tmp, add_ext(inst[i].name, ".sym"));
@ -1641,12 +1645,12 @@ static void save_inst(FILE *fd, int select_only)
} }
fprintf(fd, " %.16g %.16g %hd %hd ",inst[i].x0, inst[i].y0, inst[i].rot, inst[i].flip ); fprintf(fd, " %.16g %.16g %hd %hd ",inst[i].x0, inst[i].y0, inst[i].rot, inst[i].flip );
save_ascii_string(inst[i].prop_ptr,fd, 1); save_ascii_string(inst[i].prop_ptr,fd, 1);
if(embedded_saved && !embedded_saved[inst[i].ptr] && inst[i].embed) { if(ptr >= 0 && embedded_saved && !embedded_saved[ptr] && inst[i].embed) {
embedded_saved[inst[i].ptr] = 1; embedded_saved[ptr] = 1;
fprintf(fd, "[\n"); fprintf(fd, "[\n");
save_embedded_symbol( xctx->sym+inst[i].ptr, fd); save_embedded_symbol( xctx->sym+ptr, fd);
fprintf(fd, "]\n"); fprintf(fd, "]\n");
xctx->sym[inst[i].ptr].flags |= EMBEDDED; xctx->sym[ptr].flags |= EMBEDDED;
} }
} }
my_free(_ALLOC_ID_, &embedded_saved); my_free(_ALLOC_ID_, &embedded_saved);
@ -2671,6 +2675,7 @@ void push_undo(void)
/* redo: /* redo:
* 0: undo (with push current state for allowing following redo) * 0: undo (with push current state for allowing following redo)
* 4: undo, do not push state for redo
* 1: redo * 1: redo
* 2: read top data from undo stack without changing undo stack * 2: read top data from undo stack without changing undo stack
*/ */
@ -2694,11 +2699,12 @@ void pop_undo(int redo, int set_modify_status)
} else { } else {
return; return;
} }
} else if(redo == 0) { /* undo */ } else if(redo == 0 || redo == 4) { /* 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);
if(xctx->head_undo_ptr == xctx->cur_undo_ptr) { if(redo == 0 && xctx->head_undo_ptr == xctx->cur_undo_ptr) {
dbg(1, "pop_undo(): doing push_undo, head=%d cur=%d\n", xctx->head_undo_ptr, xctx->cur_undo_ptr);
xctx->push_undo(); xctx->push_undo();
xctx->head_undo_ptr--; xctx->head_undo_ptr--;
xctx->cur_undo_ptr--; xctx->cur_undo_ptr--;

View File

@ -117,7 +117,7 @@ void hier_psprint(char **res, int what) /* netlister driver */
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch])); my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--; xctx->currsch--;
unselect_all(1); unselect_all(1);
xctx->pop_undo(0, 0); xctx->pop_undo(4, 0);
my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name)); my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name));
xctx->do_copy_area = save; xctx->do_copy_area = save;
if(what & 1) ps_draw(4); /* trailer */ if(what & 1) ps_draw(4); /* trailer */
@ -441,7 +441,7 @@ int global_spice_netlist(int global) /* netlister driver */
xctx->currsch--; xctx->currsch--;
unselect_all(1); unselect_all(1);
dbg(1, "global_spice_netlist(): invoking pop_undo(0, 0)\n"); dbg(1, "global_spice_netlist(): invoking pop_undo(0, 0)\n");
xctx->pop_undo(0, 0); xctx->pop_undo(4, 0);
my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name)); my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name));
dbg(1, "spice_netlist(): invoke prepare_netlist_structs for %s\n", xctx->current_name); dbg(1, "spice_netlist(): invoke prepare_netlist_structs for %s\n", xctx->current_name);
err |= prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ err |= prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */

View File

@ -231,7 +231,7 @@ int global_tedax_netlist(int global) /* netlister driver */
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch])); my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--; xctx->currsch--;
unselect_all(1); unselect_all(1);
xctx->pop_undo(0, 0); xctx->pop_undo(4, 0);
my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name)); my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name));
err |= prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ err |= prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */

View File

@ -382,7 +382,7 @@ int global_verilog_netlist(int global) /* netlister driver */
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch])); my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--; xctx->currsch--;
unselect_all(1); unselect_all(1);
xctx->pop_undo(0, 0); xctx->pop_undo(4, 0);
my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name)); my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name));
err |= prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ err |= 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 */ /* symbol vs schematic pin check, we do it here since now we have ALL symbols loaded */

View File

@ -483,7 +483,7 @@ int global_vhdl_netlist(int global) /* netlister driver */
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch])); my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--; xctx->currsch--;
unselect_all(1); unselect_all(1);
xctx->pop_undo(0, 0); xctx->pop_undo(4, 0);
my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name)); my_strncpy(xctx->current_name, rel_sym_path(xctx->sch[xctx->currsch]), S(xctx->current_name));
err |= prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ err |= 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 */ /* symbol vs schematic pin check, we do it here since now we have ALL symbols loaded */