From 0bb345f764f3c098e8a5b631fddb507ec6c67c71 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Thu, 27 Apr 2023 11:52:51 +0200 Subject: [PATCH] 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. --- src/save.c | 22 ++++++++++++++-------- src/spice_netlist.c | 4 ++-- src/tedax_netlist.c | 2 +- src/verilog_netlist.c | 2 +- src/vhdl_netlist.c | 2 +- 5 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/save.c b/src/save.c index b419b1f4..060702db 100644 --- a/src/save.c +++ b/src/save.c @@ -1628,9 +1628,13 @@ static void save_inst(FILE *fd, int select_only) embedded_saved = my_calloc(_ALLOC_ID_, xctx->symbols, sizeof(int)); for(i=0;iinstances; ++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; - xctx->sym[inst[i].ptr].flags &=~EMBEDDED; + if(ptr >=0) xctx->sym[ptr].flags &=~EMBEDDED; fputs("C ", fd); if(oldversion) { 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 ); save_ascii_string(inst[i].prop_ptr,fd, 1); - if(embedded_saved && !embedded_saved[inst[i].ptr] && inst[i].embed) { - embedded_saved[inst[i].ptr] = 1; + if(ptr >= 0 && embedded_saved && !embedded_saved[ptr] && inst[i].embed) { + embedded_saved[ptr] = 1; fprintf(fd, "[\n"); - save_embedded_symbol( xctx->sym+inst[i].ptr, fd); + save_embedded_symbol( xctx->sym+ptr, fd); fprintf(fd, "]\n"); - xctx->sym[inst[i].ptr].flags |= EMBEDDED; + xctx->sym[ptr].flags |= EMBEDDED; } } my_free(_ALLOC_ID_, &embedded_saved); @@ -2671,6 +2675,7 @@ void push_undo(void) /* redo: * 0: undo (with push current state for allowing following redo) + * 4: undo, do not push state for redo * 1: redo * 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 { return; } - } else if(redo == 0) { /* undo */ + } else if(redo == 0 || redo == 4) { /* 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); - 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->head_undo_ptr--; xctx->cur_undo_ptr--; diff --git a/src/spice_netlist.c b/src/spice_netlist.c index 7f89fa44..0fb763c6 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -117,7 +117,7 @@ void hier_psprint(char **res, int what) /* netlister driver */ my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch])); xctx->currsch--; 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)); xctx->do_copy_area = save; if(what & 1) ps_draw(4); /* trailer */ @@ -441,7 +441,7 @@ int global_spice_netlist(int global) /* netlister driver */ xctx->currsch--; unselect_all(1); 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)); 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 */ diff --git a/src/tedax_netlist.c b/src/tedax_netlist.c index c7bad0fc..d60c299f 100644 --- a/src/tedax_netlist.c +++ b/src/tedax_netlist.c @@ -231,7 +231,7 @@ int global_tedax_netlist(int global) /* netlister driver */ my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch])); xctx->currsch--; 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)); err |= prepare_netlist_structs(1); /* so 'lab=...' attributes for unnamed nets are set */ diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index 6c7809f8..7d409fca 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -382,7 +382,7 @@ int global_verilog_netlist(int global) /* netlister driver */ my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch])); xctx->currsch--; 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)); 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 */ diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c index d651d971..2e940c9f 100644 --- a/src/vhdl_netlist.c +++ b/src/vhdl_netlist.c @@ -483,7 +483,7 @@ int global_vhdl_netlist(int global) /* netlister driver */ my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch])); xctx->currsch--; 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)); 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 */