Closed effelsberg closed 9 years ago
From the Tcl docs: this is not a bug, it's how Windows works.
Under Windows, the environment variables PATH and COMSPEC in any capitalization are converted automatically to upper case. For instance, the PATH variable could be exported by the operating system as “path”, “Path”, “PaTh”, etc., causing otherwise simple Tcl code to have to support many special cases. All other environment variables inherited by Tcl are left unmodified. Setting an env array variable to blank is the same as unsetting it as this is the behavior of the underlying Windows OS. It should be noted that relying on an existing and empty environment variable will not work on Windows and is discouraged for cross-platform usage.
Thinking about it again, there is still some slight annoyance:
% set env(PATH) ""
% info exists env(PATH)
1
% set env(PATH)
can't read "env(PATH)": no such variable
<< Gosh, Schrödinger's cat of a variable is dead and alive at the same time! >>
% unset env(PATH)
<< No error message, it must have existed then. But let's make a final check ... >>
% info exists env(PATH)
0
% unset env(PATH)
can't unset "env(PATH)": no such element in array
<< It's dead, Jim. >>
Here's what I just did in [os pathfind]:
set thePath ""
catch {set thePath $env(PATH)}
if {$thePath eq ""} { ... }
Does this fix findpath-1.1?
Also, how is findpath-1.3 failing? It doesn't involve an empty PATH.
Confirmation
pathfind-1.1 passes with your changes.
Now more on pathind-1.3
There is a strange thing: I ran the tests on a different machine (with Windows Vista) and pathfind-1.3 passed. Of course, I didn't investigate why everything was OK. But thinking about it revealed its nature.
About the reason of the failure:
On Windows [file dirname [info nameofexecutable]] returns:
C:/Tcl/bin
See? If you split this path by colons, you'll get:
{"C" "/Tcl/bin"}
Why does this work on the Vista machine but not on the Windows 7 machine? On the Vista machine I've got everything on drive C:, so globbing for "/Tcl/bin" uses drive C: as the root. On the Windows 7 machine there's Tcl installed on C: but all live action happens on D:, so "/Tcl/bin" gets translated by glob to "D:/Tcl/bin" and this doesn't exist.
OK, I see. Now as it happens, pathfind-1.3 is specifically for the case where splitting the path with ":" is OK; I can reasonably constrain it so that it doesn't run on Windows.
Now, I use Tcl/Tk a lot on (at my day job) on Windows with MinGW's bash shell, in which case separating on ":" is the right thing to do; so on Windows [os pathfind] tries ";" first, and then ":". Perhaps I should change it: only fall back to ":" if there are no ";". Thoughts?
Using a MinGW shell doesn't mean that you also have Unix-like paths in your programs. The shell tries to translate between Unix paths and Windows paths, at least that's the way it works for me. The result for me is a combination that features a drive prefix and slashes.
E.g. this simple argument dumper:
#include <stdio.h>
int main(int argc, char **argv) {
int i;
for (i = 0; i < argc; i++) {
printf("Arg %d: %s\n", i, argv[i]);
}
return 0;
}
See how the path gets half-transformed:
$ arg_dump /c/Tcl/bin
Arg 0: d:\arg_dump.exe
Arg 1: c:/Tcl/bin
And if I start ActiveTcl's tclsh from bash, I get genuine Windows paths in env(PATH) including backslashes.
Do you have Unix paths in your env(PATH)? What do [file volumes] and [file separator] give you?
My bad. On Windows under MinGW, the PATH is colon-delimited; and I (working on a Mac) made the unwarranted assumption that tclsh received that environment variable unchanged. Of course, it doesn't; everything is translated back to Windows standard before tclsh sees it. I'll fix [os pathfind] this evening or tomorrow.
Fixed. I now just use the official tcl_platform(pathSeparator) (D'oh!). Also, the FindWith command in that module had a completely gratuitous 'glob'; now cleaned up.
Some analysis for pathfind-1.1 follows, and it is not your fault but rather something in the Tcl interpreter itself. However, would be nice if the tests (or the quill lib itself) are aware of it.
With Tcl 8.6.1 from ActiveState and also a tclkit858/tclkit860 (from Pat Thoyts?):
A regular array works fine: