From 631fedb11b500a2c3b66fdd7820e213bf77487d5 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Thu, 20 Apr 2023 10:44:31 +0200 Subject: [PATCH] enabled escape_chars convenience function, added "embedded" parameter to load_sym_def() to better distinguish loading an embedded symbol from loading a regular symbol with a provided file descriptor --- src/actions.c | 99 +++++++++++++++++++++++-------------------- src/netlist.c | 2 +- src/save.c | 27 +++++++----- src/scheduler.c | 28 +++++++----- src/spice_netlist.c | 2 +- src/token.c | 2 +- src/verilog_netlist.c | 2 +- src/vhdl_netlist.c | 2 +- src/xinit.c | 1 + src/xschem.h | 3 +- 10 files changed, 93 insertions(+), 75 deletions(-) diff --git a/src/actions.c b/src/actions.c index cb7e52ed..428029ea 100644 --- a/src/actions.c +++ b/src/actions.c @@ -114,52 +114,57 @@ void print_version() exit(EXIT_SUCCESS); } -#if 0 -* char *escape_chars(char *dest, const char *source, int size) -* { -* int s=0; -* int d=0; -* size--; /* reserve space for \0 */ -* while(source && source[s]) { -* switch(source[s]) { -* case '\n': -* if(d < size-1) { -* dest[d++] = '\\'; -* dest[d++] = 'n'; -* } -* break; -* case '\t': -* if(d < size-1) { -* dest[d++] = '\\'; -* dest[d++] = 't'; -* } -* break; -* case '\\': -* case '\'': -* case ' ': -* case ';': -* case '$': -* case '!': -* case '#': -* case '{': -* case '}': -* case '[': -* case ']': -* case '"': -* if(d < size-1) { -* dest[d++] = '\\'; -* dest[d++] = source[s]; -* } -* break; -* default: -* if(d < size) dest[d++] = source[s]; -* } -* s++; -* } -* dest[d] = '\0'; -* return dest; -* } -#endif +char *escape_chars(const char *source) +{ + int s=0; + int d=0; + static char *dest = NULL; + size_t slen, size; + + if(!source) { + if(dest) my_free(_ALLOC_ID_, &dest); + return NULL; + } + slen = strlen(source); + size = slen + 1; + my_realloc(_ALLOC_ID_, &dest, size); + while(source && source[s]) { + if(d >= size - 2) { + 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 '"': + dest[d++] = '\\'; + dest[d++] = source[s]; + break; + default: + dest[d++] = source[s]; + } + s++; + } + dest[d] = '\0'; + return dest; +} void set_snap(double newsnap) /* 20161212 set new snap factor and just notify new value */ { @@ -1473,7 +1478,7 @@ void go_back(int confirm) /* 20171006 add confirm */ /* when returning after editing an embedded symbol * load immediately symbol definition before going back (.xschem_embedded... file will be lost) */ - load_sym_def(xctx->sch[xctx->currsch], NULL); + load_sym_def(xctx->sch[xctx->currsch], NULL, 0); from_embedded_sym=1; } my_strncpy(xctx->sch[xctx->currsch] , "", S(xctx->sch[xctx->currsch])); diff --git a/src/netlist.c b/src/netlist.c index 51277665..2db26eda 100644 --- a/src/netlist.c +++ b/src/netlist.c @@ -1407,7 +1407,7 @@ int sym_vs_sch_pins() } break; case '[': - load_sym_def(name, fd); + load_sym_def(name, fd, 1); break; case ']': read_line(fd, 0); diff --git a/src/save.c b/src/save.c index 718ce3ee..5c34091d 100644 --- a/src/save.c +++ b/src/save.c @@ -2186,7 +2186,7 @@ static void read_xschem_file(FILE *fd) } read_line(fd, 0); /* skip garbage after '[' */ if(!found) { - load_sym_def(xctx->inst[xctx->instances-1].name, fd); + load_sym_def(xctx->inst[xctx->instances-1].name, fd, 1); found = 2; } } @@ -2371,8 +2371,9 @@ int save_schematic(const char *schname) /* 20171020 added return value */ return 1; } -/* from == -1 --> link symbols to all instances, from 0 to instances-1 */ -void link_symbols_to_instances(int from) /* from >= 0 : linking symbols from pasted schematic / clipboard */ +/* from == -1: link symbols to all instances, from 0 to instances-1 + * from >= 0: link symbols from pasted schematic / clipboard */ +void link_symbols_to_instances(int from) { int cond, i, merge = 1; char *type=NULL; @@ -3080,7 +3081,11 @@ void sort_symbol_pins(xRect *pin_array, int npins, const char *name) } } -/* Global (or static global) variables used: +/* load_sym_def(): load a symbol definition looking up 'name' in the search paths. + * if 'embed_fd' FILE pointer is given read from there instead of searching 'name' + * 'embedded' parameter: set to 1 if loading an embedded symbol (embed_fd FILE pointer is given) + * set to 0 if loading a symbol that is not embedded from the given FILE pointer. + * Global (or static global) variables used: * cadlayers * errfp * xctx->file_version @@ -3088,7 +3093,7 @@ void sort_symbol_pins(xRect *pin_array, int npins, const char *name) * xctx->symbols * has_x */ -int load_sym_def(const char *name, FILE *embed_fd) +int load_sym_def(const char *name, FILE *embed_fd, int embedded) { static int recursion_counter=0; /* safe to keep even with multiple schematics, operation not interruptable */ Lcc *lcc; /* size = level */ @@ -3137,12 +3142,12 @@ int load_sym_def(const char *name, FILE *embed_fd) lcc=NULL; my_realloc(_ALLOC_ID_, &lcc, (level + 1) * sizeof(Lcc)); max_level = level + 1; - if(!strcmp(xctx->file_version,"1.0")) { - my_strncpy(sympath, abs_sym_path(name, ".sym"), S(sympath)); - } else { - my_strncpy(sympath, abs_sym_path(name, ""), S(sympath)); - } if(!embed_fd) { /* regular symbol: open file */ + if(!strcmp(xctx->file_version,"1.0")) { + my_strncpy(sympath, abs_sym_path(name, ".sym"), S(sympath)); + } else { + my_strncpy(sympath, abs_sym_path(name, ""), S(sympath)); + } if((lcc[level].fd=fopen(sympath,fopen_read_mode))==NULL) { /* not found: try web URL */ if( strstr(xctx->current_dirname, "http://") == xctx->current_dirname || @@ -3684,7 +3689,7 @@ int load_sym_def(const char *name, FILE *embed_fd) dbg(1, "l_s_d(): fclose2, level=%d, fd=%p\n", level, lcc[0].fd); fclose(lcc[0].fd); } - if(embed_fd || strstr(name, ".xschem_embedded_")) { + if(embedded || strstr(name, ".xschem_embedded_")) { symbol[symbols].flags |= EMBEDDED; } else { symbol[symbols].flags &= ~EMBEDDED; diff --git a/src/scheduler.c b/src/scheduler.c index 33609dba..dd8585c4 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -693,6 +693,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 */ + else if(!strcmp(argv[1], "escape_chars")) + { + if(argc > 2) { + Tcl_SetResult(interp, escape_chars(argv[2]), TCL_VOLATILE); + } + } + /* exit * Exit the program, ask for confirm if current file modified. */ else if(!strcmp(argv[1], "exit")) @@ -2916,7 +2925,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg else if( !strcmp((xctx->inst[i].ptr + xctx->sym)->type, "iopin") ) dir="inout"; else dir = NULL; if(dir) { - lab = get_tok_value(xctx->inst[i].prop_ptr, "lab", 0); + lab = xctx->inst[i].lab; if(first == 0) Tcl_AppendResult(interp, " ", NULL); Tcl_AppendResult(interp, "{", lab, "} {", dir, "}", NULL); first = 0; @@ -3610,16 +3619,13 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg * testmode */ else if(!strcmp(argv[1], "test")) { - Ptr_hashtable table = {NULL, 0}; - Ptr_hashentry *entry; - double a = 10.1; - ptr_hash_init(&table, 37); - ptr_hash_lookup(&table, "val", &a, XINSERT); - - entry = ptr_hash_lookup(&table, "val", NULL, XLOOKUP); - dbg(0, "val=%g\n", *(double *)entry->value); - ptr_hash_free(&table); - + 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); } diff --git a/src/spice_netlist.c b/src/spice_netlist.c index 16167761..52bfc3bc 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -173,7 +173,7 @@ static int spice_netlist(FILE *fd, int spice_stop ) if(!strcmp(type, "ipin")) d = 'I'; if(!strcmp(type, "opin")) d = 'O'; if(!strcmp(type, "iopin")) d = 'B'; - fprintf(fd, "%s:%c ",get_tok_value(xctx->inst[i].prop_ptr, "lab",0), d); + fprintf(fd, "%s:%c ",xctx->inst[i].lab, d); } else { print_spice_element(fd, i) ; /* this is the element line */ } diff --git a/src/token.c b/src/token.c index afbff6dc..b6574b62 100644 --- a/src/token.c +++ b/src/token.c @@ -180,7 +180,7 @@ 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); /* append another symbol to the xctx->sym[] array */ + load_sym_def(name, NULL, 0); /* append another symbol to the xctx->sym[] array */ } dbg(1, "match_symbol(): returning %d\n",i); return i; diff --git a/src/verilog_netlist.c b/src/verilog_netlist.c index 8729c588..5f808104 100644 --- a/src/verilog_netlist.c +++ b/src/verilog_netlist.c @@ -215,7 +215,7 @@ int global_verilog_netlist(int global) /* netlister driver */ /* 20071006 print top level params if defined in symbol */ str_tmp = add_ext(xctx->sch[xctx->currsch], ".sym"); if(!stat(str_tmp, &buf)) { - load_sym_def(str_tmp, NULL ); + load_sym_def(str_tmp, NULL, 0); print_verilog_param(fd,xctx->symbols-1); /* added print top level params */ remove_symbol(xctx->symbols - 1); } diff --git a/src/vhdl_netlist.c b/src/vhdl_netlist.c index 0e0124bb..48f398b8 100644 --- a/src/vhdl_netlist.c +++ b/src/vhdl_netlist.c @@ -212,7 +212,7 @@ int global_vhdl_netlist(int global) /* netlister driver */ /* 20071009 print top level generics if defined in symbol */ str_tmp = add_ext(xctx->sch[xctx->currsch], ".sym"); if(!stat(str_tmp, &buf)) { - load_sym_def(str_tmp, NULL ); + load_sym_def(str_tmp, NULL, 0); print_generic(fd,"entity", xctx->symbols-1); /* added print top level params */ remove_symbol(xctx->symbols - 1); } else { diff --git a/src/xinit.c b/src/xinit.c index 4e06c464..7d7239ef 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -665,6 +665,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); free_rawfile(0); free_xschem_data(); /* delete the xctx struct */ } diff --git a/src/xschem.h b/src/xschem.h index 9b812c5d..b7f4812e 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1273,7 +1273,7 @@ extern int spice_block_netlist(FILE *fd, int i); extern void remove_symbols(void); extern void remove_symbol(int i); extern void clear_drawing(void); -extern int load_sym_def(const char name[], FILE *embed_fd); +extern int load_sym_def(const char name[], FILE *embed_fd, int embedded); extern void descend_symbol(void); extern int place_symbol(int pos, const char *symbol_name, double x, double y, short rot, short flip, const char *inst_props, int draw_sym, int first_call, int to_push_undo); @@ -1480,6 +1480,7 @@ extern void hilight_net_pin_mismatches(void); extern Node_hashentry **get_node_table_ptr(void); extern void change_elem_order(void); 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); extern void print_hilight_net(int show); extern void list_hilights(void);