From 8ea275013e73c2e001003b6019616d78233a70f4 Mon Sep 17 00:00:00 2001 From: Stefan Schippers Date: Tue, 13 Oct 2020 16:23:48 +0200 Subject: [PATCH] updated print_spice_subckt() to reflect updates done in print_spice_element(); abs_sym_path recognize ././././, ./., other strange paths., use $env(PWD) for current_dirname on startup instead of getcwd() if possible, to avoid dereferencing symlinks --- src/draw.c | 2 +- src/psprint.c | 2 +- src/scheduler.c | 8 +++----- src/svgdraw.c | 2 +- src/token.c | 37 +++++++++++++++++++------------------ src/xinit.c | 15 +++++++++++++-- src/xschem.h | 2 +- src/xschem.tcl | 33 +++++++++++++++++++++++++-------- 8 files changed, 64 insertions(+), 37 deletions(-) diff --git a/src/draw.c b/src/draw.c index 36215a14..f8ee33d1 100644 --- a/src/draw.c +++ b/src/draw.c @@ -69,7 +69,7 @@ void print_image() } else { if(w != xschem_w || h != xschem_h) changed_size = 1; } - my_strdup(60, &tmpstring, "tk_getSaveFile -title {Select destination file} -initialdir $env(PWD)"); + my_strdup(60, &tmpstring, "tk_getSaveFile -title {Select destination file} -initialdir [pwd]"); tcleval(tmpstring); r = tclresult(); my_free(717, &tmpstring); diff --git a/src/psprint.c b/src/psprint.c index ae0be045..116fd8aa 100644 --- a/src/psprint.c +++ b/src/psprint.c @@ -431,7 +431,7 @@ void ps_draw(void) const char *r; if(!plotfile[0]) { - my_strdup(59, &tmp, "tk_getSaveFile -title {Select destination file} -initialdir $env(PWD)"); + my_strdup(59, &tmp, "tk_getSaveFile -title {Select destination file} -initialdir [pwd]"); tcleval(tmp); my_free(878, &tmp); r = tclresult(); diff --git a/src/scheduler.c b/src/scheduler.c index 639e65fb..6706a73a 100644 --- a/src/scheduler.c +++ b/src/scheduler.c @@ -947,9 +947,7 @@ int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * arg printf("maxr[%d]=%d\n", i, xctx.maxr[i]); printf("maxl[%d]=%d\n", i, xctx.maxl[i]); } - for(i=0;i 1 && !escape && !quote) state=XSEPARATOR; + space=SPACE(c); + if( state==XBEGIN && (c=='@' || c=='$') && !escape) state=XTOKEN; + else if(state==XTOKEN && token_pos > 1 && + ( + ( (space || c == '$' || c == '@') && !escape ) || + ( (!space && c != '$' && c != '@') && escape ) + ) + ) { + state = XSEPARATOR; + } if(token_pos>=sizetok) { sizetok+=CADCHUNKALLOC; my_realloc(104, &token,sizetok); } if(state==XTOKEN) { - if(c!='\\' || escape) token[token_pos++]=c; /* 20171029 remove escaping backslashes */ + token[token_pos++]=c; } else if(state==XSEPARATOR) /* got a token */ { @@ -1445,28 +1451,23 @@ void print_spice_subckt(FILE *fd, int symbol) } } } - if(c != '@' && c!='\0' && (c!='\\' || escape) ) fputc(c,fd); - if(c == '@') s--; + if(c!='$' && c!='@' && c!='\0' ) fputc(c,fd); + if(c == '@' || c =='$') s--; state=XBEGIN; } /* 20151028 dont print escaping backslashes */ - else if(state==XBEGIN && c!='\0' && (c!='\\' || escape)) { + else if(state==XBEGIN && c!='\0') { /* do nothing */ } if(c=='\0') { break ; } - escape = (c=='\\' && !escape); - } my_free(1013, &format); my_free(1014, &token); } - - - void print_spice_element(FILE *fd, int inst) { int i=0, mult, tmp; diff --git a/src/xinit.c b/src/xinit.c index f33aa432..f13ffa7d 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -1199,8 +1199,15 @@ int Tcl_AppInit(Tcl_Interp *inter) my_strncpy(xctx.file_version, XSCHEM_FILE_VERSION, S(xctx.file_version)); compile_font(); /* restore current dir after loading font */ + if(tcleval("info exists env(PWD)")[0] == '1') { + tcleval("set current_dirname $env(PWD)"); /* $env(PWD) better than pwd_dir as it does not dereference symlinks */ + } else { + Tcl_VarEval(interp, "set current_dirname ", pwd_dir, NULL); + } + /* my_snprintf(tmp, S(tmp), "set current_dirname \"%s\"", pwd_dir); tcleval(tmp); + */ /* */ /* X INITIALIZATION */ @@ -1429,10 +1436,14 @@ int Tcl_AppInit(Tcl_Interp *inter) if(filename) { char f[PATH_MAX]; if(filename[0] !='/') { - /* can not use pwd_dir since it dereferences symlinks + /* prefer not use pwd_dir since it dereferences symlinks | \|/ */ - my_snprintf(f, S(f), "%s/%s", tclgetvar("env(PWD)"), filename); + if(tcleval("info exists env(PWD)")[0] == '1') { + my_snprintf(f, S(f), "%s/%s", tclgetvar("env(PWD)"), filename); + } else { + my_snprintf(f, S(f), "%s/%s", pwd_dir, filename); + } } else { my_snprintf(f, S(f), "%s", filename); } diff --git a/src/xschem.h b/src/xschem.h index 44a0b1d0..0c11668f 100644 --- a/src/xschem.h +++ b/src/xschem.h @@ -899,7 +899,7 @@ extern void rebuild_selected_array(void); extern void edit_property(int x); extern int xschem(ClientData clientdata, Tcl_Interp *interp, int argc, const char * argv[]); -extern void tcleval(const char str[]); +extern const char *tcleval(const char str[]); extern const char *tclresult(void); extern const char *tclgetvar(const char *s); extern void tclsetvar(const char *s, const char *value); diff --git a/src/xschem.tcl b/src/xschem.tcl index 57e37919..694803d1 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -1527,7 +1527,7 @@ proc select_netlist_dir { force {dir {} }} { if {$::OS == "Windows"} { set initdir $env(windir) } else { - set initdir $env(PWD) + set initdir [pwd] } } # 20140409 do not change netlist_dir if user Cancels action @@ -2586,7 +2586,7 @@ proc viewdata {data {ro {}}} { if {$::OS == "Windows"} { set fff [tk_getSaveFile -initialdir $env(windir) ] } else { - set fff [tk_getSaveFile -initialdir $env(PWD) ] + set fff [tk_getSaveFile -initialdir [pwd] ] } if { $fff != "" } { set fileid [open $fff "w"] @@ -2637,17 +2637,26 @@ proc rel_sym_path {symbol} { proc abs_sym_path {fname {ext {} } } { global pathlist current_dirname + # empty: do nothing if {$fname eq {} } return {} + if {$::OS == "Windows"} { + # absolute path: return as is if { [regexp {^[A-Za-z]\:/$} $fname ] } { return $fname; } } else { + # absolute path: return as is if { $fname eq "/"} { return $fname; } - # if fname is just "." return $current_dirname - if {$fname eq "."} { + + # remove any leading './' + while { [regsub {^\./} $fname {} fname] } {} + if { $fname eq {} } { set fname . } + + # if fname is just "." or "./" return $current_dirname + if {[regexp {^\./*$} $fname] } { return $current_dirname } } @@ -2655,20 +2664,26 @@ proc abs_sym_path {fname {ext {} } } { if { $ext ne {} } { set fname [file rootname $fname]$ext } - # transform ./file_or_path to file_or_path, resolve ../file_or_path + # prepend current_dirname to ../file_or_path --> $current_dirname/file_or_path if { [regexp {^\.\./} $fname ] } { if { [regexp {^/} $current_dirname] } { - set fname "[file dirname $current_dirname][regsub {^\.\.} $fname {}]" + set fname "${current_dirname}[regsub {^\.\.} $fname {}]" } + # transform ./file_or_path to file_or_path } elseif {[regexp {^\./} $fname ] } { regsub {^\./} $fname {} fname } + set name {} + if { ![regexp {^/} $fname] && ![regexp {^[A-Za-z]:} $fname] } { + # if fname is present in one of the pathlist paths get the absolute path foreach path_elem $pathlist { + # in xschem a . in pathlist means the directory of currently loaded schematic/symbol if { ![string compare $path_elem .] && [info exist current_dirname]} { set path_elem $current_dirname } + set fullpath "$path_elem/$fname" if { [file exists $fullpath] } { set name $fullpath @@ -2677,8 +2692,10 @@ proc abs_sym_path {fname {ext {} } } { } } if { ![string compare $name {}] } { + # if absolute path do nothing if { [regexp {^/} $fname] || [regexp {^[a-zA-Z]:} $fname] || [regexp ^$current_dirname $fname]} { set name $fname + # if fname is a relative path just prepend current_dirname } else { set name "$current_dirname/$fname" } @@ -3265,8 +3282,8 @@ if {$::OS == "Windows"} { set filetmp1 $env(windir)/.tmp1 set filetmp2 $env(windir)/.tmp2 } else { - set filetmp1 $env(PWD)/.tmp1 - set filetmp2 $env(PWD)/.tmp2 + set filetmp1 [pwd]/.tmp1 + set filetmp2 [pwd]/.tmp2 } # /20111106