move "auto join/trim wires" to Options menu, "m" and "ctrl-m" move commands are swapped if enable_stretch is enabled. new_prop_string() now check for true uniqueness (all inst names are expanded with expandlabel() and all bits are hashed). Fixed regression in check_unique_names()
This commit is contained in:
parent
6c7d7080b9
commit
db9c014566
|
|
@ -1392,7 +1392,7 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
|
||||||
xctx->inst[n].prop_ptr=NULL;
|
xctx->inst[n].prop_ptr=NULL;
|
||||||
xctx->inst[n].instname=NULL;
|
xctx->inst[n].instname=NULL;
|
||||||
dbg(1, "place_symbol() :all inst_ptr members set\n"); /* 03-02-2000 */
|
dbg(1, "place_symbol() :all inst_ptr members set\n"); /* 03-02-2000 */
|
||||||
if(first_call) hash_all_names();
|
if(first_call) hash_all_names(-1, XINSERT);
|
||||||
if(inst_props) {
|
if(inst_props) {
|
||||||
new_prop_string(n, inst_props,!first_call, tclgetboolvar("disable_unique_names")); /* 20171214 first_call */
|
new_prop_string(n, inst_props,!first_call, tclgetboolvar("disable_unique_names")); /* 20171214 first_call */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2228,6 +2228,8 @@ int draw_xhair = tclgetboolvar("draw_crosshair");
|
||||||
}
|
}
|
||||||
xctx->mx_double_save=xctx->mousex_snap;
|
xctx->mx_double_save=xctx->mousex_snap;
|
||||||
xctx->my_double_save=xctx->mousey_snap;
|
xctx->my_double_save=xctx->mousey_snap;
|
||||||
|
if(tclgetboolvar("enable_stretch"))
|
||||||
|
select_attached_nets(); /* stretch nets that land on selected instance pins */
|
||||||
move_objects(START,0,0,0);
|
move_objects(START,0,0,0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2244,7 +2246,8 @@ int draw_xhair = tclgetboolvar("draw_crosshair");
|
||||||
{
|
{
|
||||||
xctx->mx_double_save=xctx->mousex_snap;
|
xctx->mx_double_save=xctx->mousex_snap;
|
||||||
xctx->my_double_save=xctx->mousey_snap;
|
xctx->my_double_save=xctx->mousey_snap;
|
||||||
select_attached_nets(); /* stretch nets that land on selected instance pins */
|
if(!tclgetboolvar("enable_stretch"))
|
||||||
|
select_attached_nets(); /* stretch nets that land on selected instance pins */
|
||||||
move_objects(START,0,0,0);
|
move_objects(START,0,0,0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2927,7 +2930,7 @@ int draw_xhair = tclgetboolvar("draw_crosshair");
|
||||||
dbg(1, "callback(): DoubleClick ui_state=%d state=%d\n",xctx->ui_state,state);
|
dbg(1, "callback(): DoubleClick ui_state=%d state=%d\n",xctx->ui_state,state);
|
||||||
if(button==Button1) {
|
if(button==Button1) {
|
||||||
int sel;
|
int sel;
|
||||||
if(!xctx->lastsel) {
|
if(!xctx->lastsel && xctx->ui_state == 0) {
|
||||||
/* Following 5 lines do again a selection overriding lock,
|
/* Following 5 lines do again a selection overriding lock,
|
||||||
* so locked instance attrs can be edited */
|
* so locked instance attrs can be edited */
|
||||||
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 1);
|
sel = select_object(xctx->mousex, xctx->mousey, SELECTED, 1);
|
||||||
|
|
|
||||||
|
|
@ -1430,7 +1430,7 @@ static int update_symbol(const char *result, int x, int first_sel)
|
||||||
}
|
}
|
||||||
/* set unique name of current inst */
|
/* set unique name of current inst */
|
||||||
if(!pushed) { xctx->push_undo(); pushed=1;}
|
if(!pushed) { xctx->push_undo(); pushed=1;}
|
||||||
if(!k) hash_all_names();
|
if(!k) hash_all_names(-1, XINSERT);
|
||||||
new_prop_string(*ii, ptr, k, tclgetboolvar("disable_unique_names")); /* set new prop_ptr */
|
new_prop_string(*ii, ptr, k, tclgetboolvar("disable_unique_names")); /* set new prop_ptr */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1027,7 +1027,7 @@ void copy_objects(int what)
|
||||||
xctx->inst[xctx->instances].flip = (xctx->move_flip? !xctx->inst[n].flip:xctx->inst[n].flip);
|
xctx->inst[xctx->instances].flip = (xctx->move_flip? !xctx->inst[n].flip:xctx->inst[n].flip);
|
||||||
/* the newpropcnt argument is zero for the 1st call and used in */
|
/* the newpropcnt argument is zero for the 1st call and used in */
|
||||||
/* new_prop_string() for cleaning some internal caches. */
|
/* new_prop_string() for cleaning some internal caches. */
|
||||||
if(!newpropcnt) hash_all_names();
|
if(!newpropcnt) hash_all_names(-1, XINSERT);
|
||||||
new_prop_string(xctx->instances, xctx->inst[n].prop_ptr,newpropcnt++,
|
new_prop_string(xctx->instances, xctx->inst[n].prop_ptr,newpropcnt++,
|
||||||
tclgetboolvar("disable_unique_names"));
|
tclgetboolvar("disable_unique_names"));
|
||||||
my_strdup(_ALLOC_ID_, &xctx->inst[xctx->instances].instname,
|
my_strdup(_ALLOC_ID_, &xctx->inst[xctx->instances].instname,
|
||||||
|
|
|
||||||
|
|
@ -273,11 +273,12 @@ static void merge_inst(int k,FILE *fd)
|
||||||
xctx->inst[i].lab=NULL; /* assigned in link_symbols_to_instances */
|
xctx->inst[i].lab=NULL; /* assigned in link_symbols_to_instances */
|
||||||
xctx->inst[i].node=NULL;
|
xctx->inst[i].node=NULL;
|
||||||
load_ascii_string(&prop_ptr,fd);
|
load_ascii_string(&prop_ptr,fd);
|
||||||
if(!k) hash_all_names();
|
my_strdup(_ALLOC_ID_, &xctx->inst[i].prop_ptr, prop_ptr);
|
||||||
|
set_inst_flags(&xctx->inst[i]);
|
||||||
|
if(!k) hash_all_names(-1, XINSERT);
|
||||||
new_prop_string(i, prop_ptr, k, tclgetboolvar("disable_unique_names")); /* will also assign .instname */
|
new_prop_string(i, prop_ptr, k, tclgetboolvar("disable_unique_names")); /* will also assign .instname */
|
||||||
/* the final tmp argument is zero for the 1st call and used in */
|
/* the final tmp argument is zero for the 1st call and used in */
|
||||||
/* new_prop_string() for cleaning some internal caches. */
|
/* new_prop_string() for cleaning some internal caches. */
|
||||||
set_inst_flags(&xctx->inst[i]);
|
|
||||||
my_free(_ALLOC_ID_, &prop_ptr);
|
my_free(_ALLOC_ID_, &prop_ptr);
|
||||||
xctx->instances++;
|
xctx->instances++;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3265,7 +3265,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
||||||
/* 20110325 only modify prefix if prefix not NUL */
|
/* 20110325 only modify prefix if prefix not NUL */
|
||||||
if(prefix) name[0]=(char)prefix; /* change prefix if changing symbol type; */
|
if(prefix) name[0]=(char)prefix; /* change prefix if changing symbol type; */
|
||||||
my_strdup(_ALLOC_ID_, &ptr,subst_token(xctx->inst[inst].prop_ptr, "name", name) );
|
my_strdup(_ALLOC_ID_, &ptr,subst_token(xctx->inst[inst].prop_ptr, "name", name) );
|
||||||
if(!fast) hash_all_names();
|
if(!fast) hash_all_names(-1, XINSERT);
|
||||||
new_prop_string(inst, ptr, fast, tclgetboolvar("disable_unique_names")); /* set new prop_ptr */
|
new_prop_string(inst, ptr, fast, tclgetboolvar("disable_unique_names")); /* set new prop_ptr */
|
||||||
my_strdup(_ALLOC_ID_, &xctx->inst[inst].instname, get_tok_value(xctx->inst[inst].prop_ptr, "name", 0));
|
my_strdup(_ALLOC_ID_, &xctx->inst[inst].instname, get_tok_value(xctx->inst[inst].prop_ptr, "name", 0));
|
||||||
|
|
||||||
|
|
@ -3923,6 +3923,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
||||||
} else {
|
} else {
|
||||||
char *type;
|
char *type;
|
||||||
int cond;
|
int cond;
|
||||||
|
char *subst = NULL;
|
||||||
if(!fast) {
|
if(!fast) {
|
||||||
bbox(START,0.0,0.0,0.0,0.0);
|
bbox(START,0.0,0.0,0.0,0.0);
|
||||||
symbol_bbox(inst, &xctx->inst[inst].x1, &xctx->inst[inst].y1, &xctx->inst[inst].x2, &xctx->inst[inst].y2);
|
symbol_bbox(inst, &xctx->inst[inst].x1, &xctx->inst[inst].y1, &xctx->inst[inst].x2, &xctx->inst[inst].y2);
|
||||||
|
|
@ -3932,14 +3933,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
|
||||||
xctx->prep_hash_inst=0;
|
xctx->prep_hash_inst=0;
|
||||||
xctx->prep_net_structs=0;
|
xctx->prep_net_structs=0;
|
||||||
xctx->prep_hi_structs=0;
|
xctx->prep_hi_structs=0;
|
||||||
if(!strcmp(argv[4], "name")) hash_all_names();
|
if(!strcmp(argv[4], "name")) hash_all_names(-1, XINSERT);
|
||||||
if(argc > 5) {
|
if(argc > 5) {
|
||||||
new_prop_string(inst, subst_token(xctx->inst[inst].prop_ptr, argv[4], argv[5]),fast,
|
my_strdup2(_ALLOC_ID_, &subst, subst_token(xctx->inst[inst].prop_ptr, argv[4], argv[5]));
|
||||||
tclgetboolvar("disable_unique_names"));
|
|
||||||
} else {/* assume argc == 5 , delete attribute */
|
} else {/* assume argc == 5 , delete attribute */
|
||||||
new_prop_string(inst, subst_token(xctx->inst[inst].prop_ptr, argv[4], NULL),fast,
|
my_strdup2(_ALLOC_ID_, &subst, subst_token(xctx->inst[inst].prop_ptr, argv[4], NULL));
|
||||||
tclgetboolvar("disable_unique_names"));
|
|
||||||
}
|
}
|
||||||
|
new_prop_string(inst, subst, fast, tclgetboolvar("disable_unique_names"));
|
||||||
|
my_free(_ALLOC_ID_, &subst);
|
||||||
set_inst_flags(&xctx->inst[inst]);
|
set_inst_flags(&xctx->inst[inst]);
|
||||||
|
|
||||||
type=xctx->sym[xctx->inst[inst].ptr].type;
|
type=xctx->sym[xctx->inst[inst].ptr].type;
|
||||||
|
|
|
||||||
212
src/token.c
212
src/token.c
|
|
@ -54,24 +54,65 @@ void floater_hash_all_names(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hash_all_names(void)
|
/* if inst == -1 hash all instance names, else do only given instance
|
||||||
|
* action can be XINSERT or XDELETE to insert or remove items */
|
||||||
|
void hash_all_names(int inst, int action)
|
||||||
{
|
{
|
||||||
int i;
|
int i, mult, start, stop;
|
||||||
char *upinst = NULL, *type = NULL;
|
char *upinst = NULL;
|
||||||
int_hash_free(&xctx->inst_name_table);
|
char *upinst_ptr, *upinst_state, *single_name;
|
||||||
int_hash_init(&xctx->inst_name_table, HASHSIZE);
|
if(inst == -1) {
|
||||||
for(i=0; i<xctx->instances; ++i) {
|
int_hash_free(&xctx->inst_name_table);
|
||||||
|
int_hash_init(&xctx->inst_name_table, HASHSIZE);
|
||||||
|
}
|
||||||
|
if(inst == -1) {
|
||||||
|
start = 0;
|
||||||
|
stop = xctx->instances;
|
||||||
|
} else {
|
||||||
|
start = inst;
|
||||||
|
stop = inst + 1;
|
||||||
|
}
|
||||||
|
if(inst != -1) dbg(1, "hash_all_names(): start=%d, stop=%d, instname=%s\n",
|
||||||
|
start, stop, xctx->inst[inst].instname? xctx->inst[inst].instname : "NULL");
|
||||||
|
for(i = start; i < stop; ++i) {
|
||||||
if(xctx->inst[i].instname && xctx->inst[i].instname[0]) {
|
if(xctx->inst[i].instname && xctx->inst[i].instname[0]) {
|
||||||
if(xctx->inst[i].ptr == -1) continue;
|
my_strdup(_ALLOC_ID_, &upinst, expandlabel(xctx->inst[i].instname, &mult));
|
||||||
my_strdup(_ALLOC_ID_, &type,(xctx->inst[i].ptr+ xctx->sym)->type);
|
|
||||||
if(!type) continue;
|
|
||||||
my_strdup(_ALLOC_ID_, &upinst, xctx->inst[i].instname);
|
|
||||||
strtoupper(upinst);
|
strtoupper(upinst);
|
||||||
int_hash_lookup(&xctx->inst_name_table, upinst, i, XINSERT);
|
|
||||||
|
upinst_ptr = upinst;
|
||||||
|
while( (single_name = my_strtok_r(upinst_ptr, ",", "", &upinst_state)) ) {
|
||||||
|
upinst_ptr = NULL;
|
||||||
|
dbg(1, "hash_all_names(): inst %d, name %s --> %d\n", i, single_name, action);
|
||||||
|
int_hash_lookup(&xctx->inst_name_table, single_name, i, action);
|
||||||
|
dbg(1, "hash_all_names(): hashing %s from %s\n", single_name, xctx->inst[i].instname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
my_free(_ALLOC_ID_, &upinst);
|
my_free(_ALLOC_ID_, &upinst);
|
||||||
my_free(_ALLOC_ID_, &type);
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* return -1 if name is not used, else return instance number with same name found */
|
||||||
|
int name_is_used(char *name)
|
||||||
|
{
|
||||||
|
int mult, used = -1;
|
||||||
|
char *upinst = NULL;
|
||||||
|
char *upinst_ptr, *upinst_state, *single_name;
|
||||||
|
Int_hashentry *entry;
|
||||||
|
my_strdup(_ALLOC_ID_, &upinst, expandlabel(name, &mult));
|
||||||
|
strtoupper(upinst);
|
||||||
|
upinst_ptr = upinst;
|
||||||
|
while( (single_name = my_strtok_r(upinst_ptr, ",", "", &upinst_state)) ) {
|
||||||
|
upinst_ptr = NULL;
|
||||||
|
entry = int_hash_lookup(&xctx->inst_name_table, single_name, 1, XLOOKUP);
|
||||||
|
if(entry) {
|
||||||
|
used = entry->value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
my_free(_ALLOC_ID_, &upinst);
|
||||||
|
dbg(1, "name_is_used(%s): return inst %d\n", name, used);
|
||||||
|
return used;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* if cmd is wrapped inside tcleval(...) pass the content to tcl
|
/* if cmd is wrapped inside tcleval(...) pass the content to tcl
|
||||||
|
|
@ -107,8 +148,7 @@ void check_unique_names(int rename)
|
||||||
int i, first = 1, modified = 0;
|
int i, first = 1, modified = 0;
|
||||||
int newpropcnt = 0;
|
int newpropcnt = 0;
|
||||||
char *tmp = NULL;
|
char *tmp = NULL;
|
||||||
Int_hashentry *entry;
|
int used;
|
||||||
char *upinst = NULL;
|
|
||||||
|
|
||||||
if(xctx->hilight_nets) {
|
if(xctx->hilight_nets) {
|
||||||
xctx->enable_drill=0;
|
xctx->enable_drill=0;
|
||||||
|
|
@ -124,10 +164,9 @@ void check_unique_names(int rename)
|
||||||
if(xctx->inst[i].instname && xctx->inst[i].instname[0]) {
|
if(xctx->inst[i].instname && xctx->inst[i].instname[0]) {
|
||||||
if(xctx->inst[i].ptr == -1) continue;
|
if(xctx->inst[i].ptr == -1) continue;
|
||||||
if(!(xctx->inst[i].ptr+ xctx->sym)->type) continue;
|
if(!(xctx->inst[i].ptr+ xctx->sym)->type) continue;
|
||||||
my_strdup(_ALLOC_ID_, &upinst, xctx->inst[i].instname);
|
used = name_is_used(xctx->inst[i].instname);
|
||||||
strtoupper(upinst);
|
hash_all_names(i, XINSERT_NOREPLACE);
|
||||||
if( (entry = int_hash_lookup(&xctx->inst_name_table, upinst, i, XINSERT_NOREPLACE) ) &&
|
if( used != -1 && used != i) {
|
||||||
entry->value != i) {
|
|
||||||
dbg(0, "check_unique_names(): found duplicate: i=%d name=%s\n", i, xctx->inst[i].instname);
|
dbg(0, "check_unique_names(): found duplicate: i=%d name=%s\n", i, xctx->inst[i].instname);
|
||||||
xctx->inst[i].color = -PINLAYER;
|
xctx->inst[i].color = -PINLAYER;
|
||||||
inst_hilight_hash_lookup(i, -PINLAYER, XINSERT_NOREPLACE);
|
inst_hilight_hash_lookup(i, -PINLAYER, XINSERT_NOREPLACE);
|
||||||
|
|
@ -153,15 +192,12 @@ void check_unique_names(int rename)
|
||||||
my_strdup(_ALLOC_ID_, &tmp, xctx->inst[i].prop_ptr);
|
my_strdup(_ALLOC_ID_, &tmp, xctx->inst[i].prop_ptr);
|
||||||
new_prop_string(i, tmp, newpropcnt++, 0);
|
new_prop_string(i, tmp, newpropcnt++, 0);
|
||||||
my_strdup(_ALLOC_ID_, &xctx->inst[i].instname, get_tok_value(xctx->inst[i].prop_ptr, "name", 0));
|
my_strdup(_ALLOC_ID_, &xctx->inst[i].instname, get_tok_value(xctx->inst[i].prop_ptr, "name", 0));
|
||||||
my_strdup(_ALLOC_ID_, &upinst, xctx->inst[i].instname);
|
hash_all_names(i, XINSERT);
|
||||||
strtoupper(upinst);
|
|
||||||
int_hash_lookup(&xctx->inst_name_table, upinst, i, XINSERT);
|
|
||||||
symbol_bbox(i, &xctx->inst[i].x1, &xctx->inst[i].y1, &xctx->inst[i].x2, &xctx->inst[i].y2);
|
symbol_bbox(i, &xctx->inst[i].x1, &xctx->inst[i].y1, &xctx->inst[i].x2, &xctx->inst[i].y2);
|
||||||
bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2);
|
bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2);
|
||||||
my_free(_ALLOC_ID_, &tmp);
|
my_free(_ALLOC_ID_, &tmp);
|
||||||
}
|
}
|
||||||
} /* for(i...) */
|
} /* for(i...) */
|
||||||
my_free(_ALLOC_ID_, &upinst);
|
|
||||||
if(modified) set_modify(1);
|
if(modified) set_modify(1);
|
||||||
if(rename == 1 && xctx->hilight_nets) {
|
if(rename == 1 && xctx->hilight_nets) {
|
||||||
bbox(SET,0.0,0.0,0.0,0.0);
|
bbox(SET,0.0,0.0,0.0,0.0);
|
||||||
|
|
@ -730,87 +766,72 @@ static char *get_pin_attr_from_inst(int inst, int pin, const char *attr)
|
||||||
return pin_attr_value; /* caller is responsible for freeing up storage for pin_attr_value */
|
return pin_attr_value; /* caller is responsible for freeing up storage for pin_attr_value */
|
||||||
}
|
}
|
||||||
|
|
||||||
void new_prop_string(int i, const char *old_prop, int fast, int dis_uniq_names)
|
|
||||||
{
|
|
||||||
/* given a old_prop property string, return a new */
|
/* given a old_prop property string, return a new */
|
||||||
/* property string in xctx->inst[i].prop_ptr such that the element name is */
|
/* property string in xctx->inst[i].prop_ptr such that the element name is */
|
||||||
/* unique in current design (that is, element name is changed */
|
/* unique in current design (that is, element name is changed */
|
||||||
/* if necessary) */
|
/* if necessary) */
|
||||||
/* if old_prop=NULL return NULL */
|
/* if old_prop=NULL return NULL */
|
||||||
/* if old_prop does not contain a valid "name" or empty return old_prop */
|
/* if old_prop does not contain a valid "name" or empty return old_prop */
|
||||||
char *old_name=NULL, *new_name=NULL;
|
void new_prop_string(int i, const char *old_prop, int fast, int dis_uniq_names)
|
||||||
const char *tmp;
|
{
|
||||||
const char *tmp2;
|
char *old_name=NULL, *new_name=NULL;
|
||||||
int q,qq;
|
const char *brkt;
|
||||||
static int last[1 << 8 * sizeof(char) ]; /* safe to keep with multiple schematics, reset on 1st invocation */
|
const char *new_prop;
|
||||||
size_t old_name_len;
|
size_t old_name_len;
|
||||||
int n;
|
int n, q;
|
||||||
char *old_name_base = NULL;
|
char *old_name_base = NULL;
|
||||||
Int_hashentry *entry;
|
char *up_new_name = NULL;
|
||||||
char *up_old_name = NULL;
|
int is_used;
|
||||||
char *up_new_name = NULL;
|
|
||||||
|
dbg(1, "new_prop_string(): i=%d, old_prop=%s, fast=%d\n", i, old_prop, fast);
|
||||||
dbg(1, "new_prop_string(): i=%d, old_prop=%s, fast=%d\n", i, old_prop, fast);
|
if(old_prop==NULL) {
|
||||||
if(!fast) { /* on 1st invocation of new_prop_string */
|
my_free(_ALLOC_ID_, &xctx->inst[i].prop_ptr);
|
||||||
for(q=1;q<=255;q++) last[q]=1;
|
return;
|
||||||
}
|
}
|
||||||
if(old_prop==NULL)
|
old_name_len = my_strdup(_ALLOC_ID_, &old_name,get_tok_value(old_prop,"name",0) ); /* added old_name_len */
|
||||||
{
|
|
||||||
my_free(_ALLOC_ID_, &xctx->inst[i].prop_ptr);
|
if(old_name==NULL) {
|
||||||
return;
|
my_strdup(_ALLOC_ID_, &xctx->inst[i].prop_ptr, old_prop); /* changed to copy old props if no name */
|
||||||
}
|
return;
|
||||||
old_name_len = my_strdup(_ALLOC_ID_, &old_name,get_tok_value(old_prop,"name",0) ); /* added old_name_len */
|
}
|
||||||
my_strdup(_ALLOC_ID_, &up_old_name, old_name);
|
/* don't change old_prop if name does not conflict. */
|
||||||
strtoupper(up_old_name);
|
/* if no hash_all_names() is done and inst_table uninitialized --> use old_prop */
|
||||||
|
is_used = name_is_used(old_name);
|
||||||
if(old_name==NULL)
|
if(dis_uniq_names || is_used == -1 || is_used == i) {
|
||||||
{
|
my_strdup(_ALLOC_ID_, &xctx->inst[i].prop_ptr, old_prop);
|
||||||
my_strdup(_ALLOC_ID_, &xctx->inst[i].prop_ptr, old_prop); /* changed to copy old props if no name */
|
hash_all_names(i, XINSERT); /* add instance 'i' to xctx->inst_name_table */
|
||||||
my_free(_ALLOC_ID_, &up_old_name);
|
my_free(_ALLOC_ID_, &old_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xctx->prefix=old_name[0];
|
/* old_name is not unique. Find another unique name */
|
||||||
/* don't change old_prop if name does not conflict. */
|
old_name_base = my_malloc(_ALLOC_ID_, old_name_len+1);
|
||||||
/* if no hash_all_names() is done and inst_table uninitialized --> use old_prop */
|
n = sscanf(old_name, "%[^[0-9]",old_name_base);
|
||||||
if(dis_uniq_names || (entry = int_hash_lookup(&xctx->inst_name_table, up_old_name, i, XLOOKUP))==NULL ||
|
brkt=find_bracket(old_name);
|
||||||
entry->value == i)
|
my_realloc(_ALLOC_ID_, &new_name, old_name_len + 40); /* strlen(old_name)+40); */
|
||||||
{
|
|
||||||
my_strdup(_ALLOC_ID_, &xctx->inst[i].prop_ptr, old_prop);
|
for(q = 1 ;; ++q) {
|
||||||
int_hash_lookup(&xctx->inst_name_table, up_old_name, i, XINSERT);
|
if(n) {
|
||||||
my_free(_ALLOC_ID_, &old_name);
|
my_snprintf(new_name, old_name_len + 40, "%s%d%s", old_name_base, q, brkt);
|
||||||
my_free(_ALLOC_ID_, &up_old_name);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
old_name_base = my_malloc(_ALLOC_ID_, old_name_len+1);
|
|
||||||
n = sscanf(old_name, "%[^[0-9]",old_name_base);
|
|
||||||
tmp=find_bracket(old_name);
|
|
||||||
my_realloc(_ALLOC_ID_, &new_name, old_name_len + 40); /* strlen(old_name)+40); */
|
|
||||||
qq=fast ? last[(int)xctx->prefix] : 1;
|
|
||||||
for(q=qq;;q++)
|
|
||||||
{
|
|
||||||
if(n >= 1 ) {
|
|
||||||
my_snprintf(new_name, old_name_len + 40, "%s%d%s", old_name_base, q, tmp);
|
|
||||||
} else { /* goes here if weird name set for example to name=[3:0] or name=12 */
|
} else { /* goes here if weird name set for example to name=[3:0] or name=12 */
|
||||||
my_snprintf(new_name, old_name_len + 40, "%c%d%s", xctx->prefix,q, tmp);
|
my_snprintf(new_name, old_name_len + 40, "%d%s", q, brkt);
|
||||||
}
|
}
|
||||||
my_strdup(_ALLOC_ID_, &up_new_name, new_name);
|
is_used = name_is_used(new_name);
|
||||||
strtoupper(up_new_name);
|
if(is_used == -1 ) break;
|
||||||
if((entry = int_hash_lookup(&xctx->inst_name_table, up_new_name, i, XLOOKUP)) == NULL || entry->value == i)
|
}
|
||||||
{
|
|
||||||
last[(int)xctx->prefix]=q+1;
|
my_free(_ALLOC_ID_, &old_name_base);
|
||||||
break;
|
dbg(1, "new_prop_string(): new_name=%s\n", new_name);
|
||||||
}
|
new_prop = subst_token(old_prop, "name", new_name);
|
||||||
}
|
dbg(1, "new_prop_string(): old_prop=|%s|\n", old_prop);
|
||||||
my_free(_ALLOC_ID_, &old_name_base);
|
dbg(1, "new_prop_string(): new_prop=|%s|\n", new_prop);
|
||||||
tmp2 = subst_token(old_prop, "name", new_name);
|
if(strcmp(new_prop, old_prop) ) {
|
||||||
if(strcmp(tmp2, old_prop) ) {
|
my_strdup(_ALLOC_ID_, &xctx->inst[i].prop_ptr, new_prop);
|
||||||
my_strdup(_ALLOC_ID_, &xctx->inst[i].prop_ptr, tmp2);
|
my_strdup2(_ALLOC_ID_, &xctx->inst[i].instname, new_name);
|
||||||
int_hash_lookup(&xctx->inst_name_table, up_new_name, i, XINSERT); /* reinsert in hash */
|
hash_all_names(i, XINSERT);
|
||||||
}
|
}
|
||||||
my_free(_ALLOC_ID_, &old_name);
|
my_free(_ALLOC_ID_, &old_name);
|
||||||
my_free(_ALLOC_ID_, &up_old_name);
|
my_free(_ALLOC_ID_, &new_name);
|
||||||
my_free(_ALLOC_ID_, &new_name);
|
my_free(_ALLOC_ID_, &up_new_name);
|
||||||
my_free(_ALLOC_ID_, &up_new_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1108,6 +1129,7 @@ const char *subst_token(const char *s, const char *tok, const char *new_val)
|
||||||
/* if tok not found in s and new_val!=NULL add tok=new_val at end.*/
|
/* if tok not found in s and new_val!=NULL add tok=new_val at end.*/
|
||||||
/* if new_val is empty ('\0') set token value to "" (token="") */
|
/* if new_val is empty ('\0') set token value to "" (token="") */
|
||||||
/* if new_val is NULL *remove* 'token (and =val if any)' from s */
|
/* if new_val is NULL *remove* 'token (and =val if any)' from s */
|
||||||
|
/* return the updated string */
|
||||||
{
|
{
|
||||||
static char *result=NULL;
|
static char *result=NULL;
|
||||||
size_t size=0;
|
size_t size=0;
|
||||||
|
|
|
||||||
|
|
@ -989,7 +989,6 @@ typedef struct {
|
||||||
int bbox_set; /* set to 1 if a clipping bbox is set (void bbox() ) */
|
int bbox_set; /* set to 1 if a clipping bbox is set (void bbox() ) */
|
||||||
XRectangle savexrect;
|
XRectangle savexrect;
|
||||||
/* new_prop_string */
|
/* new_prop_string */
|
||||||
char prefix;
|
|
||||||
/* edit_symbol_property, update_symbol */
|
/* edit_symbol_property, update_symbol */
|
||||||
char *old_prop;
|
char *old_prop;
|
||||||
int edit_sym_i;
|
int edit_sym_i;
|
||||||
|
|
@ -1503,7 +1502,8 @@ extern float my_atof(const char *p);
|
||||||
extern const char *subst_token(const char *s, const char *tok, const char *new_val);
|
extern const char *subst_token(const char *s, const char *tok, const char *new_val);
|
||||||
extern void new_prop_string(int i, const char *old_prop,int fast, int dis_uniq_names);
|
extern void new_prop_string(int i, const char *old_prop,int fast, int dis_uniq_names);
|
||||||
extern void hash_name(char *token, int remove);
|
extern void hash_name(char *token, int remove);
|
||||||
extern void hash_all_names(void);
|
extern void hash_all_names(int inst, int action); /* if i == -1 hash all instances, else do only inst */
|
||||||
|
extern int name_is_used(char *name);
|
||||||
extern void floater_hash_all_names(void);
|
extern void floater_hash_all_names(void);
|
||||||
extern void symbol_bbox(int i, double *x1,double *y1, double *x2, double *y2);
|
extern void symbol_bbox(int i, double *x1,double *y1, double *x2, double *y2);
|
||||||
/* extern char *escape_chars(char *dest, const char *source, int size); */
|
/* extern char *escape_chars(char *dest, const char *source, int size); */
|
||||||
|
|
|
||||||
|
|
@ -5983,6 +5983,15 @@ proc build_widgets { {topwin {} } } {
|
||||||
-onvalue disk -offvalue memory -command {switch_undo}
|
-onvalue disk -offvalue memory -command {switch_undo}
|
||||||
$topwin.menubar.option.menu add checkbutton -label "Enable stretch" -variable enable_stretch \
|
$topwin.menubar.option.menu add checkbutton -label "Enable stretch" -variable enable_stretch \
|
||||||
-accelerator Y
|
-accelerator Y
|
||||||
|
|
||||||
|
$topwin.menubar.option.menu add checkbutton -label "Auto Join/Trim Wires" -variable autotrim_wires \
|
||||||
|
-command {
|
||||||
|
if {$autotrim_wires == 1} {
|
||||||
|
xschem trim_wires
|
||||||
|
xschem redraw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$topwin.menubar.option.menu add checkbutton -label "Show netlist win" -variable netlist_show \
|
$topwin.menubar.option.menu add checkbutton -label "Show netlist win" -variable netlist_show \
|
||||||
-accelerator {Shift+A}
|
-accelerator {Shift+A}
|
||||||
$topwin.menubar.option.menu add checkbutton -label "Flat netlist" -variable flat_netlist \
|
$topwin.menubar.option.menu add checkbutton -label "Flat netlist" -variable flat_netlist \
|
||||||
|
|
@ -6248,13 +6257,6 @@ proc build_widgets { {topwin {} } } {
|
||||||
$topwin.menubar.tools.menu add command -label "Break wires at mouse position, align cut point" \
|
$topwin.menubar.tools.menu add command -label "Break wires at mouse position, align cut point" \
|
||||||
-command "xschem wire_cut" -accelerator {Alt-Right Butt.}
|
-command "xschem wire_cut" -accelerator {Alt-Right Butt.}
|
||||||
toolbar_add ToolBreak "xschem break_wires" "Break wires at selected\ninstance pin intersections" $topwin
|
toolbar_add ToolBreak "xschem break_wires" "Break wires at selected\ninstance pin intersections" $topwin
|
||||||
$topwin.menubar.tools.menu add checkbutton -label "Auto Join/Trim Wires" -variable autotrim_wires \
|
|
||||||
-command {
|
|
||||||
if {$autotrim_wires == 1} {
|
|
||||||
xschem trim_wires
|
|
||||||
xschem redraw
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$topwin.menubar.tools.menu add command -label "Select all connected wires/labels/pins" \
|
$topwin.menubar.tools.menu add command -label "Select all connected wires/labels/pins" \
|
||||||
-accelerator {Shift-Right Butt.} \
|
-accelerator {Shift-Right Butt.} \
|
||||||
-command { xschem connected_nets}
|
-command { xschem connected_nets}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue