>>>>> On Wed, 09 May 2007 17:36:37 +0900, YAMAMOTO Mitsuharu <[EMAIL >>>>> PROTECTED]> said:
> Though the non-ASCII unibyte `default-directory' case seems to be > sufficient for the originally reported problem, we should also handle > the following cases in order to make Fexpand_file_name consistent and > exhaustive with respect to non-ASCII unibyte file names: > 1. Case that "~" or "~user" is expanded to a non-ASCII file name: > This case is similar to the non-ASCII unibyte `default-directory' > case. > 2. Case that the argument `name' is in non-ASCII unibyte and > `default-directory' is in multibyte: > This case may return a wrong result either with or without my > previous patch. I tried handling these cases (with DECODE_FILE instead of string_to_multibyte). What's pointed to by `newdir' previously is now stored in a Lisp string `new_directory' until adjustments of multibyteness has been completed. YAMAMOTO Mitsuharu [EMAIL PROTECTED] Index: src/fileio.c =================================================================== RCS file: /cvsroot/emacs/emacs/src/fileio.c,v retrieving revision 1.580 diff -c -p -r1.580 fileio.c *** src/fileio.c 22 Mar 2007 12:15:04 -0000 1.580 --- src/fileio.c 10 May 2007 09:09:53 -0000 *************** See also the function `substitute-in-fil *** 1060,1067 **** int collapse_newdir = 1; int is_escaped = 0; #endif /* DOS_NT */ ! int length; ! Lisp_Object handler, result; int multibyte; CHECK_STRING (name); --- 1060,1066 ---- int collapse_newdir = 1; int is_escaped = 0; #endif /* DOS_NT */ ! Lisp_Object handler, new_directory, result; int multibyte; CHECK_STRING (name); *************** See also the function `substitute-in-fil *** 1345,1351 **** default_directory if nm is not absolute, and finally collapse /./ and /foo/../ sequences. ! We set newdir to be the appropriate prefix if one is needed: - the relevant user directory if nm starts with ~ or ~user - the specified drive's working dir (DOS/NT only) if nm does not start with / --- 1344,1350 ---- default_directory if nm is not absolute, and finally collapse /./ and /foo/../ sequences. ! We set new_directory to be the appropriate prefix if one is needed: - the relevant user directory if nm starts with ~ or ~user - the specified drive's working dir (DOS/NT only) if nm does not start with / *************** See also the function `substitute-in-fil *** 1356,1362 **** return an absolute name, if the final prefix is not absolute we append it to the current working directory. */ ! newdir = 0; if (nm[0] == '~') /* prefix ~ */ { --- 1355,1361 ---- return an absolute name, if the final prefix is not absolute we append it to the current working directory. */ ! new_directory = Qnil; if (nm[0] == '~') /* prefix ~ */ { *************** See also the function `substitute-in-fil *** 1366,1373 **** #endif /* VMS */ || nm[1] == 0) /* ~ by itself */ { ! if (!(newdir = (unsigned char *) egetenv ("HOME"))) ! newdir = (unsigned char *) ""; nm++; #ifdef DOS_NT collapse_newdir = 0; --- 1365,1376 ---- #endif /* VMS */ || nm[1] == 0) /* ~ by itself */ { ! unsigned char *homedir = (unsigned char *) egetenv ("HOME"); ! ! if (homedir) ! new_directory = make_unibyte_string (homedir, strlen (homedir)); ! else ! new_directory = empty_string; nm++; #ifdef DOS_NT collapse_newdir = 0; *************** See also the function `substitute-in-fil *** 1392,1398 **** UNBLOCK_INPUT; if (pw) { ! newdir = (unsigned char *) pw -> pw_dir; #ifdef VMS nm = p + 1; /* skip the terminator */ #else --- 1395,1403 ---- UNBLOCK_INPUT; if (pw) { ! unsigned char *homedir = (unsigned char *) pw -> pw_dir; ! ! new_directory = make_unibyte_string (homedir, strlen (homedir)); #ifdef VMS nm = p + 1; /* skip the terminator */ #else *************** See also the function `substitute-in-fil *** 1411,1433 **** #ifdef DOS_NT /* On DOS and Windows, nm is absolute if a drive name was specified; use the drive's current directory as the prefix if needed. */ ! if (!newdir && drive) { /* Get default directory if needed to make nm absolute. */ if (!IS_DIRECTORY_SEP (nm[0])) { ! newdir = alloca (MAXPATHLEN + 1); ! if (!getdefdir (toupper (drive) - 'A' + 1, newdir)) ! newdir = NULL; } ! if (!newdir) { /* Either nm starts with /, or drive isn't mounted. */ ! newdir = alloca (4); ! newdir[0] = DRIVE_LETTER (drive); ! newdir[1] = ':'; ! newdir[2] = '/'; ! newdir[3] = 0; } } #endif /* DOS_NT */ --- 1416,1438 ---- #ifdef DOS_NT /* On DOS and Windows, nm is absolute if a drive name was specified; use the drive's current directory as the prefix if needed. */ ! if (NILP (new_directory) && drive) { /* Get default directory if needed to make nm absolute. */ if (!IS_DIRECTORY_SEP (nm[0])) { ! unsigned char defdir[MAXPATHLEN + 1]; ! ! if (getdefdir (toupper (drive) - 'A' + 1, defdir)) ! new_directory = make_unibyte_string (defdir, strlen (defdir)); } ! if (NILP (new_directory)) { /* Either nm starts with /, or drive isn't mounted. */ ! new_directory = make_uninit_string (3); ! SSET (new_directory, 0, DRIVE_LETTER (drive)); ! SSET (new_directory, 1, ':'); ! SSET (new_directory, 2, '/'); } } #endif /* DOS_NT */ *************** See also the function `substitute-in-fil *** 1446,1465 **** #ifdef VMS && !index (nm, ':') #endif ! && !newdir) { ! newdir = SDATA (default_directory); ! multibyte |= STRING_MULTIBYTE (default_directory); #ifdef DOS_NT /* Note if special escape prefix is present, but remove for now. */ ! if (newdir[0] == '/' && newdir[1] == ':') { is_escaped = 1; ! newdir += 2; } #endif } #ifdef DOS_NT if (newdir) { --- 1451,1506 ---- #ifdef VMS && !index (nm, ':') #endif ! && NILP (new_directory)) { ! new_directory = default_directory; #ifdef DOS_NT /* Note if special escape prefix is present, but remove for now. */ ! if (SREF (new_directory, 0) == '/' && SREF (new_directory, 1) == ':') { is_escaped = 1; ! new_directory = ! make_specified_string (SDATA (new_directory) + 2, -1, ! SBYTES (new_directory) - 2, ! STRING_MULTIBYTE (new_directory)); } #endif } + if (NILP (new_directory)) + newdir = 0; + else + { + /* If the multibyteness of `nm' (which is stored in `multibyte') + and that of 'new_directory' do not match, apply DECODE_FILE + to the unibyte side. Because DECODE_FILE may invoke GC and + string relocation, any pointers (`nm' in this case) that may + point to some string data must be adjusted after the + potential GC. */ + if (multibyte != STRING_MULTIBYTE (new_directory)) + { + struct gcpro gcpro1, gcpro2; + + if (nm != SDATA (name)) + name = make_specified_string (nm, -1, strlen (nm), multibyte); + if (multibyte) + { + GCPRO2 (name, default_directory); + new_directory = DECODE_FILE (new_directory); + UNGCPRO; + } + else + { + GCPRO2 (new_directory, default_directory); + name = DECODE_FILE (name); + UNGCPRO; + } + nm = SDATA (name); + multibyte = 1; + } + newdir = SDATA (new_directory); + } + #ifdef DOS_NT if (newdir) { *************** See also the function `substitute-in-fil *** 1532,1537 **** --- 1573,1580 ---- if (newdir) { + int length; + /* Get rid of any slash at the end of newdir, unless newdir is just / or // (an incomplete UNC name). */ length = strlen (newdir); _______________________________________________ emacs-pretest-bug mailing list emacs-pretest-bug@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-pretest-bug