Initial commit of newLISP.
[newlisp.git] / win32-path.c
blob4b99c24f84c9f8c067bd8120f8bf21b306bcd010
1 /* win32-path.c - directory and file functions working on UTF-16
2 file and path names
4 Copyright (C) 2007,2008 Michael Sabin
6 This program 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 This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <wchar.h>
22 #include <windows.h>
23 #include "newlisp.h"
24 #include "protos.h"
27 utf8_to_utf16
28 Uses the Windows API to convert a UTF-8 string to a UTF-16 string.
29 Returns a pointer to a WCHAR string, or NULL if there was an error
30 (like if an invalid utf8 string was provided).
31 Note that the returned string must be free()ed.
33 WCHAR * utf8_to_utf16(const char *utf8str)
35 int size = -1;
36 WCHAR *utf16str = NULL;
38 size = MultiByteToWideChar(
39 CP_UTF8,
40 0, /* no flags=ignore errors if possible */
41 utf8str,
42 -1, /* read until NULL character */
43 NULL,
44 0 /* just calculate size */
47 if (size == 0) return (NULL);
49 utf16str = (WCHAR*)allocMemory((size+1) * sizeof(WCHAR));
51 size = MultiByteToWideChar(
52 CP_UTF8,
54 utf8str,
55 -1,
56 utf16str,
57 size
58 );
60 if (size == 0)
62 free(utf16str);
63 return(NULL);
65 else
66 return(utf16str);
71 utf16_to_utf8ptr
72 Used in win32_realpath.
73 Generally wrapped by utf16_to_utf8.
75 int utf16_to_utf8ptr(const WCHAR *utf16str, char * utf8str, int size)
78 if (size < 1) return(-1);
80 size = WideCharToMultiByte(
81 CP_UTF8,
83 utf16str,
84 -1,
85 utf8str,
86 size,
87 NULL,
88 NULL
91 if (size == 0)
92 return(-1);
93 else
94 return(0);
98 utf16_to_utf8
99 Uses the Windows API to convert a UTF-16 string to a UTF-8 string.
100 Returns a pointer to a char string, or NULL if there was an error
101 (like if an invalid utf16 string was provided).
102 Note that the returned string must be free()ed.
104 char * utf16_to_utf8(const WCHAR *utf16str)
106 int size = -1;
107 char *utf8str = NULL;
109 size = WideCharToMultiByte(
110 CP_UTF8,
112 utf16str,
116 NULL,
117 NULL
120 if (size == 0) return (NULL);
122 utf8str = (char*)allocMemory((size+1) * sizeof(char));
124 if (utf16_to_utf8ptr(utf16str, utf8str, size) == -1)
126 free(utf8str);
127 return(NULL);
129 else
130 return(utf8str);
135 win32_realpath
136 Identical interface as realpath
137 for both ANSI and UTF-16 path names on Windows.
138 Has the following functional differences
139 * If GetFullPathNameW, first converts the UTF-8 file name to UTF-16 (WCHAR)
140 * Uses GetFullPathNameA or GetFullPathNameW to receive the char/WCHAR path
141 * If GetFullPathNameW, converts the UTF-16 WCHAR path back to UTF-8
143 char *win32_realpath(const char *filepath, char *realpath)
146 #ifdef USE_WIN_UTF16PATH
148 WCHAR * utf16filepath;
149 WCHAR utf16realpath[MAX_PATH + 2];
150 int err;
152 utf16filepath = utf8_to_utf16(filepath);
153 err = GetFullPathNameW(utf16filepath, MAX_PATH, utf16realpath, NULL);
154 free(utf16filepath);
156 if (err == 0)
157 return(NULL);
159 if (utf16_to_utf8ptr(utf16realpath, realpath, MAX_PATH) == -1)
160 return(NULL);
162 #else
164 if(GetFullPathNameA(filepath, MAX_PATH, realpath, NULL) == 0)
165 return(NULL);
167 #endif
169 return (realpath);
175 fileSizeW
176 Same behavior as fileSize() in nl-filesys.c
177 but accepts a WCHAR path.
178 Primarily for use in p_fileInfo()
180 INT64 fileSizeW(WCHAR * pathName)
182 int handle;
183 INT64 size;
185 handle = _wopen(pathName,O_RDONLY | O_BINARY, 0);
186 size = lseek(handle, 0, SEEK_END);
187 close(handle);
188 if(size == -1) size = 0;
189 return(size);
193 /* ----------------------------------------------------------------------------
194 Wrappers for wide-character functions.
195 Same interface as the standard functions.
196 Adds the following functionality:
197 * first converts the UTF-8 string to UTF-16
198 * if there a conversion error, return fail
199 * calls the wide-character function
200 ---------------------------------------------------------------------------- */
202 int rename_utf16(const char* a, const char* b)
204 int i;
205 WCHAR * utf16a;
206 WCHAR * utf16b;
208 utf16a = utf8_to_utf16(a);
209 if (utf16a == NULL) return (-1);
210 utf16b = utf8_to_utf16(b);
211 if (utf16b == NULL) return (-1);
213 i = _wrename(utf16a, utf16b);
214 free(utf16a);
215 free(utf16b);
216 return i;
219 int stat_utf16(const char* a, struct stat* b)
221 int i;
222 WCHAR * utf16a = utf8_to_utf16(a);
223 if (utf16a == NULL) return (-1);
225 i = _wstat(utf16a, (struct _stat*)b);
226 free(utf16a);
227 return i;
230 int chdir_utf16(const char* a)
232 int i;
233 WCHAR * utf16a = utf8_to_utf16(a);
234 if (utf16a == NULL) return (-1);
236 i = _wchdir(utf16a);
237 free(utf16a);
238 return i;
241 int open_utf16(const char* a, int b, int c)
243 int i;
244 WCHAR * utf16a = utf8_to_utf16(a);
245 if (utf16a == NULL) return (-1);
247 i = _wopen(utf16a, b, c);
248 free(utf16a);
249 return i;
252 int mkdir_utf16(const char* a)
254 int i;
255 WCHAR * utf16a = utf8_to_utf16(a);
256 if (utf16a == NULL) return (-1);
258 i = _wmkdir(utf16a);
259 free(utf16a);
260 return i;
263 int rmdir_utf16(const char* a)
265 int i;
266 WCHAR * utf16a = utf8_to_utf16(a);
267 if (utf16a == NULL) return (-1);
269 i = _wrmdir(utf16a);
270 free(utf16a);
271 return i;
274 int unlink_utf16(const char* a)
276 int i;
277 WCHAR * utf16a = utf8_to_utf16(a);
278 if (utf16a == NULL) return (-1);
280 i = _wunlink(utf16a);
281 free(utf16a);
282 return i;
285 _WDIR * opendir_utf16(const char* a)
287 _WDIR * dir;
288 WCHAR * utf16a = utf8_to_utf16(a);
289 if (utf16a == NULL) return (NULL);
291 dir = _wopendir(utf16a);
292 free(utf16a);
293 return dir;
296 /* eof */