From 76ef66475748699166d1d5f18a60be7743418bee Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Fri, 4 Dec 2020 00:30:13 +0100 Subject: [PATCH] undo data structures into xctx context --- src/globals.c | 6 +---- src/in_memory_undo.c | 32 ++++++++++++------------ src/main.c | 4 +-- src/save.c | 58 ++++++++++++++++++++++---------------------- src/xinit.c | 31 +++++++++++++---------- src/xschem.h | 9 ++++--- src/xschem.tcl | 10 ++++++++ 7 files changed, 81 insertions(+), 69 deletions(-) diff --git a/src/globals.c b/src/globals.c index f4f1e48d..c6f85b5f 100644 --- a/src/globals.c +++ b/src/globals.c @@ -123,7 +123,7 @@ char *netlist_dir=NULL; /* user set netlist directory via cmd-option or menu or int top_subckt = 0; int spiceprefix = 1; int unzoom_nodrift=1; -int change_lw=0; /* allow change xctx->lw */ +int change_lw=0; /* allow change lw */ int incr_hilight=1; unsigned short enable_stretch=0; int auto_hilight=0; @@ -193,10 +193,6 @@ int text_svg=1; /* use svg element for text instead of xschem's internal double cadhalfdotsize = CADHALFDOTSIZE; unsigned int color_index[256]; /* layer color lookup table */ unsigned int rectcolor ; /* this is the currently used layer */ -char *undo_dirname = NULL; -int cur_undo_ptr=0; -int tail_undo_ptr=0; -int head_undo_ptr=0; int max_undo=MAX_UNDO; int draw_dots=1; int draw_single_layer=-1; diff --git a/src/in_memory_undo.c b/src/in_memory_undo.c index 843efddc..c7e8a079 100644 --- a/src/in_memory_undo.c +++ b/src/in_memory_undo.c @@ -160,9 +160,9 @@ void free_instances(int slot) void clear_undo(void) { int slot; - cur_undo_ptr = 0; - tail_undo_ptr = 0; - head_undo_ptr = 0; + xctx->cur_undo_ptr = 0; + xctx->tail_undo_ptr = 0; + xctx->head_undo_ptr = 0; if(!initialized) return; for(slot=0; slotcur_undo_ptr%max_undo; my_strdup(173, &uslot[slot].gptr, xctx->schvhdlprop); my_strdup(174, &uslot[slot].vptr, xctx->schverilogprop); @@ -303,9 +303,9 @@ void push_undo(void) } - cur_undo_ptr++; - head_undo_ptr = cur_undo_ptr; - tail_undo_ptr = head_undo_ptr <= max_undo? 0: head_undo_ptr-max_undo; + 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; } @@ -315,22 +315,22 @@ void pop_undo(int redo) if(no_undo)return; if(redo) { - if(cur_undo_ptr < head_undo_ptr) { - cur_undo_ptr++; + if(xctx->cur_undo_ptr < xctx->head_undo_ptr) { + xctx->cur_undo_ptr++; } else { return; } } else { /*redo=0 (undo) */ - if(cur_undo_ptr == tail_undo_ptr) return; - if(head_undo_ptr == cur_undo_ptr) { + if(xctx->cur_undo_ptr == xctx->tail_undo_ptr) return; + if(xctx->head_undo_ptr == xctx->cur_undo_ptr) { push_undo(); - head_undo_ptr--; - cur_undo_ptr--; + xctx->head_undo_ptr--; + xctx->cur_undo_ptr--; } - if(cur_undo_ptr<=0) return; /* check undo tail */ - cur_undo_ptr--; + if(xctx->cur_undo_ptr<=0) return; /* check undo tail */ + xctx->cur_undo_ptr--; } - slot = cur_undo_ptr%max_undo; + slot = xctx->cur_undo_ptr%max_undo; clear_drawing(); unselect_all(); my_strdup(198, &xctx->schvhdlprop, uslot[slot].gptr); diff --git a/src/main.c b/src/main.c index fe8c30ab..b16b3c7f 100644 --- a/src/main.c +++ b/src/main.c @@ -48,8 +48,8 @@ void sig_handler(int s){ tcleval("exit"); } - if(rename(undo_dirname, emergency_dir)) { - fprintf(errfp, "rename dir %s to %s failed\n", undo_dirname, 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 diff --git a/src/save.c b/src/save.c index c8a0413b..af619a9e 100644 --- a/src/save.c +++ b/src/save.c @@ -1053,18 +1053,18 @@ void delete_undo(void) char diff_name[PATH_MAX]; /* overflow safe 20161122 */ for(i=0; iundo_dirname, i); xunlink(diff_name); } - rmdir(undo_dirname); - my_free(895, &undo_dirname); + rmdir(xctx->undo_dirname); + my_free(895, &xctx->undo_dirname); } void clear_undo(void) { - cur_undo_ptr = 0; - tail_undo_ptr = 0; - head_undo_ptr = 0; + xctx->cur_undo_ptr = 0; + xctx->tail_undo_ptr = 0; + xctx->head_undo_ptr = 0; } void push_undo(void) @@ -1078,12 +1078,12 @@ void push_undo(void) char diff_name[PATH_MAX+100]; /* overflow safe 20161122 */ if(no_undo)return; - dbg(1, "push_undo(): cur_undo_ptr=%d tail_undo_ptr=%d head_undo_ptr=%d\n", - cur_undo_ptr, tail_undo_ptr, head_undo_ptr); + dbg(1, "push_undo(): xctx->cur_undo_ptr=%d xctx->tail_undo_ptr=%d xctx->head_undo_ptr=%d\n", + xctx->cur_undo_ptr, xctx->tail_undo_ptr, xctx->head_undo_ptr); #if HAS_POPEN==1 - my_snprintf(diff_name, S(diff_name), "gzip --fast -c > %s/undo%d", undo_dirname, 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); @@ -1091,7 +1091,7 @@ void push_undo(void) return; } #elif HAS_PIPE==1 - my_snprintf(diff_name, S(diff_name), "%s/undo%d", undo_dirname, cur_undo_ptr%max_undo); + my_snprintf(diff_name, S(diff_name), "%s/undo%d", xctx->undo_dirname, xctx->cur_undo_ptr%max_undo); pipe(pd); if((pid = fork()) ==0) { /* child process */ static char f[PATH_MAX] = ""; @@ -1116,7 +1116,7 @@ void push_undo(void) close(pd[0]); /* close read side of pipe */ fd=fdopen(pd[1],"w"); #else /* uncompressed undo */ - my_snprintf(diff_name, S(diff_name), "%s/undo%d", undo_dirname, cur_undo_ptr%max_undo); + 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); @@ -1125,9 +1125,9 @@ void push_undo(void) } #endif write_xschem_file(fd); - cur_undo_ptr++; - head_undo_ptr = cur_undo_ptr; - tail_undo_ptr = head_undo_ptr <= max_undo? 0: head_undo_ptr-max_undo; + 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; #if HAS_POPEN==1 pclose(fd); #elif HAS_PIPE==1 @@ -1150,30 +1150,30 @@ void pop_undo(int redo) if(no_undo)return; if(redo) { - if(cur_undo_ptr < head_undo_ptr) { - dbg(1, "pop_undo(): redo; cur_undo_ptr=%d tail_undo_ptr=%d head_undo_ptr=%d\n", - cur_undo_ptr, tail_undo_ptr, head_undo_ptr); - cur_undo_ptr++; + if(xctx->cur_undo_ptr < xctx->head_undo_ptr) { + dbg(1, "pop_undo(): redo; xctx->cur_undo_ptr=%d xctx->tail_undo_ptr=%d xctx->head_undo_ptr=%d\n", + xctx->cur_undo_ptr, xctx->tail_undo_ptr, xctx->head_undo_ptr); + xctx->cur_undo_ptr++; } else { return; } } else { /*redo=0 (undo) */ - if(cur_undo_ptr == tail_undo_ptr) return; - dbg(1, "pop_undo(): undo; cur_undo_ptr=%d tail_undo_ptr=%d head_undo_ptr=%d\n", - cur_undo_ptr, tail_undo_ptr, head_undo_ptr); - if(head_undo_ptr == cur_undo_ptr) { + if(xctx->cur_undo_ptr == xctx->tail_undo_ptr) return; + dbg(1, "pop_undo(): undo; xctx->cur_undo_ptr=%d xctx->tail_undo_ptr=%d xctx->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(); - head_undo_ptr--; - cur_undo_ptr--; + xctx->head_undo_ptr--; + xctx->cur_undo_ptr--; } - if(cur_undo_ptr<=0) return; /* check undo tail */ - cur_undo_ptr--; + if(xctx->cur_undo_ptr<=0) return; /* check undo tail */ + xctx->cur_undo_ptr--; } clear_drawing(); unselect_all(); #if HAS_POPEN==1 - my_snprintf(diff_name, S(diff_name), "gunzip -c %s/undo%d", undo_dirname, cur_undo_ptr%max_undo); + my_snprintf(diff_name, S(diff_name), "gunzip -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); @@ -1181,7 +1181,7 @@ void pop_undo(int redo) return; } #elif HAS_PIPE==1 - my_snprintf(diff_name, S(diff_name), "%s/undo%d", undo_dirname, cur_undo_ptr%max_undo); + my_snprintf(diff_name, S(diff_name), "%s/undo%d", xctx->undo_dirname, xctx->cur_undo_ptr%max_undo); pipe(pd); if((pid = fork())==0) { /* child process */ static char f[PATH_MAX] = ""; @@ -1203,7 +1203,7 @@ void pop_undo(int redo) close(pd[1]); /* close write side of pipe */ fd=fdopen(pd[0],"r"); #else /* uncompressed undo */ - my_snprintf(diff_name, S(diff_name), "%s/undo%d", undo_dirname, cur_undo_ptr%max_undo); + 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); diff --git a/src/xinit.c b/src/xinit.c index 209999ef..b19daa3c 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -330,6 +330,7 @@ void init_pixdata() void free_xschem_data() { int i; + delete_undo(); my_free(1098, &xctx->wire); my_free(1100, &xctx->text); my_free(1107, &xctx->inst); @@ -371,7 +372,21 @@ void free_xschem_data() void alloc_xschem_data() { int i; + xctx = my_calloc(153, 1, sizeof(Xschem_ctx)); + xctx->cur_undo_ptr = 0; + 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"); + } + dbg(1, "xctx->undo_dirname=%s\n", xctx->undo_dirname); + #endif xctx->zoom=CADINITIALZOOM; xctx->mooz=1/CADINITIALZOOM; xctx->xorigin=CADINITIALX; @@ -699,7 +714,6 @@ void xwin_exit(void) dbg(1, "xwin_exit(): closed display\n"); my_free(1141, &filename); - delete_undo(); my_free(1142, &netlist_dir); my_free(1143, &xschem_executable); record_global_node(2, NULL, NULL); /* delete global node array */ @@ -930,7 +944,7 @@ void new_schematic(const char *what, const char *tk_win_path, const char *filena if(n <0) n = 0; if(n > cnt) n = cnt; xctx = save_xctx[n]; - resetwin(1, 1, 0); /* create preview pixmap. resetwin(create_pixmap, clear_pixmap, force) */ + resetwin(1, 1, 1); /* create preview pixmap. resetwin(create_pixmap, clear_pixmap, force) */ draw(); xctx = save; set_modify(xctx->modified); @@ -952,7 +966,8 @@ void new_schematic(const char *what, const char *tk_win_path, const char *filena if(n <0) n = 0; if(n > cnt) n = cnt; xctx = save_xctx[n]; - resetwin(1, 1, 0); /* create preview pixmap. resetwin(create_pixmap, clear_pixmap, force) */ + resetwin(1, 1, 1); /* create preview pixmap. resetwin(create_pixmap, clear_pixmap, force) */ + draw(); set_modify(xctx->modified); } } @@ -1290,16 +1305,6 @@ int Tcl_AppInit(Tcl_Interp *inter) /* */ alloc_data(); - #ifndef IN_MEMORY_UNDO - /* 20150327 create undo directory */ - /* 20180923 no more mkdtemp (portability issues) */ - if( !my_strdup(644, &undo_dirname, create_tmpdir("xschem_undo_") )) { - fprintf(errfp, "xinit(): problems creating tmp undo dir\n"); - tcleval( "exit"); - } - dbg(1, "undo_dirname=%s\n", undo_dirname); - #endif - init_pixdata(); init_color_array(0.0); my_snprintf(tmp, S(tmp), "%d",debug_var); diff --git a/src/xschem.h b/src/xschem.h index 4ff0e38a..36a3d689 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -537,6 +537,10 @@ typedef struct { cairo_surface_t *save_sfc; cairo_t *cairo_save_ctx; #endif + char *undo_dirname; + int cur_undo_ptr; + int tail_undo_ptr; + int head_undo_ptr; } Xschem_ctx; struct Lcc { /* used for symbols containing schematics as instances (LCC, Local Custom Cell) */ @@ -666,10 +670,6 @@ extern char *xschem_version_string; extern int split_files; extern char *netlist_dir; extern char bus_char[]; -extern char *undo_dirname; -extern int cur_undo_ptr; -extern int tail_undo_ptr; -extern int head_undo_ptr; extern int max_undo; extern int draw_dots; extern int draw_single_layer; @@ -1071,6 +1071,7 @@ extern void change_layer(); extern void launcher(); extern void windowid(); extern void preview_window(const char *what, const char *tk_win_path, const char *filename); +extern void new_schematic(const char *what, const char *tk_win_path, const char *filename); extern int window_state (Display *disp, Window win, char *arg); extern void toggle_fullscreen(); extern void toggle_only_probes(); diff --git a/src/xschem.tcl b/src/xschem.tcl index 17f23be8..87e65cbf 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -3162,6 +3162,16 @@ proc new_window {what {path {}} {filename {}}} { } } +proc test1 {} { + xschem load /home/schippes/xschem-repo/trunk/xschem_library/rom8k/rom8k.sch + new_window create .xx /home/schippes/xschem-repo/trunk/xschem_library/examples/mos_power_ampli.sch + new_window create .yy /home/schippes/xschem-repo/trunk/xschem_library/examples/MSA-2643.sch + bind .xx { new_window redraw 1 } + bind .yy { new_window redraw 2 } + bind .xx { new_window switch 1 } + bind .yy { new_window switch 2 } + bind .drw {+ new_window switch 0} +}