make translate() reentrant (caller provides pointer for result)

This commit is contained in:
stefan schippers 2026-08-07 12:16:58 +02:00
parent 482e5d23c1
commit f38be4c174
14 changed files with 105 additions and 52 deletions

View File

@ -122,8 +122,10 @@ const char *get_text_floater(int i)
if(xctx->text[i].floater_ptr) {
txt_ptr = xctx->text[i].floater_ptr;
} else {
char *res = NULL;
/* cache floater translated text to avoid re-evaluating every time schematic is drawn */
my_strdup2(_ALLOC_ID_, &xctx->text[i].floater_ptr, translate(inst, xctx->text[i].txt_ptr));
my_strdup2(_ALLOC_ID_, &xctx->text[i].floater_ptr, translate(inst, xctx->text[i].txt_ptr, res));
my_free(_ALLOC_ID_, &res);
txt_ptr = xctx->text[i].floater_ptr;
}
dbg(1, "floater: %s\n",txt_ptr);
@ -132,9 +134,11 @@ const char *get_text_floater(int i)
* (but name=something or floater=something attribute must be present) and text
* matches tcleval(...) or contains '@' */
if(strstr(txt_ptr, "tcleval(") == txt_ptr || strchr(txt_ptr, '@')) {
char *res = NULL;
/* my_strdup2(_ALLOC_ID_, &xctx->text[i].floater_ptr, tcl_hook2(xctx->text[i].txt_ptr)); */
my_strdup2(_ALLOC_ID_, &xctx->text[i].floater_ptr, translate(-1, xctx->text[i].txt_ptr));
my_strdup2(_ALLOC_ID_, &xctx->text[i].floater_ptr, translate(-1, xctx->text[i].txt_ptr, res));
txt_ptr = xctx->text[i].floater_ptr;
my_free(_ALLOC_ID_, &res);
}
}
}
@ -1561,6 +1565,7 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
int i,j,n;
char name[PATH_MAX];
char name1[PATH_MAX];
char *res = NULL;
if(symbol_name==NULL) {
tcleval("load_file_dialog {Choose symbol} *.\\{sym,tcl\\} INITIALINSTDIR");
@ -1634,7 +1639,8 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot
xctx->instances++;/* translate expects the correct balue of xctx->instances */
/* After having assigned prop_ptr to new instance translate symbol reference
* to resolve @params --> res.tcl(@value\) --> res.tcl(100) */
my_strncpy(name, translate(n, name), S(name));
my_strncpy(name, translate(n, name, res), S(name));
my_free(_ALLOC_ID_, &res);
/* parameters like res.tcl(@value\) have been resolved, so reload symbol removing previous */
if(strcmp(name, name1)) {
remove_symbol(i);

View File

@ -853,6 +853,7 @@ void draw_symbol(int what,int c, int n,int layer,short tmp_flip, short rot,
/* display PINLAYER colored instance texts even if PINLAYER disabled */
if(xctx->inst[n].color == -PINLAYER || xctx->enable_layer[textlayer]) {
char *txtptr = NULL;
char *res = NULL;
#if HAS_CAIRO==1
textfont = symptr->text[j].font;
if((textfont && textfont[0]) || (symptr->text[j].flags & (TEXT_BOLD | TEXT_OBLIQUE | TEXT_ITALIC))) {
@ -874,7 +875,8 @@ 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));
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 : "<NULL>");
@ -1034,6 +1036,7 @@ 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;
@ -1046,7 +1049,8 @@ void draw_temp_symbol(int what, GC gc, int n,int layer,short tmp_flip, short rot
#if HAS_CAIRO==1
customfont = set_text_custom_font(&text);
#endif
my_strdup2(_ALLOC_ID_, &txtptr, translate(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 */
my_strdup2(_ALLOC_ID_, &txtptr, translate3(txtptr, 0, xctx->inst[n].prop_ptr,
xctx->sym[xctx->inst[n].ptr].templ, NULL, NULL));

View File

@ -1599,6 +1599,7 @@ static int update_symbol(const char *result, int x, int selected_inst)
int *ii = &xctx->edit_sym_i; /* static var */
int *netl_com = &xctx->netlist_commands; /* static var */
int modified = 0;
char *res = NULL;
dbg(1, "update_symbol(): entering, selected_inst = %d\n", selected_inst);
*ii = selected_inst;
@ -1644,7 +1645,8 @@ static int update_symbol(const char *result, int x, int selected_inst)
/* 20171220 calculate bbox before changes to correctly redraw areas */
/* must be recalculated as cairo text extents vary with zoom factor. */
symbol_bbox(*ii, &xctx->inst[*ii].x1, &xctx->inst[*ii].y1, &xctx->inst[*ii].x2, &xctx->inst[*ii].y2);
my_strdup2(_ALLOC_ID_, &old_translated_sym, translate(*ii, xctx->inst[*ii].name));
my_strdup2(_ALLOC_ID_, &old_translated_sym, translate(*ii, xctx->inst[*ii].name, res));
my_free(_ALLOC_ID_, &res);
/* update property string from tcl dialog */
if(!no_change_props)
{
@ -1677,7 +1679,8 @@ static int update_symbol(const char *result, int x, int selected_inst)
* to use for inst name (from symbol template) */
prefix = 0;
sym_number = -1;
my_strdup2(_ALLOC_ID_, &translated_sym, translate(*ii, symbol));
my_strdup2(_ALLOC_ID_, &translated_sym, translate(*ii, symbol, res));
my_free(_ALLOC_ID_, &res);
dbg(1, "update_symbol: %s -- %s\n", translated_sym, old_translated_sym);
if(changed_symbol ||
( !strcmp(symbol, xctx->inst[*ii].name) && strcmp(translated_sym, old_translated_sym) ) ) {

View File

@ -965,6 +965,7 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho
int lvs_ignore = 0;
char *textfont;
int c_for_text;
char *res = NULL;
type = xctx->sym[xctx->inst[n].ptr].type;
lvs_ignore=tclgetboolvar("lvs_ignore");
@ -1179,13 +1180,12 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho
for(j=0;j< (xctx->inst[n].ptr+ xctx->sym)->texts; ++j)
{
double xscale, yscale;
get_sym_text_size(n, j, &xscale, &yscale);
text = symptr->text[j];
/* if(xscale*FONTWIDTH* xctx->mooz<1) continue; */
if(!xctx->show_hidden_texts && (text.flags & (HIDE_TEXT | HIDE_TEXT_INSTANTIATED))) continue;
if( hide && text.txt_ptr && strcmp(text.txt_ptr, "@symname") && strcmp(text.txt_ptr, "@name") ) continue;
txtptr= translate(n, text.txt_ptr);
txtptr= translate(n, text.txt_ptr, res);
ROTATION(rot, flip, 0.0,0.0,text.x0,text.y0,x1,y1);
textlayer = c_for_text;
/* do not allow custom text color on hilighted instances */
@ -1234,6 +1234,7 @@ static void ps_draw_symbol(int c, int n,int layer, int what, short tmp_flip, sho
}
if(textlayer != c) set_ps_colors(c);
}
if(res) my_free(_ALLOC_ID_, &res);
}
}

View File

@ -3521,6 +3521,7 @@ void link_symbols_to_instances(int from)
int cond, i, merge = 1;
char *type=NULL;
char *name = NULL;
char *res = NULL;
if(from < 0 ) {
from = 0;
@ -3530,7 +3531,8 @@ void link_symbols_to_instances(int from)
dbg(2, "link_symbols_to_instances(): inst=%d\n", i);
dbg(2, "link_symbols_to_instances(): matching inst %d name=%s \n",i, xctx->inst[i].name);
dbg(2, "link_symbols_to_instances(): -------\n");
my_strdup2(_ALLOC_ID_, &name, tcl_hook2(translate(i, xctx->inst[i].name)));
my_strdup2(_ALLOC_ID_, &name, tcl_hook2(translate(i, xctx->inst[i].name, res)));
my_free(_ALLOC_ID_, &res);
xctx->inst[i].ptr = match_symbol(name);
my_free(_ALLOC_ID_, &name);
}
@ -5217,6 +5219,8 @@ int descend_symbol(void)
int n = 0;
struct stat buf;
int save_netlist_type = xctx->netlist_type;
char *res = NULL;
if(xctx->currsch + 1 >= CADMAXHIER) {
dbg(0, "descend_symbol(): max hierarchy depth reached: %d", CADMAXHIER);
return 0;
@ -5240,7 +5244,8 @@ int descend_symbol(void)
if(ret == 0) clear_all_hilights();
if(ret == -1) return 0; /* user cancel */
}
my_snprintf(name, S(name), "%s", translate(n, xctx->inst[n].name));
my_snprintf(name, S(name), "%s", translate(n, xctx->inst[n].name, res));
my_free(_ALLOC_ID_, &res);
/* dont allow descend in the default missing symbol */
if((xctx->inst[n].ptr+ xctx->sym)->type &&
!strcmp( (xctx->inst[n].ptr+ xctx->sym)->type,"missing")) return 0;

View File

@ -4899,6 +4899,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
int sym_number = -1;
char *subst = NULL;
int inst;
char *res = NULL;
if(!xctx) {Tcl_SetResult(interp, not_avail, TCL_STATIC); return TCL_ERROR;}
if(argc < 3) {
@ -4919,7 +4920,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
hash_names(inst, XDELETE);
set_inst_prop(inst);
my_strdup2(_ALLOC_ID_, &translated_sym, translate(inst, xctx->inst[inst].name));
my_strdup2(_ALLOC_ID_, &translated_sym, translate(inst, xctx->inst[inst].name, res));
my_free(_ALLOC_ID_, &res);
sym_number=match_symbol(translated_sym);
if(sym_number > 0) {
@ -5836,7 +5838,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
} else {
char *translated_sym = NULL;
int sym_number = -1;
char *subst = NULL, *old_name = NULL;;
char *subst = NULL, *old_name = NULL;
char *res = NULL;
if(!fast) {
symbol_bbox(inst, &xctx->inst[inst].x1, &xctx->inst[inst].y1, &xctx->inst[inst].x2, &xctx->inst[inst].y2);
@ -5870,7 +5873,8 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
if(old_name) {
update_attached_floaters(old_name, inst, 0);
}
my_strdup2(_ALLOC_ID_, &translated_sym, translate(inst, xctx->inst[inst].name));
my_strdup2(_ALLOC_ID_, &translated_sym, translate(inst, xctx->inst[inst].name, res));
my_free(_ALLOC_ID_, &res);
sym_number=match_symbol(translated_sym);
if(sym_number > 0) {
@ -6526,12 +6530,14 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
if(argc>3) {
int i;
char *s = NULL;
char *res = NULL;
if(!strcmp(argv[2], "-1")) i = -1;
else if((i = get_instance(argv[2])) < 0 ) {
Tcl_SetResult(interp, "xschem translate: instance not found", TCL_STATIC);
return TCL_ERROR;
}
my_strdup2(_ALLOC_ID_, &s, translate(i, argv[3]));
my_strdup2(_ALLOC_ID_, &s, translate(i, argv[3], res));
my_free(_ALLOC_ID_, &res);
Tcl_ResetResult(interp);
Tcl_SetResult(interp, s, TCL_VOLATILE);
my_free(_ALLOC_ID_, &s);

View File

@ -354,6 +354,7 @@ void symbol_bbox(int i, double *x1,double *y1, double *x2, double *y2)
{
double xscale, yscale;
char *estr = NULL;
char *res = NULL;
get_sym_text_size(i, j, &xscale, &yscale);
text = (xctx->inst[i].ptr+ xctx->sym)->text[j];
@ -361,7 +362,7 @@ void symbol_bbox(int i, double *x1,double *y1, double *x2, double *y2)
sym_flip = flip;
sym_rot = rot;
dbg(1, "symbol_bbox(): instance %d text n: %d text str=%s\n", i,j, text.txt_ptr? text.txt_ptr:"<NULL>");
tmp_txt = translate(i, text.txt_ptr);
tmp_txt = translate(i, text.txt_ptr, res);
dbg(1, "symbol_bbox(): translated text: %s\n", tmp_txt);
if(tmp_txt && !strncmp(tmp_txt, "@spice", 6)) continue; /* annotator texts not used in bbox */
ROTATION(rot, flip, 0.0,0.0,text.x0, text.y0,text_x0,text_y0);
@ -376,6 +377,7 @@ void symbol_bbox(int i, double *x1,double *y1, double *x2, double *y2)
dbg(1, "symbol bbox: text bbox: %s, %g %g %g %g\n", tmp_txt, xx1, yy1, xx2, yy2);
dbg(1, "symbol bbox: text bbox: zoom=%g, lw=%g\n", xctx->zoom, xctx->lw);
my_free(_ALLOC_ID_, &estr);
my_free(_ALLOC_ID_, &res);
#if HAS_CAIRO==1
if(customfont) {
cairo_restore(xctx->cairo_ctx);

View File

@ -107,25 +107,27 @@ static int spectre_netlist(FILE *fd, int spectre_stop )
} else {
char *val = NULL;
const char *m;
char *res = NULL;
if(print_spectre_element(fd, i)) {
fprintf(fd, "//// end_element\n");
}
/* hash device_model attribute if any */
my_strdup2(_ALLOC_ID_, &val, get_tok_value(xctx->inst[i].prop_ptr, "spectre_device_model", 2));
m = val;
if(strchr(val, '@')) m = translate(i, val);
if(strchr(val, '@')) m = translate(i, val, res);
else m = tcl_hook2(m);
if(m[0]) str_hash_lookup(&spectre_model_table, spectre_model_name(m), m, XINSERT);
else {
my_strdup2(_ALLOC_ID_, &val,
get_tok_value(xctx->sym[xctx->inst[i].ptr].prop_ptr, "spectre_device_model", 2));
m = val;
if(strchr(val, '@')) m = translate(i, val);
if(strchr(val, '@')) m = translate(i, val, res);
else m = tcl_hook2(m);
if(m[0]) str_hash_lookup(&spectre_model_table, spectre_model_name(m), m, XINSERT);
}
my_free(_ALLOC_ID_, &spectre_mod_name_res);
my_free(_ALLOC_ID_, &val);
if(res) my_free(_ALLOC_ID_, &res);
}
}
}

View File

@ -221,25 +221,27 @@ static int spice_netlist(FILE *fd, int spice_stop )
} else {
char *val = NULL;
const char *m;
char *res = NULL;
if(print_spice_element(fd, i)) {
fprintf(fd, "**** end_element\n");
}
/* hash device_model attribute if any */
my_strdup2(_ALLOC_ID_, &val, get_tok_value(xctx->inst[i].prop_ptr, "device_model", 2));
m = val;
if(strchr(val, '@')) m = translate(i, val);
if(strchr(val, '@')) m = translate(i, val, res);
else m = tcl_hook2(m);
if(m[0]) str_hash_lookup(&model_table, model_name(m), m, XINSERT);
else {
my_strdup2(_ALLOC_ID_, &val,
get_tok_value(xctx->sym[xctx->inst[i].ptr].prop_ptr, "device_model", 2));
m = val;
if(strchr(val, '@')) m = translate(i, val);
if(strchr(val, '@')) m = translate(i, val, res);
else m = tcl_hook2(m);
if(m[0]) str_hash_lookup(&model_table, model_name(m), m, XINSERT);
}
my_free(_ALLOC_ID_, &model_name_result);
my_free(_ALLOC_ID_, &val);
if(res) my_free(_ALLOC_ID_, &res);
}
}
}

View File

@ -868,6 +868,7 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot,
draw_texts:
if( xctx->sym_txt && !(xctx->inst[n].flags & HIDE_SYMBOL_TEXTS) && (layer == cadlayers)) {
const char *txtptr;
char *res = NULL;
if(c != layer) c_for_text = c;
else if(xctx->inst[n].flags & PIN_OR_LABEL) c_for_text = TEXTWIRELAYER;
else c_for_text = TEXTLAYER;
@ -880,7 +881,7 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot,
/* if(xscale*FONTWIDTH* xctx->mooz<1) continue; */
if(!xctx->show_hidden_texts && (symptr->text[j].flags & (HIDE_TEXT | HIDE_TEXT_INSTANTIATED))) continue;
if( hide && text.txt_ptr && strcmp(text.txt_ptr, "@symname") && strcmp(text.txt_ptr, "@name") ) continue;
txtptr= translate(n, text.txt_ptr);
txtptr= translate(n, text.txt_ptr, res);
ROTATION(rot, flip, 0.0,0.0,text.x0,text.y0,x1,y1);
textlayer = c_for_text;
/* do not allow custom text color on hilighted instances */
@ -921,6 +922,7 @@ static void svg_draw_symbol(int c, int n,int layer,short tmp_flip, short rot,
x0+x1, y0+y1, xscale, yscale);
}
}
if(res) my_free(_ALLOC_ID_, &res);
}
}

View File

@ -1042,13 +1042,17 @@ static void print_vhdl_primitive(FILE *fd, int inst) /* netlist primitives, 200
else if(strcmp(token,"@symname")==0) /* of course symname must not be present */
/* in hash table */
{
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 0, 0)));
char *res = NULL;
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 0, 0), res));
my_mstrcat(_ALLOC_ID_, &result, s, NULL);
my_free(_ALLOC_ID_, &res);
}
else if (strcmp(token,"@symname_ext")==0)
{
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 1, 0)));
char *res = NULL;
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 1, 0), res));
my_mstrcat(_ALLOC_ID_, &result, s, NULL);
my_free(_ALLOC_ID_, &res);
}
else if(strcmp(token,"@schname_ext")==0) /* of course schname must not be present */
/* in hash table */
@ -1534,10 +1538,15 @@ void print_vhdl_element(FILE *fd, int inst)
/* print instance name and subckt */
dbg(2, "print_vhdl_element(): printing inst name & subcircuit name\n");
if( (lab = expandlabel(name, &tmp)) != NULL)
fprintf(fd, "%d %s : %s\n", tmp, lab, sanitize(translate(inst, get_sym_name(inst, 0, 0, 0))) );
else /* name in some strange format, probably an error */
fprintf(fd, "1 %s : %s\n", name, sanitize(translate(inst, get_sym_name(inst, 0, 0, 0))) );
if( (lab = expandlabel(name, &tmp)) != NULL) {
char *res = NULL;
fprintf(fd, "%d %s : %s\n", tmp, lab, sanitize(translate(inst, get_sym_name(inst, 0, 0, 0), res)) );
my_free(_ALLOC_ID_, &res);
} else { /* name in some strange format, probably an error */
char *res = NULL;
fprintf(fd, "1 %s : %s\n", name, sanitize(translate(inst, get_sym_name(inst, 0, 0, 0), res)) );
my_free(_ALLOC_ID_, &res);
}
dbg(2, "print_vhdl_element(): printing generics passed as properties\n");
@ -2435,13 +2444,17 @@ int print_spice_element(FILE *fd, int inst)
}
else if (strcmp(token,"@symname")==0) /* of course symname must not be present in attributes */
{
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 0, 0)));
char *res = NULL;
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 0, 0), res));
my_mstrcat(_ALLOC_ID_, &result, s, NULL);
my_free(_ALLOC_ID_, &res);
}
else if (strcmp(token,"@symname_ext")==0) /* of course symname_ext must not be present in attributes */
{
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 1, 0)));
char *res = NULL;
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 1, 0), res));
my_mstrcat(_ALLOC_ID_, &result, s, NULL);
my_free(_ALLOC_ID_, &res);
}
else if(strcmp(token,"@topschname")==0) /* of course topschname must not be present in attributes */
{
@ -2814,13 +2827,17 @@ int print_spectre_element(FILE *fd, int inst)
}
else if (strcmp(token,"@symname")==0) /* of course symname must not be present in attributes */
{
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 0, 0)));
char *res = NULL;
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 0, 0), res));
my_mstrcat(_ALLOC_ID_, &result, s, NULL);
my_free(_ALLOC_ID_, &res);
}
else if (strcmp(token,"@symname_ext")==0) /* of course symname_ext must not be present in attributes */
{
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 1, 0)));
char *res = NULL;
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 1, 0), res));
my_mstrcat(_ALLOC_ID_, &result, s, NULL);
my_free(_ALLOC_ID_, &res);
}
else if(strcmp(token,"@topschname")==0) /* of course topschname must not be present in attributes */
{
@ -3167,10 +3184,12 @@ void print_tedax_element(FILE *fd, int inst)
int net_mult;
int pin_mult;
int n;
char *res = NULL;
Int_hashtable table={NULL, 0};
subcircuit = 1;
fprintf(fd, "__subcircuit__ %s %s\n",
sanitize(translate(inst, get_sym_name(inst, 0, 0, 0))), xctx->inst[inst].instname);
sanitize(translate(inst, get_sym_name(inst, 0, 0, 0), res)), xctx->inst[inst].instname);
my_free(_ALLOC_ID_, &res);
int_hash_init(&table, 37);
for(i=0;i<no_of_pins; ++i) {
my_strdup2(_ALLOC_ID_, &net, net_name(inst,i, &net_mult, 0, 1));
@ -3308,13 +3327,17 @@ void print_tedax_element(FILE *fd, int inst)
else if(strcmp(token,"@symname")==0) /* of course symname must not be present */
/* in hash table */
{
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 0, 0)));
char *res = NULL;
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 0, 0), res));
fputs(s, fd);
my_free(_ALLOC_ID_, &res);
}
else if (strcmp(token,"@symname_ext")==0)
{
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 1, 0)));
char *res = NULL;
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 1, 0), res));
fputs(s, fd);
my_free(_ALLOC_ID_, &res);
}
else if(strcmp(token,"@schname_ext")==0) /* of course schname must not be present */
/* in hash table */
@ -3570,13 +3593,17 @@ static void print_verilog_primitive(FILE *fd, int inst) /* netlist switch level
else if(strcmp(token,"@symname")==0) /* of course symname must not be present */
/* in hash table */
{
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 0, 0)));
char *res = NULL;
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 0, 0), res));
my_mstrcat(_ALLOC_ID_, &result, s, NULL);
my_free(_ALLOC_ID_, &res);
}
else if (strcmp(token,"@symname_ext")==0)
{
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 1, 0)));
char *res = NULL;
const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 1, 0), res));
my_mstrcat(_ALLOC_ID_, &result, s, NULL);
my_free(_ALLOC_ID_, &res);
}
else if(strcmp(token,"@schname_ext")==0) /* of course schname must not be present */
/* in hash table */
@ -4466,14 +4493,12 @@ char *get_fqdevice(const char *param, int modelparam, const char *instname)
/* substitute given tokens in a string with their corresponding values */
/* ex.: name=@name w=@w l=@l ---> name=m112 w=3e-6 l=0.8e-6 */
/* if s==NULL return emty string */
const char *translate(int inst, const char *s)
const char *translate(int inst, const char *s, char *result)
{
static int mutex = 0;
#ifdef __unix__
static regex_t *get_sp_cur = NULL;
#endif
static const char *empty="";
static char *result=NULL; /* safe to keep even with multiple schematics */
size_t size=0;
size_t tmp;
register int c, state=TOK_BEGIN, space;
@ -4495,7 +4520,6 @@ const char *translate(int inst, const char *s)
char *instname = NULL;
if(!s && inst == -1) {
if(result) my_free(_ALLOC_ID_, &result);
#ifdef __unix__
if(get_sp_cur) {
regfree(get_sp_cur);
@ -4527,12 +4551,6 @@ const char *translate(int inst, const char *s)
return empty;
}
if(mutex > 0) {
dbg(0, "translate(): reentrant call, mutex=%d, skip and return empty string", mutex);
return empty;
}
mutex++;
/* if spice_get_* token not processed by tcl use enginering notation (2m, 3u, ...) */
if(!(strstr(s, "tcleval(") == s)) engineering = 1;
instname = (inst >=0 && xctx->inst[inst].instname) ? xctx->inst[inst].instname : "";
@ -5312,8 +5330,6 @@ const char *translate(int inst, const char *s)
* if result is like: 'tcleval(some_string)' pass it thru tcl evaluation so expressions
* can be calculated */
mutex--;
my_strdup2(_ALLOC_ID_, &result, tcl_hook2(result));
my_strdup2(_ALLOC_ID_, &result, spice_get_node(result));

View File

@ -97,6 +97,7 @@ int global_verilog_netlist(int global, int alert) /* netlister driver */
Str_hashtable subckt_table = {NULL, 0};
int lvs_ignore = tclgetboolvar("lvs_ignore");
int save_prev_mod = xctx->prev_set_modify;
char *res = NULL;
exit_code = 0; /* reset exit code */
split_f = tclgetboolvar("split_files");
@ -140,7 +141,8 @@ int global_verilog_netlist(int global, int alert) /* netlister driver */
str_tmp = get_tok_value(xctx->sym[xctx->inst[i].ptr].prop_ptr, "verilog_format", 2);
my_strdup(_ALLOC_ID_, &tmp_string, str_tmp);
fprintf(fd, "%s\n", str_tmp ? translate(i, tmp_string) : "<NULL>");
fprintf(fd, "%s\n", str_tmp ? translate(i, tmp_string, res) : "<NULL>");
my_free(_ALLOC_ID_, &res);
}
}
@ -436,6 +438,7 @@ int verilog_block_netlist(FILE *fd, int i, int alert)
char *name = NULL;
int lvs_ignore = tclgetboolvar("lvs_ignore");
const char *default_schematic;
char *res = NULL;
split_f = tclgetboolvar("split_files");
if(!strboolcmp( get_tok_value(xctx->sym[i].prop_ptr,"verilog_stop",0),"true") )
@ -490,7 +493,8 @@ int verilog_block_netlist(FILE *fd, int i, int alert)
if(!xctx->tok_size && strcmp(fmt_attr, "verilog_format"))
str_tmp = get_tok_value(xctx->sym[xctx->inst[j].ptr].prop_ptr, "verilog_format", 2);
my_strdup(_ALLOC_ID_, &tmp_string, str_tmp);
fprintf(fd, "%s\n", str_tmp ? translate(j, tmp_string) : "<NULL>");
fprintf(fd, "%s\n", str_tmp ? translate(j, tmp_string, res) : "<NULL>");
my_free(_ALLOC_ID_, &res);
}
}

View File

@ -974,7 +974,7 @@ static void xwin_exit(void)
clear_expandlabel_data();
get_sym_template(NULL, NULL); /* clear static data in function */
list_tokens(NULL, 0); /* clear static data in function */
translate(-1, NULL); /* 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 */

View File

@ -1657,7 +1657,7 @@ extern char *find_nth(const char *str, const char *sep, const char *quote, int k
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);
extern const char *translate(int inst, const char* s, char *result);
extern const char* translate2(Lcc *lcc, int level, char* s);
extern const char *translate3(const char* s, int eat_escapes, const char *s1,
const char *s2, const char *s3, const char *s4);