[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#7159: 24.0.50; (1) `file-name-(non)directory': bad return values, (2
bug#7159: 24.0.50; (1) `file-name-(non)directory': bad return values, (2) `directory-sep-char'
Mon, 4 Oct 2010 10:59:12 -0700
(setq toto (wildcard-to-regexp "c:/foo/bar/b*.el"))
gives "\\`c:/foo/bar/address@hidden'" (where ^@ is a control char)
(setq titi (substring 2 toto))
gives "c:/foo/bar/address@hidden'" (^@ is a control char)
(file-name-absolute-p toto) ; -> t
(file-name-absolute-p titi) ; -> t
That is all as one would expect. `file-name-absolute-p' has no
problem with either file-name string, even though neither string
is a legitimate file name and both contain a control char.
This is normal (IMO).
(file-name-directory titi) ; gives "c:/foo/bar/address@hidden"
(file-name-nondirectory titi) ; gives "'"
These functions should know how to parse titi to produce "c:/foo/bar/"
and "address@hidden'", respectively (where ^@ is the control char).
It is not expected that these functions return names that necessarily
map to actual directories or files. What is expected is that they
remove the non-directory and directory components of the strings they
are passed. That is not happening here.
(setq baz "c:/foo/bar/*\\.el\\'")
(file-name-nondirectory baz) ; gives "'"
(setq baz "c:/foo/bar/*\\.el\\ABC")
(file-name-nondirectory baz) ; gives "ABC"
So I suspect that the `file-name-nondirectory' part of this bug
is at least in part a Windows problem. The code seems to be
interpreting the backslash (?\) near the end as a directory
separator. If so, that is definitely wrong. Even on Windows, the
code should use the value of `directory-sep-char', which is ?/,
However, I see from the doc string that `directory-sep-char' has
been made obsolete:
directory-sep-char is a variable defined in `subr.el'.
Its value is 47
This variable is obsolete since 21.1;
do not use it, just use `/'.
This variable is potentially risky when used as a file local variable.
Directory separator character for built-in functions that return file names.
The value is always ?/.
That seems misguided, and the buggy behavior noted above is a good
example of why. The correct way to handle this would be to make
`directory-sep-char' a defconst with value ?/. And code should always
use this named constant, NOT a literal ?/. The bugged behavior here
shows why: someone coding `file-name-nondirectory' seems to have
treated (hard-coded) ?\ as the directory separator on Windows (just a
Note too that the code has another minor bug: The call to
`make-obsolete-variable' (which should anyway be removed, and the
defvar simply replaced by a defconst) incorrectly uses "`/'" instead
of "?/". The doc string itself is correct in referring to "?/".
(defconst directory-sep-char ?/
"Directory separator character for built-in functions that return file names.
The value is always ?/.")
(make-obsolete-variable 'directory-sep-char "do not use it, just use `/'."
In GNU Emacs 188.8.131.52 (i386-mingw-nt5.1.2600) of 2010-09-20 on 3249CTO
Windowing system distributor `Microsoft Corp.', version 5.1.2600
configured using `configure --with-gcc (4.4) --no-opt --cflags
- bug#7159: 24.0.50; (1) `file-name-(non)directory': bad return values, (2) `directory-sep-char',
Drew Adams <=