Mercurial > hg > xemacs-beta
diff src/fileio.c @ 2526:902d5bd9b75c
[xemacs-hg @ 2005-01-28 02:36:11 by ben]
Support symlinks under Windows
nt.c, fileio.c: Fix sync comments.
config.h.in, dired-msw.c, emacs.c, event-msw.c, fileio.c, glyphs.c, lisp.h, nt.c, process-nt.c, realpath.c, sound.c, symsinit.h, sysdep.c, sysfile.h, syswindows.h, win32.c: Add support for treating shortcuts under Windows as symbolic links.
Enabled with mswindows-shortcuts-are-links (t by default). Rewrite
lots of places to use PATHNAME_CONVERT_OUT, which is moved to
sysfile.h. Add PATHNAME_RESOLVE_LINKS, which only does things
under Windows.
Add profiling section for expand_file_name calls.
nt.c, sysdep.c: Unicode-ize.
realpath.c: Renamed from readlink_and_correct_case. Fix some problems with
Windows implementation due to incorrect understanding of workings
of the function.
sound.c, ntplay.c, sound.h: Rename play_sound_file to nt_play_sound_file and pass
internally-formatted data to it to avoid converting out and back
again.
text.h: is_c -> is_ascii.
author | ben |
---|---|
date | Fri, 28 Jan 2005 02:36:28 +0000 |
parents | 3d8143fc88e1 |
children | 6c7605dfcf07 |
line wrap: on
line diff
--- a/src/fileio.c Fri Jan 28 02:05:05 2005 +0000 +++ b/src/fileio.c Fri Jan 28 02:36:28 2005 +0000 @@ -23,6 +23,7 @@ /* More syncing: FSF Emacs 19.34.6 by Marc Paquette <marcpa@cam.org> (Note: Sync messages from Marc Paquette may indicate incomplete synching, so beware.) */ +/* Some functions synched with FSF 21.0.103. */ /* Mule-ized completely except for the #if 0-code including decrypt-string and encrypt-string. --ben 7-2-00 */ /* #if 0-code Mule-ized, 2-22-03. --ben */ @@ -38,6 +39,7 @@ #include "frame.h" #include "insdel.h" #include "lstream.h" +#include "profile.h" #include "process.h" #include "redisplay.h" #include "sysdep.h" @@ -129,6 +131,8 @@ Lisp_Object Qcompute_buffer_file_truename; +Lisp_Object QSin_expand_file_name; + EXFUN (Frunning_temacs_p, 0); /* DATA can be anything acceptable to signal_error (). @@ -325,6 +329,25 @@ } + +Ibyte * +find_end_of_directory_component (const Ibyte *path, Bytecount len) +{ + const Ibyte *p = path + len; + + while (p != path && !IS_DIRECTORY_SEP (p[-1]) +#ifdef WIN32_FILENAMES + /* only recognise drive specifier at the beginning */ + && !(p[-1] == ':' + /* handle the "/:d:foo" and "/:foo" cases correctly */ + && ((p == path + 2 && !IS_DIRECTORY_SEP (*path)) + || (p == path + 4 && IS_DIRECTORY_SEP (*path)))) +#endif + ) p--; + + return (Ibyte *) p; +} + DEFUN ("file-name-directory", Ffile_name_directory, 1, 1, 0, /* Return the directory component in file name FILENAME. Return nil if FILENAME does not include a directory. @@ -352,17 +375,7 @@ #endif beg = XSTRING_DATA (filename); /* XEmacs: no need to alloca-copy here */ - p = beg + XSTRING_LENGTH (filename); - - while (p != beg && !IS_DIRECTORY_SEP (p[-1]) -#ifdef WIN32_FILENAMES - /* only recognise drive specifier at the beginning */ - && !(p[-1] == ':' - /* handle the "/:d:foo" and "/:foo" cases correctly */ - && ((p == beg + 2 && !IS_DIRECTORY_SEP (*beg)) - || (p == beg + 4 && IS_DIRECTORY_SEP (*beg)))) -#endif - ) p--; + p = find_end_of_directory_component (beg, XSTRING_LENGTH (filename)); if (p == beg) return Qnil; @@ -522,7 +535,11 @@ return call2_check_string (handler, Qfile_name_as_directory, filename); buf = alloca_ibytes (XSTRING_LENGTH (filename) + 10); - return build_intstring (file_name_as_directory (buf, XSTRING_DATA (filename))); + file_name_as_directory (buf, XSTRING_DATA (filename)); + if (qxestrcmp (buf, XSTRING_DATA (filename))) + return build_intstring (buf); + else + return filename; } /* @@ -735,6 +752,9 @@ int length; Lisp_Object handler = Qnil; struct gcpro gcpro1, gcpro2, gcpro3; + PROFILE_DECLARE (); + + PROFILE_RECORD_ENTERING_SECTION (QSin_expand_file_name); /* both of these get set below */ GCPRO3 (name, default_directory, handler); @@ -745,8 +765,10 @@ call the corresponding file handler. */ handler = Ffind_file_name_handler (name, Qexpand_file_name); if (!NILP (handler)) - RETURN_UNGCPRO (call3_check_string (handler, Qexpand_file_name, - name, default_directory)); + RETURN_UNGCPRO_EXIT_PROFILING (QSin_expand_file_name, + call3_check_string + (handler, Qexpand_file_name, + name, default_directory)); /* Use the buffer's default-directory if DEFAULT_DIRECTORY is omitted. */ if (NILP (default_directory)) @@ -762,8 +784,9 @@ { handler = Ffind_file_name_handler (default_directory, Qexpand_file_name); if (!NILP (handler)) - RETURN_UNGCPRO (call3 (handler, Qexpand_file_name, - name, default_directory)); + RETURN_UNGCPRO_EXIT_PROFILING (QSin_expand_file_name, + call3 (handler, Qexpand_file_name, + name, default_directory)); } o = XSTRING_DATA (default_directory); @@ -927,13 +950,14 @@ } } xfree (newnm, Ibyte *); - RETURN_UNGCPRO (name); + RETURN_UNGCPRO_EXIT_PROFILING (QSin_expand_file_name, name); } #endif /* WIN32_FILENAMES */ #ifndef WIN32_NATIVE if (nm == XSTRING_DATA (name)) - RETURN_UNGCPRO (name); - RETURN_UNGCPRO (build_intstring (nm)); + RETURN_UNGCPRO_EXIT_PROFILING (QSin_expand_file_name, name); + RETURN_UNGCPRO_EXIT_PROFILING (QSin_expand_file_name, + build_intstring (nm)); #endif /* not WIN32_NATIVE */ } } @@ -1301,10 +1325,11 @@ Lisp_Object result = build_intstring (newtarget); xfree (newtarget, Ibyte *); - RETURN_UNGCPRO (result); + RETURN_UNGCPRO_EXIT_PROFILING (QSin_expand_file_name, result); } #else /* not WIN32_FILENAMES */ - RETURN_UNGCPRO (make_string (target, o - target)); + RETURN_UNGCPRO_EXIT_PROFILING (QSin_expand_file_name, + make_string (target, o - target)); #endif /* not WIN32_FILENAMES */ } @@ -1360,7 +1385,7 @@ p = path; /* Try doing it all at once. */ - if (!qxe_realpath (path, resolved_path)) + if (!qxe_realpath (path, resolved_path, 0)) { /* Didn't resolve it -- have to do it one component at a time. */ /* "realpath" is a typically useless, stupid un*x piece of crap. @@ -1379,7 +1404,11 @@ resolved_name are undefined." Since we depend on undocumented semantics of various system - realpath()s, we just use our own version in realpath.c. */ + realpath()s, we just use our own version in realpath.c. + + Note also that our own version differs in its semantics from any + standard version, since it accepts and returns internal-format + text, not external-format. */ for (;;) { Ibyte *pos; @@ -1402,7 +1431,7 @@ if (p != pos) p = 0; - if (qxe_realpath (path, resolved_path)) + if (qxe_realpath (path, resolved_path, 0)) { if (p) *p = DIRECTORY_SEP; @@ -2338,7 +2367,7 @@ if (!NILP (handler)) RETURN_UNGCPRO (call2 (handler, Qfile_readable_p, abspath)); -#if defined(WIN32_FILENAMES) +#if defined (WIN32_FILENAMES) /* Under MS-DOS and Windows, open does not work for directories. */ UNGCPRO; if (qxe_access (XSTRING_DATA (abspath), 0) == 0) @@ -2443,9 +2472,42 @@ val = make_string (buf, valsize); xfree (buf, Ibyte *); return val; -#else /* not HAVE_READLINK */ +#elif defined (WIN32_NATIVE) + if (mswindows_shortcuts_are_symlinks) + { + /* We want to resolve the directory component and leave the rest + alone. */ + Ibyte *path = XSTRING_DATA (filename); + Ibyte *dirend = + find_end_of_directory_component (path, XSTRING_LENGTH (filename)); + Ibyte *fname; + DECLARE_EISTRING (dir); + + if (dirend != path) + { + Ibyte *resdir; + DECLARE_EISTRING (resname); + + eicpy_raw (dir, path, dirend - path); + PATHNAME_RESOLVE_LINKS (eidata (dir), resdir); + eicpy_rawz (resname, resdir); + eicat_rawz (resname, dirend); + path = eidata (resname); + } + + fname = mswindows_read_link (path); + if (!fname) + return Qnil; + { + Lisp_Object val = build_intstring (fname); + xfree (fname, Ibyte *); + return val; + } + } return Qnil; -#endif /* not HAVE_READLINK */ +#else + return Qnil; +#endif } DEFUN ("file-directory-p", Ffile_directory_p, 1, 1, 0, /* @@ -2499,7 +2561,7 @@ return call2 (handler, Qfile_accessible_directory_p, filename); -#if !defined(WIN32_NATIVE) +#if !defined (WIN32_NATIVE) if (NILP (Ffile_directory_p (filename))) return (Qnil); else @@ -4300,6 +4362,10 @@ void vars_of_fileio (void) { + QSin_expand_file_name = + build_msg_string ("(in expand-file-name)"); + staticpro (&QSin_expand_file_name); + DEFVAR_LISP ("auto-save-file-format", &Vauto_save_file_format /* *Format in which to write auto-save files. Should be a list of symbols naming formats that are defined in `format-alist'.