--diff option to visually compare two different (versions of) schematics

This commit is contained in:
stefan schippers 2022-12-13 13:51:33 +01:00
parent 5a8e0c9ba2
commit e01f545567
11 changed files with 92 additions and 19 deletions

View File

@ -60,6 +60,7 @@ Options:
--tcl <tcl_script> Execute specified tcl instructions before any other action,
this can be used to change xschemrc variables.
--command <tcl_cmd> Execute specified tcl commands after completing startup.
--diff <file> Show differences with given file.
--script <file> Execute specified tcl file as a command script (perhaps with xschem commands).
--tcp_port <number> Listen to specified tcp port for client connections. (number >=1024).
-i --no_rcload Do not load any xschemrc file.

View File

@ -71,6 +71,7 @@
<li><a href="https://xschem.sourceforge.io/stefan/xschem_man/video_tutorials/copy_from_window_to_window.mp4">[Video] Copying objects across xschem windows</a></li>
<li><a href="https://xschem.sourceforge.io/stefan/xschem_man/video_tutorials/inherited_connections.mp4">[Video] Symbols with inherited connections</a></li>
<li><a href="https://xschem.sourceforge.io/stefan/xschem_man/video_tutorials/search_replace.mp4">[Video] Search / replace function</a></li>
<li><a href="https://xschem.sourceforge.io/stefan/xschem_man/video_tutorials/xschem_diff.mp4">[Video] Visualize differences between two schematics weith xschem</a></li>
<li><a href="https://xschem.sourceforge.io/stefan/xschem_man/video_tutorials/stretch.mp4">[Video] How to stretch objects</a></li>
<li><a href="https://xschem.sourceforge.io/stefan/xschem_man/video_tutorials/parametric_subckts.mp4">[Video] Parameters in subcircuits</a></li>
<li><a href="https://xschem.sourceforge.io/stefan/xschem_man/video_tutorials/wires_pins_grid.mp4">[Video] Create pins from net labels, fix grid align issues, wires</a></li>

View File

