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:
parent
631fedb11b
commit
9eb4e9440c
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
18
src/save.c
18
src/save.c
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
80
src/token.c
80
src/token.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue