From 014ebf0477a47cc967e9674dfca273c666825e09 Mon Sep 17 00:00:00 2001 From: stefan schippers Date: Thu, 18 May 2023 20:55:14 +0200 Subject: [PATCH] is_from_web() function to avoid code repetitions, more heuristics when trying to descend into web hierarchies --- src/actions.c | 10 ++++++---- src/save.c | 42 ++++++++++++++++++++++++++++++++---------- src/xinit.c | 3 +-- src/xschem.h | 1 + 4 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/actions.c b/src/actions.c index 4cc802d1..15077424 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1535,8 +1535,7 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst) struct stat buf; /* get sch/sym name from parent schematic downloaded from web */ - if( strstr(xctx->current_dirname, "http://") == xctx->current_dirname || - strstr(xctx->current_dirname, "https://") == xctx->current_dirname) { + if(is_from_web(xctx->current_dirname)) { web_url = 1; } dbg(1, "get_sch_from_sym(): symbol %s inst=%d web_url=%d\n", sym->name, inst, web_url); @@ -1583,8 +1582,11 @@ void get_sch_from_sym(char *filename, xSymbol *sym, int inst) /* download item into ${XSCHEM_TMP_DIR}/xschem_web */ tclvareval("try_download_url {", xctx->current_dirname, "} {", filename, "}", NULL); } - /* load it */ - my_strncpy(filename, sympath, PATH_MAX); + if(stat(sympath, &buf)) { /* not found !!! build abs_sym_path to look into local fs and hope fror the best */ + my_strncpy(filename, abs_sym_path(sym->name, ".sch"), PATH_MAX); + } else { + my_strncpy(filename, sympath, PATH_MAX); + } } my_free(_ALLOC_ID_, &str_tmp); dbg(1, "get_sch_from_sym(): sym->name=%s, filename=%s\n", sym->name, filename); diff --git a/src/save.c b/src/save.c index 74e857a3..eaa40cce 100644 --- a/src/save.c +++ b/src/save.c @@ -2434,8 +2434,7 @@ void load_schematic(int load_symbols, const char *fname, int reset_undo, int ale my_strncpy(name, fname, S(name)); dbg(1, "load_schematic(): fname=%s\n", fname); /* remote web object specified */ - if(strstr(fname , "http://") == fname || - strstr(fname , "https://") == fname) { + if(is_from_web(fname)) { /* download into ${XSCHEM_TMP_DIR}/xschem_web */ tclvareval("download_url {", fname, "}", NULL); /* build local file name of downloaded object */ @@ -2449,8 +2448,7 @@ void load_schematic(int load_symbols, const char *fname, int reset_undo, int ale my_strncpy(xctx->current_name, rel_sym_path(name), S(xctx->current_name)); /* local filename specified but coming (push, pop) from web object ... */ - } else if((strstr(xctx->current_dirname, "http://") == xctx->current_dirname || - strstr(xctx->current_dirname, "https://") == xctx->current_dirname)) { + } else if(is_from_web(xctx->current_dirname)) { /* ... but not local file from web download --> reset current_dirname */ char sympath[PATH_MAX]; my_snprintf(sympath, S(sympath), "%s/xschem_web", tclgetvar("XSCHEM_TMP_DIR")); @@ -3105,6 +3103,22 @@ void sort_symbol_pins(xRect *pin_array, int npins, const char *name) } } +/* return 1 if http or https url + * return 2 if cached /tmp/xschem_web/... file/directory + * return 0 otherwise + */ +int is_from_web(const char *f) +{ + static char tmp[PATH_MAX] = ""; + int res = 0; + if(!tmp[0]) my_snprintf(tmp, S(tmp), "%s/xschem_web", tclgetvar("XSCHEM_TMP_DIR")); + if(strstr(f, "http://") == f || strstr(f, "https://") == f) res = 1; + /* if(strstr(f, tmp) == f) res = 2; */ + dbg(1, "is_from_web(%s) = %d\n", f, res); + return res; +} + + /* 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' * Global (or static global) variables used: @@ -3192,8 +3206,7 @@ int load_sym_def(const char *name, FILE *embed_fd) } if((lcc[level].fd=fopen(sympath,fopen_read_mode))==NULL) { /* not found: try web URL */ - if( strstr(xctx->current_dirname, "http://") == xctx->current_dirname || - strstr(xctx->current_dirname, "https://") == xctx->current_dirname) { + if(is_from_web(xctx->current_dirname)) { my_snprintf(sympath, S(sympath), "%s/xschem_web/%s", tclgetvar("XSCHEM_TMP_DIR"), get_cell_w_ext(name, 0)); if((lcc[level].fd=fopen(sympath,fopen_read_mode))==NULL) { /* not already cached in .../xschem_web/ so download */ @@ -4104,22 +4117,31 @@ void descend_symbol(void) load_schematic(1, name_embedded, 1, 1); } else { char *sympath = NULL; + char *current_dirname_save = NULL; + int web_url; unselect_all(1); remove_symbols(); /* must follow save (if) embedded */ - if( /* ... we are in a schematic downloaded from web ... */ - (strstr(xctx->current_dirname, "http://") == xctx->current_dirname || - strstr(xctx->current_dirname, "https://") == xctx->current_dirname)) { + web_url = is_from_web(xctx->current_dirname); + + /* ... we are in a schematic downloaded from web ... */ + if(web_url) { /* symbols have already been downloaded while loading parent schematic: set local file path */ my_mstrcat(_ALLOC_ID_, &sympath, tclgetvar("XSCHEM_TMP_DIR"), "/xschem_web/", get_cell_w_ext(tcl_hook2(name), 0), NULL); + my_strdup(_ALLOC_ID_, ¤t_dirname_save, xctx->current_dirname); /* save http url */ } - if(stat(sympath, &buf)) { /* not found */ + if(!sympath || stat(sympath, &buf)) { /* not found */ dbg(1, "descend_symbol: not found: %s\n", sympath); my_strdup2(_ALLOC_ID_, &sympath, abs_sym_path(tcl_hook2(name), "")); } dbg(1, "descend_symbol(): name=%s, sympath=%s, dirname=%s\n", name, sympath, xctx->current_dirname); load_schematic(1, sympath, 1, 1); + if(web_url) { + /* restore web url current_dirname that is reset by load_schematic with local path */ + my_strncpy(xctx->current_dirname, current_dirname_save, S(xctx->current_dirname)); + my_free(_ALLOC_ID_, ¤t_dirname_save); + } my_free(_ALLOC_ID_, &sympath); } zoom_full(1, 0, 1, 0.97); diff --git a/src/xinit.c b/src/xinit.c index 410764d8..aeb73c0c 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -2440,8 +2440,7 @@ int Tcl_AppInit(Tcl_Interp *inter) char f[PATH_MAX]; #ifdef __unix__ - if(strstr(cli_opt_filename, "http://") == cli_opt_filename || - strstr(cli_opt_filename, "https://") == cli_opt_filename) { + if(is_from_web(cli_opt_filename)) { my_snprintf(f, S(f), "%s", cli_opt_filename); } else if(cli_opt_filename[0] == '~' && cli_opt_filename[1] == '/') { my_snprintf(f, S(f), "%s%s", home_dir, cli_opt_filename + 1); diff --git a/src/xschem.h b/src/xschem.h index 11c4e6a2..4083db10 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -1309,6 +1309,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 is_from_web(const char *f); extern int load_sym_def(const char name[], FILE *embed_fd); extern void descend_symbol(void); extern int place_symbol(int pos, const char *symbol_name, double x, double y, short rot, short flip,