some simplification and refactoring of print_spice_element() and translate()

This commit is contained in:
stefan schippers 2025-02-07 13:22:08 +01:00
parent 1573ea3cad
commit 51ff56357d
1 changed files with 838 additions and 857 deletions

View File

@ -2212,107 +2212,38 @@ int print_spice_element(FILE *fd, int inst)
token[token_pos]='\0'; token[token_pos]='\0';
token_pos=0; token_pos=0;
/* if spiceprefix==0 and token == @spiceprefix then set empty value */
if (!tclgetboolvar("spiceprefix") && !strcmp(token, "@spiceprefix")) {
value=NULL;
} else {
size_t tok_val_len;
size_t tok_size;
dbg(1, "print_spice_element(): token: |%s|\n", token);
my_strdup2(_ALLOC_ID_, &val, get_tok_value(xctx->inst[inst].prop_ptr, token+1, 0));
tok_size = xctx->tok_size;
value = val;
if(strchr(value, '@')) {
/* Symbol format string contains model=@modp,
* resolve @modp looking in instance attributes ... */
char *parent_prop_ptr = NULL;
char *parent_templ = NULL;
if(xctx->currsch > 0) {
/* ... also look up modp also in **parent** instance prop_ptr and symbol template attribute */
parent_prop_ptr = xctx->hier_attr[xctx->currsch - 1].prop_ptr;
parent_templ = xctx->hier_attr[xctx->currsch - 1].templ;
}
dbg(1, "print_spice_element(): before translate3(): value=%s\n", value);
value = translate3(val, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, parent_templ);
dbg(1, "print_spice_element(): after translate3(): value=%s\n", value);
}
tok_val_len = strlen(value);
if(!strcmp(token, "@spiceprefix") && value[0]) {
my_realloc(_ALLOC_ID_, &spiceprefixtag, tok_val_len+22);
my_snprintf(spiceprefixtag, tok_val_len+22, "**** spice_prefix %s\n", value);
value = spiceprefixtag;
}
xctx->tok_size = tok_size;
/* xctx->tok_size==0 indicates that token(+1) does not exist in instance attributes */
if (!xctx->tok_size) value=get_tok_value(template, token+1, 0);
token_exists = xctx->tok_size;
if(strstr(value, "expr(") ) {
my_strdup2(_ALLOC_ID_, &val, value);
value = eval_expr(translate3(val, 1, xctx->inst[inst].prop_ptr, template, NULL));
}
if(!strcmp("@savecurrent", token)) {
token_exists = 0; /* processed later */
value = NULL;
}
}
if(!token_exists && token[0] =='%') {
/* result_pos += my_snprintf(result + result_pos, tmp, "%s", token + 1); */
my_mstrcat(_ALLOC_ID_, &result, token + 1, NULL);
/* fputs(token + 1, fd); */
} else if (value && value[0]!='\0') {
/* instance names (name) and node labels (lab) go thru the expandlabel function. */
/*if something else must be parsed, put an if here! */
if (!(strcmp(token+1,"name") && strcmp(token+1,"lab")) /* expand name/labels */
&& ((lab = expandlabel(value, &itmp)) != NULL)) {
/* result_pos += my_snprintf(result + result_pos, tmp, "%s", lab); */
my_mstrcat(_ALLOC_ID_, &result, lab, NULL);
/* fputs(lab,fd); */
} else {
/* result_pos += my_snprintf(result + result_pos, tmp, "%s", value); */
my_mstrcat(_ALLOC_ID_, &result, value, NULL);
/* fputs(value,fd); */
}
} if(strcmp(token,"@symref")==0)
else if(strcmp(token,"@symref")==0)
{ {
const char *s = get_sym_name(inst, 9999, 1, 0); const char *s = get_sym_name(inst, 9999, 1, 0);
/* result_pos += my_snprintf(result + result_pos, tmp, "%s", s); */
my_mstrcat(_ALLOC_ID_, &result, s, NULL); my_mstrcat(_ALLOC_ID_, &result, s, NULL);
} }
else if (strcmp(token,"@symname")==0) /* of course symname must not be present in attributes */ 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))); const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 0, 0)));
/* result_pos += my_snprintf(result + result_pos, tmp, "%s", s); */
my_mstrcat(_ALLOC_ID_, &result, s, NULL); my_mstrcat(_ALLOC_ID_, &result, s, NULL);
/* fputs(s,fd); */
} }
else if (strcmp(token,"@symname_ext")==0) /* of course symname_ext must not be present in attributes */ 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))); const char *s = sanitize(translate(inst, get_sym_name(inst, 0, 1, 0)));
/* result_pos += my_snprintf(result + result_pos, tmp, "%s", s); */
my_mstrcat(_ALLOC_ID_, &result, s, NULL); my_mstrcat(_ALLOC_ID_, &result, s, NULL);
/* fputs(s,fd); */
} }
else if(strcmp(token,"@topschname")==0) /* of course topschname must not be present in attributes */ else if(strcmp(token,"@topschname")==0) /* of course topschname must not be present in attributes */
{ {
const char *topsch; const char *topsch;
topsch = get_trailing_path(xctx->sch[0], 0, 1); topsch = get_trailing_path(xctx->sch[0], 0, 1);
/* result_pos += my_snprintf(result + result_pos, tmp, "%s", topsch); */
my_mstrcat(_ALLOC_ID_, &result, topsch, NULL); my_mstrcat(_ALLOC_ID_, &result, topsch, NULL);
} }
else if(strcmp(token,"@schname_ext")==0) /* of course schname must not be present in attributes */ else if(strcmp(token,"@schname_ext")==0) /* of course schname must not be present in attributes */
{ {
/* result_pos += my_snprintf(result + result_pos, tmp, "%s", xctx->current_name); */
my_mstrcat(_ALLOC_ID_, &result, xctx->current_name, NULL); my_mstrcat(_ALLOC_ID_, &result, xctx->current_name, NULL);
/* fputs(xctx->current_name, fd); */
} }
else if(strcmp(token,"@savecurrent")==0) else if(strcmp(token,"@savecurrent")==0)
{ {
@ -2321,14 +2252,12 @@ int print_spice_element(FILE *fd, int inst)
const char *sc = get_tok_value(xctx->inst[inst].prop_ptr, "savecurrent", 0); const char *sc = get_tok_value(xctx->inst[inst].prop_ptr, "savecurrent", 0);
if(!sc[0]) sc = get_tok_value(template, "savecurrent", 0); if(!sc[0]) sc = get_tok_value(template, "savecurrent", 0);
if(!strboolcmp(sc , "true")) { if(!strboolcmp(sc , "true")) {
/* result_pos += my_snprintf(result + result_pos, tmp, "\n.save I( ?1 %s )", instname); */
my_mstrcat(_ALLOC_ID_, &result, "\n.save I( ?1 ", instname, " )", NULL); my_mstrcat(_ALLOC_ID_, &result, "\n.save I( ?1 ", instname, " )", NULL);
} }
} }
else if(strcmp(token,"@schname")==0) /* of course schname must not be present in attributes */ else if(strcmp(token,"@schname")==0) /* of course schname must not be present in attributes */
{ {
const char *schname = get_cell(xctx->current_name, 0); const char *schname = get_cell(xctx->current_name, 0);
/* result_pos += my_snprintf(result + result_pos, tmp, "%s", schname); */
my_mstrcat(_ALLOC_ID_, &result, schname, NULL); my_mstrcat(_ALLOC_ID_, &result, schname, NULL);
} }
else if(strcmp(token,"@pinlist")==0) /* of course pinlist must not be present in attributes */ else if(strcmp(token,"@pinlist")==0) /* of course pinlist must not be present in attributes */
@ -2346,7 +2275,6 @@ int print_spice_element(FILE *fd, int inst)
if(!int_hash_lookup(&table, name, 1, XINSERT_NOREPLACE)) { if(!int_hash_lookup(&table, name, 1, XINSERT_NOREPLACE)) {
str_ptr = net_name(inst, i, &multip, 0, 1); str_ptr = net_name(inst, i, &multip, 0, 1);
/* result_pos += my_snprintf(result + result_pos, tmp, "?%d %s ", multip, str_ptr); */
my_mstrcat(_ALLOC_ID_, &result, "?", my_itoa(multip), " ", str_ptr, " ", NULL); my_mstrcat(_ALLOC_ID_, &result, "?", my_itoa(multip), " ", str_ptr, " ", NULL);
} }
} }
@ -2361,7 +2289,6 @@ int print_spice_element(FILE *fd, int inst)
if(strboolcmp(get_tok_value(prop,"spice_ignore",0), "true")) { if(strboolcmp(get_tok_value(prop,"spice_ignore",0), "true")) {
str_ptr = net_name(inst,i, &multip, 0, 1); str_ptr = net_name(inst,i, &multip, 0, 1);
/* result_pos += my_snprintf(result + result_pos, tmp, "?%d %s ", multip, str_ptr); */
my_mstrcat(_ALLOC_ID_, &result, "?", my_itoa(multip), " ", str_ptr, " ", NULL); my_mstrcat(_ALLOC_ID_, &result, "?", my_itoa(multip), " ", str_ptr, " ", NULL);
} }
break; break;
@ -2413,7 +2340,6 @@ int print_spice_element(FILE *fd, int inst)
} }
my_free(_ALLOC_ID_, &tmpstr); my_free(_ALLOC_ID_, &tmpstr);
} }
/* result_pos += my_snprintf(result + result_pos, tmp, "%s", value); */
my_mstrcat(_ALLOC_ID_, &result, value, NULL); my_mstrcat(_ALLOC_ID_, &result, value, NULL);
my_free(_ALLOC_ID_, &pin_attr_value); my_free(_ALLOC_ID_, &pin_attr_value);
} }
@ -2424,7 +2350,6 @@ int print_spice_element(FILE *fd, int inst)
if(strboolcmp(si, "true")) { if(strboolcmp(si, "true")) {
str_ptr = net_name(inst,n, &multip, 0, 1); str_ptr = net_name(inst,n, &multip, 0, 1);
/* result_pos += my_snprintf(result + result_pos, tmp, "?%d %s ", multip, str_ptr); */
my_mstrcat(_ALLOC_ID_, &result, "?", my_itoa(multip), " ", str_ptr, " ", NULL); my_mstrcat(_ALLOC_ID_, &result, "?", my_itoa(multip), " ", str_ptr, " ", NULL);
} }
} }
@ -2442,42 +2367,106 @@ int print_spice_element(FILE *fd, int inst)
dbg(1, "print_spice_element(): tclpropeval {%s} {%s} {%s}", token, name, xctx->inst[inst].name); dbg(1, "print_spice_element(): tclpropeval {%s} {%s} {%s}", token, name, xctx->inst[inst].name);
res = tcleval(tclcmd); res = tcleval(tclcmd);
/* result_pos += my_snprintf(result + result_pos, tmp, "%s", res); */
my_mstrcat(_ALLOC_ID_, &result, res, NULL); my_mstrcat(_ALLOC_ID_, &result, res, NULL);
/* fprintf(fd, "%s", tclresult()); */
my_free(_ALLOC_ID_, &tclcmd); my_free(_ALLOC_ID_, &tclcmd);
} /* /20171029 */ }
/* if spiceprefix==0 and token == @spiceprefix then set empty value */
else if (!tclgetboolvar("spiceprefix") && !strcmp(token, "@spiceprefix")) {
value=NULL;
/* else tcl var spiceprefix is enabled */
}
else {
/* here a @token in format string will be replaced by value in instance prop_ptr
* or symbol template */
size_t tok_val_len;
size_t tok_size;
dbg(1, "print_spice_element(): token: |%s|\n", token);
my_strdup2(_ALLOC_ID_, &val, get_tok_value(xctx->inst[inst].prop_ptr, token+1, 0));
/* xctx->tok_size==0 indicates that token(+1) does not exist in instance attributes
* so try to get from symbol template */
if (!xctx->tok_size) {
my_strdup2(_ALLOC_ID_, &val, get_tok_value(template, token+1, 0));
}
token_exists = xctx->tok_size;
tok_size = xctx->tok_size;
value = val;
if(strchr(value, '@')) {
/* Symbol format string contains model=@modp,
* resolve @modp looking in instance attributes ... */
char *parent_prop_ptr = NULL;
char *parent_templ = NULL;
if(xctx->currsch > 0) {
/* ... look up modp also in **parent** instance prop_ptr and symbol template attribute */
parent_prop_ptr = xctx->hier_attr[xctx->currsch - 1].prop_ptr;
parent_templ = xctx->hier_attr[xctx->currsch - 1].templ;
}
dbg(1, "print_spice_element(): before translate3(): value=%s\n", value);
value = translate3(val, 0, xctx->inst[inst].prop_ptr, parent_prop_ptr, parent_templ);
dbg(1, "print_spice_element(): after translate3(): value=%s\n", value);
}
tok_val_len = strlen(value);
xctx->tok_size = tok_size;
/* @spiceprefix needs a special tag for postprocessing */
if(!strcmp(token, "@spiceprefix") && value[0]) {
my_realloc(_ALLOC_ID_, &spiceprefixtag, tok_val_len+22);
my_snprintf(spiceprefixtag, tok_val_len+22, "**** spice_prefix %s\n", value);
value = spiceprefixtag;
}
if(strstr(value, "expr(") ) {
my_strdup2(_ALLOC_ID_, &val, value);
value = eval_expr(translate3(val, 1, xctx->inst[inst].prop_ptr, template, NULL));
}
/* token=%xxxx and xxxx is not defined in prop_ptr or template: return xxxx */
if(!token_exists && token[0] =='%') {
my_mstrcat(_ALLOC_ID_, &result, token + 1, NULL);
}
/* And finally set the value of token into result string */
else if (value && value[0]!='\0') {
/* instance names (name) and node labels (lab) go thru the expandlabel function. */
/*if something else must be parsed, put an if here! */
if (!(strcmp(token+1,"name") && strcmp(token+1,"lab")) /* expand name/labels */
&& ((lab = expandlabel(value, &itmp)) != NULL)) {
my_mstrcat(_ALLOC_ID_, &result, lab, NULL);
} else {
my_mstrcat(_ALLOC_ID_, &result, value, NULL);
}
}
} /* else */
/* append token separator to output result ... */
if(c != '%' && c != '@' && c!='\0' ) { if(c != '%' && c != '@' && c!='\0' ) {
char str[2]; char str[2];
str[0] = (unsigned char) c; str[0] = (unsigned char) c;
str[1] = '\0'; str[1] = '\0';
/* result_pos += my_snprintf(result + result_pos, 2, "%c", c); */ /* no realloc needed */
my_mstrcat(_ALLOC_ID_, &result, str, NULL); my_mstrcat(_ALLOC_ID_, &result, str, NULL);
/* fputc(c,fd); */
} }
/* ... unless it is the start of another token, so push back to input string */
if(c == '@' || c == '%' ) s--; if(c == '@' || c == '%' ) s--;
state=TOK_BEGIN; state=TOK_BEGIN;
my_free(_ALLOC_ID_, &val); my_free(_ALLOC_ID_, &val);
} } /* else if (state==TOK_SEP) */
else if(state==TOK_BEGIN && c!='\0') { else if(state==TOK_BEGIN && c!='\0') {
char str[2]; char str[2];
str[0] = (unsigned char) c; str[0] = (unsigned char) c;
str[1] = '\0'; str[1] = '\0';
/* result_pos += my_snprintf(result + result_pos, 2, "%c", c); */ /* no realloc needed */
my_mstrcat(_ALLOC_ID_, &result, str, NULL); my_mstrcat(_ALLOC_ID_, &result, str, NULL);
/* fputc(c,fd); */
} }
if(c=='\0') if(c=='\0')
{ {
char str[2]; char str[2];
str[0] = '\n'; str[0] = '\n';
str[1] = '\0'; str[1] = '\0';
/* result_pos += my_snprintf(result + result_pos, 2, "%c", '\n'); */ /* no realloc needed */
my_mstrcat(_ALLOC_ID_, &result, str, NULL); my_mstrcat(_ALLOC_ID_, &result, str, NULL);
/* fputc('\n',fd); */
break; break;
} }
} /* while(1) */ } /* while(1) */
@ -2509,7 +2498,7 @@ int print_spice_element(FILE *fd, int inst)
my_free(_ALLOC_ID_, &name); my_free(_ALLOC_ID_, &name);
my_free(_ALLOC_ID_, &token); my_free(_ALLOC_ID_, &token);
my_free(_ALLOC_ID_, &result); my_free(_ALLOC_ID_, &result);
my_free(_ALLOC_ID_, &spiceprefixtag); if(spiceprefixtag) my_free(_ALLOC_ID_, &spiceprefixtag);
/* my_free(_ALLOC_ID_, &translatedvalue); */ /* my_free(_ALLOC_ID_, &translatedvalue); */
return 1; return 1;
} }
@ -3752,7 +3741,6 @@ const char *translate(int inst, const char* s)
{ {
static regex_t *get_sp_cur = NULL; static regex_t *get_sp_cur = NULL;
static const char *empty=""; static const char *empty="";
static char *translated_tok = NULL;
static char *result=NULL; /* safe to keep even with multiple schematics */ static char *result=NULL; /* safe to keep even with multiple schematics */
size_t size=0; size_t size=0;
size_t tmp; size_t tmp;
@ -3776,7 +3764,6 @@ const char *translate(int inst, const char* s)
if(!s && inst == -1) { if(!s && inst == -1) {
if(result) my_free(_ALLOC_ID_, &result); if(result) my_free(_ALLOC_ID_, &result);
if(translated_tok) my_free(_ALLOC_ID_, &translated_tok);
if(get_sp_cur) { if(get_sp_cur) {
regfree(get_sp_cur); regfree(get_sp_cur);
get_sp_cur = NULL; get_sp_cur = NULL;
@ -3816,7 +3803,6 @@ const char *translate(int inst, const char* s)
while(1) while(1)
{ {
c=*s++; c=*s++;
if(c=='\\') { if(c=='\\') {
escape=1; escape=1;
@ -4489,11 +4475,6 @@ const char *translate(int inst, const char* s)
dbg(1, "2 translate(): lcc[%d].prop_ptr=%s, value1=%s\n", i-1, lcc[i-1].prop_ptr, value1); dbg(1, "2 translate(): lcc[%d].prop_ptr=%s, value1=%s\n", i-1, lcc[i-1].prop_ptr, value1);
i--; i--;
} }
if(strstr(value1, "expr(") == value1) {
dbg(1, "translate(): expr():%s\n", value1);
my_strdup2(_ALLOC_ID_, &value1, eval_expr(
translate3(value1, 1, xctx->inst[inst].prop_ptr, xctx->sym[xctx->inst[inst].ptr].templ, NULL)));
}
tmp=strlen(value1); tmp=strlen(value1);
STR_ALLOC(&result, tmp + result_pos, &size); STR_ALLOC(&result, tmp + result_pos, &size);
memcpy(result+result_pos, value1, tmp+1); memcpy(result+result_pos, value1, tmp+1);
@ -4515,17 +4496,17 @@ const char *translate(int inst, const char* s)
} /* while(1) */ } /* while(1) */
dbg(2, "translate(): returning %s\n", result); dbg(2, "translate(): returning %s\n", result);
my_free(_ALLOC_ID_, &token); my_free(_ALLOC_ID_, &token);
/* if result is like: 'tcleval(some_string)' pass it thru tcl evaluation so expressions /* resolve spice_get_node patterns.
* if result is like: 'tcleval(some_string)' pass it thru tcl evaluation so expressions
* can be calculated */ * can be calculated */
my_strdup2(_ALLOC_ID_, &translated_tok, spice_get_node(tcl_hook2(result))); my_strdup2(_ALLOC_ID_, &result, spice_get_node(tcl_hook2(result)));
if(strstr(translated_tok, "expr(")) { if(strstr(result, "expr(")) {
dbg(1, "translate(): expr():%s\n", translated_tok); dbg(1, "translate(): expr():%s\n", result);
my_strdup2(_ALLOC_ID_, &translated_tok, eval_expr( my_strdup2(_ALLOC_ID_, &result, eval_expr(
translate3(translated_tok, 1, xctx->inst[inst].prop_ptr, xctx->sym[xctx->inst[inst].ptr].templ, NULL))); translate3(result, 1, xctx->inst[inst].prop_ptr, xctx->sym[xctx->inst[inst].ptr].templ, NULL)));
} }
return result;
return translated_tok;
} }
const char *translate2(Lcc *lcc, int level, char* s) const char *translate2(Lcc *lcc, int level, char* s)