1 /* Cygwin support routines.
2 Copyright (C) 2011-2012 Free Software Foundation, Inc.
4 This file is part of GNU Emacs.
6 GNU Emacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 GNU Emacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 #include "character.h"
25 static Lisp_Object Qutf_16le
;
28 fchdir_unwind (Lisp_Object dir_fd
)
30 (void) fchdir (XFASTINT (dir_fd
));
31 (void) close (XFASTINT (dir_fd
));
36 chdir_to_default_directory ()
39 int old_cwd_fd
= open (".", O_RDONLY
| O_DIRECTORY
);
42 error ("could not open current directory: %s", strerror (errno
));
44 record_unwind_protect (fchdir_unwind
, make_number (old_cwd_fd
));
46 new_cwd
= Funhandled_file_name_directory (
47 Fexpand_file_name (build_string ("."), Qnil
));
48 if (!STRINGP (new_cwd
))
49 new_cwd
= build_string ("/");
51 if (chdir (SDATA (ENCODE_FILE (new_cwd
))))
52 error ("could not chdir: %s", strerror (errno
));
56 conv_filename_to_w32_unicode (Lisp_Object in
, int absolute_p
)
58 ssize_t converted_len
;
59 Lisp_Object converted
;
61 int count
= SPECPDL_INDEX ();
63 chdir_to_default_directory ();
65 flags
= CCP_POSIX_TO_WIN_W
;
67 flags
|= CCP_RELATIVE
;
70 in
= ENCODE_FILE (in
);
72 converted_len
= cygwin_conv_path (flags
, SDATA (in
), NULL
, 0);
73 if (converted_len
< 2)
74 error ("cygwin_conv_path: %s", strerror (errno
));
76 converted
= make_uninit_string (converted_len
- 1);
77 if (cygwin_conv_path (flags
, SDATA (in
),
78 SDATA (converted
), converted_len
))
79 error ("cygwin_conv_path: %s", strerror (errno
));
81 return unbind_to (count
, converted
);
85 conv_filename_from_w32_unicode (const wchar_t* in
, int absolute_p
)
87 ssize_t converted_len
;
88 Lisp_Object converted
;
90 int count
= SPECPDL_INDEX ();
92 chdir_to_default_directory ();
94 flags
= CCP_WIN_W_TO_POSIX
;
96 flags
|= CCP_RELATIVE
;
99 converted_len
= cygwin_conv_path (flags
, in
, NULL
, 0);
100 if (converted_len
< 1)
101 error ("cygwin_conv_path: %s", strerror (errno
));
103 converted
= make_uninit_string (converted_len
- 1 /*subtract terminator*/);
104 if (cygwin_conv_path (flags
, in
, SDATA (converted
), converted_len
))
105 error ("cygwin_conv_path: %s", strerror (errno
));
107 return unbind_to (count
, DECODE_FILE (converted
));
111 from_unicode (Lisp_Object str
)
114 if (!STRING_MULTIBYTE (str
) &&
117 str
= Fsubstring (str
, make_number (0), make_number (-1));
120 return code_convert_string_norecord (str
, Qutf_16le
, 0);
124 to_unicode (Lisp_Object str
, Lisp_Object
*buf
)
126 *buf
= code_convert_string_norecord (str
, Qutf_16le
, 1);
127 /* We need to make a another copy (in addition to the one made by
128 code_convert_string_norecord) to ensure that the final string is
129 _doubly_ zero terminated --- that is, that the string is
130 terminated by two zero bytes and one utf-16le null character.
131 Because strings are already terminated with a single zero byte,
132 we just add one additional zero. */
133 str
= make_uninit_string (SBYTES (*buf
) + 1);
134 memcpy (SDATA (str
), SDATA (*buf
), SBYTES (*buf
));
135 SDATA (str
) [SBYTES (*buf
)] = '\0';
137 return WCSDATA (*buf
);
140 DEFUN ("cygwin-convert-path-to-windows",
141 Fcygwin_convert_path_to_windows
, Scygwin_convert_path_to_windows
,
143 doc
: /* Convert PATH to a Windows path. If ABSOLUTE-P if
144 non-nil, return an absolute path.*/)
145 (Lisp_Object path
, Lisp_Object absolute_p
)
147 return from_unicode (
148 conv_filename_to_w32_unicode (path
, EQ (absolute_p
, Qnil
) ? 0 : 1));
151 DEFUN ("cygwin-convert-path-from-windows",
152 Fcygwin_convert_path_from_windows
, Scygwin_convert_path_from_windows
,
154 doc
: /* Convert a Windows path to a Cygwin path. If ABSOLUTE-P
155 if non-nil, return an absolute path.*/)
156 (Lisp_Object path
, Lisp_Object absolute_p
)
158 return conv_filename_from_w32_unicode (to_unicode (path
, &path
),
159 EQ (absolute_p
, Qnil
) ? 0 : 1);
163 syms_of_cygw32 (void)
165 /* No, not utf-16-le: that one has a BOM. */
166 DEFSYM (Qutf_16le
, "utf-16le");
167 defsubr (&Scygwin_convert_path_from_windows
);
168 defsubr (&Scygwin_convert_path_to_windows
);