diff --git a/src/actions.c b/src/actions.c index d2016e2d..92c2effd 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1183,20 +1183,25 @@ void get_sch_from_sym(char *filename, xSymbol *sym) const char *str_tmp; int web_url = 0; + + /* 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) { web_url = 1; } if((str_tmp = get_tok_value(sym->prop_ptr, "schematic",0 ))[0]) { my_strdup2(1252, &sch, str_tmp); + /* for schematics referenced from web symbols do not build absolute path */ if(web_url) my_strncpy(filename, sch, PATH_MAX); else my_strncpy(filename, abs_sym_path(sch, ""), PATH_MAX); my_free(1253, &sch); } else { if(tclgetboolvar("search_schematic")) { + /* for schematics referenced from web symbols do not build absolute path */ if(web_url) my_strncpy(filename, add_ext(sym->name, ".sch"), PATH_MAX); else my_strncpy(filename, abs_sym_path(sym->name, ".sch"), PATH_MAX); } else { + /* for schematics referenced from web symbols do not build absolute path */ if(web_url) my_strncpy(filename, add_ext(sym->name, ".sch"), PATH_MAX); else my_strncpy(filename, add_ext(abs_sym_path(sym->name, ""), ".sch"), PATH_MAX); } @@ -1322,10 +1327,13 @@ int descend_schematic(int instnumber) dbg(1, "descend_schematic(): filename=%s\n", filename); unselect_all(1); remove_symbols(); + /* we are descending from a parent schematic downloaded from the web */ if( strstr(xctx->current_dirname, "http://") == xctx->current_dirname || strstr(xctx->current_dirname, "https://") == xctx->current_dirname) { char sympath[PATH_MAX]; + /* download item into ${XSCHEM_TMP_DIR}/xschem_web */ tclvareval("try_download_url {", xctx->current_dirname, "} {", filename, "}", NULL); + /* build local file name of downloaded object and load it */ my_snprintf(sympath, S(sympath), "%s/xschem_web/%s", tclgetvar("XSCHEM_TMP_DIR"), get_cell_w_ext(filename, 0)); load_schematic(1, sympath, 1); } else { diff --git a/src/save.c b/src/save.c index db7ac9b4..9275bc62 100644 --- a/src/save.c +++ b/src/save.c @@ -2161,26 +2161,40 @@ void load_schematic(int load_symbols, const char *fname, int reset_undo) /* 2015 if(fname && fname[0]) { my_strncpy(filename, fname, S(filename)); my_strncpy(name, filename, S(name)); + /* remote web object specified */ if(strstr(filename , "http://") == filename || strstr(filename , "https://") == filename) { + /* download into ${XSCHEM_TMP_DIR}/xschem_web */ tclvareval("download_url {", filename, "}", NULL); + /* build local file name of downloaded object */ my_snprintf(name, S(name), "%s/xschem_web/%s", tclgetvar("XSCHEM_TMP_DIR"), get_cell_w_ext(filename, 0)); + /* build current_dirname by stripping off last filename from url */ my_snprintf(msg, S(msg), "regsub {/\\.$} [get_directory {%s}] {}", filename); my_strncpy(xctx->current_dirname, tcleval(msg), S(xctx->current_dirname)); + /* local file name */ my_strncpy(xctx->sch[xctx->currsch], name, S(xctx->sch[xctx->currsch])); + /* local relative reference */ my_strncpy(xctx->current_name, rel_sym_path(name), S(xctx->current_name)); - } else if(/* xctx->currsch > 0 && */ (strstr(xctx->current_dirname, "http://") == xctx->current_dirname || + + /* 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)) { + /* ... but not local file from web download --> reset current_dirname */ if(strstr(filename, "/tmp/xschem_web") != filename) { my_snprintf(msg, S(msg), "regsub {/\\.$} [get_directory {%s}] {}", filename); my_strncpy(xctx->current_dirname, tcleval(msg), S(xctx->current_dirname)); } + /* local file name */ my_strncpy(xctx->sch[xctx->currsch], filename, S(xctx->sch[xctx->currsch])); + /* local relative reference */ my_strncpy(xctx->current_name, rel_sym_path(filename), S(xctx->current_name)); + /* local file specified and not coming from web url */ } else { my_snprintf(msg, S(msg), "regsub {/\\.$} [get_directory {%s}] {}", filename); my_strncpy(xctx->current_dirname, tcleval(msg), S(xctx->current_dirname)); + /* local file name */ my_strncpy(xctx->sch[xctx->currsch], filename, S(xctx->sch[xctx->currsch])); + /* local relative reference */ my_strncpy(xctx->current_name, rel_sym_path(filename), S(xctx->current_name)); } /* if name is /some/path/. remove /. at end */ @@ -3677,10 +3691,12 @@ void descend_symbol(void) remove_symbols(); /* must follow save (if) embedded */ dbg(1, "name=%s, sympath=%s\n", name, sympath); - if( stat(sympath, &buf) && /* file does not exists */ + if( stat(sympath, &buf) && /* file does not exists ... */ + /* ... and we are in a schematic downloaded from web ... */ (strstr(xctx->current_dirname, "http://") == xctx->current_dirname || strstr(xctx->current_dirname, "https://") == xctx->current_dirname)) { - my_snprintf(sympath, S(sympath), "%s/%s", tclgetvar("XSCHEM_TMP_DIR"), get_cell_w_ext(name, 0)); + /* symbols have already been downloaded while loading parent schematic: set local file path */ + my_snprintf(sympath, S(sympath), "%s/xschem_web/%s", tclgetvar("XSCHEM_TMP_DIR"), get_cell_w_ext(name, 0)); load_schematic(1, sympath, 1); } else { load_schematic(1, sympath, 1); diff --git a/src/xschem.tcl b/src/xschem.tcl index 7eb116cf..a46976a9 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -4433,6 +4433,7 @@ proc get_directory {f} { return $r } +# fetch a remote url into ${XSCHEM_TMP_DIR}/xschem_web proc download_url {url} { global XSCHEM_TMP_DIR download_url_helper if {![file exists ${XSCHEM_TMP_DIR}/xschem_web]} { @@ -4443,19 +4444,24 @@ proc download_url {url} { return $r } +# use some heuristic to find a sub sch/sym reference in the web repository. proc try_download_url {dirname sch_or_sym} { set url $dirname/$sch_or_sym # puts "try_download_url: dirname=$dirname, sch_or_sym=$sch_or_sym" set r [download_url $url] if { $r!=0} { + # count # of directories in sch/sym reference set nitems [regexp -all {/+} $sch_or_sym] # puts "try_download_url: dirname=$dirname, sch_or_sym=$sch_or_sym, nitems=$nitems" while { $nitems > 0} { + # remove one path component from dirname and try to download URL set dirname [get_directory $dirname] incr nitems -1 + set url $dirname/$sch_or_sym + set r [download_url $url] + # done if url found + if { $r == 0 } { break } } - set url $dirname/$sch_or_sym - set r [download_url $url] } }