/* File: in_memory_undo.c * * This file is part of XSCHEM, * a schematic capture and Spice/Vhdl/Verilog netlisting tool for circuit * simulation. * Copyright (C) 1998-2023 Stefan Frederik Schippers * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "xschem.h" static void free_undo_lines(int slot) { int i, c; for(c = 0;cuslot[slot].lines[c]; ++i) { my_free(_ALLOC_ID_, &xctx->uslot[slot].lptr[c][i].prop_ptr); } my_free(_ALLOC_ID_, &xctx->uslot[slot].lptr[c]); xctx->uslot[slot].lines[c] = 0; } } static void free_undo_rects(int slot) { int i, c; for(c = 0;cuslot[slot].rects[c]; ++i) { my_free(_ALLOC_ID_, &xctx->uslot[slot].bptr[c][i].prop_ptr); } my_free(_ALLOC_ID_, &xctx->uslot[slot].bptr[c]); xctx->uslot[slot].rects[c] = 0; } } static void free_undo_polygons(int slot) { int i, c; for(c = 0;cuslot[slot].polygons[c]; ++i) { my_free(_ALLOC_ID_, &xctx->uslot[slot].pptr[c][i].prop_ptr); my_free(_ALLOC_ID_, &xctx->uslot[slot].pptr[c][i].x); my_free(_ALLOC_ID_, &xctx->uslot[slot].pptr[c][i].y); my_free(_ALLOC_ID_, &xctx->uslot[slot].pptr[c][i].selected_point); } my_free(_ALLOC_ID_, &xctx->uslot[slot].pptr[c]); xctx->uslot[slot].polygons[c] = 0; } } static void free_undo_arcs(int slot) { int i, c; for(c = 0;cuslot[slot].arcs[c]; ++i) { my_free(_ALLOC_ID_, &xctx->uslot[slot].aptr[c][i].prop_ptr); } my_free(_ALLOC_ID_, &xctx->uslot[slot].aptr[c]); xctx->uslot[slot].arcs[c] = 0; } } static void free_undo_wires(int slot) { int i; for(i = 0;iuslot[slot].wires; ++i) { my_free(_ALLOC_ID_, &xctx->uslot[slot].wptr[i].prop_ptr); } my_free(_ALLOC_ID_, &xctx->uslot[slot].wptr); xctx->uslot[slot].wires = 0; } static void free_undo_texts(int slot) { int i; for(i = 0;iuslot[slot].texts; ++i) { my_free(_ALLOC_ID_, &xctx->uslot[slot].tptr[i].prop_ptr); my_free(_ALLOC_ID_, &xctx->uslot[slot].tptr[i].txt_ptr); my_free(_ALLOC_ID_, &xctx->uslot[slot].tptr[i].font); my_free(_ALLOC_ID_, &xctx->uslot[slot].tptr[i].floater_instname); my_free(_ALLOC_ID_, &xctx->uslot[slot].tptr[i].floater_ptr); } my_free(_ALLOC_ID_, &xctx->uslot[slot].tptr); xctx->uslot[slot].texts = 0; } static void free_undo_instances(int slot) { int i; for(i = 0;iuslot[slot].instances; ++i) { my_free(_ALLOC_ID_, &xctx->uslot[slot].iptr[i].name); my_free(_ALLOC_ID_, &xctx->uslot[slot].iptr[i].prop_ptr); my_free(_ALLOC_ID_, &xctx->uslot[slot].iptr[i].instname); my_free(_ALLOC_ID_, &xctx->uslot[slot].iptr[i].lab); } my_free(_ALLOC_ID_, &xctx->uslot[slot].iptr); xctx->uslot[slot].instances = 0; } static void free_undo_symbols(int slot) { int i, j, c, symbols; xSymbol *sym; symbols = xctx->uslot[slot].symbols; for(i = 0;i < symbols; ++i) { sym = &xctx->uslot[slot].symptr[i]; my_free(_ALLOC_ID_, &sym->name); my_free(_ALLOC_ID_, &sym->prop_ptr); my_free(_ALLOC_ID_, &sym->type); my_free(_ALLOC_ID_, &sym->templ); for(c = 0;cpolygons[c]; ++j) { if(sym->poly[c][j].prop_ptr != NULL) { my_free(_ALLOC_ID_, &sym->poly[c][j].prop_ptr); } my_free(_ALLOC_ID_, &sym->poly[c][j].x); my_free(_ALLOC_ID_, &sym->poly[c][j].y); my_free(_ALLOC_ID_, &sym->poly[c][j].selected_point); } my_free(_ALLOC_ID_, &sym->poly[c]); sym->polygons[c] = 0; for(j = 0;jlines[c]; ++j) { if(sym->line[c][j].prop_ptr != NULL) { my_free(_ALLOC_ID_, &sym->line[c][j].prop_ptr); } } my_free(_ALLOC_ID_, &sym->line[c]); sym->lines[c] = 0; for(j = 0;jarcs[c]; ++j) { if(sym->arc[c][j].prop_ptr != NULL) { my_free(_ALLOC_ID_, &sym->arc[c][j].prop_ptr); } } my_free(_ALLOC_ID_, &sym->arc[c]); sym->arcs[c] = 0; for(j = 0;jrects[c]; ++j) { if(sym->rect[c][j].prop_ptr != NULL) { my_free(_ALLOC_ID_, &sym->rect[c][j].prop_ptr); } } my_free(_ALLOC_ID_, &sym->rect[c]); sym->rects[c] = 0; } for(j = 0;jtexts; ++j) { if(sym->text[j].prop_ptr != NULL) { my_free(_ALLOC_ID_, &sym->text[j].prop_ptr); } if(sym->text[j].txt_ptr != NULL) { my_free(_ALLOC_ID_, &sym->text[j].txt_ptr); } if(sym->text[j].font != NULL) { my_free(_ALLOC_ID_, &sym->text[j].font); } if(sym->text[j].floater_instname != NULL) { my_free(_ALLOC_ID_, &sym->text[j].floater_instname); } if(sym->text[j].floater_ptr != NULL) { my_free(_ALLOC_ID_, &sym->text[j].floater_ptr); } } my_free(_ALLOC_ID_, &sym->text); sym->texts = 0; my_free(_ALLOC_ID_, &sym->line); my_free(_ALLOC_ID_, &sym->rect); my_free(_ALLOC_ID_, &sym->poly); my_free(_ALLOC_ID_, &sym->arc); my_free(_ALLOC_ID_, &sym->lines); my_free(_ALLOC_ID_, &sym->rects); my_free(_ALLOC_ID_, &sym->polygons); my_free(_ALLOC_ID_, &sym->arcs); } my_free(_ALLOC_ID_, &xctx->uslot[slot].symptr); xctx->uslot[slot].symbols = 0; } static void mem_init_undo(void) { int slot; dbg(1, "mem_init_undo(): undo_initialized = %d\n", xctx->undo_initialized); if(!xctx->undo_initialized) { for(slot = 0;slotuslot[slot].lines = my_calloc(_ALLOC_ID_, cadlayers, sizeof(int)); xctx->uslot[slot].rects = my_calloc(_ALLOC_ID_, cadlayers, sizeof(int)); xctx->uslot[slot].arcs = my_calloc(_ALLOC_ID_, cadlayers, sizeof(int)); xctx->uslot[slot].polygons = my_calloc(_ALLOC_ID_, cadlayers, sizeof(int)); xctx->uslot[slot].lptr = my_calloc(_ALLOC_ID_, cadlayers, sizeof(xLine *)); xctx->uslot[slot].bptr = my_calloc(_ALLOC_ID_, cadlayers, sizeof(xRect *)); xctx->uslot[slot].aptr = my_calloc(_ALLOC_ID_, cadlayers, sizeof(xArc *)); xctx->uslot[slot].pptr = my_calloc(_ALLOC_ID_, cadlayers, sizeof(xPoly *)); } xctx->undo_initialized = 1; } } /* called when program resets undo stack (for example when loading a new file */ void mem_clear_undo(void) { int slot; dbg(1, "mem_clear_undo(): undo_initialized = %d\n", xctx->undo_initialized); xctx->cur_undo_ptr = 0; xctx->tail_undo_ptr = 0; xctx->head_undo_ptr = 0; if(!xctx->undo_initialized) return; for(slot = 0; slotundo_initialized); if(!xctx->undo_initialized) return; mem_clear_undo(); for(slot = 0;slotuslot[slot].lines); my_free(_ALLOC_ID_, &xctx->uslot[slot].rects); my_free(_ALLOC_ID_, &xctx->uslot[slot].arcs); my_free(_ALLOC_ID_, &xctx->uslot[slot].polygons); my_free(_ALLOC_ID_, &xctx->uslot[slot].lptr); my_free(_ALLOC_ID_, &xctx->uslot[slot].bptr); my_free(_ALLOC_ID_, &xctx->uslot[slot].aptr); my_free(_ALLOC_ID_, &xctx->uslot[slot].pptr); } xctx->undo_initialized = 0; } void mem_push_undo(void) { int slot, i, c; if(xctx->no_undo)return; mem_init_undo(); slot = xctx->cur_undo_ptr%MAX_UNDO; my_strdup(_ALLOC_ID_, &xctx->uslot[slot].gptr, xctx->schvhdlprop); my_strdup(_ALLOC_ID_, &xctx->uslot[slot].vptr, xctx->schverilogprop); my_strdup(_ALLOC_ID_, &xctx->uslot[slot].sptr, xctx->schprop); my_strdup(_ALLOC_ID_, &xctx->uslot[slot].kptr, xctx->schsymbolprop); my_strdup(_ALLOC_ID_, &xctx->uslot[slot].eptr, xctx->schtedaxprop); free_undo_lines(slot); free_undo_rects(slot); free_undo_polygons(slot); free_undo_arcs(slot); free_undo_wires(slot); free_undo_texts(slot); free_undo_instances(slot); free_undo_symbols(slot); memcpy(xctx->uslot[slot].lines, xctx->lines, sizeof(xctx->lines[0]) * cadlayers); memcpy(xctx->uslot[slot].rects, xctx->rects, sizeof(xctx->rects[0]) * cadlayers); memcpy(xctx->uslot[slot].arcs, xctx->arcs, sizeof(xctx->arcs[0]) * cadlayers); memcpy(xctx->uslot[slot].polygons, xctx->polygons, sizeof(xctx->polygons[0]) * cadlayers); for(c = 0;cuslot[slot].lptr[c] = my_calloc(_ALLOC_ID_, xctx->lines[c], sizeof(xLine)); xctx->uslot[slot].bptr[c] = my_calloc(_ALLOC_ID_, xctx->rects[c], sizeof(xRect)); xctx->uslot[slot].pptr[c] = my_calloc(_ALLOC_ID_, xctx->polygons[c], sizeof(xPoly)); xctx->uslot[slot].aptr[c] = my_calloc(_ALLOC_ID_, xctx->arcs[c], sizeof(xArc)); } xctx->uslot[slot].wptr = my_calloc(_ALLOC_ID_, xctx->wires, sizeof(xWire)); xctx->uslot[slot].tptr = my_calloc(_ALLOC_ID_, xctx->texts, sizeof(xText)); xctx->uslot[slot].iptr = my_calloc(_ALLOC_ID_, xctx->instances, sizeof(xInstance)); xctx->uslot[slot].symptr = my_calloc(_ALLOC_ID_, xctx->symbols, sizeof(xSymbol)); xctx->uslot[slot].texts = xctx->texts; xctx->uslot[slot].instances = xctx->instances; xctx->uslot[slot].symbols = xctx->symbols; xctx->uslot[slot].wires = xctx->wires; for(c = 0;clines[c]; ++i) { xctx->uslot[slot].lptr[c][i] = xctx->line[c][i]; xctx->uslot[slot].lptr[c][i].prop_ptr = NULL; my_strdup(_ALLOC_ID_, &xctx->uslot[slot].lptr[c][i].prop_ptr, xctx->line[c][i].prop_ptr); } /* rects */ for(i = 0;irects[c]; ++i) { xctx->uslot[slot].bptr[c][i] = xctx->rect[c][i]; xctx->uslot[slot].bptr[c][i].prop_ptr = NULL; xctx->uslot[slot].bptr[c][i].extraptr = NULL; my_strdup(_ALLOC_ID_, &xctx->uslot[slot].bptr[c][i].prop_ptr, xctx->rect[c][i].prop_ptr); } /* arcs */ for(i = 0;iarcs[c]; ++i) { xctx->uslot[slot].aptr[c][i] = xctx->arc[c][i]; xctx->uslot[slot].aptr[c][i].prop_ptr = NULL; my_strdup(_ALLOC_ID_, &xctx->uslot[slot].aptr[c][i].prop_ptr, xctx->arc[c][i].prop_ptr); } /*polygons */ for(i = 0;ipolygons[c]; ++i) { int points = xctx->poly[c][i].points; xctx->uslot[slot].pptr[c][i] = xctx->poly[c][i]; xctx->uslot[slot].pptr[c][i].prop_ptr = NULL; xctx->uslot[slot].pptr[c][i].x = my_malloc(_ALLOC_ID_, points * sizeof(double)); xctx->uslot[slot].pptr[c][i].y = my_malloc(_ALLOC_ID_, points * sizeof(double)); xctx->uslot[slot].pptr[c][i].selected_point = my_malloc(_ALLOC_ID_, points * sizeof(unsigned short)); memcpy(xctx->uslot[slot].pptr[c][i].x, xctx->poly[c][i].x, points * sizeof(double)); memcpy(xctx->uslot[slot].pptr[c][i].y, xctx->poly[c][i].y, points * sizeof(double)); memcpy(xctx->uslot[slot].pptr[c][i].selected_point, xctx->poly[c][i].selected_point, points * sizeof(unsigned short)); my_strdup(_ALLOC_ID_, &xctx->uslot[slot].pptr[c][i].prop_ptr, xctx->poly[c][i].prop_ptr); } } /* instances */ for(i = 0;iinstances; ++i) { xctx->uslot[slot].iptr[i] = xctx->inst[i]; xctx->uslot[slot].iptr[i].prop_ptr = NULL; xctx->uslot[slot].iptr[i].name = NULL; xctx->uslot[slot].iptr[i].instname = NULL; xctx->uslot[slot].iptr[i].lab = NULL; xctx->uslot[slot].iptr[i].node = NULL; my_strdup(_ALLOC_ID_, &xctx->uslot[slot].iptr[i].lab, xctx->inst[i].lab); my_strdup2(_ALLOC_ID_, &xctx->uslot[slot].iptr[i].instname, xctx->inst[i].instname); my_strdup(_ALLOC_ID_, &xctx->uslot[slot].iptr[i].prop_ptr, xctx->inst[i].prop_ptr); my_strdup2(_ALLOC_ID_, &xctx->uslot[slot].iptr[i].name, xctx->inst[i].name); } /* symbols */ for(i = 0;isymbols; ++i) { copy_symbol(&xctx->uslot[slot].symptr[i], &xctx->sym[i]); } /* texts */ for(i = 0;itexts; ++i) { xctx->uslot[slot].tptr[i] = xctx->text[i]; xctx->uslot[slot].tptr[i].prop_ptr = NULL; xctx->uslot[slot].tptr[i].txt_ptr = NULL; xctx->uslot[slot].tptr[i].font = NULL; xctx->uslot[slot].tptr[i].floater_instname = NULL; xctx->uslot[slot].tptr[i].floater_ptr = NULL; my_strdup(_ALLOC_ID_, &xctx->uslot[slot].tptr[i].prop_ptr, xctx->text[i].prop_ptr); my_strdup(_ALLOC_ID_, &xctx->uslot[slot].tptr[i].txt_ptr, xctx->text[i].txt_ptr); my_strdup(_ALLOC_ID_, &xctx->uslot[slot].tptr[i].font, xctx->text[i].font); my_strdup2(_ALLOC_ID_, &xctx->uslot[slot].tptr[i].floater_instname, xctx->text[i].floater_instname); my_strdup(_ALLOC_ID_, &xctx->uslot[slot].tptr[i].floater_ptr, xctx->text[i].floater_ptr); } /* wires */ for(i = 0;iwires; ++i) { xctx->uslot[slot].wptr[i] = xctx->wire[i]; xctx->uslot[slot].wptr[i].prop_ptr = NULL; xctx->uslot[slot].wptr[i].node = NULL; my_strdup(_ALLOC_ID_, &xctx->uslot[slot].wptr[i].prop_ptr, xctx->wire[i].prop_ptr); } xctx->cur_undo_ptr++; xctx->head_undo_ptr = xctx->cur_undo_ptr; xctx->tail_undo_ptr = xctx->head_undo_ptr <= MAX_UNDO? 0: xctx->head_undo_ptr-MAX_UNDO; } /* 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 mem_pop_undo(int redo, int set_modify_status) { int slot, i, c; if(xctx->no_undo)return; if(redo == 1) { if(xctx->cur_undo_ptr < xctx->head_undo_ptr) { xctx->cur_undo_ptr++; } else { return; } } else if(redo == 0) { /* undo */ if(xctx->cur_undo_ptr == xctx->tail_undo_ptr) return; if(xctx->head_undo_ptr == xctx->cur_undo_ptr) { xctx->push_undo(); xctx->head_undo_ptr--; xctx->cur_undo_ptr--; } 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 at end */ } slot = xctx->cur_undo_ptr%MAX_UNDO; clear_drawing(); unselect_all(1); my_free(_ALLOC_ID_, &xctx->wire); my_free(_ALLOC_ID_, &xctx->text); my_free(_ALLOC_ID_, &xctx->inst); for(i = 0;irect[i]); my_free(_ALLOC_ID_, &xctx->line[i]); my_free(_ALLOC_ID_, &xctx->poly[i]); my_free(_ALLOC_ID_, &xctx->arc[i]); } remove_symbols(); for(i = 0;imaxs; ++i) { my_free(_ALLOC_ID_, &xctx->sym[i].line); my_free(_ALLOC_ID_, &xctx->sym[i].rect); my_free(_ALLOC_ID_, &xctx->sym[i].arc); my_free(_ALLOC_ID_, &xctx->sym[i].poly); my_free(_ALLOC_ID_, &xctx->sym[i].lines); my_free(_ALLOC_ID_, &xctx->sym[i].polygons); my_free(_ALLOC_ID_, &xctx->sym[i].arcs); my_free(_ALLOC_ID_, &xctx->sym[i].rects); } my_free(_ALLOC_ID_, &xctx->sym); my_strdup(_ALLOC_ID_, &xctx->schvhdlprop, xctx->uslot[slot].gptr); my_strdup(_ALLOC_ID_, &xctx->schverilogprop, xctx->uslot[slot].vptr); my_strdup(_ALLOC_ID_, &xctx->schprop, xctx->uslot[slot].sptr); my_strdup(_ALLOC_ID_, &xctx->schsymbolprop, xctx->uslot[slot].kptr); my_strdup(_ALLOC_ID_, &xctx->schtedaxprop, xctx->uslot[slot].eptr); for(c = 0;cmaxl[c] = xctx->lines[c] = xctx->uslot[slot].lines[c]; xctx->line[c] = my_calloc(_ALLOC_ID_, xctx->lines[c], sizeof(xLine)); for(i = 0;ilines[c]; ++i) { xctx->line[c][i] = xctx->uslot[slot].lptr[c][i]; xctx->line[c][i].prop_ptr = NULL; my_strdup(_ALLOC_ID_, &xctx->line[c][i].prop_ptr, xctx->uslot[slot].lptr[c][i].prop_ptr); } /* rects */ xctx->maxr[c] = xctx->rects[c] = xctx->uslot[slot].rects[c]; xctx->rect[c] = my_calloc(_ALLOC_ID_, xctx->rects[c], sizeof(xRect)); for(i = 0;irects[c]; ++i) { xctx->rect[c][i] = xctx->uslot[slot].bptr[c][i]; xctx->rect[c][i].prop_ptr = NULL; xctx->rect[c][i].extraptr = NULL; my_strdup(_ALLOC_ID_, &xctx->rect[c][i].prop_ptr, xctx->uslot[slot].bptr[c][i].prop_ptr); } /* arcs */ xctx->maxa[c] = xctx->arcs[c] = xctx->uslot[slot].arcs[c]; xctx->arc[c] = my_calloc(_ALLOC_ID_, xctx->arcs[c], sizeof(xArc)); for(i = 0;iarcs[c]; ++i) { xctx->arc[c][i] = xctx->uslot[slot].aptr[c][i]; xctx->arc[c][i].prop_ptr = NULL; my_strdup(_ALLOC_ID_, &xctx->arc[c][i].prop_ptr, xctx->uslot[slot].aptr[c][i].prop_ptr); } /* polygons */ xctx->maxp[c] = xctx->polygons[c] = xctx->uslot[slot].polygons[c]; xctx->poly[c] = my_calloc(_ALLOC_ID_, xctx->polygons[c], sizeof(xPoly)); for(i = 0;ipolygons[c]; ++i) { int points = xctx->uslot[slot].pptr[c][i].points; xctx->poly[c][i] = xctx->uslot[slot].pptr[c][i]; xctx->poly[c][i].prop_ptr = NULL; my_strdup(_ALLOC_ID_, &xctx->poly[c][i].prop_ptr, xctx->uslot[slot].pptr[c][i].prop_ptr); xctx->poly[c][i].x = my_malloc(_ALLOC_ID_, points * sizeof(double)); xctx->poly[c][i].y = my_malloc(_ALLOC_ID_, points * sizeof(double)); xctx->poly[c][i].selected_point = my_malloc(_ALLOC_ID_, points * sizeof(unsigned short)); memcpy(xctx->poly[c][i].x, xctx->uslot[slot].pptr[c][i].x, points * sizeof(double)); memcpy(xctx->poly[c][i].y, xctx->uslot[slot].pptr[c][i].y, points * sizeof(double)); memcpy(xctx->poly[c][i].selected_point, xctx->uslot[slot].pptr[c][i].selected_point, points * sizeof(unsigned short)); } } /* instances */ xctx->maxi = xctx->instances = xctx->uslot[slot].instances; xctx->inst = my_calloc(_ALLOC_ID_, xctx->instances, sizeof(xInstance)); for(i = 0;iinstances; ++i) { xctx->inst[i] = xctx->uslot[slot].iptr[i]; xctx->inst[i].prop_ptr = NULL; xctx->inst[i].name = NULL; xctx->inst[i].instname = NULL; xctx->inst[i].lab = NULL; my_strdup(_ALLOC_ID_, &xctx->inst[i].prop_ptr, xctx->uslot[slot].iptr[i].prop_ptr); my_strdup2(_ALLOC_ID_, &xctx->inst[i].name, xctx->uslot[slot].iptr[i].name); my_strdup2(_ALLOC_ID_, &xctx->inst[i].instname, xctx->uslot[slot].iptr[i].instname); my_strdup(_ALLOC_ID_, &xctx->inst[i].lab, xctx->uslot[slot].iptr[i].lab); } /* symbols */ xctx->maxs = xctx->symbols = xctx->uslot[slot].symbols; xctx->sym = my_calloc(_ALLOC_ID_, xctx->symbols, sizeof(xSymbol)); for(i = 0;isymbols; ++i) { copy_symbol(&xctx->sym[i], &xctx->uslot[slot].symptr[i]); } /* texts */ xctx->maxt = xctx->texts = xctx->uslot[slot].texts; xctx->text = my_calloc(_ALLOC_ID_, xctx->texts, sizeof(xText)); for(i = 0;itexts; ++i) { xctx->text[i] = xctx->uslot[slot].tptr[i]; xctx->text[i].txt_ptr = NULL; xctx->text[i].font = NULL; xctx->text[i].floater_instname = NULL; xctx->text[i].floater_ptr = NULL; xctx->text[i].prop_ptr = NULL; my_strdup(_ALLOC_ID_, &xctx->text[i].prop_ptr, xctx->uslot[slot].tptr[i].prop_ptr); my_strdup(_ALLOC_ID_, &xctx->text[i].txt_ptr, xctx->uslot[slot].tptr[i].txt_ptr); my_strdup(_ALLOC_ID_, &xctx->text[i].font, xctx->uslot[slot].tptr[i].font); my_strdup2(_ALLOC_ID_, &xctx->text[i].floater_instname, xctx->uslot[slot].tptr[i].floater_instname); my_strdup(_ALLOC_ID_, &xctx->text[i].floater_ptr, xctx->uslot[slot].tptr[i].floater_ptr); } /* wires */ xctx->maxw = xctx->wires = xctx->uslot[slot].wires; xctx->wire = my_calloc(_ALLOC_ID_, xctx->wires, sizeof(xWire)); for(i = 0;iwires; ++i) { xctx->wire[i] = xctx->uslot[slot].wptr[i]; xctx->wire[i].prop_ptr = NULL; xctx->wire[i].node = NULL; my_strdup(_ALLOC_ID_, &xctx->wire[i].prop_ptr, xctx->uslot[slot].wptr[i].prop_ptr); } /* unnecessary since in_memory_undo saves all symbols */ /* 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; xctx->prep_net_structs = 0; xctx->prep_hi_structs = 0; update_conn_cues(WIRELAYER, 0, 0); int_hash_free(&xctx->floater_inst_table); }