From 42a0ceb51f2823978cb37fe5680176e26891ddf9 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Thu, 30 Jan 2025 21:00:46 +0100 Subject: [PATCH 1/3] findnet.c: fix some errors in distance calculation leading to "holes" in the selection of instances. --- src/findnet.c | 66 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 26 deletions(-) diff --git a/src/findnet.c b/src/findnet.c index 2616a697..ba36fc71 100644 --- a/src/findnet.c +++ b/src/findnet.c @@ -32,18 +32,20 @@ static void find_closest_wire(double mx, double my) double tmp; int i, w=-1; double threshold; + double d = distance; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; - + for(i=0;iwires; ++i) { - if( (tmp = dist(xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2, mx, my)) < distance ) + if( (tmp = dist(xctx->wire[i].x1, xctx->wire[i].y1, xctx->wire[i].x2, xctx->wire[i].y2, mx, my)) < d ) { - w = i; distance = tmp; + w = i; d = tmp; } } - if( distance <= threshold && w!=-1) + if( d <= threshold && w!=-1) { - sel.n = w; sel.type = WIRE; + sel.n = w; sel.type = WIRE; + distance = d; } } @@ -112,6 +114,7 @@ static void find_closest_polygon(double mx, double my) int i, c, j, l=-1, col = 0, bezier; double x1, y1, x2, y2; double threshold; + double d = distance; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; for(c=0;cpoints; j++) { if( POINTINSIDE(mx, my, p->x[j] - ds, p->y[j] - ds, p->x[j] + ds, p->y[j] + ds)) { - l = i; distance = 0.0;col = c; + l = i; d = 0.0;col = c; break; } } @@ -139,18 +142,19 @@ static void find_closest_polygon(double mx, double my) x2 = p->x[j+1]; y2 = p->y[j+1]; ORDER(x1, y1, x2, y2); - if( (tmp = dist(x1, y1, x2, y2, mx, my)) < distance ) + if( (tmp = dist(x1, y1, x2, y2, mx, my)) < d ) { - l = i; distance = tmp;col = c; - dbg(1, "find_closest_polygon(): distance=%.16g n=%d\n", distance, i); + l = i; d = tmp;col = c; + dbg(1, "find_closest_polygon(): d=%.16g n=%d\n", d, i); } } } } /* end for i */ } /* end for c */ - if( distance <= threshold && l!=-1) + if( d <= threshold && l!=-1) { sel.n = l; sel.type = POLYGON; sel.col = col; + distance = d; } } @@ -162,6 +166,7 @@ static void find_closest_line(double mx, double my) double tmp; int i, c, l = -1, col = 0; double threshold; + double d = distance; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; for(c=0;clines[c]; ++i) { if( (tmp = dist(xctx->line[c][i].x1, xctx->line[c][i].y1, xctx->line[c][i].x2, xctx->line[c][i].y2, mx, my)) - < distance ) + < d ) { - l = i; distance = tmp;col = c; - dbg(1, "find_closest_line(): distance=%.16g n=%d\n", distance, i); + l = i; d = tmp;col = c; + dbg(1, "find_closest_line(): d=%.16g n=%d\n", d, i); } } /* end for i */ } /* end for c */ - if( distance <= threshold && l!=-1) + if( d <= threshold && l!=-1) { sel.n = l; sel.type = LINE; sel.col = col; + distance = d; } } @@ -326,6 +332,7 @@ static void find_closest_arc(double mx, double my) int i, c, r=-1, col; int match; double threshold; + double d = distance; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; for(c=0;carcs[c]; ++i) { dist = sqrt(pow(mx-xctx->arc[c][i].x, 2) + pow(my-xctx->arc[c][i].y, 2)) - xctx->arc[c][i].r; - dist *= dist; /* square distance */ + dist *= dist; /* square d */ angle = fmod(atan2(xctx->arc[c][i].y-my, mx-xctx->arc[c][i].x)*180./XSCH_PI, 360.); if(angle<0.) angle +=360.; angle1 = xctx->arc[c][i].a; angle2 = fmod(xctx->arc[c][i].a + xctx->arc[c][i].b, 360.); match=0; - if(dist < distance) { + if(dist < d) { if(xctx->arc[c][i].b==360.) match=1; if(angle2= angle1 || angle<= angle2) { @@ -359,14 +366,15 @@ static void find_closest_arc(double mx, double my) if(match ) { dbg(1, "find_closest_arc(): i = %d\n", i); r = i; - distance = dist; + d = dist; col = c; } } /* end for i */ } /* end for c */ - if( r!=-1 && distance <= threshold ) /* * pow(xctx->arc[col][r].r, 2)) */ + if( r!=-1 && d <= threshold ) /* * pow(xctx->arc[col][r].r, 2)) */ { sel.n = r; sel.type = ARC; sel.col = col; + distance = d; } } @@ -376,6 +384,7 @@ static void find_closest_box(double mx ,double my, int override_lock) double tmp; double ds = xctx->cadhalfdotsize; int i, c, r=-1, col = 0; + double d = distance; /* correction for very small boxes */ for(c=0;crect[c][i].x1, xctx->rect[c][i].y1, xctx->rect[c][i].x2, xctx->rect[c][i].y2); - if(tmp < distance) + if(tmp < d) { - r = i; distance = tmp;col = c; + r = i; d = tmp;col = c; } } } /* end for i */ } /* end for c */ - dbg(1, "find_closest_box(): distance=%.16g\n", distance); + dbg(1, "find_closest_box(): d=%.16g\n", d); if( r!=-1 && (override_lock || strboolcmp(get_tok_value(xctx->rect[col][r].prop_ptr, "lock", 0), "true"))) { sel.n = r; sel.type = xRECT; sel.col = col; + distance = d; } } @@ -408,6 +418,7 @@ static void find_closest_element(double mx, double my, int override_lock) { double tmp; int i, r=-1; + double d = distance; for(i = 0;i < xctx->instances; ++i) { dbg(1, "find_closest_element(): %s: %g %g %g %g\n", @@ -415,14 +426,15 @@ static void find_closest_element(double mx, double my, int override_lock) if( POINTINSIDE(mx, my, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2) ) { tmp=dist_from_rect(mx, my, xctx->inst[i].xx1, xctx->inst[i].yy1, xctx->inst[i].xx2, xctx->inst[i].yy2); - if(tmp < distance) + if(tmp < d) { - r = i; distance = tmp; + r = i; d = tmp; } dbg(2, "find_closest_element(): finding closest element, instances=%d, dist=%.16g\n", i, tmp); } } /* end for i */ if( r != -1 && (override_lock || strboolcmp(get_tok_value(xctx->inst[r].prop_ptr, "lock", 0), "true")) ) { + distance = d; sel.n = r; sel.type = ELEMENT; } } @@ -437,6 +449,7 @@ static void find_closest_text(double mx, double my) int customfont; #endif char *estr = NULL; + double d = distance; threshold = CADWIREMINDIST * CADWIREMINDIST * xctx->zoom * xctx->zoom; for(i=0;itexts; ++i) { @@ -459,13 +472,14 @@ static void find_closest_text(double mx, double my) #endif if(POINTINSIDE(mx, my, xx1, yy1, xx2, yy2)) { - r = i; distance = 0; - dbg(2, "find_closest_text(): finding closest text, texts=%d, dist=%.16g\n", i, distance); + r = i; d = 0; + dbg(2, "find_closest_text(): finding closest text, texts=%d, dist=%.16g\n", i, d); } } /* end for i */ - if( distance <= threshold && r!=-1) + if( d <= threshold && r!=-1) { sel.n = r; sel.type = xTEXT; + distance = d; } } From 60d180de33181e8463072dc1ece9e39a4a0b62c7 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Thu, 30 Jan 2025 22:43:35 +0100 Subject: [PATCH 2/3] translate(): fix `regfree(get_sp_cur);` not followed by `get_sp_cur = NULL;`, leading to a random pointer to nowhere --- src/token.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/token.c b/src/token.c index 40dc0565..fbb9e305 100644 --- a/src/token.c +++ b/src/token.c @@ -3771,6 +3771,7 @@ const char *translate(int inst, const char* s) my_free(_ALLOC_ID_, &result); my_free(_ALLOC_ID_, &translated_tok); regfree(get_sp_cur); + get_sp_cur = NULL; return empty; } if(inst >= xctx->instances) { From 31a3a00c46c3c77c727f657409b62d4d2e77932d Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Thu, 30 Jan 2025 23:33:51 +0100 Subject: [PATCH 3/3] clean up translate() deallocation --- src/token.c | 21 ++++++++++++++------- src/xinit.c | 2 +- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/token.c b/src/token.c index fbb9e305..f092bb74 100644 --- a/src/token.c +++ b/src/token.c @@ -3757,6 +3757,19 @@ const char *translate(int inst, const char* s) int sim_is_xyce; char *instname = NULL; + if(!s && inst == -1) { + if(result) my_free(_ALLOC_ID_, &result); + if(translated_tok) my_free(_ALLOC_ID_, &translated_tok); + if(get_sp_cur) { + regfree(get_sp_cur); + get_sp_cur = NULL; + } + } + + if(!s || !xctx || !xctx->inst) { + return empty; + } + if(!get_sp_cur) { get_sp_cur = my_malloc(_ALLOC_ID_, sizeof(regex_t)); /* @spice_get_current_param(...) or @spice_get_modelparam_param(...) */ @@ -3767,13 +3780,7 @@ const char *translate(int inst, const char* s) } sp_prefix = tclgetboolvar("spiceprefix"); - if(!s || !xctx || !xctx->inst) { - my_free(_ALLOC_ID_, &result); - my_free(_ALLOC_ID_, &translated_tok); - regfree(get_sp_cur); - get_sp_cur = NULL; - return empty; - } + if(inst >= xctx->instances) { dbg(0, "translate(): instance number out of bounds: %d\n", inst); return empty; diff --git a/src/xinit.c b/src/xinit.c index 46160eb2..6d3058f7 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -944,7 +944,7 @@ static void xwin_exit(void) clear_expandlabel_data(); get_sym_template(NULL, NULL); /* clear static data in function */ list_tokens(NULL, 0); /* clear static data in function */ - translate(0, NULL); /* clear static data in function */ + translate(-1, NULL); /* clear static data in function */ translate2(NULL, 0, NULL); /* clear static data in function */ translate3(NULL, 0, NULL, NULL, NULL); /* clear static data in function */ subst_token(NULL, NULL, NULL); /* clear static data in function */