From 5fe2f1586b5cdb197442a4ab27a0aebf9df8c48d Mon Sep 17 00:00:00 2001 From: Stefan Frederik Date: Wed, 5 Oct 2022 01:18:45 +0200 Subject: [PATCH] refactor str_hash_* and int_hash_* functions --- src/actions.c | 4 +- src/move.c | 13 +-- src/netlist.c | 31 +++--- src/save.c | 34 +++---- src/scheduler.c | 3 +- src/spice_netlist.c | 106 +++++++++++++-------- src/token.c | 7 +- src/verilog_netlist.c | 11 +-- src/vhdl_netlist.c | 18 ++-- src/xinit.c | 36 ++++--- src/xschem.h | 27 ++++-- xschem_library/examples/test_doublepin.sch | 22 ++--- 12 files changed, 173 insertions(+), 139 deletions(-) diff --git a/src/actions.c b/src/actions.c index 9d7d0b9f..5bf970e6 100644 --- a/src/actions.c +++ b/src/actions.c @@ -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 */ diff --git a/src/move.c b/src/move.c index 0cb56596..210f250f 100644 --- a/src/move.c +++ b/src/move.c @@ -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;ilastsel;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; diff --git a/src/netlist.c b/src/netlist.c index 7ddce21b..dbb07a98 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -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;isym)->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;jsym)->rects[PINLAYER]) > 0) */ } /* if (type && !IS_LABEL_OR_PIN(type) ) */ - str_hash_free(table); + str_hash_free(&table); } /* for (i=0;ihash_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; } diff --git a/src/save.c b/src/save.c index 24923bc2..0c1aba0d 100644 --- a/src/save.c +++ b/src/save.c @@ -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 : ""); 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); } } diff --git a/src/scheduler.c b/src/scheduler.c index 6bfd1d71..5fc14bb5 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -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")) { diff --git a/src/spice_netlist.c b/src/spice_netlist.c index 88c4de98..35d82d4a 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -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;ihash_size; i++) { - model_entry=model_table[i]; + for(i=0;inext; } } - 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;ihash_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;ihash_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; } } - diff --git a/src/token.c b/src/token.c index 79d6e307..8afba380 100644 --- a/src/token.c +++ b/src/token.c @@ -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); diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index 996d7c85..f57c97b1 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -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--; diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c index 43dcb83c..bbca4c48 100644 --- a/src/vhdl_netlist.c +++ b/src/vhdl_netlist.c @@ -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--; diff --git a/src/xinit.c b/src/xinit.c index 9b48a96f..48f2aa2c 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -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;iwires;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); diff --git a/src/xschem.h b/src/xschem.h index 23ecda3c..26f87b3b 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -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); diff --git a/xschem_library/examples/test_doublepin.sch b/xschem_library/examples/test_doublepin.sch index 49eefc5f..91a83e67 100644 --- a/xschem_library/examples/test_doublepin.sch +++ b/xschem_library/examples/test_doublepin.sch @@ -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}