handle symbol_ref(param1,param2,...) symbol generator scripts, added some utility functions str_chars_replace(), is_symgen(), fix some quoting/backslash subst issues in get_sym_template()

This commit is contained in:
stefan schippers 2023-04-21 11:41:20 +02:00
parent 631fedb11b
commit 9eb4e9440c
8 changed files with 108 additions and 47 deletions

View File

@ -221,7 +221,12 @@ int set_netlist_dir(int force, char *dir)
const char *abs_sym_path(const char *s, const char *ext)
{
char c[PATH_MAX+1000];
my_snprintf(c, S(c), "abs_sym_path {%s} {%s}", s, ext);
if(is_symgen(s)) {
my_snprintf(c, S(c), "abs_sym_path [regsub {\\(.*} {%s} {}] {%s}", s, ext);
} else {
my_snprintf(c, S(c), "abs_sym_path {%s} {%s}", s, ext);
}
tcleval(c);
return tclresult();
}
@ -947,6 +952,7 @@ void attach_labels_to_inst(int interactive) /* offloaded from callback.c 201710
dbg(1, "attach_labels_to_inst(): %d %.16g %.16g %s\n", i, pinx0, piny0,labname);
}
}
if(first_call == 0) set_modify(1);
my_free(_ALLOC_ID_, &prop);
my_free(_ALLOC_ID_, &labname);
my_free(_ALLOC_ID_, &type);

View File

@ -1546,6 +1546,24 @@ char *str_replace(const char *str, const char *rep, const char *with, int escape
return result;
}
/* caller should free returned string */
char *str_chars_replace(const char *str, const char *replace_set, const char with)
{
char *res = NULL;
char *s;
my_strdup(_ALLOC_ID_, &res, str);
s = res;
dbg(0, "%s\n", res);
while( *s) {
if(strchr(replace_set, *s)) {
*s = with;
}
++s;
}
return res;
}
/* x=0 use tcl text widget x=1 use vim editor x=2 only view data */
void edit_property(int x)
{

View File

@ -24,27 +24,6 @@
#define X_TO_PS(x) ( (x+xctx->xorigin)* xctx->mooz )
#define Y_TO_PS(y) ( (y+xctx->yorigin)* xctx->mooz )
#if 0
* /* FIXME: overflow check. Not used, BTW */
* static char *strreplace(char s[], char token[], char replace[])
* {
* static char res[200];
* char *p1, *p2;
* int l;
*
* res[0] = '\0';
* l = strlen(token);
* p1 = p2 = s;
* while( (p2 = strstr(p1, token)) ) {
* strncat(res, p1, p2 - p1);
* strcat(res, replace);
* p1 = p2 = p2 + l;
* }
* strcat(res, p1);
* return res;
* }
#endif
char *utf8_enc[]={
"/recodedict 24 dict def\n",
"/recode {recodedict begin /nco&na exch def\n",

View File

@ -1639,12 +1639,17 @@ static void save_inst(FILE *fd, int select_only)
}
fprintf(fd, " %.16g %.16g %hd %hd ",inst[i].x0, inst[i].y0, inst[i].rot, inst[i].flip );
save_ascii_string(inst[i].prop_ptr,fd, 1);
if( embedded_saved && !embedded_saved[inst[i].ptr] && inst[i].embed) {
embedded_saved[inst[i].ptr] = 1;
fprintf(fd, "[\n");
save_embedded_symbol( xctx->sym+inst[i].ptr, fd);
fprintf(fd, "]\n");
xctx->sym[inst[i].ptr].flags |= EMBEDDED;
if(embedded_saved && !embedded_saved[inst[i].ptr]) {
if(is_symgen(inst[i].name)) {
embedded_saved[inst[i].ptr] = 1;
xctx->sym[inst[i].ptr].flags |= EMBEDDED;
} else if(inst[i].embed) {
embedded_saved[inst[i].ptr] = 1;
fprintf(fd, "[\n");
save_embedded_symbol( xctx->sym+inst[i].ptr, fd);
fprintf(fd, "]\n");
xctx->sym[inst[i].ptr].flags |= EMBEDDED;
}
}
}
my_free(_ALLOC_ID_, &embedded_saved);
@ -3229,6 +3234,7 @@ int load_sym_def(const char *name, FILE *embed_fd, int embedded)
case 'K': /* 1.2 file format: symbol attributes for schematics placed as symbols */
if (level==0) {
load_ascii_string(&symbol[symbols].prop_ptr, lcc[level].fd);
dbg(1, "load_sym_def: K prop=\n%s\n", symbol[symbols].prop_ptr);
if(!symbol[symbols].prop_ptr) break;
my_strdup2(_ALLOC_ID_, &symbol[symbols].templ,
get_tok_value(symbol[symbols].prop_ptr, "template", 0));

View File

@ -3619,13 +3619,6 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg
* testmode */
else if(!strcmp(argv[1], "test"))
{
FILE *fp = fopen("/home/schippes/xschem-repo/trunk/xschem_library/examples/sr_flop.sym", "r");
load_sym_def("sr_flop.sym", fp, 0);
fclose(fp);
xctx->inst[xctx->instances -1].ptr = xctx->symbols - 1;
my_strdup(_ALLOC_ID_, &xctx->inst[xctx->instances -1].name, xctx->sym[xctx->symbols - 1].name);
Tcl_ResetResult(interp);
}

View File

@ -161,7 +161,30 @@ void check_unique_names(int rename)
int_hash_free(&xctx->inst_table);
}
int is_symgen(const char *name)
{
#ifdef __unix__
int res = 0;
static regex_t *re = NULL;
if(!name) {
if(re) {
regfree(re);
my_free(_ALLOC_ID_, &re);
}
return 0;
}
if(!re) {
re = my_malloc(_ALLOC_ID_, sizeof(regex_t));
regcomp(re, "^[^ \\t()]+\\([^()]*\\)[ \\t]*$", REG_NOSUB | REG_EXTENDED);
}
if(!regexec(re, name, 0 , NULL, 0) ) res = 1;
/* regfree(&re); */
return res;
#else
return 0;
#endif
}
int match_symbol(const char *name) /* never returns -1, if symbol not found load systemlib/missing.sym */
{
@ -179,8 +202,42 @@ int match_symbol(const char *name) /* never returns -1, if symbol not found loa
}
if(!found)
{
dbg(1, "match_symbol(): matching symbol not found:%s, loading\n",name);
load_sym_def(name, NULL, 0); /* append another symbol to the xctx->sym[] array */
dbg(1, "match_symbol(): matching symbol not found:%s, loading\n",name);
if(!is_symgen(name)) {
load_sym_def(name, NULL, 0); /* append another symbol to the xctx->sym[] array */
} else { /* get symbol from generator script */
FILE *fp;
char *cmd = NULL;
char *ss = NULL;
const char *s;
char *spc_idx;
struct stat buf;
cmd = str_chars_replace(name, " (),", ' ');
spc_idx = strchr(cmd, ' ');
if(!spc_idx) goto end;
*spc_idx = '\0';
s = abs_sym_path(cmd, "");
if(stat(s, &buf)) {
load_sym_def(name, NULL, 0);
goto end;
}
my_strdup(_ALLOC_ID_, &ss, s);
*spc_idx = ' ';
my_strcat(_ALLOC_ID_, &ss, spc_idx);
fp = popen(ss, "r");
dbg(0, "%p\n", fp);
dbg(0, "%s\n", s);
dbg(0, "%s\n", ss);
dbg(0, "is_symgen=%d\n", is_symgen(name));
load_sym_def(name, fp, 1);
dbg(0, "%s\n", xctx->sym[xctx->symbols - 1].name);
pclose(fp);
my_free(_ALLOC_ID_, &ss);
end:
my_free(_ALLOC_ID_, &cmd);
}
}
dbg(1, "match_symbol(): returning %d\n",i);
return i;
@ -482,19 +539,17 @@ const char *get_sym_template(char *s,char *extra)
else if( state==TOK_VALUE && space && !quote) state=TOK_END;
STR_ALLOC(&value, value_pos, &sizeval);
STR_ALLOC(&token, token_pos, &sizetok);
if(c=='"') {
if(!escape) quote=!quote;
}
if(state==TOK_BEGIN) {
result[result_pos++] = (char)c;
} else if(state==TOK_TOKEN) {
token[token_pos++]=(char)c;
/* token[token_pos++]=(char)c; */
if( (with_quotes & 1) || escape || (c != '\\' && c != '"')) token[token_pos++]=(char)c;
} else if(state==TOK_VALUE) {
if(c=='"') {
if(!escape) quote=!quote;
if((with_quotes & 1) || escape) value[value_pos++]=(char)c;
}
else if( (c=='\\') && (with_quotes & 2) ) ; /* dont store backslash */
else value[value_pos++]=(char)c;
escape = (c=='\\' && !escape);
/* if((with_quotes & 1) || escape) value[value_pos++]=(char)c; */
if( (with_quotes & 1) || escape || (c != '\\' && c != '"')) value[value_pos++]=(char)c;
} else if(state==TOK_END) {
value[value_pos]='\0';
if((!extra || !strstr(extra, token)) && strcmp(token,"name") && strcmp(token,"spiceprefix")) {
@ -516,6 +571,7 @@ const char *get_sym_template(char *s,char *extra)
token_pos=0;
}
}
escape = (c=='\\' && !escape);
if(c=='\0') {
break;
}

View File

@ -666,6 +666,7 @@ static void delete_schematic_data(int delete_pixmap)
remove_symbols();
str_replace(NULL, NULL, NULL, 0);
escape_chars(NULL);
is_symgen(NULL);
free_rawfile(0);
free_xschem_data(); /* delete the xctx struct */
}

View File

@ -1479,6 +1479,8 @@ extern void hilight_parent_pins(void);
extern void hilight_net_pin_mismatches(void);
extern Node_hashentry **get_node_table_ptr(void);
extern void change_elem_order(void);
extern int is_symgen(const char *name);
extern char *str_chars_replace(const char *str, const char *replace_set, const char with);
extern char *str_replace(const char *str, const char *rep, const char *with, int escape);
extern char *escape_chars(const char *source);
extern int set_different_token(char **s,const char *new, const char *old);