@ -1175,7 +1175,11 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
/* redraw selection on expose, needed if no backing store available on the server 20171112 */
XSetClipRectangles(display, xctx->gc[SELLAYER], 0,0, xr, 1, Unsorted);
rebuild_selected_array();
draw_selection(xctx->gc[SELLAYER],0);
if(tclgetboolvar("compare_sch") && xctx->sch_to_compare[0]){
compare_schematics("");
} else {
draw_selection(xctx->gc[SELLAYER],0);
}
XSetClipMask(display, xctx->gc[SELLAYER], None);
}
dbg(1, "callback(): Expose\n");
@ -1826,9 +1830,19 @@ int callback(const char *winpath, int event, int mx, int my, KeySym key,
}
break;
}
if(key=='X' && state == (ShiftMask|ControlMask)) /* swap compare schematics */
{
tcleval("swap_compare_schematics");
}
if(key=='x' && state == Mod1Mask) /* compare schematics(must set first) */
{
compare_schematics("");
unselect_all(0);
if(tclgetboolvar("compare_sch")) {
tclsetvar("compare_sch", "0");
} else {
tclsetvar("compare_sch", "1");
}
draw();
}
if(key=='x' && state == ControlMask) /* cut selection into clipboard */
{

View File

@ -66,8 +66,10 @@ int textclip(int x1,int y1,int x2,int y2,
/* check if some of (xa,ya-xb,yb) is inside (x1,y1-x2,y2) */
/* coordinates should be ordered, x1<x2,ya<yb and so on... */
{
/*
dbg(2, "textclip(): %.16g %.16g %.16g %.16g - %d %d %d %d\n",
X_TO_SCREEN(xa),Y_TO_SCREEN(ya), X_TO_SCREEN(xb),Y_TO_SCREEN(yb),x1,y1,x2,y2);
*/
/* drawtemprect(xctx->gc[WIRELAYER],xa,ya,xb,yb); */
if (X_TO_SCREEN(xa)>x2) return 0;
else if (Y_TO_SCREEN(ya)>y2) return 0;
@ -85,7 +87,7 @@ void print_image()
static char lastdir[PATH_MAX] = "";
const char *r;
if(!has_x) return ;
if(!has_x) return;
if(!lastdir[0]) my_strncpy(lastdir, pwd_dir, S(lastdir));
if(!xctx->plotfile[0]) {
tclvareval("tk_getSaveFile -title {Select destination file} -initialfile {",
@ -3247,6 +3249,7 @@ void svg_embedded_graph(FILE *fd, xRect *r, double rx1, double ry1, double rx2,
size_t olength;
const double max_size = 2000.0;
if(!has_x) return;
rw = fabs(rx2 -rx1);
rh = fabs(ry2 - ry1);
scale = 1.0;
@ -3520,7 +3523,11 @@ void draw(void)
xctx->xrect[0].width, xctx->xrect[0].height);
#endif
}
draw_selection(xctx->gc[SELLAYER], 0); /* 20181009 moved outside of cadlayers loop */
if(tclgetboolvar("compare_sch") && xctx->sch_to_compare[0]){
compare_schematics("");
} else {
draw_selection(xctx->gc[SELLAYER], 0); /* 20181009 moved outside of cadlayers loop */
}
} /* if(has_x) */
}

View File

@ -185,6 +185,7 @@ char **cli_opt_argv = NULL;
int cli_opt_netlist_type = 0;
int cli_opt_flat_netlist = 0;
char cli_opt_plotfile[PATH_MAX] = "";
char cli_opt_diff[PATH_MAX] = "";
char cli_opt_netlist_dir[PATH_MAX] = "";
char cli_opt_filename[PATH_MAX] = ""; /* filename given on cmdline */
int cli_opt_no_readline=0;

View File

@ -85,6 +85,10 @@ static void check_opt(char *opt, char *optval, int type)
dbg(1, "process_options(): passing tcl command to interpreter: %s\n", optval);
if(optval) my_strdup(661, &cli_opt_tcl_post_command, optval);
} else if( (type == LONG && !strcmp("diff", opt)) ) {
dbg(1, "process_options(): diff with: %s\n", optval);
if(optval) my_strncpy(cli_opt_diff, optval, S(cli_opt_diff));
} else if( (type == LONG && !strcmp("tcp_port", opt)) ) {
dbg(1, "process_options(): setting tcp port: %s\n", optval);
if(optval) tcp_port=atoi(optval);
@ -193,6 +197,9 @@ int process_options(int argc, char *argv[])
else if(!strcmp("command", opt)) {
optval = argv[++i];
}
else if(!strcmp("diff", opt)) {
optval = argv[++i];
}
else if(!strcmp("tcp_port", opt)) {
optval = argv[++i];
}
@ -242,7 +249,7 @@ int process_options(int argc, char *argv[])
argv[arg_cnt++] = opt;
}
}
if (arg_cnt>=2) {
if (arg_cnt > 1) {
dbg(1, "process_option(): file name given: %s\n",argv[1]);
my_strncpy(cli_opt_filename, argv[1], S(cli_opt_filename));
#ifndef __unix__

View File

@ -576,7 +576,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
{
int ret = 0;
if(argc > 2) {
ret = compare_schematics(argv[2]);
ret = compare_schematics(abs_sym_path(argv[2], ""));
}
else {
ret = compare_schematics(NULL);
@ -987,6 +987,10 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
Tcl_SetResult(interp, xctx->sch_path[x], TCL_VOLATILE);
}
}
else if(!strcmp(argv[2], "sch_to_compare"))
{
Tcl_SetResult(interp, xctx->sch_to_compare, TCL_VOLATILE);
}
break;
case 't':
#ifndef __unix__
@ -1647,13 +1651,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, undo_reset = 1;
int load_symbols = 1, force = 0, undo_reset = 1, nofullzoom = 0;
size_t i;
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(!strcmp(argv[i], "nofullzoom")) nofullzoom = 1;
}
}
if(argc>2) {
@ -1690,7 +1695,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
my_strdup(375, &xctx->sch_path[xctx->currsch], ".");
xctx->sch_path_hash[xctx->currsch] = 0;
xctx->sch_inst_number[xctx->currsch] = 1;
zoom_full(1, 0, 1, 0.97);
if(nofullzoom) draw();
else zoom_full(1, 0, 1, 0.97);
}
}
}
@ -2569,6 +2575,9 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
change_layer();
}
}
else if(!strcmp(argv[2], "sch_to_compare")) {
my_strncpy(xctx->sch_to_compare, abs_sym_path(argv[3], ""), S(xctx->sch_to_compare));
}
else if(!strcmp(argv[2], "text_svg")) {
text_svg=atoi(argv[3]);
}

