use undo function pointers

This commit is contained in:
Stefan Frederik 2021-11-28 14:35:55 +01:00
parent 88b00fd546
commit 03f973e203
18 changed files with 142 additions and 138 deletions

View File

@ -780,7 +780,7 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
dbg(1, "place_symbol(): load_file_dialog returns: name=%s\n",name);
my_strncpy(name, rel_sym_path(name), S(name));
if(name[0]) {
if(first_call && to_push_undo) push_undo();
if(first_call && to_push_undo) (*xctx->push_undo_ptr)();
} else return 0;
i=match_symbol(name);
@ -1581,7 +1581,7 @@ void new_wire(int what, double mx_snap, double my_snap)
s_pnetname = tclgetboolvar("show_pin_net_names");
if( (what & PLACE) ) {
if( (xctx->ui_state & STARTWIRE) && (xctx->nl_x1!=xctx->nl_x2 || xctx->nl_y1!=xctx->nl_y2) ) {
push_undo();
(*xctx->push_undo_ptr)();
if(xctx->manhattan_lines==1) {
if(xctx->nl_xx2!=xctx->nl_xx1) {
xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1;
@ -1750,7 +1750,7 @@ void change_layer()
double x1,y1,x2,y2, a, b, r;
if(xctx->lastsel) push_undo();
if(xctx->lastsel) (*xctx->push_undo_ptr)();
for(k=0;k<xctx->lastsel;k++)
{
n=xctx->sel_array[k].n;
@ -1810,7 +1810,7 @@ void new_arc(int what, double sweep)
xctx->nl_x3, xctx->nl_y3, &xctx->nl_x, &xctx->nl_y, &xctx->nl_r, &xctx->nl_a, &xctx->nl_b);
if(xctx->nl_sweep_angle==360.) xctx->nl_b=360.;
if(xctx->nl_r>0.) {
push_undo();
(*xctx->push_undo_ptr)();
drawarc(xctx->rectcolor, NOW, xctx->nl_x, xctx->nl_y, xctx->nl_r, xctx->nl_a, xctx->nl_b, 0, 0);
store_arc(-1, xctx->nl_x, xctx->nl_y, xctx->nl_r, xctx->nl_a, xctx->nl_b, xctx->rectcolor, 0, NULL);
}
@ -1845,7 +1845,7 @@ void new_line(int what)
{
if( (xctx->nl_x1!=xctx->nl_x2 || xctx->nl_y1!=xctx->nl_y2) && (xctx->ui_state & STARTLINE) )
{
push_undo();
(*xctx->push_undo_ptr)();
if(xctx->manhattan_lines==1) {
if(xctx->nl_xx2!=xctx->nl_xx1) {
xctx->nl_xx1 = xctx->nl_x1; xctx->nl_yy1 = xctx->nl_y1;
@ -1961,7 +1961,7 @@ void new_rect(int what)
{
int save_draw;
RECTORDER(xctx->nl_x1,xctx->nl_y1,xctx->nl_x2,xctx->nl_y2);
push_undo();
(*xctx->push_undo_ptr)();
drawrect(xctx->rectcolor, NOW, xctx->nl_x1,xctx->nl_y1,xctx->nl_x2,xctx->nl_y2, 0);
save_draw = xctx->draw_window;
xctx->draw_window = 1;
@ -2037,7 +2037,7 @@ void new_polygon(int what)
/* closed poly end by clicking on first point */
((what & ADD) && xctx->nl_polyx[xctx->nl_points-1] == xctx->nl_polyx[0] &&
xctx->nl_polyy[xctx->nl_points-1] == xctx->nl_polyy[0]) ) {
push_undo();
(*xctx->push_undo_ptr)();
drawtemppolygon(xctx->gctiled, NOW, xctx->nl_polyx, xctx->nl_polyy, xctx->nl_points+1);
store_poly(-1, xctx->nl_polyx, xctx->nl_polyy, xctx->nl_points, xctx->rectcolor, 0, NULL);
/* fprintf(errfp, "new_poly: finish: nl_points=%d\n", xctx->nl_points); */
@ -2226,7 +2226,7 @@ int place_text(int draw_text, double mx, double my)
txt = (char *)tclgetvar("retval");
if(!strcmp(txt,"")) return 0; /* dont allocate text object if empty string given */
push_undo();
(*xctx->push_undo_ptr)();
check_text_storage();
t->txt_ptr=NULL;
t->prop_ptr=NULL; /* 20111006 added missing initialization of pointer */

View File

@ -1105,7 +1105,7 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
if(key=='u' && state==Mod1Mask) /* align to grid */
{
if(xctx->semaphore >= 2) break;
push_undo();
(*xctx->push_undo_ptr)();
round_schematic_to_grid(c_snap);
set_modify(1);
if(tclgetboolvar("autotrim_wires")) trim_wires();
@ -1136,21 +1136,21 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
if(key=='u' && state==0) /* undo */
{
if(xctx->semaphore >= 2) break;
pop_undo(0, 1); /* 2nd parameter: set_modify_status */
(*xctx->pop_undo_ptr)(0, 1); /* 2nd parameter: set_modify_status */
draw();
break;
}
if(key=='U' && state==ShiftMask) /* redo */
{
if(xctx->semaphore >= 2) break;
pop_undo(1, 1); /* 2nd parameter: set_modify_status */
(*xctx->pop_undo_ptr)(1, 1); /* 2nd parameter: set_modify_status */
draw();
break;
}
if(key=='&') /* check wire connectivity */
{
if(xctx->semaphore >= 2) break;
push_undo();
(*xctx->push_undo_ptr)();
trim_wires();
draw();
break;

View File

@ -414,7 +414,7 @@ void break_wires_at_pins(void)
{
if( (x0!=xctx->wire[i].x1 && x0!=xctx->wire[i].x2) ||
(y0!=xctx->wire[i].y1 && y0!=xctx->wire[i].y2) ) {
if(!changed) { push_undo(); changed=1;}
if(!changed) { (*xctx->push_undo_ptr)(); changed=1;}
check_wire_storage();
xctx->wire[xctx->wires].x1=xctx->wire[i].x1;
xctx->wire[xctx->wires].y1=xctx->wire[i].y1;
@ -470,7 +470,7 @@ void break_wires_at_pins(void)
if( (x0!=xctx->wire[i].x1 && x0!=xctx->wire[i].x2) ||
(y0!=xctx->wire[i].y1 && y0!=xctx->wire[i].y2) ) {
/* printf("touch in mid point: %d\n", l+1); */
if(!changed) { push_undo(); changed=1;}
if(!changed) { (*xctx->push_undo_ptr)(); changed=1;}
check_wire_storage();
xctx->wire[xctx->wires].x1=xctx->wire[i].x1;
xctx->wire[xctx->wires].y1=xctx->wire[i].y1;

View File

@ -409,7 +409,7 @@ void edit_rect_property(void)
preserve = atoi(tclgetvar("preserve_unchanged_attrs"));
if(strcmp(tclgetvar("rcode"),"") )
{
push_undo();
(*xctx->push_undo_ptr)();
set_modify(1);
for(i=0; i<xctx->lastsel; i++) {
if(xctx->sel_array[i].type != xRECT) continue;
@ -464,7 +464,7 @@ void edit_line_property(void)
if(strcmp(tclgetvar("rcode"),"") )
{
int y1, y2;
push_undo();
(*xctx->push_undo_ptr)();
set_modify(1);
bbox(START, 0.0 , 0.0 , 0.0 , 0.0);
for(i=0; i<xctx->lastsel; i++) {
@ -517,7 +517,7 @@ void edit_wire_property(void)
preserve = atoi(tclgetvar("preserve_unchanged_attrs"));
if(strcmp(tclgetvar("rcode"),"") )
{
push_undo();
(*xctx->push_undo_ptr)();
set_modify(1);
bbox(START, 0.0 , 0.0 , 0.0 , 0.0);
for(i=0; i<xctx->lastsel; i++) {
@ -581,7 +581,7 @@ void edit_arc_property(void)
if(strcmp(tclgetvar("rcode"),"") )
{
set_modify(1); push_undo();
set_modify(1); (*xctx->push_undo_ptr)();
for(ii=0; ii<xctx->lastsel; ii++) {
if(xctx->sel_array[ii].type != ARC) continue;
@ -648,7 +648,7 @@ void edit_polygon_property(void)
if(strcmp(tclgetvar("rcode"),"") )
{
set_modify(1); push_undo();
set_modify(1); (*xctx->push_undo_ptr)();
for(ii=0; ii<xctx->lastsel; ii++) {
if(xctx->sel_array[ii].type != POLYGON) continue;
@ -743,7 +743,7 @@ void edit_text_property(int x)
if(strcmp(tclgetvar("rcode"),"") )
{
dbg(1, "edit_text_property(): rcode !=\"\"\n");
set_modify(1); push_undo();
set_modify(1); (*xctx->push_undo_ptr)();
bbox(START,0.0,0.0,0.0,0.0);
for(k=0;k<xctx->lastsel;k++)
{
@ -986,7 +986,7 @@ void update_symbol(const char *result, int x)
&xctx->inst[*ii].x2, &xctx->inst[*ii].y2);
if(sym_number>=0) /* changing symbol ! */
{
if(!pushed) { push_undo(); pushed=1;}
if(!pushed) { (*xctx->push_undo_ptr)(); pushed=1;}
delete_inst_node(*ii); /* 20180208 fix crashing bug: delete node info if changing symbol */
/* if number of pins is different we must delete these data *before* */
/* changing ysmbol, otherwise *ii might end up deleting non allocated data. */
@ -1004,7 +1004,7 @@ void update_symbol(const char *result, int x)
char * ss=NULL;
my_strdup(119, &ss, xctx->inst[*ii].prop_ptr);
if( set_different_token(&ss, new_prop, xctx->old_prop, 0, 0) ) {
if(!pushed) { push_undo(); pushed=1;}
if(!pushed) { (*xctx->push_undo_ptr)(); pushed=1;}
my_strdup(111, &xctx->inst[*ii].prop_ptr, ss);
set_modify(1);
}
@ -1015,12 +1015,12 @@ void update_symbol(const char *result, int x)
if(!xctx->inst[*ii].prop_ptr || strcmp(xctx->inst[*ii].prop_ptr, new_prop)) {
dbg(1, "update_symbol(): changing prop: |%s| -> |%s|\n",
xctx->inst[*ii].prop_ptr, new_prop);
if(!pushed) { push_undo(); pushed=1;}
if(!pushed) { (*xctx->push_undo_ptr)(); pushed=1;}
my_strdup(84, &xctx->inst[*ii].prop_ptr, new_prop);
set_modify(1);
}
} else {
if(!pushed) { push_undo(); pushed=1;}
if(!pushed) { (*xctx->push_undo_ptr)(); pushed=1;}
my_strdup(86, &xctx->inst[*ii].prop_ptr, "");
set_modify(1);
}
@ -1037,7 +1037,7 @@ void update_symbol(const char *result, int x)
name, xctx->inst[*ii].prop_ptr);
my_strdup(89, &ptr,subst_token(xctx->inst[*ii].prop_ptr, "name", name) );
/* set name of current inst */
if(!pushed) { push_undo(); pushed=1;}
if(!pushed) { (*xctx->push_undo_ptr)(); pushed=1;}
if(!k) hash_all_names(*ii);
new_prop_string(*ii, ptr, k, tclgetboolvar("disable_unique_names")); /* set new prop_ptr */
}
@ -1111,7 +1111,7 @@ void change_elem_order(void)
tcleval("text_line {Object Sequence number} 0");
if(strcmp(tclgetvar("rcode"),"") )
{
push_undo();
(*xctx->push_undo_ptr)();
set_modify(1);
xctx->prep_hash_inst=0;
xctx->prep_net_structs=0;
@ -1208,27 +1208,27 @@ void edit_property(int x)
{
if(xctx->netlist_type==CAD_SYMBOL_ATTRS &&
(!xctx->schsymbolprop || strcmp(xctx->schsymbolprop, tclgetvar("retval") ) ) ) {
set_modify(1); push_undo();
set_modify(1); (*xctx->push_undo_ptr)();
my_strdup(422, &xctx->schsymbolprop, (char *) tclgetvar("retval"));
} else if(xctx->netlist_type==CAD_VERILOG_NETLIST &&
(!xctx->schverilogprop || strcmp(xctx->schverilogprop, tclgetvar("retval") ) ) ) {
set_modify(1); push_undo();
set_modify(1); (*xctx->push_undo_ptr)();
my_strdup(94, &xctx->schverilogprop, (char *) tclgetvar("retval"));
} else if(xctx->netlist_type==CAD_SPICE_NETLIST &&
(!xctx->schprop || strcmp(xctx->schprop, tclgetvar("retval") ) ) ) {
set_modify(1); push_undo();
set_modify(1); (*xctx->push_undo_ptr)();
my_strdup(95, &xctx->schprop, (char *) tclgetvar("retval"));
} else if(xctx->netlist_type==CAD_TEDAX_NETLIST &&
(!xctx->schtedaxprop || strcmp(xctx->schtedaxprop, tclgetvar("retval") ) ) ) {
set_modify(1); push_undo();
set_modify(1); (*xctx->push_undo_ptr)();
my_strdup(96, &xctx->schtedaxprop, (char *) tclgetvar("retval"));
} else if(xctx->netlist_type==CAD_VHDL_NETLIST &&
(!xctx->schvhdlprop || strcmp(xctx->schvhdlprop, tclgetvar("retval") ) ) ) {
set_modify(1); push_undo();
set_modify(1); (*xctx->push_undo_ptr)();
my_strdup(97, &xctx->schvhdlprop, (char *) tclgetvar("retval"));
}
}

View File

@ -22,8 +22,6 @@
#include "xschem.h"
#ifdef IN_MEMORY_UNDO
static void free_undo_lines(int slot)
{
int i, c;
@ -213,10 +211,10 @@ static void init_undo()
}
/* called when program resets undo stack (for example when loading a new file */
void clear_undo(void)
void mem_clear_undo(void)
{
int slot;
dbg(1, "clear_undo(): undo_initialized = %d\n", xctx->undo_initialized);
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;
@ -234,12 +232,12 @@ void clear_undo(void)
}
/* used to delete everything when program exits */
void delete_undo(void)
void mem_delete_undo(void)
{
int slot;
dbg(1, "delete_undo(): undo_initialized = %d\n", xctx->undo_initialized);
dbg(1, "mem_delete_undo(): undo_initialized = %d\n", xctx->undo_initialized);
if(!xctx->undo_initialized) return;
clear_undo();
(*xctx->clear_undo_ptr)();
for(slot = 0;slot<MAX_UNDO; slot++) {
my_free(804, &xctx->uslot[slot].lines);
my_free(805, &xctx->uslot[slot].rects);
@ -253,7 +251,7 @@ void delete_undo(void)
xctx->undo_initialized = 0;
}
void push_undo(void)
void mem_push_undo(void)
{
int slot, i, c;
xSymbol *sym;
@ -457,7 +455,7 @@ void push_undo(void)
* 1: redo
* 2: read top data from undo stack without changing undo stack
*/
void pop_undo(int redo, int set_modify_status)
void mem_pop_undo(int redo, int set_modify_status)
{
int slot, i, c;
xSymbol *sym;
@ -473,7 +471,7 @@ void pop_undo(int redo, int set_modify_status)
} 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();
(*xctx->push_undo_ptr)();
xctx->head_undo_ptr--;
xctx->cur_undo_ptr--;
}
@ -692,5 +690,3 @@ void pop_undo(int redo, int set_modify_status)
xctx->prep_hi_structs = 0;
update_conn_cues(0, 0);
}
#endif

View File

@ -27,10 +27,8 @@
#include <locale.h>
void sig_handler(int s){
#ifndef IN_MEMORY_UNDO
char emergency_prefix[PATH_MAX];
const char *emergency_dir;
#endif
if(s==SIGINT) {
@ -38,20 +36,23 @@ void sig_handler(int s){
return;
}
#ifndef IN_MEMORY_UNDO
/* 20180923 no more mkdtemp */
my_snprintf(emergency_prefix, S(emergency_prefix), "xschem_emergencysave_%s_",
skip_dir(xctx->sch[xctx->currsch]));
if( !(emergency_dir = create_tmpdir(emergency_prefix)) ) {
fprintf(errfp, "xinit(): problems creating emergency save dir\n");
tcleval("exit");
if(xctx->undo_type == 0 ) { /* on disk undo */
my_snprintf(emergency_prefix, S(emergency_prefix), "xschem_emergencysave_%s_",
skip_dir(xctx->sch[xctx->currsch]));
if( !(emergency_dir = create_tmpdir(emergency_prefix)) ) {
fprintf(errfp, "xinit(): problems creating emergency save dir\n");
tcleval("exit");
}
if(rename(xctx->undo_dirname, emergency_dir)) {
fprintf(errfp, "rename dir %s to %s failed\n", xctx->undo_dirname, emergency_dir);
}
fprintf(errfp, "EMERGENCY SAVE DIR: %s\n", emergency_dir);
}
if(rename(xctx->undo_dirname, emergency_dir)) {
fprintf(errfp, "rename dir %s to %s failed\n", xctx->undo_dirname, emergency_dir);
}
fprintf(errfp, "EMERGENCY SAVE DIR: %s\n", emergency_dir);
#endif
fprintf(errfp, "\nFATAL: signal %d\n", s);
fprintf(errfp, "while editing: %s\n", skip_dir(xctx->sch[xctx->currsch]));
exit(EXIT_FAILURE);

View File

@ -582,7 +582,7 @@ void copy_objects(int what)
int l, firstw, firsti;
bbox(START, 0.0 , 0.0 , 0.0 , 0.0);
newpropcnt=0;
set_modify(1); push_undo(); /* 20150327 push_undo */
set_modify(1); (*xctx->push_undo_ptr)(); /* 20150327 push_undo */
firstw = firsti = 1;
@ -1053,7 +1053,7 @@ void move_objects(int what, int merge, double dx, double dy)
set_modify(1);
if( !(xctx->ui_state & (STARTMERGE | PLACE_SYMBOL | PLACE_TEXT)) ) { /* no undo push for MERGE ad PLACE, already done before */
dbg(1, "move_objects(): push undo state\n");
push_undo();
(*xctx->push_undo_ptr)();
}
xctx->ui_state &= ~PLACE_SYMBOL;
xctx->ui_state &= ~PLACE_TEXT;

View File

@ -319,7 +319,7 @@ void merge_file(int selection_load, const char ext[])
xctx->prep_hash_inst=0;
xctx->prep_hash_wires=0;
got_mouse = 0;
push_undo();
(*xctx->push_undo_ptr)();
unselect_all();
old=xctx->instances;
while(!endfile)

View File

@ -1066,7 +1066,7 @@ void load_schematic(int load_symbols, const char *filename, int reset_undo) /* 2
xctx->prep_net_structs=0;
xctx->prep_hash_inst=0;
xctx->prep_hash_wires=0;
if(reset_undo) clear_undo();
if(reset_undo) (*xctx->clear_undo_ptr)();
if(reset_undo) xctx->prev_set_modify = -1; /* will force set_modify(0) to set window title */
else xctx->prev_set_modify = 0; /* will prevent set_modify(0) from setting window title */
if(filename && filename[0]) {
@ -1139,8 +1139,6 @@ void load_schematic(int load_symbols, const char *filename, int reset_undo) /* 2
update_conn_cues(0, 0);
}
#ifndef IN_MEMORY_UNDO
void delete_undo(void)
{
int i;
@ -1177,10 +1175,11 @@ void push_undo(void)
#if HAS_POPEN==1
my_snprintf(diff_name, S(diff_name), "gzip --fast -c > %s/undo%d", xctx->undo_dirname, xctx->cur_undo_ptr%MAX_UNDO);
my_snprintf(diff_name, S(diff_name), "gzip --fast -c > %s/undo%d",
xctx->undo_dirname, xctx->cur_undo_ptr%MAX_UNDO);
fd = popen(diff_name,"w");
if(!fd) {
fprintf(errfp, "push_undo(): failed to open write pipe %s\n", diff_name);
fprintf(errfp, "(*xctx->push_undo_ptr)(): failed to open write pipe %s\n", diff_name);
xctx->no_undo=1;
return;
}
@ -1206,7 +1205,7 @@ void push_undo(void)
#endif
execlp("gzip", "gzip", "--fast", "-c", NULL); /* replace current process with comand */
/* never gets here */
fprintf(errfp, "push_undo(): problems with execlp\n");
fprintf(errfp, "(*xctx->push_undo_ptr)(): problems with execlp\n");
Tcl_Eval(interp, "exit");
}
close(pd[0]); /* close read side of pipe */
@ -1215,7 +1214,7 @@ void push_undo(void)
my_snprintf(diff_name, S(diff_name), "%s/undo%d", xctx->undo_dirname, xctx->cur_undo_ptr%MAX_UNDO);
fd = fopen(diff_name,"w");
if(!fd) {
fprintf(errfp, "push_undo(): failed to open undo file %s\n", diff_name);
fprintf(errfp, "(*xctx->push_undo_ptr)(): failed to open undo file %s\n", diff_name);
xctx->no_undo=1;
return;
}
@ -1263,7 +1262,7 @@ void pop_undo(int redo, int set_modify_status)
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) {
push_undo();
(*xctx->push_undo_ptr)();
xctx->head_undo_ptr--;
xctx->cur_undo_ptr--;
}
@ -1280,7 +1279,7 @@ void pop_undo(int redo, int set_modify_status)
my_snprintf(diff_name, S(diff_name), "gzip -d -c %s/undo%d", xctx->undo_dirname, xctx->cur_undo_ptr%MAX_UNDO);
fd=popen(diff_name, "r");
if(!fd) {
fprintf(errfp, "pop_undo(): failed to open read pipe %s\n", diff_name);
fprintf(errfp, "(*xctx->pop_undo_ptr)(): failed to open read pipe %s\n", diff_name);
xctx->no_undo=1;
return;
}
@ -1312,7 +1311,7 @@ void pop_undo(int redo, int set_modify_status)
my_snprintf(diff_name, S(diff_name), "%s/undo%d", xctx->undo_dirname, xctx->cur_undo_ptr%MAX_UNDO);
fd=fopen(diff_name, "r");
if(!fd) {
fprintf(errfp, "pop_undo(): failed to open read pipe %s\n", diff_name);
fprintf(errfp, "(*xctx->pop_undo_ptr)(): failed to open read pipe %s\n", diff_name);
xctx->no_undo=1;
return;
}
@ -1339,8 +1338,6 @@ void pop_undo(int redo, int set_modify_status)
dbg(2, "pop_undo(): returning\n");
}
#endif /* ifndef IN_MEMORY_UNDO */
/* given a 'symname' component instantiation in a LCC schematic instance
* get the type attribute from symbol global properties.
* first look in already loaded symbols else inspect symbol file
@ -1348,7 +1345,8 @@ void pop_undo(int redo, int set_modify_status)
* return symbol type in type pointer or "" if no type or no symbol found
* if pintable given (!=NULL) hash all symbol pins
* if embed_fd is not NULL read symbol from embedded '[...]' tags using embed_fd file pointer */
void get_sym_type(const char *symname, char **type, struct int_hashentry **pintable, FILE *embed_fd, int *sym_num_pins)
static void get_sym_type(const char *symname, char **type,
struct int_hashentry **pintable, FILE *embed_fd, int *sym_n_pins)
{
int i, c, n = 0;
char name[PATH_MAX];
@ -1371,7 +1369,7 @@ void get_sym_type(const char *symname, char **type, struct int_hashentry **pinta
}
/* hash pins to get LCC schematic have same order as corresponding symbol */
if(found && pintable) {
*sym_num_pins = xctx->sym[i].rects[PINLAYER];
*sym_n_pins = xctx->sym[i].rects[PINLAYER];
for (c = 0; c < xctx->sym[i].rects[PINLAYER]; c++) {
int_hash_lookup(pintable, get_tok_value(xctx->sym[i].rect[PINLAYER][c].prop_ptr, "name", 0), c, XINSERT);
}
@ -1421,7 +1419,7 @@ void get_sym_type(const char *symname, char **type, struct int_hashentry **pinta
/* hash pins to get LCC schematic have same order as corresponding symbol */
int_hash_lookup(pintable, get_tok_value(box.prop_ptr, "name", 0), n++, XINSERT);
dbg(1, "get_sym_type() : hashing %s\n", get_tok_value(box.prop_ptr, "name", 0));
++(*sym_num_pins);
++(*sym_n_pins);
}
break;
default:
@ -1442,28 +1440,28 @@ void get_sym_type(const char *symname, char **type, struct int_hashentry **pinta
/* given a .sch file used as instance in LCC schematics, order its pin
* as in corresponding .sym file if it exists */
void align_sch_pins_with_sym(const char *name, int pos)
static void align_sch_pins_with_sym(const char *name, int pos)
{
char *ptr;
char symname[PATH_MAX];
char *symtype = NULL;
const char *pinname;
int i, fail = 0, sym_num_pins=0;
int i, fail = 0, sym_n_pins=0;
struct int_hashentry *pintable[HASHSIZE];
if ((ptr = strrchr(name, '.')) && !strcmp(ptr, ".sch")) {
my_strncpy(symname, add_ext(name, ".sym"), S(symname));
for(i = 0; i < HASHSIZE; i++) pintable[i] = NULL;
/* hash all symbol pins with their position into pintable hash*/
get_sym_type(symname, &symtype, pintable, NULL, &sym_num_pins);
get_sym_type(symname, &symtype, pintable, NULL, &sym_n_pins);
if(symtype[0]) { /* found a .sym for current .sch LCC instance */
xRect *box = NULL;
if (sym_num_pins!=xctx->sym[pos].rects[PINLAYER]) {
if (sym_n_pins!=xctx->sym[pos].rects[PINLAYER]) {
dbg(0, " align_sch_pins_with_sym(): warning: number of pins mismatch between %s and %s\n",
name, symname);
fail = 1;
}
box = (xRect *) my_malloc(1168, sizeof(xRect) * sym_num_pins);
box = (xRect *) my_malloc(1168, sizeof(xRect) * sym_n_pins);
dbg(1, "align_sch_pins_with_sym(): symbol: %s\n", symname);
for(i=0; i < xctx->sym[pos].rects[PINLAYER]; i++) {
struct int_hashentry *entry;
@ -1492,7 +1490,8 @@ void align_sch_pins_with_sym(const char *name, int pos)
}
/* replace i/o/iopin instances of LCC schematics with symbol pins (boxes on PINLAYER layer) */
void add_pinlayer_boxes(int *lastr, xRect **bb, const char *symtype, char *prop_ptr, double i_x0, double i_y0)
static void add_pinlayer_boxes(int *lastr, xRect **bb,
const char *symtype, char *prop_ptr, double i_x0, double i_y0)
{
int i, save;
const char *label;
@ -1525,7 +1524,7 @@ void add_pinlayer_boxes(int *lastr, xRect **bb, const char *symtype, char *prop_
lastr[PINLAYER]++;
}
void use_lcc_pins(int level, char *symtype, char (*filename)[PATH_MAX])
static void use_lcc_pins(int level, char *symtype, char (*filename)[PATH_MAX])
{
if(level == 0) {
if (!strcmp(symtype, "ipin")) {
@ -1659,7 +1658,7 @@ int load_sym_def(const char *name, FILE *embed_fd)
char *skip_line;
const char *dash;
xSymbol * symbol;
int symbols, sym_num_pins=0;
int symbols, sym_n_pins=0;
check_symbol_storage();
symbol = xctx->sym;
@ -2037,7 +2036,7 @@ int load_sym_def(const char *name, FILE *embed_fd)
/* get symbol type by looking into list of loaded symbols or (if not found) by
* opening/closing the symbol file and getting the 'type' attribute from global symbol attributes
* if fd_tmp set read symbol from embedded tags '[...]' */
get_sym_type(symname, &symtype, NULL, fd_tmp, &sym_num_pins);
get_sym_type(symname, &symtype, NULL, fd_tmp, &sym_n_pins);
xfseek(lcc[level].fd, filepos, SEEK_SET); /* rewind file pointer */
}
@ -2204,7 +2203,7 @@ void make_schematic_symbol_from_sel(void)
tcleval("tk_messageBox -type ok -message {Cannot overwrite current schematic}");
}
else if (strlen(filename)) {
if (xctx->lastsel) push_undo();
if (xctx->lastsel) (*xctx->push_undo_ptr)();
make_schematic(filename);
delete(0/*to_push_undo*/);
place_symbol(-1, filename, 0, 0, 0, 0, NULL, 4, 1, 0/*to_push_undo*/);

View File

@ -104,7 +104,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1],"align"))
{
cmd_found = 1;
push_undo();
(*xctx->push_undo_ptr)();
round_schematic_to_grid(tclgetdoublevar("cadsnap"));
if(tclgetvar("autotrim_wires")) trim_wires();
set_modify(1);
@ -1788,7 +1788,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1],"push_undo"))
{
cmd_found = 1;
push_undo();
(*xctx->push_undo_ptr)();
Tcl_ResetResult(interp);
}
}
@ -1829,7 +1829,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1],"redo"))
{
cmd_found = 1;
pop_undo(1, 1); /* 2nd param: set_modify_status */
(*xctx->pop_undo_ptr)(1, 1); /* 2nd param: set_modify_status */
Tcl_ResetResult(interp);
}
@ -1898,7 +1898,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
bbox(START,0.0,0.0,0.0,0.0);
my_strncpy(symbol, argv[3], S(symbol));
push_undo();
(*xctx->push_undo_ptr)();
set_modify(1);
if(!fast) {
xctx->prep_hash_inst=0;
@ -2280,7 +2280,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
bbox(START,0.0,0.0,0.0,0.0);
symbol_bbox(inst, &xctx->inst[inst].x1, &xctx->inst[inst].y1, &xctx->inst[inst].x2, &xctx->inst[inst].y2);
bbox(ADD, xctx->inst[inst].x1, xctx->inst[inst].y1, xctx->inst[inst].x2, xctx->inst[inst].y2);
push_undo();
(*xctx->push_undo_ptr)();
}
set_modify(1);
xctx->prep_hash_inst=0;
@ -2400,7 +2400,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
else if(!strcmp(argv[1],"trim_wires"))
{
cmd_found = 1;
push_undo();
(*xctx->push_undo_ptr)();
trim_wires();
draw();
Tcl_ResetResult(interp);
@ -2418,7 +2418,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
if(argc > 3) {
set_modify = atoi(argv[3]);
}
pop_undo(redo, set_modify); /* 2nd param: set_modify_status */
(*xctx->pop_undo_ptr)(redo, set_modify); /* 2nd param: set_modify_status */
Tcl_ResetResult(interp);
}
@ -2495,7 +2495,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
if(argc >= 7) pos=atol(argv[6]);
if(argc == 8) prop = argv[7];
else prop = NULL;
push_undo();
(*xctx->push_undo_ptr)();
storeobject(pos, x1,y1,x2,y2,WIRE,0,0,prop);
xctx->prep_hi_structs=0;
xctx->prep_net_structs=0;

View File

@ -328,7 +328,7 @@ void delete(int to_push_undo)
j = 0;
bbox(START, 0.0 , 0.0 , 0.0 , 0.0);
rebuild_selected_array();
if(to_push_undo && xctx->lastsel) push_undo();
if(to_push_undo && xctx->lastsel) (*xctx->push_undo_ptr)();
/* first calculate bbox, because symbol_bbox() needs translate (@#0:net_name) which
* needs prepare_netlist_structs which needs a consistent xctx->inst[] data structure */

View File

@ -36,15 +36,16 @@ void hier_psprint(void) /* netlister driver */
char *sch = NULL;
if(!ps_draw(1)) return; /* prolog */
push_undo();
(*xctx->push_undo_ptr)();
str_hash_free(subckt_table);
zoom_full(0, 0, 1, 0.97);
ps_draw(2); /* page */
dbg(1,"--> %s\n", skip_dir( xctx->sch[xctx->currsch]) );
unselect_all();
remove_symbols(); /* ensure all unused symbols purged before descending hierarchy */
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() */
/* reload data without popping undo stack, this populates embedded symbols if any */
(*xctx->pop_undo_ptr)(2, 0);
/* link_symbols_to_instances(-1); */ /* done in (*xctx->pop_undo_ptr)() */
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;
@ -84,7 +85,7 @@ void hier_psprint(void) /* netlister driver */
xctx->currsch--;
unselect_all();
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */
pop_undo(0, 0);
(*xctx->pop_undo_ptr)(0, 0);
ps_draw(4); /* trailer */
zoom_full(0, 0, 1, 0.97);
draw();
@ -110,7 +111,7 @@ void global_spice_netlist(int global) /* netlister driver */
split_f = tclgetboolvar("split_files");
top_sub = tclgetboolvar("top_subckt");
push_undo();
(*xctx->push_undo_ptr)();
xctx->netlist_unconn_cnt=0; /* unique count of unconnected pins while netlisting */
statusmsg("",2); /* clear infowindow */
str_hash_free(subckt_table);
@ -257,8 +258,9 @@ 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 */
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() */
/* reload data without popping undo stack, this populates embedded symbols if any */
(*xctx->pop_undo_ptr)(2, 0);
/* link_symbols_to_instances(-1); */ /* done in (*xctx->pop_undo_ptr)() */
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;
@ -297,7 +299,7 @@ void global_spice_netlist(int global) /* netlister driver */
unselect_all();
/* remove_symbols(); */
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */
pop_undo(0, 0);
(*xctx->pop_undo_ptr)(0, 0);
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 */
sym_vs_sch_pins();

View File

@ -33,7 +33,7 @@ void global_tedax_netlist(int global) /* netlister driver */
char cellname[PATH_MAX]; /* 20081211 overflow safe 20161122 */
char *abs_path = NULL;
push_undo();
(*xctx->push_undo_ptr)();
statusmsg("",2); /* clear infowindow */
record_global_node(2, NULL, NULL); /* delete list of global nodes */
bus_char[0] = bus_char[1] = '\0';
@ -88,8 +88,9 @@ 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 */
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() */
/* reload data without popping undo stack, this populates embedded symbols if any */
(*xctx->pop_undo_ptr)(2, 0);
/* link_symbols_to_instances(-1); */ /* done in (*xctx->pop_undo_ptr)() */
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;
@ -113,7 +114,7 @@ void global_tedax_netlist(int global) /* netlister driver */
unselect_all();
/* remove_symbols(); */
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */
pop_undo(0, 0);
(*xctx->pop_undo_ptr)(0, 0);
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 */

View File

@ -210,7 +210,7 @@ void check_unique_names(int rename)
if(rename == 1) {
if(first) {
bbox(START,0.0,0.0,0.0,0.0);
set_modify(1); push_undo();
set_modify(1); (*xctx->push_undo_ptr)();
xctx->prep_hash_inst=0;
xctx->prep_net_structs=0;
xctx->prep_hi_structs=0;

View File

@ -42,7 +42,7 @@ void global_verilog_netlist(int global) /* netlister driver */
int split_f;
split_f = tclgetboolvar("split_files");
push_undo();
(*xctx->push_undo_ptr)();
xctx->netlist_unconn_cnt=0; /* unique count of unconnected pins while netlisting */
statusmsg("",2); /* clear infowindow */
str_hash_free(subckt_table);
@ -92,8 +92,9 @@ void global_verilog_netlist(int global) /* netlister driver */
/* flush data structures (remove unused symbols) */
unselect_all();
remove_symbols(); /* removed 25122002, readded 04112003 */
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() */
/* reload data without popping undo stack, this populates embedded symbols if any */
(*xctx->pop_undo_ptr)(2, 0);
/* link_symbols_to_instances(-1); */ /* done in (*xctx->pop_undo_ptr)() */
dbg(1, "global_verilog_netlist(): sch[currsch]=%s\n", xctx->sch[xctx->currsch]);
/* print top subckt port directions */
@ -281,8 +282,9 @@ 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 */
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() */
/* reload data without popping undo stack, this populates embedded symbols if any */
(*xctx->pop_undo_ptr)(2, 0);
/* link_symbols_to_instances(-1); */ /* done in (*xctx->pop_undo_ptr)() */
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;
@ -319,7 +321,7 @@ void global_verilog_netlist(int global) /* netlister driver */
unselect_all();
/* remove_symbols(); */
/* load_schematic(1,xctx->sch[xctx->currsch], 0); */
pop_undo(0, 0);
(*xctx->pop_undo_ptr)(0, 0);
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 */
sym_vs_sch_pins();

View File

@ -43,7 +43,7 @@ void global_vhdl_netlist(int global) /* netlister driver */
int split_f;
split_f = tclgetboolvar("split_files");
push_undo();
(*xctx->push_undo_ptr)();
xctx->netlist_unconn_cnt=0; /* unique count of unconnected pins while netlisting */
statusmsg("",2); /* clear infowindow */
/* top sch properties used for library use declarations and type definitions */
@ -113,8 +113,9 @@ 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 */
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() */
/* reload data without popping undo stack, this populates embedded symbols if any */
(*xctx->pop_undo_ptr)(2, 0);
/* link_symbols_to_instances(-1); */ /* done in (*xctx->pop_undo_ptr)() */
/* 20071009 print top level generics if defined in symbol */
str_tmp = add_ext(xctx->sch[xctx->currsch], ".sym");
@ -338,8 +339,9 @@ 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 */
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() */
/* reload data without popping undo stack, this populates embedded symbols if any */
(*xctx->pop_undo_ptr)(2, 0);
/* link_symbols_to_instances(-1); */ /* done in (*xctx->pop_undo_ptr)() */
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;
@ -377,7 +379,7 @@ void global_vhdl_netlist(int global) /* netlister driver */
unselect_all();
/* remove_symbols(); */
/* load_schematic(1, xctx->sch[xctx->currsch], 0); */
pop_undo(0, 0);
(*xctx->pop_undo_ptr)(0, 0);
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 */
sym_vs_sch_pins();

View File

@ -321,7 +321,7 @@ void init_pixdata()/* populate xctx->fill_type array that is used in create_gc()
void free_xschem_data()
{
int i;
delete_undo();
(*xctx->delete_undo_ptr)();
free_simdata();
my_free(1098, &xctx->wire);
my_free(1100, &xctx->text);
@ -402,15 +402,21 @@ void alloc_xschem_data(const char *top_path)
xctx->head_undo_ptr = 0;
xctx->tail_undo_ptr = 0;
xctx->undo_dirname = NULL;
#ifndef IN_MEMORY_UNDO
/* 20150327 create undo directory */
/* 20180923 no more mkdtemp (portability issues) */
if( !my_strdup(644, &xctx->undo_dirname, create_tmpdir("xschem_undo_") )) {
fprintf(errfp, "xinit(): problems creating tmp undo dir\n");
tcleval("exit");
xctx->undo_type = 0; /* 0: on disk, 1: in memory */
xctx->push_undo_ptr = &push_undo;
xctx->pop_undo_ptr = &pop_undo;
xctx->delete_undo_ptr = &delete_undo;
xctx->clear_undo_ptr = &clear_undo;
xctx->undo_initialized = 0; /* in_memory_undo */
if(xctx->undo_type == 0) {
/* create undo directory */
if( !my_strdup(644, &xctx->undo_dirname, create_tmpdir("xschem_undo_") )) {
fprintf(errfp, "xinit(): problems creating tmp undo dir\n");
tcleval("exit");
}
dbg(1, "undo_dirname=%s\n", xctx->undo_dirname);
}
dbg(1, "undo_dirname=%s\n", xctx->undo_dirname);
#endif
xctx->zoom=CADINITIALZOOM;
xctx->mooz=1/CADINITIALZOOM;
xctx->xorigin=CADINITIALX;
@ -582,15 +588,7 @@ void alloc_xschem_data(const char *top_path)
xctx->fill_type=my_calloc(640, cadlayers, sizeof(int));
xctx->fill_pattern = 1;
xctx->draw_window = 0;
#ifdef IN_MEMORY_UNDO
xctx->undo_initialized = 0; /* in_memory_undo */
#endif
xctx->time_last_modify = 0;
xctx->push_undo_ptr = &push_undo;
xctx->pop_undo_ptr = &pop_undo;
xctx->delete_undo_ptr = &delete_undo;
xctx->clear_undo_ptr = &clear_undo;
}
void delete_schematic_data(void)

View File

@ -677,11 +677,9 @@ typedef struct {
char *old_prop;
int edit_sym_i;
int netlist_commands;
#ifdef IN_MEMORY_UNDO
/* in_memory_undo */
Undo_slot uslot[MAX_UNDO];
int undo_initialized;
#endif
/* */
int nl_sel, nl_sem;
XSegment *biggridpoint;
@ -713,6 +711,7 @@ typedef struct {
int fill_pattern;
int draw_window;
time_t time_last_modify;
int undo_type; /* 0: on disk, 1: in memory */
void (*push_undo_ptr)(void);
void (*pop_undo_ptr)(int, int);
void (*delete_undo_ptr)(void);
@ -1061,6 +1060,10 @@ extern void push_undo(void);
extern void pop_undo(int redo, int set_modify_status);
extern void delete_undo(void);
extern void clear_undo(void);
extern void mem_push_undo(void);
extern void mem_pop_undo(int redo, int set_modify_status);
extern void mem_delete_undo(void);
extern void mem_clear_undo(void);
extern void load_schematic(int load_symbol, const char *abs_name, int reset_undo);
extern void link_symbols_to_instances(int from);
extern void load_ascii_string(char **ptr, FILE *fd);