From 210aea296d30ee6cd83c85fbebf104b806bdcba5 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Fri, 7 Aug 2026 13:20:34 +0200 Subject: [PATCH] make translate2() and translate3() reentrant (caller provides and frees pointer for result) --- src/actions.c | 32 ++++++++++----- src/draw.c | 14 +++---- src/editprop.c | 4 +- src/save.c | 4 +- src/scheduler.c | 11 ++++-- src/spectre_netlist.c | 4 +- src/spice_netlist.c | 4 +- src/token.c | 90 ++++++++++++++++++++----------------------- src/xinit.c | 2 - src/xschem.h | 4 +- 10 files changed, 94 insertions(+), 75 deletions(-) diff --git a/src/actions.c b/src/actions.c index eec582da..68e561bb 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1905,13 +1905,15 @@ void launcher(void) my_strdup2(_ALLOC_ID_, &command, get_tok_value(sym->prop_ptr, "tclcommand", 0)); } if(strchr(command, '@')) { - my_strdup2(_ALLOC_ID_, &command, translate3(command, 1, prop_ptr, NULL, NULL, NULL)); + char *res = NULL; + my_strdup2(_ALLOC_ID_, &command, translate3(command, 1, prop_ptr, NULL, NULL, NULL, res)); if(xctx->sel_array[0].type==ELEMENT) { xSymbol *sym = xctx->inst[n].ptr + xctx->sym; if(strchr(command, '@')) { - my_strdup2(_ALLOC_ID_, &command, translate3(command, 1, sym->prop_ptr, NULL, NULL, NULL)); + my_strdup2(_ALLOC_ID_, &command, translate3(command, 1, sym->prop_ptr, NULL, NULL, NULL, res)); } } + my_free(_ALLOC_ID_, &res); } my_strncpy(program, get_tok_value(prop_ptr,"program",0), S(program)); /* handle backslashes */ url = get_tok_value(prop_ptr,"url",0); /* handle backslashes */ @@ -1948,13 +1950,16 @@ const char *get_sym_name(int inst, int ndir, int ext, int abs_path) const char *sym; char *sch = NULL; size_t schematic_token_found = 0; + char *res = NULL; /* instance based symbol selection */ /* resolve schematic=generator.tcl( @n ) where n=11 is defined in instance attrs */ my_strdup2(_ALLOC_ID_, &sch, get_tok_value(xctx->inst[inst].prop_ptr,"schematic", 6)); schematic_token_found = xctx->tok_size; - if(sch && sch[0]) - my_strdup2(_ALLOC_ID_, &sch, translate3(sch, 1, xctx->inst[inst].prop_ptr, NULL, NULL, NULL)); + if(sch && sch[0]) { + my_strdup2(_ALLOC_ID_, &sch, translate3(sch, 1, xctx->inst[inst].prop_ptr, NULL, NULL, NULL, res)); + my_free(_ALLOC_ID_, &res); + } if(sch && sch[0]) my_strdup2(_ALLOC_ID_, &sch, tcl_hook2( str_replace(sch, "@symname", get_cell(xctx->inst[inst].name, 0), '\\', -1))); @@ -2183,6 +2188,7 @@ void get_additional_symbols(int what) char *sch = NULL; char symbol_base_sch[PATH_MAX] = ""; size_t schematic_token_found = 0; + char *res = NULL; if(xctx->inst[i].ptr < 0) continue; dbg(1, "get_additional_symbols(): inst=%d (%s) sch=%s\n",i, xctx->inst[i].name, sch); @@ -2197,7 +2203,8 @@ void get_additional_symbols(int what) dbg(1, "get_additional_symbols(): schematic=%s\n", sch); schematic_token_found = xctx->tok_size; - my_strdup2(_ALLOC_ID_, &sch, translate3(sch, 1, xctx->inst[i].prop_ptr, NULL, NULL, NULL)); + my_strdup2(_ALLOC_ID_, &sch, translate3(sch, 1, xctx->inst[i].prop_ptr, NULL, NULL, NULL, res)); + my_free(_ALLOC_ID_, &res); dbg(1, " get_additional_symbols(): sch=%s tok_size= %ld\n", sch, xctx->tok_size); my_strdup2(_ALLOC_ID_, &sch, tcl_hook2( @@ -2215,6 +2222,7 @@ void get_additional_symbols(int what) char *sym = NULL; char *symname_attr = NULL; int ignore_schematic = 0; + char *res = NULL; xSymbol *symptr = xctx->inst[i].ptr + xctx->sym; my_strdup2(_ALLOC_ID_, &default_schematic, get_tok_value(symptr->prop_ptr,"default_schematic",0)); @@ -2237,12 +2245,15 @@ void get_additional_symbols(int what) my_strdup(_ALLOC_ID_, &spice_sym_def, translate3(spice_sym_def, 1, xctx->inst[i].prop_ptr, symptr->templ, - symname_attr, NULL)); + symname_attr, NULL, + res)); my_strdup(_ALLOC_ID_, &spectre_sym_def, translate3(spectre_sym_def, 1, xctx->inst[i].prop_ptr, symptr->templ, - symname_attr, NULL)); + symname_attr, NULL, + res)); my_free(_ALLOC_ID_, &symname_attr); + my_free(_ALLOC_ID_, &res); /* if instance symbol has default_schematic set to ignore copy the symbol anyway, since * the base symbol will not be netlisted by *_block_netlist() */ found = ignore_schematic ? NULL : int_hash_lookup(&sym_table, sym, 0, XLOOKUP); @@ -2316,6 +2327,7 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst, int fallback) int file_exists=0; int cancel = 0; int is_gen = 0; + char *res = NULL; my_strncpy(filename, "", PATH_MAX); @@ -2342,8 +2354,10 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst, int fallback) /* instance based symbol selection */ /* resolve schematic=generator.tcl( @n ) where n=11 is defined in instance attrs */ my_strdup2(_ALLOC_ID_, &str_tmp, get_tok_value(xctx->inst[inst].prop_ptr,"schematic", 6)); - if(str_tmp[0]) - my_strdup2(_ALLOC_ID_, &str_tmp, translate3(str_tmp, 1, xctx->inst[inst].prop_ptr, NULL, NULL, NULL)); + if(str_tmp[0]) { + my_strdup2(_ALLOC_ID_, &str_tmp, translate3(str_tmp, 1, xctx->inst[inst].prop_ptr, NULL, NULL, NULL, res)); + my_free(_ALLOC_ID_, &res); + } /* * my_strdup(_ALLOC_ID_, &str_tmp, translate3(get_tok_value(xctx->inst[inst].prop_ptr,"schematic", 6), * 1, xctx->inst[inst].prop_ptr, NULL, NULL, NULL)); diff --git a/src/draw.c b/src/draw.c index c3ad6a7e..0e2c63ad 100644 --- a/src/draw.c +++ b/src/draw.c @@ -876,12 +876,12 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot, #endif dbg(1, "draw_symbol(): drawing string: before translate(): text.txt_ptr=%s\n", text.txt_ptr); my_strdup2(_ALLOC_ID_, &txtptr, translate(n, text.txt_ptr, res)); - my_free(_ALLOC_ID_, &res); /* do another round of substitutions if some @var are found, but if not found leave @var as is */ dbg(1, "draw_symbol(): drawing string: str=%s prop=%s\n", txtptr, text.prop_ptr ? text.prop_ptr : ""); - my_strdup2(_ALLOC_ID_, &txtptr, translate3(txtptr, 0, xctx->inst[n].prop_ptr, - xctx->sym[xctx->inst[n].ptr].templ, NULL, NULL)); + my_strdup2(_ALLOC_ID_, &txtptr, translate3(txtptr, 0, xctx->inst[n].prop_ptr, + xctx->sym[xctx->inst[n].ptr].templ, NULL, NULL, res)); + my_free(_ALLOC_ID_, &res); dbg(1, "draw_symbol(): after translate3: str=%s\n", txtptr); draw_string(textlayer, what, txtptr, (text.rot + ( (flip && (text.rot & 1) ) ? rot+2 : rot) ) & 0x3, @@ -1036,10 +1036,10 @@ void draw_temp_symbol(int what, GC gc, int n,int layer,short tmp_flip, short rot if( !(xctx->inst[n].flags & HIDE_SYMBOL_TEXTS) && layer==SELLAYER && xctx->sym_txt) { char *txtptr = NULL; - char *res = NULL; for(j=0;j< symptr->texts; ++j) { double xscale, yscale; + char *res = NULL; get_sym_text_size(n, j, &xscale, &yscale); text = symptr->text[j]; @@ -1050,10 +1050,10 @@ void draw_temp_symbol(int what, GC gc, int n,int layer,short tmp_flip, short rot customfont = set_text_custom_font(&text); #endif my_strdup2(_ALLOC_ID_, &txtptr, translate(n, text.txt_ptr, res)); + /* do another round of substitutions if some @var are found, but if not found leave @var as is */ + my_strdup2(_ALLOC_ID_, &txtptr, translate3(txtptr, 0, xctx->inst[n].prop_ptr, + xctx->sym[xctx->inst[n].ptr].templ, NULL, NULL, res)); my_free(_ALLOC_ID_, &res); - /* do another round of substitutions if some @var are found, but if not found leave @var as is */ - my_strdup2(_ALLOC_ID_, &txtptr, translate3(txtptr, 0, xctx->inst[n].prop_ptr, - xctx->sym[xctx->inst[n].ptr].templ, NULL, NULL)); dbg(1, "draw_temp_symbol(): after translate3: str=%s\n", txtptr); if(txtptr[0]) draw_temp_string(gc, what, txtptr, (text.rot + ( (flip && (text.rot & 1) ) ? rot+2 : rot) ) & 0x3, diff --git a/src/editprop.c b/src/editprop.c index 43d60140..f2ef3fcb 100644 --- a/src/editprop.c +++ b/src/editprop.c @@ -1542,6 +1542,7 @@ int drc_check(int i) char *check_result = NULL; int start = 0; int end = xctx->instances; + char *res1 = NULL; if(!tcleval("info procs fet_drc")[0]) { return ret; @@ -1554,7 +1555,8 @@ int drc_check(int i) my_strdup(_ALLOC_ID_, &drc, get_tok_value(xctx->sym[xctx->inst[j].ptr].prop_ptr, "drc", 2)); if(drc) { my_strdup(_ALLOC_ID_, &res, translate3(drc, 1, - xctx->inst[j].prop_ptr, xctx->sym[xctx->inst[j].ptr].templ, NULL, NULL)); + xctx->inst[j].prop_ptr, xctx->sym[xctx->inst[j].ptr].templ, NULL, NULL, res1)); + my_free(_ALLOC_ID_, &res1); dbg(1, "drc_check(): res = |%s|, drc=|%s|\n", res, drc); if(res) { const char *result; diff --git a/src/save.c b/src/save.c index 50572c31..e53301ea 100644 --- a/src/save.c +++ b/src/save.c @@ -4752,10 +4752,12 @@ int load_sym_def(const char *name, FILE *embed_fd) tt[i].floater_instname = tmptext.floater_instname; dbg(1, "l_s_d(): txt1: level=%d tt[i].txt_ptr=%s, i=%d\n", level, tt[i].txt_ptr, i); if (level>0) { - const char* tmp = translate2(lcc, level, tt[i].txt_ptr); + char *res = NULL; + const char* tmp = translate2(lcc, level, tt[i].txt_ptr, res); dbg(1, "l_s_d(): txt2: tt[i].txt_ptr=%s, i=%d\n", tt[i].txt_ptr, i); rot = lcc[level].rot; flip = lcc[level].flip; my_strdup2(_ALLOC_ID_, &tt[i].txt_ptr, tmp); + my_free(_ALLOC_ID_, &res); dbg(1, "l_s_d(): txt3: tt[i].txt_ptr=%s, i=%d\n", tt[i].txt_ptr, i); /* allow annotation inside LCC instances. */ if(!strcmp(tt[i].txt_ptr, "@spice_get_voltage")) { diff --git a/src/scheduler.c b/src/scheduler.c index 25b970f1..3e716d09 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -6554,15 +6554,20 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg { char *s = NULL; int eat_escapes = 0; + char *res = NULL; if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;} if(argc > 3) eat_escapes = atoi(argv[3]); - if(argc > 6) my_strdup2(_ALLOC_ID_, &s, translate3(argv[2], eat_escapes, argv[4], argv[5], argv[6], NULL)); - else if(argc > 5) my_strdup2(_ALLOC_ID_, &s, translate3(argv[2], eat_escapes, argv[4], argv[5], NULL, NULL)); - else if(argc > 4) my_strdup2(_ALLOC_ID_, &s, translate3(argv[2], eat_escapes, argv[4], NULL, NULL, NULL)); + if(argc > 6) + my_strdup2(_ALLOC_ID_, &s, translate3(argv[2], eat_escapes, argv[4], argv[5], argv[6], NULL, res)); + else if(argc > 5) + my_strdup2(_ALLOC_ID_, &s, translate3(argv[2], eat_escapes, argv[4], argv[5], NULL, NULL, res)); + else if(argc > 4) + my_strdup2(_ALLOC_ID_, &s, translate3(argv[2], eat_escapes, argv[4], NULL, NULL, NULL, res)); else { Tcl_SetResult(interp, "xschem translate3: missing arguments", TCL_STATIC); return TCL_ERROR; } + if(res) my_free(_ALLOC_ID_, &res); Tcl_ResetResult(interp); Tcl_SetResult(interp, s, TCL_VOLATILE); my_free(_ALLOC_ID_, &s); diff --git a/src/spectre_netlist.c b/src/spectre_netlist.c index cad60ed0..14263f16 100644 --- a/src/spectre_netlist.c +++ b/src/spectre_netlist.c @@ -554,11 +554,13 @@ int spectre_block_netlist(FILE *fd, int i, int alert) if(sym_def) { char *symname_attr = NULL; const char *translated_sym_def; + char *res = NULL; my_mstrcat(_ALLOC_ID_, &symname_attr, "symname=", get_cell(name, 0), NULL); - translated_sym_def = translate3(sym_def, 1, xctx->sym[i].templ, symname_attr, NULL, NULL); + translated_sym_def = translate3(sym_def, 1, xctx->sym[i].templ, symname_attr, NULL, NULL, res); my_free(_ALLOC_ID_, &symname_attr); fprintf(fd, "%s\n", translated_sym_def); my_free(_ALLOC_ID_, &sym_def); + my_free(_ALLOC_ID_, &res); } else { const char *s = get_tok_value(xctx->sym[i].templ,"model",0); if(!s[0]) s = get_cell(sanitize(name), 0); diff --git a/src/spice_netlist.c b/src/spice_netlist.c index df84c3e3..73ac38c9 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -668,11 +668,13 @@ int spice_block_netlist(FILE *fd, int i, int alert) if(sym_def) { char *symname_attr = NULL; const char *translated_sym_def; + char *res = NULL; my_mstrcat(_ALLOC_ID_, &symname_attr, "symname=", get_cell(name, 0), NULL); - translated_sym_def = translate3(sym_def, 1, xctx->sym[i].templ, symname_attr, NULL, NULL); + translated_sym_def = translate3(sym_def, 1, xctx->sym[i].templ, symname_attr, NULL, NULL, res); my_free(_ALLOC_ID_, &symname_attr); fprintf(fd, "%s\n", translated_sym_def); my_free(_ALLOC_ID_, &sym_def); + my_free(_ALLOC_ID_, &res); } else { const char *s = get_tok_value(xctx->sym[i].templ, "model",0); if(!s[0]) s = get_cell(sanitize(name), 0); diff --git a/src/token.c b/src/token.c index 4485ff3c..d47e493d 100644 --- a/src/token.c +++ b/src/token.c @@ -1207,15 +1207,17 @@ static void print_vhdl_primitive(FILE *fd, int inst) /* netlist primitives, 200 if(strchr(result, '@')) { /* netlist_commands often have @ characters due to ngspice syntax. Do not translate */ if(strcmp(xctx->sym[xctx->inst[inst].ptr].type, "netlist_commands")) { + char *res = NULL; my_strdup2(_ALLOC_ID_, &result, - translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, NULL, NULL)); + translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, NULL, NULL, res)); /* can not put template in above translate3: -----------------------^^^^ * if instance has VHI=VHI, format string has VHI=@VHI, and symbol template has VHI=3 * we do not want token @VHI to resolve to 3, but stop at VHI as specified in instance */ if(strchr(result, '@')) { my_strdup2(_ALLOC_ID_, &result, - translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL)); + translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL, res)); } + my_free(_ALLOC_ID_, &res); } } my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result)); /* tcl evaluation if tcleval(....) */ @@ -1914,6 +1916,7 @@ static int has_included_subcircuit(int inst, int symbol, char **result) int i; int exp_no_of_pins = 0; /* number of single bit ports, ie all buses expanded */ char *net, *net_save; + char *res = NULL; Str_hashentry *entry; Str_hashtable table = {NULL, 0}; @@ -1928,7 +1931,7 @@ static int has_included_subcircuit(int inst, int symbol, char **result) my_mstrcat(_ALLOC_ID_, &symname_attr, " symref=", get_sym_name(inst, 9999, 1, 1), NULL); translated_sym_def = translate3(spice_sym_def, 1, xctx->inst[inst].prop_ptr, xctx->sym[symbol].templ, - symname_attr, NULL); + symname_attr, NULL, res); dbg(1, "has_included_subcircuit(): translated_sym_def=%s\n", translated_sym_def); dbg(1, "has_included_subcircuit(): symname=%s\n", symname); @@ -1966,6 +1969,7 @@ static int has_included_subcircuit(int inst, int symbol, char **result) tclvareval("has_included_subcircuit {", get_cell(symname, 0), "} {", translated_sym_def, "} ", my_itoa(exp_no_of_pins), NULL); + my_free(_ALLOC_ID_, &res); my_free(_ALLOC_ID_, &symname_attr); if(tclresult()[0]) { /* a valid spice_sym_def netlist was found */ char *subckt_pin, *pin_save; @@ -2604,6 +2608,7 @@ int print_spice_element(FILE *fd, int inst) char *parent_prop_ptr = NULL; char *parent_templ = NULL; char *schname_attr = NULL; + char *res = NULL; my_mstrcat(_ALLOC_ID_, &schname_attr, "schname=\"", get_cell(xctx->current_name, 0), "\"", NULL); if(xctx->currsch > 0) { @@ -2629,26 +2634,26 @@ int print_spice_element(FILE *fd, int inst) */ my_strdup2(_ALLOC_ID_, &val, - translate3(token, 0, xctx->inst[inst].prop_ptr, NULL, NULL, NULL)); + translate3(token, 0, xctx->inst[inst].prop_ptr, NULL, NULL, NULL, res)); /* can not put template in above translate3: ---------------------------^^^^ * if instance has VHI=VHI, format string has VHI=@VHI, and symbol template has VHI=3 * we do not want token @VHI to resolve to 3, but stop at VHI as specified in instance */ if(strchr(val, '@')) { my_strdup2(_ALLOC_ID_, &val, - translate3(val, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL)); + translate3(val, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL, res)); } /* nmos instance format string: @model --> @modeln */ dbg(1, "print_spice_element(): 1st round: val: |%s|\n", val); if(strchr(val, '@')) { my_strdup2(_ALLOC_ID_, &val, - translate3(val, 1, schname_attr, xctx->inst[inst].prop_ptr, NULL, NULL)); + translate3(val, 1, schname_attr, xctx->inst[inst].prop_ptr, NULL, NULL, res)); /* ............ --> replace @symname with symbol name */ dbg(1, "print_spice_element(): 2nd round: val: |%s|\n", val); /* normal passgate.sym placement, nmos instance format string: ad="expr('int((@nf + 1)/2) * @W / @nf * 0.29')" --> ad="expr('int((1 + 1)/2) * W_N/ 1 * 0.29')" */ if(strchr(val, '@')) { my_strdup2(_ALLOC_ID_, &val, - translate3(val, 0, xctx->inst[inst].prop_ptr, parent_templ, NULL, NULL)); + translate3(val, 0, xctx->inst[inst].prop_ptr, parent_templ, NULL, NULL, res)); dbg(1, "print_spice_element(): 3nd round: val: |%s|\n", val); /* normal passgate.sym placement, nmos instance format string: * @modeln --> nfet_01v8 */ @@ -2686,6 +2691,7 @@ int print_spice_element(FILE *fd, int inst) my_mstrcat(_ALLOC_ID_, &result, value, NULL); } } + if(res) my_free(_ALLOC_ID_, &res); } /* else */ /* append token separator to output result ... */ @@ -2984,6 +2990,7 @@ int print_spectre_element(FILE *fd, int inst) size_t tok_val_len; char *parent_prop_ptr = NULL; char *parent_templ = NULL; + char *res = NULL; /* char *parent_sym_extra = NULL; */ if(xctx->currsch > 0) { @@ -3011,45 +3018,29 @@ int print_spectre_element(FILE *fd, int inst) my_strdup2(_ALLOC_ID_, &val, - translate3(token, 0, xctx->inst[inst].prop_ptr, NULL, NULL, NULL)); + translate3(token, 0, xctx->inst[inst].prop_ptr, NULL, NULL, NULL, res)); /* can not put template in above translate3: ---------------------------^^^^ * if instance has VHI=VHI, format string has VHI=@VHI, and symbol template has VHI=3 * we do not want token @VHI to resolve to 3, but stop at VHI as specified in instance */ if(strchr(val, '@')) { my_strdup2(_ALLOC_ID_, &val, - translate3(val, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL)); + translate3(val, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL, res)); } /* nmos instance format string: @model --> @modeln */ dbg(1, "print_spectre_element(): 1st round: val: |%s|\n", val); if(strchr(val, '@')) { - #if 0 - if(parent_prop_ptr) { + my_strdup2(_ALLOC_ID_, &val, + translate3(val, 0, xctx->inst[inst].prop_ptr, NULL, NULL, NULL, res)); + dbg(1, "print_spectre_element(): 2nd round: val: |%s|\n", val); + /* normal passgate.sym placement, nmos instance format string: + ad="expr('int((@nf + 1)/2) * @W / @nf * 0.29')" --> ad="expr('int((1 + 1)/2) * W_N/ 1 * 0.29')" */ + if(strchr(val, '@')) { my_strdup2(_ALLOC_ID_, &val, - translate3(val, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, parent_templ, NULL)); - /* instance based passgate.sym placement, nmos instance format string: @modeln --> pippon */ - /* ad="expr('int((@nf + 1)/2) * @W / @nf * 0.29')" --> ad="expr('int((1 + 1)/2) * W_N / 1 * 0.29')" */ - if(strchr(val, '@')) { - my_strdup2(_ALLOC_ID_, &val, - translate3(val, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, parent_templ, NULL)); - /* ad="expr('int((1 + 1)/2) * W_N / 1 * 0.29')" --> ad="expr('int((1 + 1)/2) * 5 / 1 * 0.29')" */ - } - } else { - #endif - my_strdup2(_ALLOC_ID_, &val, - translate3(val, 0, xctx->inst[inst].prop_ptr, NULL, NULL, NULL)); - dbg(1, "print_spectre_element(): 2nd round: val: |%s|\n", val); + translate3(val, 0, xctx->inst[inst].prop_ptr, parent_templ, NULL, NULL, res)); + dbg(1, "print_spectre_element(): 3nd round: val: |%s|\n", val); /* normal passgate.sym placement, nmos instance format string: - ad="expr('int((@nf + 1)/2) * @W / @nf * 0.29')" --> ad="expr('int((1 + 1)/2) * W_N/ 1 * 0.29')" */ - if(strchr(val, '@')) { - my_strdup2(_ALLOC_ID_, &val, - translate3(val, 0, xctx->inst[inst].prop_ptr, parent_templ, NULL, NULL)); - dbg(1, "print_spectre_element(): 3nd round: val: |%s|\n", val); - /* normal passgate.sym placement, nmos instance format string: - * @modeln --> nfet_01v8 */ - } - #if 0 + * @modeln --> nfet_01v8 */ } - #endif dbg(1, "print_spectre_element(): final: val: |%s|\n", val); } /* still unresolved: set to empty */ @@ -3082,6 +3073,7 @@ int print_spectre_element(FILE *fd, int inst) my_mstrcat(_ALLOC_ID_, &result, value, NULL); } } + if(res) my_free(_ALLOC_ID_, &res); } /* else */ /* append token separator to output result ... */ @@ -3752,18 +3744,20 @@ static void print_verilog_primitive(FILE *fd, int inst) /* netlist switch level if(result) { dbg(1, "print_verilog_primitive(): before translate3() result=%s\n", result); if(strchr(result, '@')) { + char *res = NULL; /* netlist_commands often have @ characters due to ngspice syntax. Do not translate */ if(strcmp(xctx->sym[xctx->inst[inst].ptr].type, "netlist_commands")) { my_strdup2(_ALLOC_ID_, &result, - translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, NULL, NULL)); + translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, NULL, NULL, res)); /* can not put template in above translate3: -----------------------^^^^ * if instance has VHI=VHI, format string has VHI=@VHI, and symbol template has VHI=3 * we do not want token @VHI to resolve to 3, but stop at VHI as specified in instance */ if(strchr(result, '@')) { my_strdup2(_ALLOC_ID_, &result, - translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL)); + translate3(result, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, template, NULL, res)); } } + if(res) my_free(_ALLOC_ID_, &res); } my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result)); /* tcl evaluation if tcleval(....) */ if(is_expr(result)) { @@ -5254,6 +5248,7 @@ const char *translate(int inst, const char *s, char *result) } else { int i = level; char *schname_attr = NULL; + char *res = NULL; my_mstrcat(_ALLOC_ID_, &schname_attr, "schname=\"", get_cell(xctx->current_name, 0), "\"", NULL); my_strdup2(_ALLOC_ID_, &value1, value); /* recursive substitution of value using parent level prop_ptr attributes */ @@ -5276,13 +5271,13 @@ const char *translate(int inst, const char *s, char *result) i--; } if(strchr(value1, '@')) { - my_strdup(_ALLOC_ID_, &value1, translate3(value1, 1, schname_attr, NULL, NULL, NULL)); + my_strdup(_ALLOC_ID_, &value1, translate3(value1, 1, schname_attr, NULL, NULL, NULL, res)); } /* substitute remaing @params */ i = level; while(i > 0) { if(strchr(value1, '@')) { - my_strdup(_ALLOC_ID_, &value1, translate3(value1, 1, lcc[i-1].prop_ptr, NULL, NULL, NULL)); + my_strdup(_ALLOC_ID_, &value1, translate3(value1, 1, lcc[i-1].prop_ptr, NULL, NULL, NULL, res)); dbg(1, "2 translate(): lcc[%d].prop_ptr=%s, value1=%s\n", i-1, lcc[i-1].prop_ptr, value1); } else break; i--; @@ -5292,7 +5287,7 @@ const char *translate(int inst, const char *s, char *result) i = level; while(i > 0) { if(strchr(value1, '@')) { - my_strdup(_ALLOC_ID_, &value1, translate3(value1, 1, lcc[i-1].templ, NULL, NULL, NULL)); + my_strdup(_ALLOC_ID_, &value1, translate3(value1, 1, lcc[i-1].templ, NULL, NULL, NULL, res)); dbg(1, "2 translate(): lcc[%d].prop_ptr=%s, value1=%s\n", i-1, lcc[i-1].prop_ptr, value1); } else break; i--; @@ -5303,6 +5298,7 @@ const char *translate(int inst, const char *s, char *result) memcpy(result+result_pos, value1, tmp+1); result_pos+=tmp; my_free(_ALLOC_ID_, &value1); + if(res) my_free(_ALLOC_ID_, &res); } } token_pos = 0; @@ -5334,18 +5330,19 @@ const char *translate(int inst, const char *s, char *result) my_strdup2(_ALLOC_ID_, &result, spice_get_node(result)); if(is_expr(result) && inst >= 0) { + char *res = NULL; dbg(1, "translate(): expr():%s\n", result); my_strdup2(_ALLOC_ID_, &result, eval_expr( translate3(result, 1, xctx->inst[inst].prop_ptr, xctx->sym[xctx->inst[inst].ptr].templ, - NULL, NULL))); + NULL, NULL, res))); + my_free(_ALLOC_ID_, &res); } return result; } -const char *translate2(Lcc *lcc, int level, char* s) +const char *translate2(Lcc *lcc, int level, char* s, char *result) { static const char *empty=""; - static char *result = NULL; int i, escape = 0; register int c, state = TOK_BEGIN, space; const char *tmp_sym_name; @@ -5353,7 +5350,6 @@ const char *translate2(Lcc *lcc, int level, char* s) char *token = NULL, *value = NULL; if(!s) { - my_free(_ALLOC_ID_, &result); return empty; } size = CADCHUNKALLOC; @@ -5490,11 +5486,10 @@ const char *translate2(Lcc *lcc, int level, char* s) * == 1 --> return empty token if no definition found in s* strings */ const char *translate3(const char *s, int eat_escapes, const char *s1, - const char *s2, const char *s3, const char *s4) + const char *s2, const char *s3, const char *s4, char *translated_tok) { static const char *empty=""; - static char *translated_tok = NULL; - static char *result=NULL; /* safe to keep even with multiple schematics */ + char *result=NULL; /* safe to keep even with multiple schematics */ register int c, state=TOK_BEGIN, space; char *token=NULL; size_t sizetok=0; @@ -5506,8 +5501,6 @@ const char *translate3(const char *s, int eat_escapes, const char *s1, const char *sptr[5]; /* 1...4 used */ if(!s || !xctx) { - my_free(_ALLOC_ID_, &result); - my_free(_ALLOC_ID_, &translated_tok); return empty; } xctx->tok_size = 0; @@ -5593,6 +5586,7 @@ const char *translate3(const char *s, int eat_escapes, const char *s1, dbg(1, "translate3(): result=|%s|\n", result); my_strdup2(_ALLOC_ID_, &translated_tok, tcl_hook2(result)); xctx->tok_size = found_value; + if(result) my_free(_ALLOC_ID_, &result); return translated_tok; } diff --git a/src/xinit.c b/src/xinit.c index 29631c14..473d4fd7 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -975,8 +975,6 @@ static void xwin_exit(void) get_sym_template(NULL, NULL); /* clear static data in function */ list_tokens(NULL, 0); /* clear static data in function */ translate(-1, NULL, NULL); /* clear static data in function */ - translate2(NULL, 0, NULL); /* clear static data in function */ - translate3(NULL, 0, NULL, NULL, NULL, NULL); /* clear static data in function */ subst_token(NULL, NULL, NULL); /* clear static data in function */ find_nth(NULL, "", "", 0, 0); /* clear static data in function */ trim_chars(NULL, ""); /* clear static data in function */ diff --git a/src/xschem.h b/src/xschem.h index c622fb3d..c26f5a71 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1658,9 +1658,9 @@ extern int isonlydigit(const char *s); extern char *spice_get_node(const char *token); extern char *get_fqdevice(const char *param, int modelparam, const char *instname); extern const char *translate(int inst, const char* s, char *result); -extern const char* translate2(Lcc *lcc, int level, char* s); +extern const char* translate2(Lcc *lcc, int level, char* s, char *result); extern const char *translate3(const char* s, int eat_escapes, const char *s1, - const char *s2, const char *s3, const char *s4); + const char *s2, const char *s3, const char *s4, char *translated_tok); extern void print_tedax_element(FILE *fd, int inst); extern int print_spice_element(FILE *fd, int inst); extern void print_spice_subckt_nodes(FILE *fd, int symbol);