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

This commit is contained in:
stefan schippers 2023-04-20 10:44:31 +02:00
parent 6c364a74cc
commit 631fedb11b
10 changed files with 93 additions and 75 deletions

View File

@ -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]));

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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 */
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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 {

View File

@ -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 */
}

View File

@ -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);