Subject: filename coding systems and w32-*-file-name functions

From: "Juanma Barranquero" <[email-masked]>
Date: Wed, 26 Nov 2008 15:38:00 +0100

Package: emacs,w32
X-Debbugs-CC: [email-masked]

---------- Forwarded message ----------
From: Juanma Barranquero <[email-masked]>
Date: Tue, Nov 25, 2008 at 02:38
Subject: filename coding systems and w32-*-file-name functions
To: Emacs Devel <[email-masked]>

Is this to be expected (I don't think so) or should I file a bug report?

ELISP> temporary-file-directory
"c:/DOCUME~1/Juanma/CONFIG~1/Temp/"

ELISP> (w32-long-file-name temporary-file-directory)
"c:/Documents and Settings/Juanma/Configuraci\363n local/Temp/"

ELISP> (decode-coding-string (w32-long-file-name
temporary-file-directory) file-name-coding-system)
#("c:/Documents and Settings/Juanma/Configuración local/Temp/" 0 58
 (charset windows-1252))                 ;;; this one is the correct name

ELISP> (let ((dir (read-directory-name "Dir: ")))    ;;; c:/acción
        (list dir
              (w32-short-file-name dir)
              (w32-long-file-name dir)))
("c:/acción/" nil nil)

ELISP> (let ((dir (read-directory-name "Dir: ")))    ;;; c:/accion
        (list dir
              (w32-short-file-name dir)
              (w32-long-file-name dir)))
("c:/accion/" "c:/accion/" "c:/accion/")

So it seems like w32-(long|short)-file-name have issues with coding
systems and should use (default-)file-name-coding-system.

            Juanma

---------------------------------------

This happens in 22.X too (I haven't checked older Emacsen).

The following patch fixes it, though I'm puzzled by a few things:

 - In w32-long-file-name, I'm building a string, decoding it, and then
   building another string out of the first one's SDATA, because with
   the simpler

     return DECODE_FILE (build_string (longname));

   the function returns

      #("c:/acción/" 0 10
        (charset windows-1252))

   which is a bit weird (though it's the same output from

     (decode-coding-string (encode-coding-string "c:/acción" 'cp1252) 'cp1252)

   so it is perhaps right.

 - I've read comments stating that ENCODE_FILE and DECODE_FILE can trigger a
   GC, but I've checked every use of them in the sources and got the feeling
   that sometimes Lisp_Object's are protected and sometimes not; so I'm
   thoroughly confused. In any case, I think there's no need of GCPRO
   anything in these two functions.

Comments?

   Juanma

Index: src/w32proc.c
===================================================================
RCS file: /sources/emacs/emacs/src/w32proc.c,v
retrieving revision 1.84
diff -u -2 -b -r1.84 w32proc.c
--- src/w32proc.c	22 Jul 2008 15:28:21 -0000	1.84
+++ src/w32proc.c	26 Nov 2008 12:51:37 -0000
@@ -64,4 +64,5 @@
 #include "w32term.h"
 #include "dispextern.h"		/* for xstrcasecmp */
+#include "coding.h"

 #define RVA_TO_PTR(var,section,filedata) \
@@ -1782,5 +1783,5 @@

   /* luckily, this returns the short version of each element in the path.  */
-  if (GetShortPathName (SDATA (filename), shortname, MAX_PATH) == 0)
+  if (GetShortPathName (SDATA (ENCODE_FILE (filename)), shortname,
MAX_PATH) == 0)
     return Qnil;

@@ -1811,5 +1812,5 @@
   filename = Fexpand_file_name (filename, Qnil);

-  if (!w32_get_long_filename (SDATA (filename), longname, MAX_PATH))
+  if (!w32_get_long_filename (SDATA (ENCODE_FILE (filename)),
longname, MAX_PATH))
     return Qnil;

@@ -1822,5 +1823,7 @@
     longname[2] = '\0';

-  return build_string (longname);
+  filename = DECODE_FILE (build_string (longname));
+
+  return build_string (SDATA (filename));
 }