From c06a896d4f8ee1a492eae1b915307b4cef9d9de9 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Fri, 9 Feb 2024 02:37:53 +0100 Subject: [PATCH] instance based schematic selection: if instance specified schematic=... not existing use base schematic (symbolname.sch) --- src/actions.c | 70 ++++++++++++++++++++++++++++++++----------------- src/scheduler.c | 11 +++++--- src/token.c | 5 +++- src/xinit.c | 2 +- src/xschem.h | 4 +-- 5 files changed, 59 insertions(+), 33 deletions(-) diff --git a/src/actions.c b/src/actions.c index b2ab2192..485606b8 100644 --- a/src/actions.c +++ b/src/actions.c @@ -217,7 +217,7 @@ void print_version() printf("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"); } -char *escape_chars(const char *source) +char *escape_chars(const char *source, const char *charset) { int s=0; int d=0; @@ -236,32 +236,41 @@ char *escape_chars(const char *source) size += 2; my_realloc(_ALLOC_ID_, &dest, size); } - switch(source[s]) { - case '\n': - dest[d++] = '\\'; - dest[d++] = 'n'; - break; - case '\t': - dest[d++] = '\\'; - dest[d++] = 't'; - break; - case '\\': - case '\'': - case ' ': - case ';': - case '$': - case '!': - case '#': - case '{': - case '}': - case '[': - case ']': - case '"': + if(!strcmp(charset, "")) { + switch(source[s]) { + case '\n': + dest[d++] = '\\'; + dest[d++] = 'n'; + break; + case '\t': + dest[d++] = '\\'; + dest[d++] = 't'; + break; + case '\\': + case '\'': + case ' ': + case ';': + case '$': + case '!': + case '#': + case '{': + case '}': + case '[': + case ']': + case '"': + dest[d++] = '\\'; + dest[d++] = source[s]; + break; + default: + dest[d++] = source[s]; + } + } else { + if(strchr(charset, source[s])) { dest[d++] = '\\'; dest[d++] = source[s]; - break; - default: + } else { dest[d++] = source[s]; + } } s++; } @@ -1850,6 +1859,7 @@ void get_additional_symbols(int what) static int num_syms; /* no context switch between start and end so it is safe */ Int_hashentry *found; Int_hashtable sym_table = {NULL, 0}; + struct stat buf; if(what == 1) { /* start */ int_hash_init(&sym_table, HASHSIZE); @@ -1864,6 +1874,7 @@ void get_additional_symbols(int what) char *verilog_sym_def = NULL; char *default_schematic = NULL; char *sch = NULL; + char symbol_base_sch[PATH_MAX] = ""; /* copy instance based *_sym_def attributes to symbol */ my_strdup(_ALLOC_ID_, &spice_sym_def, get_tok_value(xctx->inst[i].prop_ptr,"spice_sym_def",0)); @@ -1873,6 +1884,11 @@ void get_additional_symbols(int what) str_replace( get_tok_value(xctx->inst[i].prop_ptr,"schematic",2), "@symname", get_cell(xctx->inst[i].name, 0), '\\'))); dbg(1, "get_additional_symbols(): sch=%s\n", sch); + if(sch[0] && stat(abs_sym_path(sch, ""), &buf)) {/* schematic does not exist */ + my_snprintf(symbol_base_sch, PATH_MAX, "%s.sch", get_cell(xctx->sym[xctx->inst[i].ptr].name, 9999)); + dbg(1, "get_additional_symbols(): schematic not existing\n"); + dbg(1, "using: %s\n", symbol_base_sch); + } if(xctx->tok_size && xctx->inst[i].ptr>= 0) { /* token exists and instance points to valid symbol */ int j; char *sym = NULL; @@ -1900,12 +1916,18 @@ void get_additional_symbols(int what) copy_symbol(&xctx->sym[j], symptr); xctx->sym[j].base_name = symptr->name; my_strdup(_ALLOC_ID_, &xctx->sym[j].name, sym); + /* the copied symbol will not inherit the default_schematic attribute otherwise it will also * be skipped */ if(default_schematic) { my_strdup(_ALLOC_ID_, &xctx->sym[j].prop_ptr, subst_token(xctx->sym[j].prop_ptr, "default_schematic", NULL)); /* delete attribute */ } + /* if symbol has no corresponding schematic file use symbol base schematic */ + if(symbol_base_sch[0]) { + my_strdup(_ALLOC_ID_, &xctx->sym[j].prop_ptr, + subst_token(xctx->sym[j].prop_ptr, "schematic", symbol_base_sch)); + } if(spice_sym_def) { my_strdup(_ALLOC_ID_, &xctx->sym[j].prop_ptr, subst_token(xctx->sym[j].prop_ptr, "spice_sym_def", spice_sym_def)); diff --git a/src/scheduler.c b/src/scheduler.c index 0b5c868e..2d06cfcd 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -795,12 +795,15 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg Tcl_ResetResult(interp); } - /* escape_chars source - * escape tcl special characters with backslash */ + /* escape_chars source [charset] + * escape tcl special characters with backslash + * if charset is given escape characters in charset */ else if(!strcmp(argv[1], "escape_chars")) { - if(argc > 2) { - Tcl_SetResult(interp, escape_chars(argv[2]), TCL_VOLATILE); + if(argc > 3) { + Tcl_SetResult(interp, escape_chars(argv[2], argv[3]), TCL_VOLATILE); + } else if(argc > 2) { + Tcl_SetResult(interp, escape_chars(argv[2], ""), TCL_VOLATILE); } } diff --git a/src/token.c b/src/token.c index 79106f6d..6aecefcb 100644 --- a/src/token.c +++ b/src/token.c @@ -2163,6 +2163,9 @@ int print_spice_element(FILE *fd, int inst) /* Symbol format string contains model=@modp, * instance attributes does not contain a modp=xxx, * look up modp in **parent** symbol template attribute */ + dbg(1, "model: instance=%s ,val=%s, tok=%s, value=%s template=%s\n", + xctx->inst[inst].instname, + val, token, value, xctx->hier_attr[xctx->currsch - 1].templ); if(value[0] == '\0') { value=get_tok_value(xctx->hier_attr[xctx->currsch - 1].templ, val+1, 0); } @@ -2170,7 +2173,7 @@ int print_spice_element(FILE *fd, int inst) else if(val[0] == '@' && !strpbrk(value + 1, "@ ")) { /* value = translate(inst, val); */ value = get_tok_value(xctx->inst[inst].prop_ptr, val + 1, 0); - dbg(1, "val=%s, tok=%s, value=%s template=%s\n", + dbg(1, "val=%s, tok=%s, value=%s template=%s", val, token, value, xctx->hier_attr[xctx->currsch - 1].templ); if(value[0] == '\0') { value=get_tok_value(xctx->hier_attr[xctx->currsch - 1].templ, val+1, 0); diff --git a/src/xinit.c b/src/xinit.c index f444a54d..999216cb 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -708,7 +708,7 @@ static void delete_schematic_data(int delete_pixmap) * inst & wire .node fields, instance name hash */ remove_symbols(); str_replace(NULL, NULL, NULL, 0); - escape_chars(NULL); + escape_chars(NULL, ""); sanitize(NULL); is_generator(NULL); extra_rawfile(3, NULL, NULL, -1.0, -1.0); diff --git a/src/xschem.h b/src/xschem.h index b9519bea..8838668b 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1607,8 +1607,6 @@ extern void hash_name(char *token, int remove); extern void hash_names(int inst, int action); /* if i == -1 hash all instances, else do only inst */ extern void floater_hash_all_names(void); extern void symbol_bbox(int i, double *x1,double *y1, double *x2, double *y2); -/* extern char *escape_chars(char *dest, const char *source, int size); */ - extern void set_inst_prop(int i); extern void unselect_wire(int i); extern void select_hilight_net(void); @@ -1679,7 +1677,7 @@ extern void change_elem_order(int n); extern int is_generator(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 char *escape_chars(const char *source, const char *charset); extern int set_different_token(char **s,const char *new, const char *old); extern void print_hilight_net(int show); extern void list_hilights(void);