From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Drew Adams" Newsgroups: gmane.emacs.bugs Subject: bug#7617: 24.0.50; `expand-file-name': removal of slashes Date: Sun, 12 Dec 2010 10:03:08 -0800 Message-ID: <022D0B344DB64B2A9E1B771B0695237E@us.oracle.com> References: <7F477A16FFA145E5AB532A96F55D5CDC@us.oracle.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1292178358 5995 80.91.229.12 (12 Dec 2010 18:25:58 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sun, 12 Dec 2010 18:25:58 +0000 (UTC) Cc: 7617@debbugs.gnu.org To: "'Eli Zaretskii'" Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sun Dec 12 19:25:51 2010 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1PRqcG-0002OM-UA for geb-bug-gnu-emacs@m.gmane.org; Sun, 12 Dec 2010 19:25:50 +0100 Original-Received: from localhost ([127.0.0.1]:46160 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PRqcF-00022M-9n for geb-bug-gnu-emacs@m.gmane.org; Sun, 12 Dec 2010 13:25:47 -0500 Original-Received: from [140.186.70.92] (port=40723 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PRqc6-0001ys-Jr for bug-gnu-emacs@gnu.org; Sun, 12 Dec 2010 13:25:40 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PRqc4-0006oE-UX for bug-gnu-emacs@gnu.org; Sun, 12 Dec 2010 13:25:38 -0500 Original-Received: from debbugs.gnu.org ([140.186.70.43]:43688) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PRqc4-0006o8-Sn for bug-gnu-emacs@gnu.org; Sun, 12 Dec 2010 13:25:36 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.69) (envelope-from ) id 1PRqBO-0006r5-1U; Sun, 12 Dec 2010 12:58:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: "Drew Adams" Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-To: owner@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sun, 12 Dec 2010 17:58:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 7617 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 7617-submit@debbugs.gnu.org id=B7617.129217663926299 (code B ref 7617); Sun, 12 Dec 2010 17:58:01 +0000 Original-Received: (at 7617) by debbugs.gnu.org; 12 Dec 2010 17:57:19 +0000 Original-Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1PRqAg-0006q7-Ho for submit@debbugs.gnu.org; Sun, 12 Dec 2010 12:57:19 -0500 Original-Received: from rcsinet10.oracle.com ([148.87.113.121]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1PRqAe-0006pu-Ln for 7617@debbugs.gnu.org; Sun, 12 Dec 2010 12:57:17 -0500 Original-Received: from rcsinet15.oracle.com (rcsinet15.oracle.com [148.87.113.117]) by rcsinet10.oracle.com (Switch-3.4.2/Switch-3.4.2) with ESMTP id oBCI3NLh006672 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sun, 12 Dec 2010 18:03:24 GMT Original-Received: from acsmt355.oracle.com (acsmt355.oracle.com [141.146.40.155]) by rcsinet15.oracle.com (Switch-3.4.2/Switch-3.4.1) with ESMTP id oBCI3GxI027164; Sun, 12 Dec 2010 18:03:23 GMT Original-Received: from abhmt013.oracle.com by acsmt354.oracle.com with ESMTP id 867118981292176986; Sun, 12 Dec 2010 10:03:06 -0800 Original-Received: from dradamslap1 (/10.159.218.180) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sun, 12 Dec 2010 10:03:06 -0800 X-Mailer: Microsoft Office Outlook 11 In-Reply-To: X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.5994 Thread-Index: AcuaFW1dEl4vIDG3Qgaz7+IAIdwRfQACNBoQ X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Resent-Date: Sun, 12 Dec 2010 12:58:02 -0500 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:42443 Archived-At: > Please explain why you consider this a bug. foo//bar is at best > equivalent to foo/bar, In what way is that _ever_ equivalent? Please show the equivalence for any of the OS's that Emacs supports. In interactive use, `...//abc...' is treated as just `/abc...' by Emacs. The prefix `.../' is ignored until you hit `RET'. And then the prefix is dropped when you enter the file name (`RET') - but only then. And that's appropriate. Other than when you actually hit `RET', the prefix should not be removed but simply ignored. Ignoring the prefix is a user convenience. Dropping it when you hit `RET' guarantees that the caller (e.g. a file-system utility) never sees it. So much for treating the `...//abc...' as `/abc...'. As to collapsing multiple consecutive slashes, which is something completely different - what is the rationale for that? You claim that `foo//bar' is equivalent to `foo/bar'. Where do you get that? Unix? GNU/Linux? Windows? VMS? I don't think so. If they were equivalent, the Emacs would transform `...//abc...' to just `.../abc...' when you hit `RET', not transform it to `/abc...'. Try changing that behavior and see how many Emacs users give you their opinion about how equivalent `//' and `/' are. ;-) > and at worst simply fails various system calls > and naive Lisp code that doesn't expect more than one slash in a row. Red herring. When such a name is actually _entered_ (`RET') the prefix `.../' is removed. So there is no way that system calls see such a name. And arguing on the basis of some supposed "naive Lisp code" is pretty weak. Which Lisp code currently depends on this collapsing? And you know, if you introduce _any_ change in behavior, no matter how bad, some Lisp code will eventually adapt to it and thus expect it. That is no argument at all. > > But I see that comments in > > the current C code indicate that it is intentional (but not _why_). > > I didn't find any related discussions that would explain the immediate > reasons for the above change. So I don't know (and certainly don't > remember ;-) why it was made. But I do think it's the right behavior > for expand-file-name, because other primitives and Lisp code normally > expects a canonicalized file name, so it would make sense to have a > single primitive that produces such canonicalized file names. Then please create a separate primitive the does just that. Currently, there is no way to maintain the integrity of the user's input if that input is passed through `expand-file-name' to do what the doc says `expand*' does. Currently, using `expand*' on input can easily change perfectly valid input (valid for Emacs, since it ignores and ultimately removes the prefix `.../') into input that is invalid (represents no file at all). IOW, please separate this slash-collapsing from what `expand-file-name' is actually _documented_ to do - there is nothing about slash collapsing in `expand*'s contract with its users. Make a separate function `collapse-slashes' which does (only) that, if you like. Then the cleaned-up `expand-file-name' can be used alone on user input without changing valid references to actual files into non-matches. Or if you prefer, leave `expand*' the way it is (but document the slash-collapsing), and create another primitive that does only what `expand*' is documented as doing: everything except the slash-collapsing. That new primitive would ignore a `...//' prefix up to the second slash - the same way Emacs ignores it during input. That primitive would simply expand the file name wrt the dir argument, removing `.' etc. as documented now - in sum, exactly what we _say_ `expand*' does, and no more. I don't really care which is done: clean up `expand*' or provide a new function that does what we _say_ `expand*' does (and what it actually did prior to Emacs 21). Either way I will have a function I can call to get the currently _documented_ `expand*' behavior (and only that). I will be able to apply it to user input and know that I haven't suddenly moved the target of the input from one file to another (probably nonexistent) one. > > But shouldn't `expand-file-name' do the right thing if the > > second arg is in fact `file-directory-p'? > > > > For a user on GNU/Linux with $HOME = /home/toto": > > (file-directory-p "~/today//usr") -> nil, but > > (file-directory-p "~//usr/") --> t, and we have the same problem: > > (expand-file-name "foo" "~//usr/") -> "/home/toto/usr/foo" > > > > Surely the behavior here is buggy, no? > > Sorry, I don't see a bug here. Please explain more. > > > The result should be "/home/toto//usr/foo", I would think. > > Not clear why. As I said, "/home/toto//usr/foo" is at best equivalent > to "/home/toto/usr/foo", It is not equivalent - neither at best nor at worst - not at all. In Emacs, file-name input `/home/toto//usr/foo' is interpreted as `/usr/foo' when you enter it. That _is_ an equivalence (for Emacs file-name input). The former is not valid for the file system, of course, but in Emacs the two names are _equivalent as input_. Assuming the file `/usr/foo' exists, `/home/toto//usr/foo' targets it validly (in Emacs). But `/home/toto/usr/foo' is not valid: Most likely no such file exists, and if it did exist it would anyway not be the same file as `/usr/foo'. That's the point. Valid file-name input (for Emacs) is in this case changed by `expand-file-name' into invalid input (invalid in the sense of not representing the same file). Not good; a bug. > and at worst will simply fail in another > place. So what does the former give you that the latter doesn't? See above. It maintains the integrity of the user's input: `/home/toto//usr/foo' is, as Emacs file-name input, equivalent to `/usr/foo'. `/home/toto/usr/foo' is _not_ equivalent. > > _Why should_ `expand-file-name' collapse multiple consecutive > > slashes into a single slash? > > In order to produce a _canonicalized_ file name. "Canonicalization" should not change which file is targeted. Just because you call the behavior "canonicalization" does not mean that the transformation is a good one. That's a word game. If the user's input targets file `/usr/foo', true canonicalization should not change the target to `/home/toto/usr/foo', which is something completely different. > > Finally, I need the Emacs 20 behavior for this for some of my code. > > Can you describe the use-case where the old behavior is needed? No, and it is irrelevant. I need the behavior of `expand-file-name' minus the slash-collapsing part. It does not matter why I need such a function. If `expand-file-name' were defined in Lisp I would just gather the part of it that I need into a new function. But I cannot do that because it is in C. But why is it in C, BTW? Is that really necessary? If you argue that some parts of it deal with platform issues and so are better handled in C, then I ask why not leave only those parts in C and move the actual logic of the function - what it is documented as _doing_, to Lisp? Expansion of the file name, removal of `.' etc. could be done in Lisp with if necessary sub-calls to C primitives to perform any platform-dependent stuff that cannot be done in Lisp. When Emacs code is in C it is much more difficult for users to (re)use it. > > Oh, and another thing. This behavior of `expand-file-name' > > is not documented. > > Well, one could argue that "canonicalized" does mean removing > consecutive slashes, No, one cannot argue that honestly. You could define any transformation you like, call it "canonicalization", and then claim that all of its behavior is documented as soon as you have simply said that it "canonicalizes". That's completely disingenuous. > but I guess it's easy enough to say that explicitly in the doc string. Please add this missing information to the doc string, if you refuse to see the misbehavior bug. And I hope I can get some information about how, in Lisp, to get the `expand*' behavior minus the target-changing slash-collapsing.