From 584f88fba1490a4317b8c572d80469022b9b3e17 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Thu, 9 Nov 2023 13:57:58 +0100 Subject: [PATCH] object iterator, object spatial hash table for all objects. tbu in the future maybe. Fix crashing bug when copying ngspice_probe.sym if annotation is enabled --- src/callback.c | 6 -- src/hash_iterator.c | 55 ++++++++++++++ src/netlist.c | 180 ++++++++++++++++++++++++++++++++++++++++++++ src/scheduler.c | 42 ++++++++++- src/select.c | 102 +++++++++++++++---------- src/token.c | 50 ++++++------ src/xinit.c | 3 + src/xschem.h | 36 +++++++-- src/xschem.tcl | 2 +- 9 files changed, 400 insertions(+), 76 deletions(-) diff --git a/src/callback.c b/src/callback.c index 01757d72..a04135bb 100644 --- a/src/callback.c +++ b/src/callback.c @@ -218,9 +218,6 @@ static void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr) double xx, cursor2; /* xx is the p-th sweep variable value, cursor2 is cursor 'b' x position */ Raw *raw = xctx->raw; int save_datasets = -1, save_npoints = -1; - - - /* transform multiple OP points into a dc sweep */ if(raw && raw->sim_type && !strcmp(raw->sim_type, "op") && raw->datasets > 1 && raw->npoints[0] == 1) { save_datasets = raw->datasets; @@ -228,9 +225,6 @@ static void backannotate_at_cursor_b_pos(xRect *r, Graph_ctx *gr) save_npoints = raw->npoints[0]; raw->npoints[0] = raw->allpoints; } - - - sweep_idx = get_raw_index(find_nth(get_tok_value(r->prop_ptr, "sweep", 0), ", ", "\"", 0, 1)); if(sweep_idx < 0) sweep_idx = 0; cursor2 = xctx->graph_cursor2_x; diff --git a/src/hash_iterator.c b/src/hash_iterator.c index 3245ecdd..9334f7c4 100644 --- a/src/hash_iterator.c +++ b/src/hash_iterator.c @@ -134,3 +134,58 @@ Wireentry *wire_iterator_next(Iterator_ctx *ctx) } +void init_object_iterator(Iterator_ctx *ctx, double x1, double y1, double x2, double y2) +{ + ctx->objectflag = NULL; + dbg(3, "init_object_iterator(): objects=%d\n", xctx->n_hash_objects); + if(xctx->n_hash_objects) { + my_realloc(_ALLOC_ID_, &ctx->objectflag, xctx->n_hash_objects * sizeof(unsigned short)); + memset(ctx->objectflag, 0, xctx->n_hash_objects * sizeof(unsigned short)); + } + /* calculate square 4 1st corner of drawing area */ + ctx->x1a = (int)floor(x1 / BOXSIZE) ; + ctx->y1a = (int)floor(y1 / BOXSIZE) ; + /* calculate square 4 2nd corner of drawing area */ + ctx->x2a = (int)floor(x2 / BOXSIZE); + ctx->y2a = (int)floor(y2 / BOXSIZE); + ctx->i = ctx->x1a; + ctx->j = ctx->y1a; + ctx->tmpi = ctx->i % NBOXES; if(ctx->tmpi < 0) ctx->tmpi += NBOXES; + ctx->tmpj = ctx->j % NBOXES; if(ctx->tmpj < 0) ctx->tmpj += NBOXES; + ctx->counti = 0; + ctx->objectptr = xctx->object_spatial_table[ctx->tmpi][ctx->tmpj]; + ctx->countj = 0; +} + +Objectentry *object_iterator_next(Iterator_ctx *ctx) +{ + Objectentry *ptr; + /* dbg(3, "object_iterator_next(): obhjects=%d\n", xctx->n_hash_objects); */ + while(1) { + while(ctx->objectptr) { + ptr = ctx->objectptr; + ctx->objectptr = ctx->objectptr->next; + if(!ctx->objectflag[ptr->n]) { + ctx->objectflag[ptr->n] = 1; + return ptr; + } + } + if(ctx->j < ctx->y2a && ctx->countj++ < NBOXES) { + ctx->j++; + ctx->tmpj = ctx->j % NBOXES; if(ctx->tmpj < 0) ctx->tmpj += NBOXES; + ctx->objectptr = xctx->object_spatial_table[ctx->tmpi][ctx->tmpj]; + } else if(ctx->i < ctx->x2a && ctx->counti++ < NBOXES) { + ctx->i++; + ctx->j = ctx->y1a; + ctx->countj = 0; + ctx->tmpi = ctx->i % NBOXES; if(ctx->tmpi < 0) ctx->tmpi += NBOXES; + ctx->tmpj = ctx->j % NBOXES; if(ctx->tmpj < 0) ctx->tmpj += NBOXES; + ctx->objectptr = xctx->object_spatial_table[ctx->tmpi][ctx->tmpj]; + } else { + my_free(_ALLOC_ID_, &ctx->objectflag); + return NULL; + } + } +} + + diff --git a/src/netlist.c b/src/netlist.c index 5604f202..bf17c2eb 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -112,6 +112,7 @@ void hash_inst(int what, int n) /* 20171203 insert object bbox in spatial hash t } } } + void hash_instances(void) /* 20171203 insert object bbox in spatial hash table */ { int n; @@ -124,6 +125,185 @@ void hash_instances(void) /* 20171203 insert object bbox in spatial hash table * xctx->prep_hash_inst=1; } + +/* START HASH ALL OBJECTS */ + +static Objectentry *delobjectentry(Objectentry *t) +{ + Objectentry *tmp; + while( t ) { + tmp = t->next; + my_free(_ALLOC_ID_, &t); + t = tmp; + } + return NULL; +} + +void del_object_table(void) +{ + int i,j; + + for(i=0;iobject_spatial_table[i][j] = delobjectentry(xctx->object_spatial_table[i][j]); + xctx->prep_hash_object=0; + xctx->n_hash_objects = 0; + dbg(1, "del_object_table(): cleared object hash table\n"); +} + + + +static void objectdelete(int type, int n, int c, int x, int y) +{ + Objectentry *saveptr, **prevptr; + + prevptr = &xctx->object_spatial_table[x][y]; + while( (*prevptr)->type != type || (*prevptr)->n != n || (*prevptr)->c != c) prevptr = &(*prevptr)->next; + saveptr = (*prevptr)->next; + my_free(_ALLOC_ID_, prevptr); + *prevptr = saveptr; +} + +static void objectinsert(int type, int n, int c, int x, int y) +{ + Objectentry *ptr, *newptr; + ptr=xctx->object_spatial_table[x][y]; + newptr=my_malloc(_ALLOC_ID_, sizeof(Instentry)); + newptr->next=ptr; + newptr->type=type; + newptr->n=n; + newptr->c=c; + xctx->object_spatial_table[x][y]=newptr; + dbg(2, "objectnsert(): inserting object %d %d %d at %d,%d\n",type, n, c, x, y); +} + +/* what: + * 0, XINSERT : add to hash + * 1, XDELETE : remove from hash + */ +void hash_object(int what, int type, int n, int c) +{ + int tmpi,tmpj, counti,countj,i,j; + double tmpd; + double x1, y1, x2, y2; + int x1a, x2a, y1a, y2a; + int skip = 0; + + switch(type) { + case ELEMENT: + x1=xctx->inst[n].x1; + x2=xctx->inst[n].x2; + y1=xctx->inst[n].y1; + y2=xctx->inst[n].y2; + break; + case xRECT: + x1 = xctx->rect[c][n].x1; + y1 = xctx->rect[c][n].y1; + x2 = xctx->rect[c][n].x2; + y2 = xctx->rect[c][n].y2; + break; + case WIRE: + x1 = xctx->wire[n].x1; + y1 = xctx->wire[n].y1; + x2 = xctx->wire[n].x2; + y2 = xctx->wire[n].y2; + break; + case LINE: + x1 = xctx->line[c][n].x1; + y1 = xctx->line[c][n].y1; + x2 = xctx->line[c][n].x2; + y2 = xctx->line[c][n].y2; + break; + case POLYGON: + polygon_bbox(xctx->poly[c][n].x, xctx->poly[c][n].y, xctx->poly[c][n].points, &x1, &y1, &x2, &y2); + break; + case ARC: + arc_bbox(xctx->arc[c][n].x, xctx->arc[c][n].y, xctx->arc[c][n].r, + xctx->arc[c][n].a, xctx->arc[c][n].b, &x1, &y1, &x2, &y2); + break; + case xTEXT: + text_bbox(get_text_floater(n), + xctx->text[n].xscale, xctx->text[n].yscale, xctx->text[n].rot, xctx->text[n].flip, + xctx->text[n].hcenter, xctx->text[n].vcenter, + xctx->text[n].x0, xctx->text[n].y0, + &x1,&y1, &x2,&y2, &tmpi, &tmpd); + break; + default: + skip = 1; + x1 = 0.0; + y1 = 0.0; + x2 = 0.0; + y2 = 0.0; + break; + } + if(skip) return; + xctx->n_hash_objects++; /* total number of objects in spatial hash table */ + /* ordered bbox */ + if( x2 < x1) { tmpd=x2;x2=x1;x1=tmpd;} + if( y2 < y1) { tmpd=y2;y2=y1;y1=tmpd;} + + /* calculate square 4 1st bbox point of object[k] */ + x1a=(int)floor(x1/BOXSIZE); + y1a=(int)floor(y1/BOXSIZE); + + /* calculate square 4 2nd bbox point of object[k] */ + x2a=(int)floor(x2/BOXSIZE); + y2a=(int)floor(y2/BOXSIZE); + + /*loop thru all squares that intersect bbox of object[k] */ + counti=0; + for(i=x1a; i<=x2a && counti < NBOXES; ++i) + { + ++counti; + tmpi=i%NBOXES; if(tmpi<0) tmpi+=NBOXES; + countj=0; + for(j=y1a; j<=y2a && countj < NBOXES; ++j) + { + ++countj; + tmpj=j%NBOXES; if(tmpj<0) tmpj+=NBOXES; + /* insert object_ptr[n] in region [tmpi, tmpj] */ + if(what == XINSERT) objectinsert(type, n, c, tmpi, tmpj); + else objectdelete(type, n, c, tmpi, tmpj); + } + } +} + +void hash_objects(void) /* 20171203 insert object bbox in spatial hash table */ +{ + int n, c; + + if(xctx->prep_hash_object) return; + del_object_table(); + for(n=0; ninstances; ++n) { + hash_object(XINSERT, ELEMENT, n, 0); + } + for(n=0; nwires; ++n) { + hash_object(XINSERT, WIRE, n, 0); + } + for(n=0; ntexts; ++n) { + hash_object(XINSERT, xTEXT, n, 0); + } + for(c=0;crects[c]; n++) { + hash_object(XINSERT, xRECT, n, c); + } + for(n=0; nlines[c]; n++) { + hash_object(XINSERT, LINE, n, c); + } + for(n=0; narcs[c]; n++) { + hash_object(XINSERT, ARC, n, c); + } + for(n=0; npolygons[c]; n++) { + hash_object(XINSERT, POLYGON, n, c); + } + + } + xctx->prep_hash_object=1; +} + +/* END HASH ALL OBJECTS */ + static void instpindelete(int n,int pin, int x, int y) { Instpinentry *saveptr, **prevptr, *ptr; diff --git a/src/scheduler.c b/src/scheduler.c index c0250947..ea4d6c15 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -4643,9 +4643,49 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg /* test * Testmode ... */ - else if(!strcmp(argv[1], "test") ) + else if(0 && !strcmp(argv[1], "test") ) { + Iterator_ctx ctx; + Objectentry *objectptr; + int type, n, c; if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} + + hash_objects(); + dbg(0, "n_hash_objects=%d\n", xctx->n_hash_objects); + + for(init_object_iterator(&ctx, 1000., -1000., 2000., -400.); (objectptr = object_iterator_next(&ctx)) ;) { + type = objectptr->type; + n = objectptr->n; + c = objectptr->c; + dbg(0, "type=%d, n=%d c=%d\n", type, n, c); + switch(type) { + case ELEMENT: + select_element(n, SELECTED, 1, 1); + break; + case WIRE: + select_wire(n, SELECTED, 1); + break; + case xTEXT: + select_text(n, SELECTED, 1); + break; + case xRECT: + select_box(c, n, SELECTED, 1, 0); + break; + case LINE: + select_line(c, n, SELECTED, 1); + break; + case POLYGON: + select_polygon(c, n, SELECTED, 1); + break; + case ARC: + select_arc(c, n, SELECTED, 1); + break; + } + } + rebuild_selected_array(); + draw(); + + del_object_table(); Tcl_ResetResult(interp); } diff --git a/src/select.c b/src/select.c index 4441f0db..09e35ec1 100644 --- a/src/select.c +++ b/src/select.c @@ -1260,21 +1260,29 @@ void select_inside(double x1,double y1, double x2, double y2, int sel) /*added u en_s = tclgetboolvar("enable_stretch"); for(i=0;iwires; ++i) { - if(RECT_INSIDE(xctx->wire[i].x1,xctx->wire[i].y1,xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2)) - { - xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ - sel ? select_wire(i,SELECTED, 1): select_wire(i,0, 1); - } - else if( sel && en_s && POINTINSIDE(xctx->wire[i].x1,xctx->wire[i].y1, x1,y1,x2,y2) ) - { - xctx->ui_state |= SELECTION; - select_wire(i,SELECTED1, 1); - } - else if( sel && en_s && POINTINSIDE(xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2) ) - { - xctx->ui_state |= SELECTION; - select_wire(i,SELECTED2, 1); - } + if(sel) { + if(RECT_INSIDE(xctx->wire[i].x1,xctx->wire[i].y1,xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2)) + { + xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ + select_wire(i, SELECTED, 1); + } + else if(en_s && POINTINSIDE(xctx->wire[i].x1,xctx->wire[i].y1, x1,y1,x2,y2) ) + { + xctx->ui_state |= SELECTION; + select_wire(i, SELECTED1, 1); + } + else if(en_s && POINTINSIDE(xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2) ) + { + xctx->ui_state |= SELECTION; + select_wire(i, SELECTED2, 1); + } + } else { + if(RECT_INSIDE(xctx->wire[i].x1,xctx->wire[i].y1,xctx->wire[i].x2,xctx->wire[i].y2, x1,y1,x2,y2)) + { + xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ + select_wire(i, 0, 1); + } + } } for(i=0;itexts; ++i) { @@ -1302,17 +1310,25 @@ void select_inside(double x1,double y1, double x2, double y2, int sel) /*added u } for(i=0;iinstances; ++i) { - if(RECT_INSIDE(xctx->inst[i].xx1, xctx->inst[i].yy1, xctx->inst[i].xx2, xctx->inst[i].yy2, x1,y1,x2,y2)) - { - xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ - if(sel) { - if(strboolcmp(get_tok_value(xctx->inst[i].prop_ptr, "lock", 0), "true")) { - select_element(i, SELECTED, 1, 1); + if(RECT_INSIDE(xctx->inst[i].xx1, xctx->inst[i].yy1, xctx->inst[i].xx2, xctx->inst[i].yy2, x1,y1,x2,y2)) + { + xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ + if(sel) { + if(strboolcmp(get_tok_value(xctx->inst[i].prop_ptr, "lock", 0), "true")) { + select_element(i, SELECTED, 1, 1); + } + } else { + select_element(i, 0, 1, 0); } - } else { - select_element(i, 0, 1, 0); } - } + #if 0 + else { + xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ + if(sel) { + select_element(i, 0, 1, 0); + } + } + #endif } for(c=0;clines[c]; ++i) { - if(RECT_INSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1,xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2)) - { - xctx->ui_state |= SELECTION; - sel? select_line(c,i,SELECTED,1): select_line(c,i,0,1); - } - else if( sel && en_s && POINTINSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1, x1,y1,x2,y2) ) - { - xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ - select_line(c, i,SELECTED1,1); - } - else if( sel && en_s && POINTINSIDE(xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2) ) - { - xctx->ui_state |= SELECTION; - select_line(c, i,SELECTED2,1); - } + if(sel) { + if(RECT_INSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1,xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2)) + { + xctx->ui_state |= SELECTION; + select_line(c,i,SELECTED,1); + } + else if(en_s && POINTINSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1, x1,y1,x2,y2) ) + { + xctx->ui_state |= SELECTION; /* set xctx->ui_state to SELECTION also if unselecting by area ???? */ + select_line(c, i,SELECTED1,1); + } + else if(en_s && POINTINSIDE(xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2) ) + { + xctx->ui_state |= SELECTION; + select_line(c, i,SELECTED2,1); + } + } else { + if(RECT_INSIDE(xctx->line[c][i].x1,xctx->line[c][i].y1,xctx->line[c][i].x2,xctx->line[c][i].y2, x1,y1,x2,y2)) + { + xctx->ui_state |= SELECTION; + select_line(c,i,0,1); + } + } } for(i=0;iarcs[c]; ++i) { x = xctx->arc[c][i].x; diff --git a/src/token.c b/src/token.c index 8e05d920..98561095 100644 --- a/src/token.c +++ b/src/token.c @@ -3618,7 +3618,7 @@ const char *translate(int inst, const char* s) if(net == NULL || net[0] == '\0') { my_strdup2(_ALLOC_ID_, &net, net_name(inst, 0, &multip, 0, 0)); } - if(multip == 1) { + if(multip == 1 && net && net[0] && path) { char *rn; len = strlen(path) + strlen(net) + 1; dbg(1, "translate() @spice_get_voltage: inst=%s\n", instname); @@ -3629,31 +3629,33 @@ const char *translate(int inst, const char* s) */ rn = resolved_net(net); - my_strdup2(_ALLOC_ID_, &fqnet, rn); - if(rn) my_free(_ALLOC_ID_, &rn); - strtolower(fqnet); - dbg(1, "translate() @spice_get_voltage: fqnet=%s start_level=%d\n", fqnet, start_level); - idx = get_raw_index(fqnet); - if(idx >= 0) { - val = xctx->raw->cursor_b_val[idx]; + if(rn) { + my_strdup2(_ALLOC_ID_, &fqnet, rn); + if(rn) my_free(_ALLOC_ID_, &rn); + strtolower(fqnet); + dbg(1, "translate() @spice_get_voltage: fqnet=%s start_level=%d\n", fqnet, start_level); + idx = get_raw_index(fqnet); + if(idx >= 0) { + val = xctx->raw->cursor_b_val[idx]; + } + if(idx < 0) { + valstr = ""; + xctx->tok_size = 0; + len = 0; + } else { + valstr = dtoa_eng(val); + len = xctx->tok_size; + } + if(len) { + STR_ALLOC(&result, len + result_pos, &size); + memcpy(result+result_pos, valstr, len+1); + result_pos += len; + } + dbg(1, "inst %d, net=%s, fqnet=%s idx=%d valstr=%s\n", inst, net, fqnet, idx, valstr); + if(fqnet) my_free(_ALLOC_ID_, &fqnet); } - if(idx < 0) { - valstr = ""; - xctx->tok_size = 0; - len = 0; - } else { - valstr = dtoa_eng(val); - len = xctx->tok_size; - } - if(len) { - STR_ALLOC(&result, len + result_pos, &size); - memcpy(result+result_pos, valstr, len+1); - result_pos += len; - } - dbg(1, "inst %d, net=%s, fqnet=%s idx=%d valstr=%s\n", inst, net, fqnet, idx, valstr); - my_free(_ALLOC_ID_, &fqnet); } - my_free(_ALLOC_ID_, &net); + if(net) my_free(_ALLOC_ID_, &net); } } } diff --git a/src/xinit.c b/src/xinit.c index af9d3383..85f60fb9 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -483,6 +483,7 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->simdata = NULL; xctx->simdata_ninst = 0; xctx->prep_hash_inst = 0; + xctx->prep_hash_object = 0; xctx->prep_hash_wires = 0; xctx->modified = 0; xctx->semaphore = 0; @@ -499,8 +500,10 @@ static void alloc_xschem_data(const char *top_path, const char *win_path) xctx->instpin_spatial_table[i][j] = NULL; xctx->wire_spatial_table[i][j] = NULL; xctx->inst_spatial_table[i][j] = NULL; + xctx->object_spatial_table[i][j] = NULL; } } + xctx->n_hash_objects = 0; xctx->node_table = my_calloc(_ALLOC_ID_, HASHSIZE, sizeof(Node_hashentry *)); xctx->inst_name_table.table = NULL; xctx->inst_name_table.size = 0; diff --git a/src/xschem.h b/src/xschem.h index 53e65d58..2b2f0a1e 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -811,6 +811,17 @@ struct instentry int n; }; + +typedef struct objectentry Objectentry; +struct objectentry +{ + struct objectentry *next; + int type; + int n; + int c; +}; + + typedef struct { int x1a, x2a; @@ -819,8 +830,10 @@ typedef struct int tmpi, tmpj; Instentry *instanceptr; Wireentry *wireptr; + Objectentry *objectptr; unsigned short *instflag; unsigned short *wireflag; + unsigned short *objectflag; } Iterator_ctx; @@ -920,6 +933,7 @@ typedef struct { int prep_net_structs; int prep_hi_structs; int prep_hash_inst; + int prep_hash_object; int prep_hash_wires; Simdata *simdata; int simdata_ninst; @@ -932,6 +946,8 @@ typedef struct { Instpinentry *instpin_spatial_table[NBOXES][NBOXES]; Wireentry *wire_spatial_table[NBOXES][NBOXES]; Instentry *inst_spatial_table[NBOXES][NBOXES]; + Objectentry *object_spatial_table[NBOXES][NBOXES]; /* spatial hash table for all objects (rect selection) */ + int n_hash_objects; /* total number of objects in object_spatial_table */ Window window; Pixmap save_pixmap; XRectangle xrect[1]; @@ -1291,13 +1307,20 @@ extern int text_bbox(const char * str,double xscale, double yscale, extern int get_color(int value); extern void incr_hilight_color(void); -extern void hash_inst(int what, int n); extern void get_inst_pin_coord(int i, int j, double *x, double *y); + extern void del_inst_table(void); -extern void hash_wires(void); -extern void hash_wire(int what, int n, int incremental); +extern void hash_inst(int what, int n); extern void hash_instances(void); /* 20171203 insert instance bbox in spatial hash table */ +extern void del_wire_table(void); +extern void hash_wire(int what, int n, int incremental); +extern void hash_wires(void); + +extern void del_object_table(void); +extern void hash_object(int what, int type, int n, int c); +extern void hash_objects(void); /* hash all objects */ + #if HAS_CAIRO==1 extern cairo_status_t png_reader(void* in_closure, unsigned char* out_data, unsigned int length); extern int text_bbox_nocairo(const char * str,double xscale, double yscale, @@ -1489,8 +1512,13 @@ extern int create_text(int draw_text, double x, double y, int rot, int flip, con const char *props, double hsize, double vsize); extern void init_inst_iterator(Iterator_ctx *ctx, double x1, double y1, double x2, double y2); extern Instentry *inst_iterator_next(Iterator_ctx *ctx); + extern void init_wire_iterator(Iterator_ctx *ctx, double x1, double y1, double x2, double y2); extern Wireentry *wire_iterator_next(Iterator_ctx *ctx); + +extern void init_object_iterator(Iterator_ctx *ctx, double x1, double y1, double x2, double y2); +extern Objectentry *object_iterator_next(Iterator_ctx *ctx); + extern void check_unique_names(int rename); extern unsigned int str_hash(const char *tok); @@ -1647,8 +1675,6 @@ extern void set_clip_mask(int what); extern int pending_events(void); #endif extern void get_square(double x, double y, int *xx, int *yy); -extern void del_wire_table(void); -extern void del_object_table(void); extern const char *create_tmpdir(char *prefix); extern FILE *open_tmpfile(char *prefix, char **filename); extern void create_ps(char** psfile, int what, int fullzoom); diff --git a/src/xschem.tcl b/src/xschem.tcl index bbfdf79d..89be388a 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -2442,7 +2442,7 @@ proc graph_edit_properties {n} { entry .graphdialog.center.right.rawentry -width 30 button .graphdialog.center.right.rawbut -text {Raw file:} -command { .graphdialog.center.right.rawentry delete 0 end - .graphdialog.center.right.rawentry insert 0 [select_raw] + .graphdialog.center.right.rawentry insert 0 [string map [list $netlist_dir {$netlist_dir}] [select_raw]] xschem setprop rect 2 $graph_selected rawfile [.graphdialog.center.right.rawentry get] fast xschem setprop rect 2 $graph_selected sim_type [.graphdialog.center.right.list get] fast if {[file_exists [.graphdialog.center.right.rawentry get]]} {