refactor str_hash_* and int_hash_* functions

This commit is contained in:
Stefan Frederik 2022-10-05 01:18:45 +02:00
parent 1c407e5dd6
commit 5fe2f1586b
12 changed files with 173 additions and 139 deletions

View File

@ -1853,7 +1853,6 @@ void new_wire(int what, double mx_snap, double my_snap)
{
int big = xctx->wires> 2000 || xctx->instances > 2000 ;
int s_pnetname;
xctx->hash_size = HASHSIZE;
if( (what & PLACE) ) {
s_pnetname = tclgetboolvar("show_pin_net_names");
if( (xctx->ui_state & STARTWIRE) && (xctx->nl_x1!=xctx->nl_x2 || xctx->nl_y1!=xctx->nl_y2) ) {
@ -1907,7 +1906,8 @@ void new_wire(int what, double mx_snap, double my_snap)
* this clears both xctx->prep_hi_structs and xctx->prep_net_structs. */
if(!big) {
bbox(START , 0.0 , 0.0 , 0.0 , 0.0);
int_hash_lookup(xctx->node_redraw_table, xctx->wire[xctx->wires-1].node, 0, XINSERT_NOREPLACE);
if(xctx->node_redraw_table.table == NULL) int_hash_init(&xctx->node_redraw_table, HASHSIZE);
int_hash_lookup(&(xctx->node_redraw_table), xctx->wire[xctx->wires-1].node, 0, XINSERT_NOREPLACE);
}
if(!big) {
find_inst_to_be_redrawn(1 + 4 + 8); /* add bboxes before and after symbol_bbox, don't use selection */

View File

@ -492,15 +492,16 @@ void find_inst_to_be_redrawn(int what)
int s_pnetname = tclgetboolvar("show_pin_net_names");
xctx->hash_size = HASHSIZE;
dbg(1,"find_inst_to_be_redrawn(): what=%d\n", what);
if(what & 16) {
my_free(1202, &xctx->inst_redraw_table);
xctx->inst_redraw_table_size = 0;
if((s_pnetname || xctx->hilight_nets)) int_hash_free(xctx->node_redraw_table);
if((s_pnetname || xctx->hilight_nets)) int_hash_free(&xctx->node_redraw_table);
return;
}
if((s_pnetname || xctx->hilight_nets)) {
if(xctx->node_redraw_table.table == NULL) int_hash_init(&xctx->node_redraw_table, HASHSIZE);
if(what & 32) prepare_netlist_structs(0);
if(!(what & 8)) {
for(i=0;i<xctx->lastsel;i++)
@ -514,14 +515,14 @@ void find_inst_to_be_redrawn(int what)
for(p = 0; p < (inst[n].ptr + xctx->sym)->rects[PINLAYER]; p++) {
if( inst[n].node && inst[n].node[p]) {
dbg(1,"find_inst_to_be_redrawn(): hashing inst %s, node %s\n", inst[n].instname, inst[n].node[p]);
int_hash_lookup(xctx->node_redraw_table, xctx->inst[n].node[p], 0, XINSERT_NOREPLACE);
int_hash_lookup(&xctx->node_redraw_table, xctx->inst[n].node[p], 0, XINSERT_NOREPLACE);
}
}
}
}
/* collect all nodes connected to selected wires (node names will change if wire deleted/moved) */
if(xctx->sel_array[i].type == WIRE) {
int_hash_lookup(xctx->node_redraw_table, xctx->wire[n].node, 0, XINSERT_NOREPLACE);
int_hash_lookup(&xctx->node_redraw_table, xctx->wire[n].node, 0, XINSERT_NOREPLACE);
}
}
} /* if(!(what & 8)) */
@ -544,7 +545,7 @@ void find_inst_to_be_redrawn(int what)
}
for(p = 0; p < rects; p++) {
if(xctx->inst[i].node && xctx->inst[i].node[p]) {
nentry = int_hash_lookup(xctx->node_redraw_table, xctx->inst[i].node[p], 0, XLOOKUP);
nentry = int_hash_lookup(&xctx->node_redraw_table, xctx->inst[i].node[p], 0, XLOOKUP);
if(nentry) {
dbg(1, "find_inst_to_be_redrawn(): 2 bboxing inst %s\n", xctx->inst[i].instname);
if(what & 1) bbox(ADD, xctx->inst[i].x1, xctx->inst[i].y1, xctx->inst[i].x2, xctx->inst[i].y2);
@ -561,7 +562,7 @@ void find_inst_to_be_redrawn(int what)
if(what & 5) for(i=0;i < xctx->wires; i++) {
if(xctx->wire[i].node) {
nentry = int_hash_lookup(xctx->node_redraw_table, xctx->wire[i].node, 0, XLOOKUP);
nentry = int_hash_lookup(&xctx->node_redraw_table, xctx->wire[i].node, 0, XLOOKUP);
if(nentry) {
if(xctx->wire[i].bus){
double ov, y1, y2;

View File

@ -635,38 +635,37 @@ static void name_pass_through_nets()
Instpinentry *iptr;
xInstance * const inst = xctx->inst;
int const instances = xctx->instances;
Str_hashentry *table[17];
Str_hashtable table = {NULL, 0};
Str_hashentry *entry;
const char *pin_name;
int *pt_symbol = NULL; /* pass-through symbols, symbols with duplicated ports */
int there_are_pt = 0;
xctx->hash_size = 17;
pt_symbol = my_calloc(1573, xctx->symbols, sizeof(int));
pt_symbol = my_calloc(973, xctx->symbols, sizeof(int));
for(i = 0; i < xctx->symbols; i++) {
memset(table, 0, xctx->hash_size * sizeof(Str_hashentry *));
str_hash_init(&table, 17);
for(j = 0; j < xctx->sym[i].rects[PINLAYER]; j++) {
const char *pin_name = get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr, "name", 0);
entry = str_hash_lookup(table, pin_name, "1", XINSERT_NOREPLACE);
entry = str_hash_lookup(&table, pin_name, "1", XINSERT_NOREPLACE);
if(entry) {
pt_symbol[i] = 1;
there_are_pt = 1;
}
}
str_hash_free(&table);
if(pt_symbol[i]) dbg(1, "duplicated pins: %s\n", xctx->sym[i].name);
}
str_hash_free(table);
if(!there_are_pt) { /* nothing to do: no pass through symbols */
my_free(1573, &pt_symbol);
return;
}
do { /* keep looping until propagation of nets occurs */
changed = 0;
memset(table, 0, xctx->hash_size * sizeof(Str_hashentry *));
for (i=0;i<instances;i++) {
dbg(1, "instance %d: %s\n", i, inst[i].instname);
if(inst[i].ptr<0) continue;
if(!pt_symbol[ inst[i].ptr ]) continue;
str_hash_init(&table, 17);
my_strdup(1565, &type, (inst[i].ptr + xctx->sym)->type);
if (type && !IS_LABEL_OR_PIN(type) ) {
if ((rects = (inst[i].ptr+ xctx->sym)->rects[PINLAYER]) > 0) {
@ -689,7 +688,7 @@ static void name_pass_through_nets()
xctx->wire[wptr->n].x2, xctx->wire[wptr->n].y2, x0,y0)) {
if(xctx->wire[wptr->n].node) {
dbg(1, "pin_name=%s, node=%s\n", pin_name, xctx->wire[wptr->n].node);
entry = str_hash_lookup(table, pin_name, xctx->wire[wptr->n].node, XINSERT_NOREPLACE);
entry = str_hash_lookup(&table, pin_name, xctx->wire[wptr->n].node, XINSERT_NOREPLACE);
if(entry) signal_short(xctx->wire[wptr->n].node, entry->value);
}
}
@ -710,7 +709,7 @@ static void name_pass_through_nets()
if ((iptr->x0==x0) && (iptr->y0==y0)) {
if(xctx->inst[iptr->n].node[0]) {
dbg(1, "pin_name=%s, node=%s\n", pin_name, xctx->inst[iptr->n].node[0]);
entry = str_hash_lookup(table, pin_name, xctx->inst[iptr->n].node[0], XINSERT_NOREPLACE);
entry = str_hash_lookup(&table, pin_name, xctx->inst[iptr->n].node[0], XINSERT_NOREPLACE);
if(entry) signal_short(xctx->inst[iptr->n].node[0], entry->value);
}
@ -736,7 +735,7 @@ static void name_pass_through_nets()
xctx->wire[wptr->n].x2, xctx->wire[wptr->n].y2, x0,y0)) {
if(!xctx->wire[wptr->n].node) { /* net is unnamed */
dbg(1, "lookup pin_name=%s\n", pin_name);
entry = str_hash_lookup(table, pin_name, NULL, XLOOKUP);
entry = str_hash_lookup(&table, pin_name, NULL, XLOOKUP);
if(entry) { /* found duplicated pin */
my_strdup(1568, &xctx->wire[wptr->n].node, entry->value);
my_strdup(1569, &xctx->wire[wptr->n].prop_ptr,
@ -751,13 +750,12 @@ static void name_pass_through_nets()
} /* for (j=0;j<rects;j++) */
} /* if ((rects = (inst[i].ptr+ xctx->sym)->rects[PINLAYER]) > 0) */
} /* if (type && !IS_LABEL_OR_PIN(type) ) */
str_hash_free(table);
str_hash_free(&table);
} /* for (i=0;i<instances;i++) */
} while(changed);
my_free(1570, &type);
my_free(1571, &type2);
my_free(1572, &pt_symbol);
xctx->hash_size = HASHSIZE;
}
@ -1196,13 +1194,12 @@ void prepare_netlist_structs(int for_netlist)
int warning_overlapped_symbols(int sel)
{
int i;
Int_hashentry *table[HASHSIZE];
Int_hashtable table = {NULL, 0};
Int_hashentry *found;
char str[2048];
char s[512];
xctx->hash_size = HASHSIZE;
memset(table, 0, HASHSIZE * sizeof(Int_hashentry *));
int_hash_init(&table, HASHSIZE);
for(i = 0; i < xctx->instances; i++) {
dbg(1, "instance:%s: %s\n", xctx->inst[i].instname, xctx->inst[i].name);
my_snprintf(s, S(s), "%g %g %g %g",
@ -1210,7 +1207,7 @@ int warning_overlapped_symbols(int sel)
dbg(1, " bbox: %g %g %g %g\n", xctx->inst[i].xx1, xctx->inst[i].yy1, xctx->inst[i].xx2, xctx->inst[i].yy2);
dbg(1, " s=%s\n", s);
found = int_hash_lookup(table, s, i, XINSERT_NOREPLACE);
found = int_hash_lookup(&table, s, i, XINSERT_NOREPLACE);
if(found) {
if(sel == 0) {
xctx->inst[i].color = -PINLAYER;
@ -1225,7 +1222,7 @@ int warning_overlapped_symbols(int sel)
tcleval("show_infotext"); /* critical error: force ERC window showing */
}
}
int_hash_free(table);
int_hash_free(&table);
if(sel && xctx->need_reb_sel_arr) rebuild_selected_array();
return 0;
}

View File

@ -304,7 +304,6 @@ static int read_dataset(FILE *fd, const char *type)
int n = 0, done_header = 0, ac = 0;
int exit_status = 0, npoints, nvars;
int dbglev=1;
xctx->hash_size = HASHSIZE;
xctx->graph_sim_type = NULL;
dbg(1, "read_dataset(): type=%s\n", type ? type : "<NULL>");
while((fgets(line, sizeof(line), fd)) ) {
@ -397,7 +396,7 @@ static int read_dataset(FILE *fd, const char *type)
n = sscanf(line, "No. Variables: %d", &nvars);
dbg(dbglev, "read_dataset(): nvars=%d\n", nvars);
if(xctx->graph_datasets > 0 && xctx->graph_nvars != nvars) {
if(xctx->graph_datasets > 0 && xctx->graph_nvars != nvars && xctx->graph_sim_type) {
dbg(0, "Xschem requires all datasets to be saved with identical and same number of variables\n");
dbg(0, "There is a mismatch, so this and following datasets will not be read\n");
return 1;
@ -447,15 +446,15 @@ static int read_dataset(FILE *fd, const char *type)
}
if(xctx->graph_sim_type && !strcmp(xctx->graph_sim_type, "ac")) { /* AC */
my_strcat(415, &xctx->graph_names[i << 1], varname);
int_hash_lookup(xctx->graph_raw_table, xctx->graph_names[i << 1], (i << 1), XINSERT_NOREPLACE);
int_hash_lookup(&xctx->graph_raw_table, xctx->graph_names[i << 1], (i << 1), XINSERT_NOREPLACE);
if(strstr(varname, "v(") == varname || strstr(varname, "i(") == varname)
my_mstrcat(664, &xctx->graph_names[(i << 1) + 1], "ph(", varname + 2, NULL);
else
my_mstrcat(540, &xctx->graph_names[(i << 1) + 1], "ph(", varname, ")", NULL);
int_hash_lookup(xctx->graph_raw_table, xctx->graph_names[(i << 1) + 1], (i << 1) + 1, XINSERT_NOREPLACE);
int_hash_lookup(&xctx->graph_raw_table, xctx->graph_names[(i << 1) + 1], (i << 1) + 1, XINSERT_NOREPLACE);
} else {
my_strcat(541, &xctx->graph_names[i], varname);
int_hash_lookup(xctx->graph_raw_table, xctx->graph_names[i], i, XINSERT_NOREPLACE);
int_hash_lookup(&xctx->graph_raw_table, xctx->graph_names[i], i, XINSERT_NOREPLACE);
}
/* use hash table to store index number of variables */
dbg(dbglev, "read_dataset(): get node list -> names[%d] = %s\n", i, xctx->graph_names[i]);
@ -477,7 +476,6 @@ void free_rawfile(int dr)
int i;
int deleted = 0;
xctx->hash_size = HASHSIZE;
if(xctx->graph_names) {
deleted = 1;
for(i = 0 ; i < xctx->graph_nvars; i++) {
@ -501,7 +499,7 @@ void free_rawfile(int dr)
xctx->graph_datasets = 0;
xctx->graph_nvars = 0;
xctx->graph_annotate_p = -1;
int_hash_free(xctx->graph_raw_table);
if(xctx->graph_raw_table.table) int_hash_free(&xctx->graph_raw_table);
if(deleted && dr) draw();
}
@ -570,6 +568,7 @@ int raw_read(const char *f, const char *type)
{
int res = 0;
FILE *fd;
int_hash_init(&xctx->graph_raw_table, HASHSIZE);
if(xctx->graph_values || xctx->graph_npoints || xctx->graph_nvars || xctx->graph_datasets) {
dbg(0, "raw_read(): must clear current raw file before loading new\n");
return res;
@ -608,21 +607,20 @@ int get_raw_index(const char *node)
dbg(1, "get_raw_index(): node=%s\n", node);
xctx->hash_size = HASHSIZE;
if(sch_waves_loaded() >= 0) {
my_strncpy(inode, node, S(inode));
strtolower(inode);
entry = int_hash_lookup(xctx->graph_raw_table, inode, 0, XLOOKUP);
entry = int_hash_lookup(&xctx->graph_raw_table, inode, 0, XLOOKUP);
if(!entry) {
my_snprintf(vnode, S(vnode), "v(%s)", inode);
entry = int_hash_lookup(xctx->graph_raw_table, vnode, 0, XLOOKUP);
entry = int_hash_lookup(&xctx->graph_raw_table, vnode, 0, XLOOKUP);
}
if(!entry && strstr(inode, "i(v.x")) {
char *ptr = inode;
inode[2] = 'i';
inode[3] = '(';
ptr += 2;
entry = int_hash_lookup(xctx->graph_raw_table, ptr, 0, XLOOKUP);
entry = int_hash_lookup(&xctx->graph_raw_table, ptr, 0, XLOOKUP);
}
if(entry) return entry->value;
}
@ -2446,14 +2444,13 @@ void pop_undo(int redo, int set_modify_status)
* if pintable given (!=NULL) hash all symbol pins
* if embed_fd is not NULL read symbol from embedded '[...]' tags using embed_fd file pointer */
static void get_sym_type(const char *symname, char **type,
Int_hashentry **pintable, FILE *embed_fd, int *sym_n_pins)
Int_hashtable *pintable, FILE *embed_fd, int *sym_n_pins)
{
int i, c, n = 0;
char name[PATH_MAX];
FILE *fd;
char tag[1];
int found = 0;
xctx->hash_size = HASHSIZE;
if(!strcmp(xctx->file_version,"1.0")) {
my_strncpy(name, abs_sym_path(symname, ".sym"), S(name));
} else {
@ -2550,14 +2547,13 @@ static void align_sch_pins_with_sym(const char *name, int pos)
char *symtype = NULL;
const char *pinname;
int i, fail = 0, sym_n_pins=0;
Int_hashentry *pintable[HASHSIZE];
Int_hashtable pintable = {NULL, 0};
xctx->hash_size = HASHSIZE;
if ((ptr = strrchr(name, '.')) && !strcmp(ptr, ".sch")) {
my_strncpy(symname, add_ext(name, ".sym"), S(symname));
memset(pintable, 0, HASHSIZE * sizeof(Int_hashentry *));
int_hash_init(&pintable, HASHSIZE);
/* hash all symbol pins with their position into pintable hash*/
get_sym_type(symname, &symtype, pintable, NULL, &sym_n_pins);
get_sym_type(symname, &symtype, &pintable, NULL, &sym_n_pins);
if(symtype[0]) { /* found a .sym for current .sch LCC instance */
xRect *rect = NULL;
if (sym_n_pins!=xctx->sym[pos].rects[PINLAYER]) {
@ -2570,7 +2566,7 @@ static void align_sch_pins_with_sym(const char *name, int pos)
for(i=0; i < xctx->sym[pos].rects[PINLAYER]; i++) {
Int_hashentry *entry;
pinname = get_tok_value(xctx->sym[pos].rect[PINLAYER][i].prop_ptr, "name", 0);
entry = int_hash_lookup(pintable, pinname, 0 , XLOOKUP);
entry = int_hash_lookup(&pintable, pinname, 0 , XLOOKUP);
if(!entry) {
dbg(0, " align_sch_pins_with_sym(): warning: pin mismatch between %s and %s : %s\n",
name, symname, pinname);
@ -2586,9 +2582,9 @@ static void align_sch_pins_with_sym(const char *name, int pos)
xctx->sym[pos].rect[PINLAYER][i] = rect[i];
}
}
int_hash_free(pintable);
my_free(1169, &rect);
}
int_hash_free(&pintable);
my_free(1170, &symtype);
}
}

View File

@ -2098,8 +2098,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
/* xschem rawfile_query index v(ldcp) */
Int_hashentry *entry;
int idx;
xctx->hash_size = HASHSIZE;
entry = int_hash_lookup(xctx->graph_raw_table, argv[3], 0, XLOOKUP);
entry = int_hash_lookup(&xctx->graph_raw_table, argv[3], 0, XLOOKUP);
idx = entry ? entry->value : -1;
Tcl_SetResult(interp, my_itoa(idx), TCL_VOLATILE);
} else if(argc > 3 && !strcmp(argv[2], "values")) {

View File

@ -22,9 +22,9 @@
#include "xschem.h"
static Str_hashentry *model_table[HASHSIZE]; /* safe even with multiple schematics */
static Str_hashtable model_table = {NULL, 0}; /* safe even with multiple schematics */
static Str_hashentry *model_entry; /* safe even with multiple schematics */
static Str_hashentry *subckt_table[HASHSIZE]; /* safe even with multiple schematics */
static Str_hashtable subckt_table = {NULL, 0}; /* safe even with multiple schematics */
void hier_psprint(void) /* netlister driver */
{
@ -33,10 +33,9 @@ void hier_psprint(void) /* netlister driver */
char filename[PATH_MAX];
char *abs_path = NULL;
xctx->hash_size = HASHSIZE;
if(!ps_draw(1)) return; /* prolog */
xctx->push_undo();
str_hash_free(subckt_table);
str_hash_init(&subckt_table, HASHSIZE);
zoom_full(0, 0, 1, 0.97);
ps_draw(2); /* page */
dbg(1,"--> %s\n", skip_dir( xctx->sch[xctx->currsch]) );
@ -59,9 +58,9 @@ void hier_psprint(void) /* netlister driver */
{
/* xctx->sym can be SCH or SYM, use hash to avoid writing duplicate subckt */
my_strdup(1228, &subckt_name, get_cell(xctx->sym[i].name, 0));
if (str_hash_lookup(subckt_table, subckt_name, "", XLOOKUP)==NULL)
if (str_hash_lookup(&subckt_table, subckt_name, "", XLOOKUP)==NULL)
{
str_hash_lookup(subckt_table, subckt_name, "", XINSERT);
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
get_sch_from_sym(filename, xctx->sym + i);
/* for printing we go down to bottom regardless of spice_stop attribute */
load_schematic(1,filename, 0);
@ -72,7 +71,7 @@ void hier_psprint(void) /* netlister driver */
}
}
my_free(1231, &abs_path);
str_hash_free(subckt_table);
str_hash_free(&subckt_table);
my_free(1229, &subckt_name);
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--;
@ -113,7 +112,6 @@ static void spice_netlist(FILE *fd, int spice_stop )
char *type=NULL;
int top_sub;
xctx->hash_size = HASHSIZE;
top_sub = tclgetboolvar("top_subckt");
if(!spice_stop) {
xctx->prep_net_structs = 0;
@ -167,10 +165,10 @@ static void spice_netlist(FILE *fd, int spice_stop )
if(print_spice_element(fd, i)) fprintf(fd, "**** end_element\n");
/* hash device_model attribute if any */
m = get_tok_value(xctx->inst[i].prop_ptr, "device_model", 0);
if(m[0]) str_hash_lookup(model_table, model_name(m), m, XINSERT);
if(m[0]) str_hash_lookup(&model_table, model_name(m), m, XINSERT);
else {
m = get_tok_value( (xctx->inst[i].ptr+ xctx->sym)->prop_ptr, "device_model", 0);
if(m[0]) str_hash_lookup(model_table, model_name(m), m, XINSERT);
if(m[0]) str_hash_lookup(&model_table, model_name(m), m, XINSERT);
}
my_free(951, &model_name_result);
}
@ -199,14 +197,13 @@ void global_spice_netlist(int global) /* netlister driver */
int top_sub;
int split_f;
xctx->hash_size = HASHSIZE;
split_f = tclgetboolvar("split_files");
top_sub = tclgetboolvar("top_subckt");
xctx->push_undo();
xctx->netlist_unconn_cnt=0; /* unique count of unconnected pins while netlisting */
statusmsg("",2); /* clear infowindow */
str_hash_free(subckt_table);
str_hash_free(model_table);
str_hash_init(&subckt_table, HASHSIZE);
str_hash_init(&model_table, HASHSIZE);
record_global_node(2, NULL, NULL); /* delete list of global nodes */
top_sub = 0;
/* tclsetvar("spiceprefix", "1"); */
@ -372,9 +369,9 @@ void global_spice_netlist(int global) /* netlister driver */
{
/* xctx->sym can be SCH or SYM, use hash to avoid writing duplicate subckt */
my_strdup(391, &subckt_name, get_cell(xctx->sym[i].name, 0));
if (str_hash_lookup(subckt_table, subckt_name, "", XLOOKUP)==NULL)
if (str_hash_lookup(&subckt_table, subckt_name, "", XLOOKUP)==NULL)
{
str_hash_lookup(subckt_table, subckt_name, "", XINSERT);
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
if( split_f && strcmp(get_tok_value(xctx->sym[i].prop_ptr,"vhdl_netlist",0),"true")==0 )
vhdl_block_netlist(fd, i);
else if(split_f && strcmp(get_tok_value(xctx->sym[i].prop_ptr,"verilog_netlist",0),"true")==0 )
@ -386,7 +383,7 @@ void global_spice_netlist(int global) /* netlister driver */
}
my_free(1233, &abs_path);
}
str_hash_free(subckt_table);
str_hash_free(&subckt_table);
my_free(944, &subckt_name);
/*clear_drawing(); */
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
@ -438,8 +435,8 @@ void global_spice_netlist(int global) /* netlister driver */
}
/* print device_model attributes */
for(i=0;i<xctx->hash_size; i++) {
model_entry=model_table[i];
for(i=0;i<model_table.size; i++) {
model_entry=model_table.table[i];
while(model_entry) {
if(first == 0) fprintf(fd,"**** begin user architecture code\n");
first++;
@ -447,7 +444,7 @@ void global_spice_netlist(int global) /* netlister driver */
model_entry = model_entry->next;
}
}
str_hash_free(model_table);
str_hash_free(&model_table);
if(first) fprintf(fd,"**** end user architecture code\n");
@ -563,15 +560,17 @@ void spice_block_netlist(FILE *fd, int i)
* return NULL if not found
* "whatever" "whatever" XDELETE delete entry if found,return NULL
*/
Str_hashentry *str_hash_lookup(Str_hashentry **table, const char *token, const char *value, int what)
Str_hashentry *str_hash_lookup(Str_hashtable *hashtable, const char *token, const char *value, int what)
{
unsigned int hashcode, idx;
Str_hashentry *entry, *saveptr, **preventry;
int s ;
int size = hashtable->size;
Str_hashentry **table = hashtable->table;
if(token==NULL) return NULL;
if(token==NULL || size == 0 || table == NULL) return NULL;
hashcode=str_hash(token);
idx=hashcode % xctx->hash_size;
idx=hashcode % size;
entry=table[idx];
preventry=&table[idx];
while(1)
@ -612,6 +611,15 @@ Str_hashentry *str_hash_lookup(Str_hashentry **table, const char *token, const c
}
}
void str_hash_init(Str_hashtable *hashtable, int size)
{
if(hashtable->size !=0 || hashtable->table != NULL) {
dbg(0, "str_hash_init(): Warning hash table not empty, possible data leak\n");
}
hashtable->size = size;
hashtable->table = my_calloc(1574, size, sizeof(Str_hashentry *));
}
static void str_hash_free_entry(Str_hashentry *entry)
{
Str_hashentry *tmp;
@ -625,14 +633,18 @@ static void str_hash_free_entry(Str_hashentry *entry)
}
void str_hash_free(Str_hashentry **table)
void str_hash_free(Str_hashtable *hashtable)
{
int i;
for(i=0;i<xctx->hash_size;i++)
{
str_hash_free_entry( table[i] );
table[i] = NULL;
if(hashtable->table) {
int i;
Str_hashentry **table = hashtable->table;
for(i=0;i < hashtable->size;i++)
{
str_hash_free_entry( table[i] );
table[i] = NULL;
}
my_free(1384, &(hashtable->table));
hashtable->size = 0;
}
}
@ -649,15 +661,17 @@ void str_hash_free(Str_hashentry **table)
* return NULL if not found
* "whatever" "whatever" XDELETE delete entry if found,return NULL
*/
Int_hashentry *int_hash_lookup(Int_hashentry **table, const char *token, const int value, int what)
Int_hashentry *int_hash_lookup(Int_hashtable *hashtable, const char *token, const int value, int what)
{
unsigned int hashcode, idx;
Int_hashentry *entry, *saveptr, **preventry;
int s ;
int size = hashtable->size;
Int_hashentry **table = hashtable->table;
if(token==NULL) return NULL;
if(token==NULL || size == 0 || table == NULL) return NULL;
hashcode=str_hash(token);
idx=hashcode % xctx->hash_size;
idx=hashcode % size;
entry=table[idx];
preventry=&table[idx];
while(1)
@ -696,6 +710,15 @@ Int_hashentry *int_hash_lookup(Int_hashentry **table, const char *token, const i
}
}
void int_hash_init(Int_hashtable *hashtable, int size)
{
if(hashtable->size !=0 || hashtable->table != NULL) {
dbg(0, "int_hash_init(): Warning hash table not empty, possible data leak\n");
}
hashtable->size = size;
hashtable->table = my_calloc(1576, size, sizeof(Int_hashentry *));
}
static void int_hash_free_entry(Int_hashentry *entry)
{
Int_hashentry *tmp;
@ -708,14 +731,17 @@ static void int_hash_free_entry(Int_hashentry *entry)
}
void int_hash_free(Int_hashentry **table)
void int_hash_free(Int_hashtable *hashtable)
{
int i;
for(i=0;i<xctx->hash_size;i++)
{
int_hash_free_entry( table[i] );
table[i] = NULL;
if(hashtable->table) {
int i;
Int_hashentry **table = hashtable->table;
for(i=0;i < hashtable->size;i++)
{
int_hash_free_entry( table[i] );
table[i] = NULL;
}
my_free(1575, &(hashtable->table));
hashtable->size = 0;
}
}

View File

@ -79,6 +79,7 @@ static Inst_hashentry *inst_hash_lookup(char *token, int value, int what)
entry->hash=hashcode;
entry->value = value;
}
my_free(1386, &token_base);
return NULL; /* token was not in hash */
}
if( entry->hash==hashcode && !strcmp(token_base, entry->token) ) { /* found a matching token */
@ -87,17 +88,18 @@ static Inst_hashentry *inst_hash_lookup(char *token, int value, int what)
my_free(1249, &entry->token);
my_free(969, &entry);
*preventry=saveptr;
my_free(1388, &token_base);
return NULL;
} else if(what == XINSERT) {
entry->value = value;
}
/* dbg(1, "inst_hash_lookup(): returning: %s , %d\n", entry->token, entry->value); */
my_free(1577, &token_base);
return entry; /* found matching entry, return the address */
}
preventry=&entry->next; /* descend into the list. */
entry = entry->next;
}
my_free(1545, &token_base);
}
static void inst_hash_free_entry(Inst_hashentry *entry)
@ -105,6 +107,7 @@ static void inst_hash_free_entry(Inst_hashentry *entry)
Inst_hashentry *tmp;
while( entry ) {
tmp = entry -> next;
my_free(1545, &entry->token);
my_free(971, &entry);
entry = tmp;
}
@ -684,6 +687,7 @@ void new_prop_string(int i, const char *old_prop, int fast, int dis_uniq_names)
{
my_strdup(446, &xctx->inst[i].prop_ptr, old_prop); /* changed to copy old props if no name */
my_strdup2(13, &xctx->inst[i].instname, "");
my_free(1579, &up_old_name);
return;
}
xctx->prefix=old_name[0];
@ -695,6 +699,7 @@ void new_prop_string(int i, const char *old_prop, int fast, int dis_uniq_names)
my_strdup2(90, &xctx->inst[i].instname, old_name);
inst_hash_lookup(up_old_name, i, XINSERT);
my_free(985, &old_name);
my_free(1578, &up_old_name);
return;
}
old_name_base = my_malloc(64, old_name_len+1);

View File

@ -21,7 +21,7 @@
*/
#include "xschem.h"
static Str_hashentry *subckt_table[HASHSIZE]; /* safe even with multiple schematics */
static Str_hashtable subckt_table = {NULL, 0}; /* safe even with multiple schematics */
static void verilog_netlist(FILE *fd , int verilog_stop)
{
@ -92,12 +92,11 @@ void global_verilog_netlist(int global) /* netlister driver */
int split_f;
const char *fmt_attr = NULL;
xctx->hash_size = HASHSIZE;
split_f = tclgetboolvar("split_files");
xctx->push_undo();
xctx->netlist_unconn_cnt=0; /* unique count of unconnected pins while netlisting */
statusmsg("",2); /* clear infowindow */
str_hash_free(subckt_table);
str_hash_init(&subckt_table, HASHSIZE);
xctx->netlist_count=0;
/* top sch properties used for library use declarations and type definitions */
/* to be printed before any entity declarations */
@ -356,9 +355,9 @@ void global_verilog_netlist(int global) /* netlister driver */
if(strcmp(xctx->sym[i].type,"subcircuit")==0 && check_lib(1, abs_path)) {
/* xctx->sym can be SCH or SYM, use hash to avoid writing duplicate subckt */
my_strdup(328, &subckt_name, get_cell(xctx->sym[i].name, 0));
if (str_hash_lookup(subckt_table, subckt_name, "", XLOOKUP)==NULL)
if (str_hash_lookup(&subckt_table, subckt_name, "", XLOOKUP)==NULL)
{
str_hash_lookup(subckt_table, subckt_name, "", XINSERT);
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
if( split_f && strcmp(get_tok_value(xctx->sym[i].prop_ptr,"vhdl_netlist",0),"true")==0 )
vhdl_block_netlist(fd, i);
else if(split_f && strcmp(get_tok_value(xctx->sym[i].prop_ptr,"spice_netlist",0),"true")==0 )
@ -370,7 +369,7 @@ void global_verilog_netlist(int global) /* netlister driver */
}
}
my_free(1235, &abs_path);
str_hash_free(subckt_table);
str_hash_free(&subckt_table);
my_free(1073, &subckt_name);
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--;

View File

@ -22,7 +22,7 @@
#include "xschem.h"
static Str_hashentry *subckt_table[HASHSIZE]; /* safe even with multiple schematics */
static Str_hashtable subckt_table = {NULL, 0}; /* safe even with multiple schematics */
static void vhdl_netlist(FILE *fd , int vhdl_stop)
{
@ -130,7 +130,6 @@ void global_vhdl_netlist(int global) /* netlister driver */
char *abs_path = NULL;
int split_f;
xctx->hash_size = HASHSIZE;
split_f = tclgetboolvar("split_files");
xctx->push_undo();
xctx->netlist_unconn_cnt=0; /* unique count of unconnected pins while netlisting */
@ -139,7 +138,7 @@ void global_vhdl_netlist(int global) /* netlister driver */
/* to be printed before any entity declarations */
xctx->netlist_count=0;
str_hash_free(subckt_table);
str_hash_init(&subckt_table, HASHSIZE);
my_snprintf(netl_filename, S(netl_filename), "%s/.%s_%d",
tclgetvar("netlist_dir"), skip_dir(xctx->sch[xctx->currsch]), getpid());
fd=fopen(netl_filename, "w");
@ -349,8 +348,8 @@ void global_vhdl_netlist(int global) /* netlister driver */
{
/* xctx->sym can be SCH or SYM, use hash to avoid writing duplicate subckt */
my_strdup(317, &subckt_name, get_cell(xctx->sym[j].name, 0));
if (str_hash_lookup(subckt_table, subckt_name, "", XLOOKUP)==NULL) {
str_hash_lookup(subckt_table, subckt_name, "", XINSERT);
if (str_hash_lookup(&subckt_table, subckt_name, "", XLOOKUP)==NULL) {
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
/* component generics */
print_generic(fd,"component", j);
@ -382,7 +381,7 @@ void global_vhdl_netlist(int global) /* netlister driver */
}
my_free(1241, &abs_path);
}
str_hash_free(subckt_table);
str_hash_free(&subckt_table);
my_free(1086, &subckt_name);
dbg(1, "global_vhdl_netlist(): netlisting top level\n");
@ -429,6 +428,7 @@ void global_vhdl_netlist(int global) /* netlister driver */
if(global)
{
int saved_hilight_nets = xctx->hilight_nets;
str_hash_init(&subckt_table, HASHSIZE);
unselect_all(1);
remove_symbols(); /* 20161205 ensure all unused symbols purged before descending hierarchy */
/* reload data without popping undo stack, this populates embedded symbols if any */
@ -450,9 +450,9 @@ void global_vhdl_netlist(int global) /* netlister driver */
{
/* xctx->sym can be SCH or SYM, use hash to avoid writing duplicate subckt */
my_strdup(327, &subckt_name, get_cell(xctx->sym[i].name, 0));
if (str_hash_lookup(subckt_table, subckt_name, "", XLOOKUP)==NULL)
if (str_hash_lookup(&subckt_table, subckt_name, "", XLOOKUP)==NULL)
{
str_hash_lookup(subckt_table, subckt_name, "", XINSERT);
str_hash_lookup(&subckt_table, subckt_name, "", XINSERT);
if( split_f && strcmp(get_tok_value(xctx->sym[i].prop_ptr,"verilog_netlist",0),"true")==0 )
verilog_block_netlist(fd, i);
else if( split_f && strcmp(get_tok_value(xctx->sym[i].prop_ptr,"spice_netlist",0),"true")==0 )
@ -464,7 +464,7 @@ void global_vhdl_netlist(int global) /* netlister driver */
}
my_free(1243, &abs_path);
}
str_hash_free(subckt_table);
str_hash_free(&subckt_table);
my_free(1087, &subckt_name);
my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch]));
xctx->currsch--;

View File

@ -324,9 +324,7 @@ static void free_xschem_data()
my_free(970, &xctx->node_table);
my_free(1385, &xctx->inst_table);
my_free(1386, &xctx->node_redraw_table);
my_free(1387, &xctx->hilight_table);
my_free(1388, &xctx->graph_raw_table);
my_free(1098, &xctx->wire);
my_free(1100, &xctx->text);
@ -470,7 +468,10 @@ static void alloc_xschem_data(const char *top_path, const char *win_path)
xctx->need_reb_sel_arr = 1;
xctx->lastsel = 0;
xctx->maxsel = 0;
xctx->hash_size = HASHSIZE;
xctx->graph_raw_table.size = 0;
xctx->graph_raw_table.table = NULL;
xctx->node_redraw_table.size = 0;
xctx->node_redraw_table.table = NULL;
xctx->prep_net_structs = 0;
xctx->prep_hi_structs = 0;
xctx->simdata = NULL;
@ -495,10 +496,8 @@ static void alloc_xschem_data(const char *top_path, const char *win_path)
}
}
xctx->node_table = my_calloc(517, HASHSIZE, sizeof(Node_hashentry *));
xctx->node_redraw_table = my_calloc(973, HASHSIZE, sizeof(Int_hashentry *));
xctx->inst_table = my_calloc(1382, HASHSIZE, sizeof(Inst_hashentry *));
xctx->hilight_table = my_calloc(1383, HASHSIZE, sizeof(Hilight_hashentry *));
xctx->graph_raw_table = my_calloc(1384, HASHSIZE, sizeof(Int_hashentry *));
xctx->inst_redraw_table = NULL;
xctx->inst_redraw_table_size = 0;
@ -665,7 +664,7 @@ static void delete_schematic_data(int delete_pixmap)
int compare_schematics(const char *f)
{
Int_hashentry *table1[HASHSIZE], *table2[HASHSIZE];
Int_hashtable table1 = {NULL, 0}, table2 = {NULL, 0};
Int_hashentry *found;
char *s = NULL;
int i;
@ -673,9 +672,8 @@ int compare_schematics(const char *f)
int ret=0; /* ret==0 means no differences found */
Xschem_ctx *save_xctx;
xctx->hash_size = HASHSIZE;
memset(table1, 0, HASHSIZE * sizeof(Int_hashentry *));
memset(table2, 0, HASHSIZE * sizeof(Int_hashentry *));
int_hash_init(&table1, HASHSIZE);
int_hash_init(&table2, HASHSIZE);
/* set filename of schematic to compare */
if(f == NULL) {
@ -697,7 +695,7 @@ int compare_schematics(const char *f)
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(table1, s, i, XINSERT_NOREPLACE);
int_hash_lookup(&table1, s, i, XINSERT_NOREPLACE);
}
for(i=0;i<xctx->wires;i++)
{
@ -705,7 +703,7 @@ int compare_schematics(const char *f)
my_realloc(1541, &s, l);
my_snprintf(s, l, "N %g %g %g %g", xctx->wire[i].x1, xctx->wire[i].y1,
xctx->wire[i].x2, xctx->wire[i].y2);
int_hash_lookup(table1, s, i, XINSERT_NOREPLACE);
int_hash_lookup(&table1, s, i, XINSERT_NOREPLACE);
}
@ -759,8 +757,8 @@ int compare_schematics(const char *f)
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(table2, s, i, XINSERT_NOREPLACE);
found = int_hash_lookup(table1, s, i, XLOOKUP);
int_hash_lookup(&table2, s, i, XINSERT_NOREPLACE);
found = int_hash_lookup(&table1, s, i, XLOOKUP);
if(!found) {
dbg(1, "schematic 2 instance %d: %s mismatch or not found in schematic 1\n", i,
xctx->inst[i].instname ? xctx->inst[i].instname : "");
@ -775,8 +773,8 @@ int compare_schematics(const char *f)
my_realloc(1535, &s, l);
my_snprintf(s, l, "N %g %g %g %g", xctx->wire[i].x1, xctx->wire[i].y1,
xctx->wire[i].x2, xctx->wire[i].y2);
int_hash_lookup(table2, s, i, XINSERT_NOREPLACE);
found = int_hash_lookup(table1, s, i, XLOOKUP);
int_hash_lookup(&table2, s, i, XINSERT_NOREPLACE);
found = int_hash_lookup(&table1, s, i, XLOOKUP);
if(!found) {
dbg(1, "schematic 2 net %d: %s mismatch or not found in schematic 1\n", i,
xctx->wire[i].prop_ptr ? xctx->wire[i].prop_ptr : "");
@ -805,7 +803,7 @@ int compare_schematics(const char *f)
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(table2, s, i, XLOOKUP);
found = int_hash_lookup(&table2, s, i, XLOOKUP);
if(!found) {
xctx->inst[i].sel = SELECTED;
xctx->need_reb_sel_arr=1;
@ -818,15 +816,15 @@ int compare_schematics(const char *f)
my_realloc(1537, &s, l);
my_snprintf(s, l, "N %g %g %g %g", xctx->wire[i].x1, xctx->wire[i].y1,
xctx->wire[i].x2, xctx->wire[i].y2);
found = int_hash_lookup(table2, s, i, XLOOKUP);
found = int_hash_lookup(&table2, s, i, XLOOKUP);
if(!found) {
xctx->wire[i].sel = SELECTED;
xctx->need_reb_sel_arr=1;
ret = 1;
}
}
int_hash_free(table1);
int_hash_free(table2);
int_hash_free(&table1);
int_hash_free(&table2);
rebuild_selected_array();
draw_selection(xctx->gc[SELLAYER], 0);
my_free(1531, &s);

View File

@ -599,6 +599,7 @@ struct inst_hashentry
};
/* generic string hash table */
typedef struct str_hashentry Str_hashentry;
struct str_hashentry
{
@ -608,6 +609,11 @@ struct str_hashentry
char *value;
};
typedef struct {
Str_hashentry **table;
int size;
} Str_hashtable;
/* generic int hash table */
typedef struct int_hashentry Int_hashentry;
struct int_hashentry
@ -618,6 +624,12 @@ struct int_hashentry
int value;
};
typedef struct {
Int_hashentry **table;
int size;
} Int_hashtable;
typedef struct node_hashentry Node_hashentry;
struct node_hashentry
{
@ -770,7 +782,6 @@ typedef struct {
int need_reb_sel_arr;
int lastsel;
int maxsel;
int hash_size; /* used in str_hash_lookup and int_hash_lookup */
Selected *sel_array;
int prep_net_structs;
int prep_hi_structs;
@ -824,7 +835,7 @@ typedef struct {
char sel_or_clip[PATH_MAX];
int onetime;
/* list of nodes, instances attached to these need redraw */
Int_hashentry **node_redraw_table;
Int_hashtable node_redraw_table;
/* list of instances, collected using previous table, that need redraw */
unsigned char *inst_redraw_table;
int inst_redraw_table_size;
@ -909,7 +920,7 @@ typedef struct {
int graph_lastsel; /* last graph that was clicked (selected) */
const char *graph_sim_type; /* type of sim, "tran", "dc", "ac", "op", ... */
int graph_annotate_p; /* point in raw file to use for annotating schematic voltages/currents/etc */
Int_hashentry **graph_raw_table;
Int_hashtable graph_raw_table;
/* when descending hierarchy xctx->current_name changes, xctx->graph_raw_schname
* holds the name of the top schematic from which the raw file was loaded */
char *graph_raw_schname;
@ -1279,11 +1290,13 @@ extern void check_unique_names(int rename);
extern void clear_instance_hash();
extern unsigned int str_hash(const char *tok);
extern void str_hash_free(Str_hashentry **table);
extern Str_hashentry *str_hash_lookup(Str_hashentry **table,
extern void str_hash_free(Str_hashtable *hashtable);
extern Str_hashentry *str_hash_lookup(Str_hashtable *hashtable,
const char *token, const char *value, int what);
extern void int_hash_free(Int_hashentry **table);
extern Int_hashentry *int_hash_lookup(Int_hashentry **table,
extern void str_hash_init(Str_hashtable *hashtable, int size);
extern void int_hash_init(Int_hashtable *hashtable, int size);
extern void int_hash_free(Int_hashtable *hashtable);
extern Int_hashentry *int_hash_lookup(Int_hashtable *hashtable,
const char *token, const int value, int what);
extern char *find_nth(const char *str, const char *sep, int n);

View File

@ -57,30 +57,30 @@ N 450 -1130 600 -1130 {
lab=AA}
N 450 -1110 600 -1110 {
lab=BB}
N 450 -410 600 -410 {
N 450 -410 630 -410 {
lab=RRSSTT}
N 450 -390 600 -390 {
N 450 -390 630 -390 {
lab=CCKK}
N 450 -370 600 -370 {
N 450 -370 630 -370 {
lab=AA}
N 450 -350 600 -350 {
N 450 -350 630 -350 {
lab=BB}
N 450 -310 480 -310 {
lab=ZZ7}
N 900 -310 930 -310 {
N 600 -310 630 -310 {
lab=ZZ8}
N 900 -410 1050 -410 {
N 930 -410 1050 -410 {
lab=RRSSTT}
N 900 -390 1050 -390 {
N 930 -390 1050 -390 {
lab=CCKK}
N 900 -370 1050 -370 {
N 930 -370 1050 -370 {
lab=AA}
N 900 -350 1050 -350 {
N 930 -350 1050 -350 {
lab=BB}
N 1350 -310 1380 -310 {
lab=ZZ9}
C {doublepin.sym} 1200 -360 0 0 {name=x9}
C {doublepin.sym} 750 -360 0 0 {name=x8}
C {doublepin.sym} 780 -360 0 1 {name=x8}
C {doublepin.sym} 750 -610 0 0 {name=x2}
C {lab_wire.sym} 520 -620 0 0 {name=l2 sig_type=std_logic lab=AA}
C {lab_pin.sym} 480 -560 0 1 {name=p3 lab=ZZ5}
@ -119,7 +119,7 @@ C {lab_wire.sym} 520 -1110 0 0 {name=l25 sig_type=std_logic lab=BB}
C {lab_pin.sym} 150 -350 0 0 {name=l33 sig_type=std_logic lab=BB}
C {doublepin.sym} 300 -610 0 0 {name=x1}
C {lab_pin.sym} 480 -310 0 1 {name=p7 lab=ZZ7}
C {lab_pin.sym} 930 -310 0 1 {name=p8 lab=ZZ8}
C {lab_pin.sym} 600 -310 0 0 {name=p8 lab=ZZ8}
C {lab_pin.sym} 150 -370 0 0 {name=l30 sig_type=std_logic lab=AA}
C {lab_pin.sym} 150 -410 0 0 {name=l31 sig_type=std_logic lab=RRSSTT}
C {lab_pin.sym} 150 -390 0 0 {name=l32 sig_type=std_logic lab=CCKK}