From a2de3e9c1b2251e7a6506c0e4502d235a52ad7fd Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Thu, 25 Aug 2022 00:25:29 +0200 Subject: [PATCH] Added compare_schematics() function. Empty graphs (no data loaded) are not editable. Set window title if opening a non-existent file. --- src/callback.c | 1 + src/netlist.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ src/save.c | 4 ++- src/scheduler.c | 20 +++++++++++--- src/xschem.h | 1 + 5 files changed, 93 insertions(+), 4 deletions(-) diff --git a/src/callback.c b/src/callback.c index a1b1c675..66a90f34 100644 --- a/src/callback.c +++ b/src/callback.c @@ -29,6 +29,7 @@ static int waves_selected(int event, int state, int button) static unsigned int excl = STARTZOOM | STARTRECT | STARTLINE | STARTWIRE | STARTPAN | STARTSELECT | STARTMOVE | STARTCOPY; if(xctx->ui_state & excl) skip = 1; + else if(!xctx->graph_values) skip = 1; else if(state & Mod1Mask) skip = 1; else if(event == MotionNotify && (state & Button2Mask)) skip = 1; else if(event == MotionNotify && (state & Button1Mask) && (state & ShiftMask)) skip = 1; diff --git a/src/netlist.c b/src/netlist.c index fce9dc97..b71c7451 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -1046,6 +1046,77 @@ void prepare_netlist_structs(int for_netlist) /* propagate_hilights(1, 0, XINSERT_NOREPLACE);*/ } + +int compare_schematics(const char *filename) +{ + Int_hashentry *table[HASHSIZE]; + Int_hashentry *found; + char *s = NULL; + int i; + size_t l; + char current_sch[PATH_MAX]; + int ret=0; /* ret==0 means no differences found */ + + my_strncpy(current_sch, abs_sym_path(xctx->current_name, ""), S(current_sch)); + clear_all_hilights(); + unselect_all(); + remove_symbols(); + xctx->no_draw = 1; + load_schematic(1, filename, 1); + + memset(table, 0, HASHSIZE * sizeof(Int_hashentry *)); + for(i = 0; i < xctx->instances; i++) { + l = 1024 + strlen(xctx->inst[i].prop_ptr ? xctx->inst[i].prop_ptr : ""); + my_realloc(1534, &s, l); + my_snprintf(s, l, "C %s %g %g %d %d %s", xctx->inst[i].name, + xctx->inst[i].x0, xctx->inst[i].y0, xctx->inst[i].rot, xctx->inst[i].flip, + xctx->inst[i].prop_ptr ? xctx->inst[i].prop_ptr : ""); + int_hash_lookup(table, s, i, XINSERT_NOREPLACE); + } + for(i=0;iwires;i++) + { + l =1024 + strlen(xctx->wire[i].prop_ptr ? xctx->wire[i].prop_ptr : ""); + my_realloc(1535, &s, l); + my_snprintf(s, l, "N %g %g %g %g %s", xctx->wire[i].x1, xctx->wire[i].y1, + xctx->wire[i].x2, xctx->wire[i].y2, + xctx->wire[i].prop_ptr ? xctx->wire[i].prop_ptr : ""); + int_hash_lookup(table, s, i, XINSERT_NOREPLACE); + } + + load_schematic(1, current_sch, 1); + xctx->no_draw = 0; + + for(i = 0; i < xctx->instances; i++) { + l = 1024 + strlen(xctx->inst[i].prop_ptr ? xctx->inst[i].prop_ptr : ""); + my_realloc(1536,&s, l); + my_snprintf(s, l, "C %s %g %g %d %d %s", xctx->inst[i].name, + xctx->inst[i].x0, xctx->inst[i].y0, xctx->inst[i].rot, xctx->inst[i].flip, + xctx->inst[i].prop_ptr ? xctx->inst[i].prop_ptr : ""); + found = int_hash_lookup(table, s, i, XLOOKUP); + if(!found) { + select_element(i,SELECTED, 1, 1); + ret = 1; + } + } + for(i=0;iwires;i++) + { + l = 1024 + strlen(xctx->wire[i].prop_ptr ? xctx->wire[i].prop_ptr : ""); + my_realloc(1537, &s, l); + my_snprintf(s, l, "N %g %g %g %g %s", xctx->wire[i].x1, xctx->wire[i].y1, + xctx->wire[i].x2, xctx->wire[i].y2, + xctx->wire[i].prop_ptr ? xctx->wire[i].prop_ptr : ""); + found = int_hash_lookup(table, s, i, XLOOKUP); + if(!found) { + select_wire(i, SELECTED, 1); + ret = 1; + } + } + int_hash_free(table); + draw(); + my_free(1531, &s); + return ret; +} + int warning_overlapped_symbols() { int i; diff --git a/src/save.c b/src/save.c index 914c668a..da4920dc 100644 --- a/src/save.c +++ b/src/save.c @@ -1121,7 +1121,8 @@ static void save_inst(FILE *fd, int select_only) } fprintf(fd, " %.16g %.16g %hd %hd ",ptr[i].x0, ptr[i].y0, ptr[i].rot, ptr[i].flip ); save_ascii_string(ptr[i].prop_ptr,fd, 1); - if( !embedded_saved[ptr[i].ptr] && !strcmp(get_tok_value(ptr[i].prop_ptr, "embed", 0), "true") ) { + if( embedded_saved && !embedded_saved[ptr[i].ptr] && + !strcmp(get_tok_value(ptr[i].prop_ptr, "embed", 0), "true") ) { /* && !(xctx->sym[ptr[i].ptr].flags & EMBEDDED)) { */ embedded_saved[ptr[i].ptr] = 1; fprintf(fd, "[\n"); @@ -1922,6 +1923,7 @@ void load_schematic(int load_symbols, const char *filename, int reset_undo) /* 2 my_snprintf(msg, S(msg), "update; alert_ {Unable to open file: %s}", filename ? filename: "(null)"); tcleval(msg); clear_drawing(); + if(reset_undo) set_modify(0); } else { clear_drawing(); dbg(1, "load_schematic(): reading file: %s\n", name); diff --git a/src/scheduler.c b/src/scheduler.c index 5d4daff8..3b4bc9ce 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -142,6 +142,7 @@ static void xschem_cmd_help(int argc, const char **argv) " wirelayer\n", " xorigin\n", " yorigin\n", + " zoom\n", "get_tok\n", "get_tok_size\n", "getprop\n", @@ -544,6 +545,16 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg Tcl_ResetResult(interp); } + else if(!strcmp(argv[1], "compare_schematics")) + { + int ret = 0; + cmd_found = 1; + if(argc > 2) { + ret = compare_schematics(argv[2]); + } + Tcl_SetResult(interp, my_itoa(ret), TCL_VOLATILE); + } + else if(!strcmp(argv[1],"connected_nets")) /* selected nets connected to currently selected ones */ { int stop_at_junction = 0; @@ -1578,13 +1589,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else if(!strcmp(argv[1],"load") ) { - int load_symbols = 1, force = 0; + int load_symbols = 1, force = 0, undo_reset = 1; size_t i; cmd_found = 1; if(argc > 3) { for(i = 3; i < argc; i++) { if(!strcmp(argv[i], "symbol")) load_symbols = 0; if(!strcmp(argv[i], "force")) force = 1; + if(!strcmp(argv[i], "noundoreset")) undo_reset = 0; } } if(argc>2) { @@ -1611,10 +1623,12 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg } if(!skip) { clear_all_hilights(); - xctx->currsch = 0; unselect_all(); + if(!undo_reset) xctx->push_undo(); + xctx->currsch = 0; remove_symbols(); - load_schematic(load_symbols, f, 1); + dbg(1, "scheduler: undo_reset=%d\n", undo_reset); + load_schematic(load_symbols, f, undo_reset); tclvareval("update_recent_file {", f, "}", NULL); my_strdup(375, &xctx->sch_path[xctx->currsch],"."); xctx->sch_path_hash[xctx->currsch] = 0; diff --git a/src/xschem.h b/src/xschem.h index 7a730113..d34deec3 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1365,6 +1365,7 @@ extern void display_hilights(char **str); extern void redraw_hilights(int clear); extern void set_tcl_netlist_type(void); extern void prepare_netlist_structs(int for_netlist); +extern int compare_schematics(const char *filename); extern int warning_overlapped_symbols(); extern void free_simdata(void); extern void delete_netlist_structs(void);