View File

@ -687,7 +687,7 @@ int compare_schematics(const char *f)
my_strncpy(xctx->sch_to_compare, f, S(xctx->sch_to_compare));
}
if(!xctx->sch_to_compare[0]) {
my_strncpy(xctx->sch_to_compare, abs_sym_path(xctx->current_name, ""), S(xctx->sch_to_compare));
my_strncpy(xctx->sch_to_compare, xctx->sch[xctx->currsch], S(xctx->sch_to_compare));
dbg(0, "Compare current schematic with saved version of itself!\n");
}
@ -2437,10 +2437,15 @@ int Tcl_AppInit(Tcl_Interp *inter)
my_snprintf(pwd_dir, S(pwd_dir), "%s", tclgetvar("env(PWD)"));
}
if(cli_opt_diff[0]) {
my_strncpy(xctx->sch_to_compare, abs_sym_path(cli_opt_diff, ""), S(xctx->sch_to_compare));
tclsetvar("compare_sch", "1");
}
if(cli_opt_filename[0]) {
char f[PATH_MAX];
#ifdef __unix__
#ifdef __unix__
if(strstr(cli_opt_filename, "http://") == cli_opt_filename ||
strstr(cli_opt_filename, "https://") == cli_opt_filename) {
my_snprintf(f, S(f), "%s", cli_opt_filename);
@ -2453,9 +2458,9 @@ int Tcl_AppInit(Tcl_Interp *inter)
} else {
my_snprintf(f, S(f), "%s", cli_opt_filename);
}
#else
#else
my_strncpy(f, abs_sym_path(cli_opt_filename, ""), S(f));
#endif
#endif
dbg(1, "Tcl_AppInit(): cli_opt_filename %s given, removing symbols\n", cli_opt_filename);
remove_symbols();
/* if cli_opt_do_netlist=1 call load_schematic with 'reset_undo=0' avoiding call
@ -2466,9 +2471,9 @@ int Tcl_AppInit(Tcl_Interp *inter)
char * tmp;
char fname[PATH_MAX];
tmp = (char *) tclgetvar("XSCHEM_START_WINDOW");
#ifndef __unix__
#ifndef __unix__
change_to_unix_fn(tmp);
#endif
#endif
dbg(1, "Tcl_AppInit(): tmp=%s\n", tmp? tmp: "NULL");
my_strncpy(fname, abs_sym_path(tmp, ""), S(fname));
/* if cli_opt_do_netlist=1 call load_schematic with 'reset_undo=0' avoiding call
@ -2528,7 +2533,10 @@ int Tcl_AppInit(Tcl_Interp *inter)
print_image();
}
}
else svg_draw();
else {
tcleval("tkwait visibility .drw");
svg_draw();
}
}
if(cli_opt_do_simulation) {

View File

@ -1050,6 +1050,7 @@ extern char **cli_opt_argv;
extern int cli_opt_netlist_type;
extern int cli_opt_flat_netlist;
extern char cli_opt_plotfile[PATH_MAX];
extern char cli_opt_diff[PATH_MAX];
extern char cli_opt_netlist_dir[PATH_MAX];
extern char cli_opt_filename[PATH_MAX];
extern int cli_opt_no_readline;

View File

@ -15,6 +15,7 @@ Options:
and before loading xschemrc.
--script <file> Execute specified tcl file as a command script (perhaps with xschem commands).
--command <tcl_cmd> Execute specified tcl commands after completing startup.
--diff <file> Show differences with given file.
--tcp_port <number> Listen to specified tcp port for client connections. (number >=1024).
-i --no_rcload Do not load any xschemrc file.
--netlist_path <path>

View File

@ -4629,6 +4629,22 @@ proc add_ext {fname ext} {
return [file rootname $fname]$ext
}
proc swap_compare_schematics {} {
global compare_sch
set sch1 [xschem get schname]
set sch2 [xschem get sch_to_compare]
if {$sch2 ne {}} {
xschem load $sch2 nofullzoom
if {[xschem get schname] eq $sch2} { ;# user did not cancel loading
if {$compare_sch} {
xschem compare_schematics $sch1
} else {
xschem set sch_to_compare $sch1
}
}
}
}
proc input_line {txt {cmd {}} {preset {}} {w 12}} {
global input_line_cmd input_line_data wm_fix
set input_line_data {}
@ -5271,7 +5287,7 @@ set tctx::global_list {
INITIALINSTDIR INITIALLOADDIR INITIALPROPDIR INITIALTEXTDIR XSCHEM_LIBRARY_PATH
auto_hilight autofocus_mainwindow
autotrim_wires bespice_listen_port big_grid_points bus_replacement_char cadgrid cadlayers
cadsnap cairo_font_name change_lw color_ps colors connect_by_kissing constrained_move
cadsnap cairo_font_name change_lw color_ps colors compare_sch connect_by_kissing constrained_move
copy_cell custom_label_prefix custom_token dark_colors dark_colorscheme dim_bg dim_value
disable_unique_names do_all_inst draw_grid draw_window edit_prop_pos edit_prop_size
edit_symbol_prop_new_sel editprop_sympath en_hilight_conn_inst enable_dim_bg enable_stretch
@ -5523,7 +5539,7 @@ proc switch_undo {} {
proc build_widgets { {topwin {} } } {
global XSCHEM_SHAREDIR tabbed_interface simulate_bg
global colors recentfile color_ps transparent_svg menu_debug_var enable_stretch
global netlist_show flat_netlist split_files tmp_bus_char
global netlist_show flat_netlist split_files tmp_bus_char compare_sch
global draw_grid big_grid_points sym_txt change_lw incr_hilight symbol_width
global cadgrid draw_window show_pin_net_names toolbar_visible hide_symbols undo_type
global disable_unique_names persistent_command autotrim_wires en_hilight_conn_inst
@ -5926,10 +5942,16 @@ proc build_widgets { {topwin {} } } {
$topwin.menubar.hilight.menu add command \
-label {Set schematic to compare and compare with} \
-command "xschem compare_schematics"
-command "set compare_sch 1; xschem compare_schematics"
$topwin.menubar.hilight.menu add command \
-label {Swap compare schematics} -accelerator {Ctrl-Shift-X} \
-command "swap_compare_schematics"
$topwin.menubar.hilight.menu add checkbutton \
-label {Compare schematics} \
-command "xschem compare_schematics {}" \
-command {
xschem unselect_all
xschem redraw } \
-variable compare_sch \
-accelerator {Alt-X}
$topwin.menubar.hilight.menu add command \
-label {Highlight net-pin name mismatches on selected instances} \
@ -6342,6 +6364,7 @@ set_ne draw_grid 1
set_ne big_grid_points 0
set_ne persistent_command 0
set_ne autotrim_wires 0
set_ne compare_sch 0
set_ne disable_unique_names 0
set_ne sym_txt 1
set_ne show_infowindow 0