| | @@ -27,10 +27,14 @@ |
| 27 | 27 | #include <sys/stat.h> |
| 28 | 28 | #include <unistd.h> |
| 29 | 29 | #include <string.h> |
| 30 | 30 | #include <errno.h> |
| 31 | 31 | #include "file.h" |
| 32 | +#if defined(_WIN32) |
| 33 | +#include <direct.h> |
| 34 | +#endif |
| 35 | + |
| 32 | 36 | |
| 33 | 37 | /* |
| 34 | 38 | ** On Windows, include the Platform SDK header file. |
| 35 | 39 | */ |
| 36 | 40 | #ifdef _WIN32 |
| | @@ -68,12 +72,12 @@ |
| 68 | 72 | }else{ |
| 69 | 73 | return stat(zFilename, buf); |
| 70 | 74 | } |
| 71 | 75 | #else |
| 72 | 76 | int rc = 0; |
| 73 | | - char *zMbcs = fossil_utf8_to_mbcs(zFilename); |
| 74 | | - rc = stat(zMbcs, buf); |
| 77 | + wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename); |
| 78 | + rc = _wstati64(zMbcs, buf); |
| 75 | 79 | fossil_mbcs_free(zMbcs); |
| 76 | 80 | return rc; |
| 77 | 81 | #endif |
| 78 | 82 | } |
| 79 | 83 | |
| | @@ -298,13 +302,17 @@ |
| 298 | 302 | |
| 299 | 303 | /* |
| 300 | 304 | ** Wrapper around the access() system call. |
| 301 | 305 | */ |
| 302 | 306 | int file_access(const char *zFilename, int flags){ |
| 303 | | - char *zMbcs = fossil_utf8_to_mbcs(zFilename); |
| 304 | | - int rc = access(zMbcs, flags); |
| 307 | +#ifdef _WIN32 |
| 308 | + wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename); |
| 309 | + int rc = _waccess(zMbcs, flags); |
| 305 | 310 | fossil_mbcs_free(zMbcs); |
| 311 | +#else |
| 312 | + int rc = access(zFilename, flags); |
| 313 | +#endif |
| 306 | 314 | return rc; |
| 307 | 315 | } |
| 308 | 316 | |
| 309 | 317 | /* |
| 310 | 318 | ** Find an unused filename similar to zBase with zSuffix appended. |
| | @@ -389,13 +397,17 @@ |
| 389 | 397 | |
| 390 | 398 | /* |
| 391 | 399 | ** Delete a file. |
| 392 | 400 | */ |
| 393 | 401 | void file_delete(const char *zFilename){ |
| 394 | | - char *z = fossil_utf8_to_mbcs(zFilename); |
| 395 | | - unlink(z); |
| 402 | +#ifdef _WIN32 |
| 403 | + wchar_t *z = fossil_utf8_to_unicode(zFilename); |
| 404 | + _wunlink(z); |
| 396 | 405 | fossil_mbcs_free(z); |
| 406 | +#else |
| 407 | + unlink(zFilename); |
| 408 | +#endif |
| 397 | 409 | } |
| 398 | 410 | |
| 399 | 411 | /* |
| 400 | 412 | ** Create the directory named in the argument, if it does not already |
| 401 | 413 | ** exist. If forceFlag is 1, delete any prior non-directory object |
| | @@ -561,24 +573,24 @@ |
| 561 | 573 | } |
| 562 | 574 | |
| 563 | 575 | /* |
| 564 | 576 | ** Get the current working directory. |
| 565 | 577 | ** |
| 566 | | -** On windows, the name is converted from MBCS to UTF8 and all '\\' |
| 578 | +** On windows, the name is converted from unicode to UTF8 and all '\\' |
| 567 | 579 | ** characters are converted to '/'. No conversions are needed on |
| 568 | 580 | ** unix. |
| 569 | 581 | */ |
| 570 | 582 | void file_getcwd(char *zBuf, int nBuf){ |
| 571 | 583 | #ifdef _WIN32 |
| 572 | 584 | char *zPwdUtf8; |
| 573 | 585 | int nPwd; |
| 574 | 586 | int i; |
| 575 | | - char zPwd[2000]; |
| 576 | | - if( getcwd(zPwd, sizeof(zPwd)-1)==0 ){ |
| 587 | + wchar_t zPwd[2000]; |
| 588 | + if( _wgetcwd(zPwd, sizeof(zPwd)-1)==0 ){ |
| 577 | 589 | fossil_fatal("cannot find the current working directory."); |
| 578 | 590 | } |
| 579 | | - zPwdUtf8 = fossil_mbcs_to_utf8(zPwd); |
| 591 | + zPwdUtf8 = fossil_unicode_to_utf8(zPwd); |
| 580 | 592 | nPwd = strlen(zPwdUtf8); |
| 581 | 593 | if( nPwd > nBuf-1 ){ |
| 582 | 594 | fossil_fatal("pwd too big: max %d\n", nBuf-1); |
| 583 | 595 | } |
| 584 | 596 | for(i=0; zPwdUtf8[i]; i++) if( zPwdUtf8[i]=='\\' ) zPwdUtf8[i] = '/'; |
| | @@ -928,14 +940,14 @@ |
| 928 | 940 | unsigned int i, j; |
| 929 | 941 | const char *zDir = "."; |
| 930 | 942 | int cnt = 0; |
| 931 | 943 | |
| 932 | 944 | #if defined(_WIN32) |
| 933 | | - char zTmpPath[MAX_PATH]; |
| 945 | + wchar_t zTmpPath[MAX_PATH]; |
| 934 | 946 | |
| 935 | | - if( GetTempPath(sizeof(zTmpPath), zTmpPath) ){ |
| 936 | | - azDirs[0] = zTmpPath; |
| 947 | + if( GetTempPathW(MAX_PATH, zTmpPath) ){ |
| 948 | + azDirs[0] = fossil_unicode_to_utf8(zTmpPath); |
| 937 | 949 | } |
| 938 | 950 | |
| 939 | 951 | azDirs[1] = fossil_getenv("TEMP"); |
| 940 | 952 | azDirs[2] = fossil_getenv("TMP"); |
| 941 | 953 | #endif |
| | @@ -1014,10 +1026,29 @@ |
| 1014 | 1026 | return sqlite3_win32_mbcs_to_utf8(zMbcs); |
| 1015 | 1027 | #else |
| 1016 | 1028 | return (char*)zMbcs; /* No-op on unix */ |
| 1017 | 1029 | #endif |
| 1018 | 1030 | } |
| 1031 | + |
| 1032 | +/* |
| 1033 | +** Translate Unicode to UTF8. Return a pointer to the translated text. |
| 1034 | +** Call fossil_mbcs_free() to deallocate any memory used to store the |
| 1035 | +** returned pointer when done. |
| 1036 | +*/ |
| 1037 | +char *fossil_unicode_to_utf8(const void *zUnicode){ |
| 1038 | +#ifdef _WIN32 |
| 1039 | + int nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0); |
| 1040 | + char *zUtf = sqlite3_malloc( nByte ); |
| 1041 | + if( zUtf==0 ){ |
| 1042 | + return 0; |
| 1043 | + } |
| 1044 | + WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, zUtf, nByte, 0, 0); |
| 1045 | + return zUtf; |
| 1046 | +#else |
| 1047 | + return (char *)zUnicode; /* No-op on unix */ |
| 1048 | +#endif |
| 1049 | +} |
| 1019 | 1050 | |
| 1020 | 1051 | /* |
| 1021 | 1052 | ** Translate UTF8 to MBCS for use in system calls. Return a pointer to the |
| 1022 | 1053 | ** translated text.. Call fossil_mbcs_free() to deallocate any memory |
| 1023 | 1054 | ** used to store the returned pointer when done. |
| | @@ -1028,18 +1059,41 @@ |
| 1028 | 1059 | return sqlite3_win32_utf8_to_mbcs(zUtf8); |
| 1029 | 1060 | #else |
| 1030 | 1061 | return (char*)zUtf8; /* No-op on unix */ |
| 1031 | 1062 | #endif |
| 1032 | 1063 | } |
| 1064 | + |
| 1065 | +/* |
| 1066 | +** Translate UTF8 to unicode for use in system calls. Return a pointer to the |
| 1067 | +** translated text.. Call fossil_mbcs_free() to deallocate any memory |
| 1068 | +** used to store the returned pointer when done. |
| 1069 | +*/ |
| 1070 | +void *fossil_utf8_to_unicode(const char *zUtf8){ |
| 1071 | +#ifdef _WIN32 |
| 1072 | + int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0); |
| 1073 | + wchar_t *zUnicode = sqlite3_malloc( nByte * 2 ); |
| 1074 | + if( zUnicode==0 ){ |
| 1075 | + return 0; |
| 1076 | + } |
| 1077 | + MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nByte); |
| 1078 | + return zUnicode; |
| 1079 | +#else |
| 1080 | + return (void *)zUtf8; /* No-op on unix */ |
| 1081 | +#endif |
| 1082 | +} |
| 1033 | 1083 | |
| 1034 | 1084 | /* |
| 1035 | 1085 | ** Return the value of an environment variable as UTF8. |
| 1036 | 1086 | */ |
| 1037 | 1087 | char *fossil_getenv(const char *zName){ |
| 1038 | | - char *zValue = getenv(zName); |
| 1039 | 1088 | #ifdef _WIN32 |
| 1040 | | - if( zValue ) zValue = fossil_mbcs_to_utf8(zValue); |
| 1089 | + wchar_t *uName = fossil_utf8_to_unicode(zName); |
| 1090 | + void *zValue = _wgetenv(uName); |
| 1091 | + fossil_mbcs_free(uName); |
| 1092 | + if( zValue ) zValue = fossil_unicode_to_utf8(zValue); |
| 1093 | +#else |
| 1094 | + char *zValue = getenv(zName); |
| 1041 | 1095 | #endif |
| 1042 | 1096 | return zValue; |
| 1043 | 1097 | } |
| 1044 | 1098 | |
| 1045 | 1099 | /* |
| | @@ -1085,11 +1139,11 @@ |
| 1085 | 1139 | |
| 1086 | 1140 | /* |
| 1087 | 1141 | ** Translate MBCS to UTF8. Return a pointer. Call fossil_mbcs_free() |
| 1088 | 1142 | ** to deallocate any memory used to store the returned pointer when done. |
| 1089 | 1143 | */ |
| 1090 | | -void fossil_mbcs_free(char *zOld){ |
| 1144 | +void fossil_mbcs_free(void *zOld){ |
| 1091 | 1145 | #ifdef _WIN32 |
| 1092 | 1146 | extern void sqlite3_free(void*); |
| 1093 | 1147 | sqlite3_free(zOld); |
| 1094 | 1148 | #else |
| 1095 | 1149 | /* No-op on unix */ |
| | @@ -1098,10 +1152,16 @@ |
| 1098 | 1152 | |
| 1099 | 1153 | /* |
| 1100 | 1154 | ** Like fopen() but always takes a UTF8 argument. |
| 1101 | 1155 | */ |
| 1102 | 1156 | FILE *fossil_fopen(const char *zName, const char *zMode){ |
| 1103 | | - char *zMbcs = fossil_utf8_to_mbcs(zName); |
| 1104 | | - FILE *f = fopen(zMbcs, zMode); |
| 1105 | | - fossil_mbcs_free(zMbcs); |
| 1157 | +#ifdef _WIN32 |
| 1158 | + wchar_t *uMode = fossil_utf8_to_unicode(zMode); |
| 1159 | + wchar_t *uName = fossil_utf8_to_unicode(zName); |
| 1160 | + FILE *f = _wfopen(uName, uMode); |
| 1161 | + fossil_mbcs_free(uName); |
| 1162 | + fossil_mbcs_free(uMode); |
| 1163 | +#else |
| 1164 | + FILE *f = fopen(zName, zMode); |
| 1165 | +#endif |
| 1106 | 1166 | return f; |
| 1107 | 1167 | } |
| 1108 | 1168 | |