diff options
Diffstat (limited to 'uisimulator/common')
-rw-r--r-- | uisimulator/common/io.c | 166 |
1 files changed, 120 insertions, 46 deletions
diff --git a/uisimulator/common/io.c b/uisimulator/common/io.c index c8b3169803..b6f294cee1 100644 --- a/uisimulator/common/io.c +++ b/uisimulator/common/io.c | |||
@@ -57,6 +57,75 @@ | |||
57 | #define O_BINARY 0 | 57 | #define O_BINARY 0 |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | /* Unicode compatibility for win32 */ | ||
61 | #if defined __MINGW32__ | ||
62 | /* Rockbox unicode functions */ | ||
63 | extern const unsigned char* utf8decode(const unsigned char *utf8, | ||
64 | unsigned short *ucs); | ||
65 | extern unsigned char* utf8encode(unsigned long ucs, unsigned char *utf8); | ||
66 | |||
67 | /* UTF-8 <-> UCS2 conversion. Note that these functions aren't thread safe | ||
68 | * due to the use of static buffers. */ | ||
69 | static wchar_t* utf8_to_ucs2(const unsigned char *utf8, int index) | ||
70 | { | ||
71 | static wchar_t wbuffer[2][MAX_PATH]; | ||
72 | wchar_t *ucs = wbuffer[index]; | ||
73 | |||
74 | while (*utf8) | ||
75 | utf8 = utf8decode(utf8, ucs++); | ||
76 | |||
77 | *ucs = 0; | ||
78 | return wbuffer[index]; | ||
79 | } | ||
80 | static unsigned char *ucs2_to_utf8(const wchar_t *ucs) | ||
81 | { | ||
82 | static unsigned char buffer[3*MAX_PATH]; | ||
83 | unsigned char *utf8 = buffer; | ||
84 | |||
85 | while (*ucs) | ||
86 | utf8 = utf8encode(*ucs++, utf8); | ||
87 | |||
88 | *utf8 = 0; | ||
89 | return buffer; | ||
90 | } | ||
91 | |||
92 | #define UTF8_TO_OS(a) utf8_to_ucs2(a,0) | ||
93 | #define OS_TO_UTF8(a) ucs2_to_utf8(a) | ||
94 | #define DIR_T _WDIR | ||
95 | #define DIRENT_T struct _wdirent | ||
96 | #define STAT_T struct _stat | ||
97 | extern int _wmkdir(const wchar_t*); | ||
98 | extern int _wrmdir(const wchar_t*); | ||
99 | #define MKDIR(a,b) (_wmkdir)(UTF8_TO_OS(a)) | ||
100 | #define RMDIR(a) (_wrmdir)(UTF8_TO_OS(a)) | ||
101 | #define OPENDIR(a) (_wopendir)(UTF8_TO_OS(a)) | ||
102 | #define READDIR(a) (_wreaddir)(a) | ||
103 | #define CLOSEDIR(a) (_wclosedir)(a) | ||
104 | #define STAT(a,b) (_wstat)(UTF8_TO_OS(a),b) | ||
105 | #define OPEN(a,b,c) (_wopen)(UTF8_TO_OS(a),b,c) | ||
106 | #define REMOVE(a) (_wremove)(UTF8_TO_OS(a)) | ||
107 | #define RENAME(a,b) (_wrename)(UTF8_TO_OS(a),utf8_to_ucs2(b,1)) | ||
108 | |||
109 | #else /* !__MINGW32__ */ | ||
110 | |||
111 | #define UTF8_TO_OS(a) (a) | ||
112 | #define OS_TO_UTF8(a) (a) | ||
113 | #define DIR_T DIR | ||
114 | #define DIRENT_T struct dirent | ||
115 | #define STAT_T struct stat | ||
116 | #define MKDIR(a,b) (mkdir)(a,b) | ||
117 | #define RMDIR(a) (rmdir)(a) | ||
118 | #define OPENDIR(a) (opendir)(a) | ||
119 | #define READDIR(a) (readdir)(a) | ||
120 | #define CLOSEDIR(a) (closedir)(a) | ||
121 | #define STAT(a,b) (stat)(a,b) | ||
122 | #define OPEN(a,b,c) (open)(a,b,c) | ||
123 | #define REMOVE(a) (remove)(a) | ||
124 | #define RENAME(a,b) (rename)(a,b) | ||
125 | |||
126 | #endif /* !__MINGW32__ */ | ||
127 | |||
128 | |||
60 | #ifdef HAVE_DIRCACHE | 129 | #ifdef HAVE_DIRCACHE |
61 | void dircache_remove(const char *name); | 130 | void dircache_remove(const char *name); |
62 | void dircache_rename(const char *oldpath, const char *newpath); | 131 | void dircache_rename(const char *oldpath, const char *newpath); |
@@ -79,7 +148,7 @@ struct dirstruct { | |||
79 | } SIM_DIR; | 148 | } SIM_DIR; |
80 | 149 | ||
81 | struct mydir { | 150 | struct mydir { |
82 | DIR *dir; | 151 | DIR_T *dir; |
83 | char *name; | 152 | char *name; |
84 | }; | 153 | }; |
85 | 154 | ||
@@ -108,18 +177,18 @@ static unsigned int rockbox2sim(int opt) | |||
108 | MYDIR *sim_opendir(const char *name) | 177 | MYDIR *sim_opendir(const char *name) |
109 | { | 178 | { |
110 | char buffer[MAX_PATH]; /* sufficiently big */ | 179 | char buffer[MAX_PATH]; /* sufficiently big */ |
111 | DIR *dir; | 180 | DIR_T *dir; |
112 | 181 | ||
113 | #ifndef __PCTOOL__ | 182 | #ifndef __PCTOOL__ |
114 | if(name[0] == '/') | 183 | if(name[0] == '/') |
115 | { | 184 | { |
116 | snprintf(buffer, sizeof(buffer), "%s%s", SIMULATOR_ARCHOS_ROOT, name); | 185 | snprintf(buffer, sizeof(buffer), "%s%s", SIMULATOR_ARCHOS_ROOT, name); |
117 | dir=(DIR *)opendir(buffer); | 186 | dir=(DIR_T *)OPENDIR(buffer); |
118 | } | 187 | } |
119 | else | 188 | else |
120 | #endif | 189 | #endif |
121 | dir=(DIR *)opendir(name); | 190 | dir=(DIR_T *)OPENDIR(name); |
122 | 191 | ||
123 | if(dir) { | 192 | if(dir) { |
124 | MYDIR *my = (MYDIR *)malloc(sizeof(MYDIR)); | 193 | MYDIR *my = (MYDIR *)malloc(sizeof(MYDIR)); |
125 | my->dir = dir; | 194 | my->dir = dir; |
@@ -135,23 +204,23 @@ struct sim_dirent *sim_readdir(MYDIR *dir) | |||
135 | { | 204 | { |
136 | char buffer[512]; /* sufficiently big */ | 205 | char buffer[512]; /* sufficiently big */ |
137 | static struct sim_dirent secret; | 206 | static struct sim_dirent secret; |
138 | struct stat s; | 207 | STAT_T s; |
139 | struct dirent *x11 = (readdir)(dir->dir); | 208 | DIRENT_T *x11 = READDIR(dir->dir); |
140 | struct tm* tm; | 209 | struct tm* tm; |
141 | 210 | ||
142 | if(!x11) | 211 | if(!x11) |
143 | return (struct sim_dirent *)0; | 212 | return (struct sim_dirent *)0; |
144 | 213 | ||
145 | strcpy((char *)secret.d_name, x11->d_name); | 214 | strcpy((char *)secret.d_name, OS_TO_UTF8(x11->d_name)); |
146 | 215 | ||
147 | /* build file name */ | 216 | /* build file name */ |
148 | #ifdef __PCTOOL__ | 217 | #ifdef __PCTOOL__ |
149 | snprintf(buffer, sizeof(buffer), "%s/%s", dir->name, x11->d_name); | 218 | snprintf(buffer, sizeof(buffer), "%s/%s", dir->name, secret.d_name); |
150 | #else | 219 | #else |
151 | snprintf(buffer, sizeof(buffer), SIMULATOR_ARCHOS_ROOT "%s/%s", | 220 | snprintf(buffer, sizeof(buffer), SIMULATOR_ARCHOS_ROOT "%s/%s", |
152 | dir->name, x11->d_name); | 221 | dir->name, secret.d_name); |
153 | #endif | 222 | #endif |
154 | stat(buffer, &s); /* get info */ | 223 | STAT(buffer, &s); /* get info */ |
155 | 224 | ||
156 | #define ATTR_DIRECTORY 0x10 | 225 | #define ATTR_DIRECTORY 0x10 |
157 | 226 | ||
@@ -171,7 +240,7 @@ struct sim_dirent *sim_readdir(MYDIR *dir) | |||
171 | void sim_closedir(MYDIR *dir) | 240 | void sim_closedir(MYDIR *dir) |
172 | { | 241 | { |
173 | free(dir->name); | 242 | free(dir->name); |
174 | closedir(dir->dir); | 243 | CLOSEDIR(dir->dir); |
175 | 244 | ||
176 | free(dir); | 245 | free(dir); |
177 | } | 246 | } |
@@ -187,14 +256,14 @@ int sim_open(const char *name, int o) | |||
187 | snprintf(buffer, sizeof(buffer), "%s%s", SIMULATOR_ARCHOS_ROOT, name); | 256 | snprintf(buffer, sizeof(buffer), "%s%s", SIMULATOR_ARCHOS_ROOT, name); |
188 | 257 | ||
189 | debugf("We open the real file '%s'\n", buffer); | 258 | debugf("We open the real file '%s'\n", buffer); |
190 | return open(buffer, opts, 0666); | 259 | return OPEN(buffer, opts, 0666); |
191 | } | 260 | } |
192 | 261 | ||
193 | fprintf(stderr, "WARNING, bad file name lacks slash: %s\n", | 262 | fprintf(stderr, "WARNING, bad file name lacks slash: %s\n", |
194 | name); | 263 | name); |
195 | return -1; | 264 | return -1; |
196 | #else | 265 | #else |
197 | return open(name, opts, 0666); | 266 | return OPEN(name, opts, 0666); |
198 | #endif | 267 | #endif |
199 | 268 | ||
200 | } | 269 | } |
@@ -208,42 +277,33 @@ int sim_creat(const char *name) | |||
208 | snprintf(buffer, sizeof(buffer), "%s%s", SIMULATOR_ARCHOS_ROOT, name); | 277 | snprintf(buffer, sizeof(buffer), "%s%s", SIMULATOR_ARCHOS_ROOT, name); |
209 | 278 | ||
210 | debugf("We create the real file '%s'\n", buffer); | 279 | debugf("We create the real file '%s'\n", buffer); |
211 | return open(buffer, O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, 0666); | 280 | return OPEN(buffer, O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, 0666); |
212 | } | 281 | } |
213 | fprintf(stderr, "WARNING, bad file name lacks slash: %s\n", name); | 282 | fprintf(stderr, "WARNING, bad file name lacks slash: %s\n", name); |
214 | return -1; | 283 | return -1; |
215 | #else | 284 | #else |
216 | return open(name, O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, 0666); | 285 | return OPEN(name, O_BINARY | O_WRONLY | O_CREAT | O_TRUNC, 0666); |
217 | #endif | 286 | #endif |
218 | } | 287 | } |
219 | 288 | ||
220 | int sim_mkdir(const char *name) | 289 | int sim_mkdir(const char *name) |
221 | { | 290 | { |
222 | #ifdef __PCTOOL__ | 291 | #ifdef __PCTOOL__ |
223 | # ifdef WIN32 | 292 | return MKDIR(name, 0777); |
224 | return mkdir(name); | ||
225 | # else | ||
226 | return mkdir(name, 0777); | ||
227 | # endif | ||
228 | #else | 293 | #else |
229 | char buffer[MAX_PATH]; /* sufficiently big */ | 294 | char buffer[MAX_PATH]; /* sufficiently big */ |
230 | 295 | ||
231 | snprintf(buffer, sizeof(buffer), "%s%s", SIMULATOR_ARCHOS_ROOT, name); | 296 | snprintf(buffer, sizeof(buffer), "%s%s", SIMULATOR_ARCHOS_ROOT, name); |
232 | 297 | ||
233 | debugf("We create the real directory '%s'\n", buffer); | 298 | debugf("We create the real directory '%s'\n", buffer); |
234 | #ifdef WIN32 | 299 | return MKDIR(buffer, 0777); |
235 | /* since we build with -DNOCYGWIN we have the plain win32 version */ | ||
236 | return mkdir(buffer); | ||
237 | #else | ||
238 | return mkdir(buffer, 0777); | ||
239 | #endif | ||
240 | #endif | 300 | #endif |
241 | } | 301 | } |
242 | 302 | ||
243 | int sim_rmdir(const char *name) | 303 | int sim_rmdir(const char *name) |
244 | { | 304 | { |
245 | #ifdef __PCTOOL__ | 305 | #ifdef __PCTOOL__ |
246 | return rmdir(name); | 306 | return RMDIR(name); |
247 | #else | 307 | #else |
248 | char buffer[MAX_PATH]; /* sufficiently big */ | 308 | char buffer[MAX_PATH]; /* sufficiently big */ |
249 | if(name[0] == '/') | 309 | if(name[0] == '/') |
@@ -251,16 +311,16 @@ int sim_rmdir(const char *name) | |||
251 | snprintf(buffer, sizeof(buffer), "%s%s", SIMULATOR_ARCHOS_ROOT, name); | 311 | snprintf(buffer, sizeof(buffer), "%s%s", SIMULATOR_ARCHOS_ROOT, name); |
252 | 312 | ||
253 | debugf("We remove the real directory '%s'\n", buffer); | 313 | debugf("We remove the real directory '%s'\n", buffer); |
254 | return rmdir(buffer); | 314 | return RMDIR(buffer); |
255 | } | 315 | } |
256 | return rmdir(name); | 316 | return RMDIR(name); |
257 | #endif | 317 | #endif |
258 | } | 318 | } |
259 | 319 | ||
260 | int sim_remove(const char *name) | 320 | int sim_remove(const char *name) |
261 | { | 321 | { |
262 | #ifdef __PCTOOL__ | 322 | #ifdef __PCTOOL__ |
263 | return remove(name); | 323 | return REMOVE(name); |
264 | #else | 324 | #else |
265 | char buffer[MAX_PATH]; /* sufficiently big */ | 325 | char buffer[MAX_PATH]; /* sufficiently big */ |
266 | 326 | ||
@@ -272,16 +332,16 @@ int sim_remove(const char *name) | |||
272 | snprintf(buffer, sizeof(buffer), "%s%s", SIMULATOR_ARCHOS_ROOT, name); | 332 | snprintf(buffer, sizeof(buffer), "%s%s", SIMULATOR_ARCHOS_ROOT, name); |
273 | 333 | ||
274 | debugf("We remove the real file '%s'\n", buffer); | 334 | debugf("We remove the real file '%s'\n", buffer); |
275 | return remove(buffer); | 335 | return REMOVE(buffer); |
276 | } | 336 | } |
277 | return remove(name); | 337 | return REMOVE(name); |
278 | #endif | 338 | #endif |
279 | } | 339 | } |
280 | 340 | ||
281 | int sim_rename(const char *oldpath, const char* newpath) | 341 | int sim_rename(const char *oldpath, const char* newpath) |
282 | { | 342 | { |
283 | #ifdef __PCTOOL__ | 343 | #ifdef __PCTOOL__ |
284 | return rename(oldpath, newpath); | 344 | return RENAME(oldpath, newpath); |
285 | #else | 345 | #else |
286 | char buffer1[MAX_PATH]; | 346 | char buffer1[MAX_PATH]; |
287 | char buffer2[MAX_PATH]; | 347 | char buffer2[MAX_PATH]; |
@@ -297,7 +357,7 @@ int sim_rename(const char *oldpath, const char* newpath) | |||
297 | newpath); | 357 | newpath); |
298 | 358 | ||
299 | debugf("We rename the real file '%s' to '%s'\n", buffer1, buffer2); | 359 | debugf("We rename the real file '%s' to '%s'\n", buffer1, buffer2); |
300 | return rename(buffer1, buffer2); | 360 | return RENAME(buffer1, buffer2); |
301 | } | 361 | } |
302 | return -1; | 362 | return -1; |
303 | #endif | 363 | #endif |
@@ -366,7 +426,7 @@ int sim_fsync(int fd) | |||
366 | 426 | ||
367 | #ifdef WIN32 | 427 | #ifdef WIN32 |
368 | /* sim-win32 */ | 428 | /* sim-win32 */ |
369 | #define dlopen(_x_, _y_) LoadLibrary(_x_) | 429 | #define dlopen(_x_, _y_) LoadLibraryW(UTF8_TO_OS(_x_)) |
370 | #define dlsym(_x_, _y_) (void *)GetProcAddress(_x_, _y_) | 430 | #define dlsym(_x_, _y_) (void *)GetProcAddress(_x_, _y_) |
371 | #define dlclose(_x_) FreeLibrary(_x_) | 431 | #define dlclose(_x_) FreeLibrary(_x_) |
372 | #else | 432 | #else |
@@ -398,7 +458,7 @@ void *sim_codec_load_ram(char* codecptr, int size, | |||
398 | { | 458 | { |
399 | snprintf(path, sizeof(path), TEMP_CODEC_FILE, codec_count); | 459 | snprintf(path, sizeof(path), TEMP_CODEC_FILE, codec_count); |
400 | 460 | ||
401 | fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU); | 461 | fd = OPEN(path, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, S_IRWXU); |
402 | if (fd >= 0) | 462 | if (fd >= 0) |
403 | break; /* Created a file ok */ | 463 | break; /* Created a file ok */ |
404 | } | 464 | } |
@@ -430,8 +490,8 @@ void *sim_codec_load_ram(char* codecptr, int size, | |||
430 | if (*pd == NULL) { | 490 | if (*pd == NULL) { |
431 | DEBUGF("failed to load %s\n", path); | 491 | DEBUGF("failed to load %s\n", path); |
432 | #ifdef WIN32 | 492 | #ifdef WIN32 |
433 | FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, | 493 | FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, |
434 | buf, sizeof buf, NULL); | 494 | buf, sizeof buf, NULL); |
435 | DEBUGF("dlopen(%s): %s\n", path, buf); | 495 | DEBUGF("dlopen(%s): %s\n", path, buf); |
436 | #else | 496 | #else |
437 | DEBUGF("dlopen(%s): %s\n", path, dlerror()); | 497 | DEBUGF("dlopen(%s): %s\n", path, dlerror()); |
@@ -467,8 +527,8 @@ void *sim_plugin_load(char *plugin, void **pd) | |||
467 | if (*pd == NULL) { | 527 | if (*pd == NULL) { |
468 | DEBUGF("failed to load %s\n", plugin); | 528 | DEBUGF("failed to load %s\n", plugin); |
469 | #ifdef WIN32 | 529 | #ifdef WIN32 |
470 | FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, | 530 | FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, |
471 | buf, sizeof(buf), NULL); | 531 | buf, sizeof(buf), NULL); |
472 | DEBUGF("dlopen(%s): %s\n", path, buf); | 532 | DEBUGF("dlopen(%s): %s\n", path, buf); |
473 | #else | 533 | #else |
474 | DEBUGF("dlopen(%s): %s\n", path, dlerror()); | 534 | DEBUGF("dlopen(%s): %s\n", path, dlerror()); |
@@ -488,13 +548,29 @@ void sim_plugin_close(void *pd) | |||
488 | dlclose(pd); | 548 | dlclose(pd); |
489 | } | 549 | } |
490 | 550 | ||
491 | #if !defined(WIN32) || defined(SDL) | 551 | #ifdef WIN32 |
492 | /* the win32 version is in debug-win32.c */ | 552 | static unsigned old_cp; |
553 | |||
554 | void debug_exit(void) | ||
555 | { | ||
556 | /* Reset console output codepage */ | ||
557 | SetConsoleOutputCP(old_cp); | ||
558 | } | ||
493 | 559 | ||
494 | void debug_init(void) | 560 | void debug_init(void) |
495 | { | 561 | { |
562 | old_cp = GetConsoleOutputCP(); | ||
563 | /* Set console output codepage to UTF8. Only works | ||
564 | * correctly when the console uses a truetype font. */ | ||
565 | SetConsoleOutputCP(65001); | ||
566 | atexit(debug_exit); | ||
567 | } | ||
568 | #else | ||
569 | void debug_init(void) | ||
570 | { | ||
496 | /* nothing to be done */ | 571 | /* nothing to be done */ |
497 | } | 572 | } |
573 | #endif | ||
498 | 574 | ||
499 | void debugf(const char *fmt, ...) | 575 | void debugf(const char *fmt, ...) |
500 | { | 576 | { |
@@ -513,8 +589,6 @@ void ldebugf(const char* file, int line, const char *fmt, ...) | |||
513 | va_end( ap ); | 589 | va_end( ap ); |
514 | } | 590 | } |
515 | 591 | ||
516 | #endif | ||
517 | |||
518 | /* rockbox off_t may be different from system off_t */ | 592 | /* rockbox off_t may be different from system off_t */ |
519 | int sim_ftruncate(int fd, long length) | 593 | int sim_ftruncate(int fd, long length) |
520 | { | 594 | { |