Fossil SCM

Split off in separate functions <p>Still experimental, but starts looking better

jan.nijtmans 2012-11-21 09:12 ticket-d17d6e5b17
Commit b59dc078187891db8420f2dcf84f5a8728364307
3 files changed +68 -35 +2 -2 +2 -2
+68 -35
--- src/file.c
+++ src/file.c
@@ -70,11 +70,11 @@
7070
}else{
7171
return stat(zFilename, buf);
7272
}
7373
#else
7474
int rc = 0;
75
- wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename);
75
+ wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
7676
rc = _wstati64(zMbcs, buf);
7777
fossil_mbcs_free(zMbcs);
7878
return rc;
7979
#endif
8080
}
@@ -301,11 +301,11 @@
301301
/*
302302
** Wrapper around the access() system call.
303303
*/
304304
int file_access(const char *zFilename, int flags){
305305
#ifdef _WIN32
306
- wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename);
306
+ wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
307307
int rc = _waccess(zMbcs, flags);
308308
fossil_mbcs_free(zMbcs);
309309
#else
310310
int rc = access(zFilename, flags);
311311
#endif
@@ -403,11 +403,11 @@
403403
tv[0].tv_sec = newMTime;
404404
tv[1].tv_sec = newMTime;
405405
utimes(zFilename, tv);
406406
#else
407407
struct _utimbuf tb;
408
- wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename);
408
+ wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
409409
tb.actime = newMTime;
410410
tb.modtime = newMTime;
411411
_wutime(zMbcs, &tb);
412412
fossil_mbcs_free(zMbcs);
413413
#endif
@@ -439,11 +439,11 @@
439439
/*
440440
** Delete a file.
441441
*/
442442
void file_delete(const char *zFilename){
443443
#ifdef _WIN32
444
- wchar_t *z = fossil_utf8_to_unicode(zFilename);
444
+ wchar_t *z = fossil_utf8_to_filename(zFilename);
445445
_wunlink(z);
446446
fossil_mbcs_free(z);
447447
#else
448448
unlink(zFilename);
449449
#endif
@@ -463,11 +463,11 @@
463463
file_delete(zName);
464464
}
465465
if( rc!=1 ){
466466
#if defined(_WIN32)
467467
int rc;
468
- wchar_t *zMbcs = fossil_utf8_to_unicode(zName);
468
+ wchar_t *zMbcs = fossil_utf8_to_filename(zName);
469469
rc = _wmkdir(zMbcs);
470470
fossil_mbcs_free(zMbcs);
471471
return rc;
472472
#else
473473
return mkdir(zName, 0755);
@@ -481,11 +481,11 @@
481481
** a file in a repository. Valid filenames follow all of the
482482
** following rules:
483483
**
484484
** * Does not begin with "/"
485485
** * Does not contain any path element named "." or ".."
486
-** * Does not contain any of these characters in the path: "\:"
486
+** * Does not contain any of these characters in the path: "\*[]?"
487487
** * Does not end with "/".
488488
** * Does not contain two or more "/" characters in a row.
489489
** * Contains at least one character
490490
*/
491491
int file_is_simple_pathname(const char *z){
@@ -495,11 +495,11 @@
495495
if( c=='.' ){
496496
if( z[1]=='/' || z[1]==0 ) return 0;
497497
if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
498498
}
499499
for(i=0; (c=z[i])!=0; i++){
500
- if( c=='\\' || c==':' ){
500
+ if( c=='\\' || c=='*' || c=='[' || c==']' || c=='?' ){
501501
return 0;
502502
}
503503
if( c=='/' ){
504504
if( z[i+1]=='/' ) return 0;
505505
if( z[i+1]=='.' ){
@@ -1089,38 +1089,53 @@
10891089
10901090
/*
10911091
** Translate Unicode to UTF8. Return a pointer to the translated text.
10921092
** Call fossil_mbcs_free() to deallocate any memory used to store the
10931093
** returned pointer when done.
1094
+*/
1095
+char *fossil_unicode_to_utf8(const void *zUnicode){
1096
+#ifdef _WIN32
1097
+ int nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0);
1098
+ char *zUtf = sqlite3_malloc( nByte );
1099
+ if( zUtf==0 ){
1100
+ return 0;
1101
+ }
1102
+ WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, zUtf, nByte, 0, 0);
1103
+ return zUtf;
1104
+#else
1105
+ return (char *)zUnicode; /* No-op on unix */
1106
+#endif
1107
+}
1108
+
1109
+/*
1110
+** Translate Unicode (filename) to UTF8. Return a pointer to the
1111
+** translated text. Call fossil_mbcs_free() to deallocate any
1112
+** memory used to store the returned pointer when done.
10941113
**
1095
-** On Windows, characters in the range U+FF01 to U+FF7F (private use area)
1114
+** On Windows, characters in the range U+F001 to U+F07F (private use area)
10961115
** are translated in ASCII characters in the range U+0001 - U+007F. The
10971116
** only place they can come from are filenames using Cygwin's trick
10981117
** to circumvent invalid characters in filenames.
10991118
** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
11001119
** This way, fossil will work nicely together with the cygwin shell
11011120
** handling those filenames. On other shells, the generated filename
11021121
** might not be as expected, but apart from that nothing goes wrong.
11031122
*/
1104
-char *fossil_unicode_to_utf8(void *zUnicode){
1123
+char *fossil_filename_to_utf8(void *zUnicode){
11051124
#ifdef _WIN32
1106
- int nByte = 0;
1107
- char *zUtf;
11081125
WCHAR *wUnicode = zUnicode;
11091126
while( *wUnicode != 0 ){
1110
- if ( (*wUnicode > 0xF000) && (*wUnicode <= 0xF07F) ){
1111
- *wUnicode &= 0x7F;
1127
+ if ( (*wUnicode & 0xFF80) == 0xF000 ){
1128
+ WCHAR converted = (*wUnicode & 0x7F);
1129
+ /* Only really convert it when the resulting char is in the given range*/
1130
+ if ( (converted < 32) || wcschr(L"\"*<>?|:", converted) ){
1131
+ *wUnicode = converted;
1132
+ }
11121133
}
11131134
++wUnicode;
11141135
}
1115
- nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0);
1116
- zUtf = sqlite3_malloc( nByte );
1117
- if( zUtf==0 ){
1118
- return 0;
1119
- }
1120
- WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, zUtf, nByte, 0, 0);
1121
- return zUtf;
1136
+ return fossil_unicode_to_utf8(zUnicode);
11221137
#else
11231138
return (char *)zUnicode; /* No-op on unix */
11241139
#endif
11251140
}
11261141
@@ -1140,34 +1155,52 @@
11401155
11411156
/*
11421157
** Translate UTF8 to unicode for use in system calls. Return a pointer to the
11431158
** translated text.. Call fossil_mbcs_free() to deallocate any memory
11441159
** used to store the returned pointer when done.
1160
+*/
1161
+void *fossil_utf8_to_unicode(const char *zUtf8){
1162
+#ifdef _WIN32
1163
+ int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
1164
+ wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
1165
+ if( zUnicode==0 ){
1166
+ return 0;
1167
+ }
1168
+ MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nByte);
1169
+
1170
+ return zUnicode;
1171
+#else
1172
+ return (void *)zUtf8; /* No-op on unix */
1173
+#endif
1174
+}
1175
+
1176
+/*
1177
+** Translate UTF8 to unicode for use in filename translations.
1178
+** Return a pointer to the translated text.. Call fossil_mbcs_free()
1179
+** to deallocate any memory used to store the returned pointer when done.
11451180
**
1146
-** On Windows, characters in the range U+001 to U+0031 and the
1181
+** On Windows, characters in the range U+0001 to U+0031 and the
11471182
** characters '"', '*', ':', '<', '>', '?', '|' and '\\' are invalid
11481183
** to be used. Therefore, translated those to characters in the
1149
-** (private use area), in the range U+0001 - U+007F, so those
1184
+** (private use area), in the range U+F001 - U+F07F, so those
11501185
** characters never arrive in any Windows API. The filenames might
11511186
** look strange in Windows explorer, but in the cygwin shell
11521187
** everything looks as expected.
11531188
**
11541189
** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
11551190
**
11561191
*/
1157
-void *fossil_utf8_to_unicode(const char *zUtf8){
1158
-#ifdef _WIN32
1159
- int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
1160
- wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
1161
- wchar_t *wUnicode;
1162
- if( zUnicode==0 ){
1163
- return 0;
1164
- }
1165
- MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nByte);
1166
- wUnicode = zUnicode;
1167
- while( --nByte > 0){
1168
- if ( (*wUnicode < 32) || wcschr(L"\"*<>?|", *wUnicode) ){
1192
+void *fossil_utf8_to_filename(const char *zUtf8){
1193
+#ifdef _WIN32
1194
+ WCHAR *zUnicode = fossil_utf8_to_unicode(zUtf8);
1195
+ WCHAR *wUnicode = zUnicode;
1196
+ /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
1197
+ if ( file_is_absolute_path(zUtf8) ){
1198
+ wUnicode += 3;
1199
+ }
1200
+ while( *wUnicode != '\0' ){
1201
+ if ( (*wUnicode < 32) || wcschr(L"\"*<>?|:", *wUnicode) ){
11691202
*wUnicode |= 0xF000;
11701203
}
11711204
++wUnicode;
11721205
}
11731206
@@ -1248,14 +1281,14 @@
12481281
** Like fopen() but always takes a UTF8 argument.
12491282
*/
12501283
FILE *fossil_fopen(const char *zName, const char *zMode){
12511284
#ifdef _WIN32
12521285
wchar_t *uMode = fossil_utf8_to_unicode(zMode);
1253
- wchar_t *uName = fossil_utf8_to_unicode(zName);
1286
+ wchar_t *uName = fossil_utf8_to_filename(zName);
12541287
FILE *f = _wfopen(uName, uMode);
12551288
fossil_mbcs_free(uName);
12561289
fossil_mbcs_free(uMode);
12571290
#else
12581291
FILE *f = fopen(zName, zMode);
12591292
#endif
12601293
return f;
12611294
}
12621295
--- src/file.c
+++ src/file.c
@@ -70,11 +70,11 @@
70 }else{
71 return stat(zFilename, buf);
72 }
73 #else
74 int rc = 0;
75 wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename);
76 rc = _wstati64(zMbcs, buf);
77 fossil_mbcs_free(zMbcs);
78 return rc;
79 #endif
80 }
@@ -301,11 +301,11 @@
301 /*
302 ** Wrapper around the access() system call.
303 */
304 int file_access(const char *zFilename, int flags){
305 #ifdef _WIN32
306 wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename);
307 int rc = _waccess(zMbcs, flags);
308 fossil_mbcs_free(zMbcs);
309 #else
310 int rc = access(zFilename, flags);
311 #endif
@@ -403,11 +403,11 @@
403 tv[0].tv_sec = newMTime;
404 tv[1].tv_sec = newMTime;
405 utimes(zFilename, tv);
406 #else
407 struct _utimbuf tb;
408 wchar_t *zMbcs = fossil_utf8_to_unicode(zFilename);
409 tb.actime = newMTime;
410 tb.modtime = newMTime;
411 _wutime(zMbcs, &tb);
412 fossil_mbcs_free(zMbcs);
413 #endif
@@ -439,11 +439,11 @@
439 /*
440 ** Delete a file.
441 */
442 void file_delete(const char *zFilename){
443 #ifdef _WIN32
444 wchar_t *z = fossil_utf8_to_unicode(zFilename);
445 _wunlink(z);
446 fossil_mbcs_free(z);
447 #else
448 unlink(zFilename);
449 #endif
@@ -463,11 +463,11 @@
463 file_delete(zName);
464 }
465 if( rc!=1 ){
466 #if defined(_WIN32)
467 int rc;
468 wchar_t *zMbcs = fossil_utf8_to_unicode(zName);
469 rc = _wmkdir(zMbcs);
470 fossil_mbcs_free(zMbcs);
471 return rc;
472 #else
473 return mkdir(zName, 0755);
@@ -481,11 +481,11 @@
481 ** a file in a repository. Valid filenames follow all of the
482 ** following rules:
483 **
484 ** * Does not begin with "/"
485 ** * Does not contain any path element named "." or ".."
486 ** * Does not contain any of these characters in the path: "\:"
487 ** * Does not end with "/".
488 ** * Does not contain two or more "/" characters in a row.
489 ** * Contains at least one character
490 */
491 int file_is_simple_pathname(const char *z){
@@ -495,11 +495,11 @@
495 if( c=='.' ){
496 if( z[1]=='/' || z[1]==0 ) return 0;
497 if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
498 }
499 for(i=0; (c=z[i])!=0; i++){
500 if( c=='\\' || c==':' ){
501 return 0;
502 }
503 if( c=='/' ){
504 if( z[i+1]=='/' ) return 0;
505 if( z[i+1]=='.' ){
@@ -1089,38 +1089,53 @@
1089
1090 /*
1091 ** Translate Unicode to UTF8. Return a pointer to the translated text.
1092 ** Call fossil_mbcs_free() to deallocate any memory used to store the
1093 ** returned pointer when done.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1094 **
1095 ** On Windows, characters in the range U+FF01 to U+FF7F (private use area)
1096 ** are translated in ASCII characters in the range U+0001 - U+007F. The
1097 ** only place they can come from are filenames using Cygwin's trick
1098 ** to circumvent invalid characters in filenames.
1099 ** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
1100 ** This way, fossil will work nicely together with the cygwin shell
1101 ** handling those filenames. On other shells, the generated filename
1102 ** might not be as expected, but apart from that nothing goes wrong.
1103 */
1104 char *fossil_unicode_to_utf8(void *zUnicode){
1105 #ifdef _WIN32
1106 int nByte = 0;
1107 char *zUtf;
1108 WCHAR *wUnicode = zUnicode;
1109 while( *wUnicode != 0 ){
1110 if ( (*wUnicode > 0xF000) && (*wUnicode <= 0xF07F) ){
1111 *wUnicode &= 0x7F;
 
 
 
 
1112 }
1113 ++wUnicode;
1114 }
1115 nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0);
1116 zUtf = sqlite3_malloc( nByte );
1117 if( zUtf==0 ){
1118 return 0;
1119 }
1120 WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, zUtf, nByte, 0, 0);
1121 return zUtf;
1122 #else
1123 return (char *)zUnicode; /* No-op on unix */
1124 #endif
1125 }
1126
@@ -1140,34 +1155,52 @@
1140
1141 /*
1142 ** Translate UTF8 to unicode for use in system calls. Return a pointer to the
1143 ** translated text.. Call fossil_mbcs_free() to deallocate any memory
1144 ** used to store the returned pointer when done.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1145 **
1146 ** On Windows, characters in the range U+001 to U+0031 and the
1147 ** characters '"', '*', ':', '<', '>', '?', '|' and '\\' are invalid
1148 ** to be used. Therefore, translated those to characters in the
1149 ** (private use area), in the range U+0001 - U+007F, so those
1150 ** characters never arrive in any Windows API. The filenames might
1151 ** look strange in Windows explorer, but in the cygwin shell
1152 ** everything looks as expected.
1153 **
1154 ** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
1155 **
1156 */
1157 void *fossil_utf8_to_unicode(const char *zUtf8){
1158 #ifdef _WIN32
1159 int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
1160 wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
1161 wchar_t *wUnicode;
1162 if( zUnicode==0 ){
1163 return 0;
1164 }
1165 MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nByte);
1166 wUnicode = zUnicode;
1167 while( --nByte > 0){
1168 if ( (*wUnicode < 32) || wcschr(L"\"*<>?|", *wUnicode) ){
1169 *wUnicode |= 0xF000;
1170 }
1171 ++wUnicode;
1172 }
1173
@@ -1248,14 +1281,14 @@
1248 ** Like fopen() but always takes a UTF8 argument.
1249 */
1250 FILE *fossil_fopen(const char *zName, const char *zMode){
1251 #ifdef _WIN32
1252 wchar_t *uMode = fossil_utf8_to_unicode(zMode);
1253 wchar_t *uName = fossil_utf8_to_unicode(zName);
1254 FILE *f = _wfopen(uName, uMode);
1255 fossil_mbcs_free(uName);
1256 fossil_mbcs_free(uMode);
1257 #else
1258 FILE *f = fopen(zName, zMode);
1259 #endif
1260 return f;
1261 }
1262
--- src/file.c
+++ src/file.c
@@ -70,11 +70,11 @@
70 }else{
71 return stat(zFilename, buf);
72 }
73 #else
74 int rc = 0;
75 wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
76 rc = _wstati64(zMbcs, buf);
77 fossil_mbcs_free(zMbcs);
78 return rc;
79 #endif
80 }
@@ -301,11 +301,11 @@
301 /*
302 ** Wrapper around the access() system call.
303 */
304 int file_access(const char *zFilename, int flags){
305 #ifdef _WIN32
306 wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
307 int rc = _waccess(zMbcs, flags);
308 fossil_mbcs_free(zMbcs);
309 #else
310 int rc = access(zFilename, flags);
311 #endif
@@ -403,11 +403,11 @@
403 tv[0].tv_sec = newMTime;
404 tv[1].tv_sec = newMTime;
405 utimes(zFilename, tv);
406 #else
407 struct _utimbuf tb;
408 wchar_t *zMbcs = fossil_utf8_to_filename(zFilename);
409 tb.actime = newMTime;
410 tb.modtime = newMTime;
411 _wutime(zMbcs, &tb);
412 fossil_mbcs_free(zMbcs);
413 #endif
@@ -439,11 +439,11 @@
439 /*
440 ** Delete a file.
441 */
442 void file_delete(const char *zFilename){
443 #ifdef _WIN32
444 wchar_t *z = fossil_utf8_to_filename(zFilename);
445 _wunlink(z);
446 fossil_mbcs_free(z);
447 #else
448 unlink(zFilename);
449 #endif
@@ -463,11 +463,11 @@
463 file_delete(zName);
464 }
465 if( rc!=1 ){
466 #if defined(_WIN32)
467 int rc;
468 wchar_t *zMbcs = fossil_utf8_to_filename(zName);
469 rc = _wmkdir(zMbcs);
470 fossil_mbcs_free(zMbcs);
471 return rc;
472 #else
473 return mkdir(zName, 0755);
@@ -481,11 +481,11 @@
481 ** a file in a repository. Valid filenames follow all of the
482 ** following rules:
483 **
484 ** * Does not begin with "/"
485 ** * Does not contain any path element named "." or ".."
486 ** * Does not contain any of these characters in the path: "\*[]?"
487 ** * Does not end with "/".
488 ** * Does not contain two or more "/" characters in a row.
489 ** * Contains at least one character
490 */
491 int file_is_simple_pathname(const char *z){
@@ -495,11 +495,11 @@
495 if( c=='.' ){
496 if( z[1]=='/' || z[1]==0 ) return 0;
497 if( z[1]=='.' && (z[2]=='/' || z[2]==0) ) return 0;
498 }
499 for(i=0; (c=z[i])!=0; i++){
500 if( c=='\\' || c=='*' || c=='[' || c==']' || c=='?' ){
501 return 0;
502 }
503 if( c=='/' ){
504 if( z[i+1]=='/' ) return 0;
505 if( z[i+1]=='.' ){
@@ -1089,38 +1089,53 @@
1089
1090 /*
1091 ** Translate Unicode to UTF8. Return a pointer to the translated text.
1092 ** Call fossil_mbcs_free() to deallocate any memory used to store the
1093 ** returned pointer when done.
1094 */
1095 char *fossil_unicode_to_utf8(const void *zUnicode){
1096 #ifdef _WIN32
1097 int nByte = WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, 0, 0, 0, 0);
1098 char *zUtf = sqlite3_malloc( nByte );
1099 if( zUtf==0 ){
1100 return 0;
1101 }
1102 WideCharToMultiByte(CP_UTF8, 0, zUnicode, -1, zUtf, nByte, 0, 0);
1103 return zUtf;
1104 #else
1105 return (char *)zUnicode; /* No-op on unix */
1106 #endif
1107 }
1108
1109 /*
1110 ** Translate Unicode (filename) to UTF8. Return a pointer to the
1111 ** translated text. Call fossil_mbcs_free() to deallocate any
1112 ** memory used to store the returned pointer when done.
1113 **
1114 ** On Windows, characters in the range U+F001 to U+F07F (private use area)
1115 ** are translated in ASCII characters in the range U+0001 - U+007F. The
1116 ** only place they can come from are filenames using Cygwin's trick
1117 ** to circumvent invalid characters in filenames.
1118 ** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
1119 ** This way, fossil will work nicely together with the cygwin shell
1120 ** handling those filenames. On other shells, the generated filename
1121 ** might not be as expected, but apart from that nothing goes wrong.
1122 */
1123 char *fossil_filename_to_utf8(void *zUnicode){
1124 #ifdef _WIN32
 
 
1125 WCHAR *wUnicode = zUnicode;
1126 while( *wUnicode != 0 ){
1127 if ( (*wUnicode & 0xFF80) == 0xF000 ){
1128 WCHAR converted = (*wUnicode & 0x7F);
1129 /* Only really convert it when the resulting char is in the given range*/
1130 if ( (converted < 32) || wcschr(L"\"*<>?|:", converted) ){
1131 *wUnicode = converted;
1132 }
1133 }
1134 ++wUnicode;
1135 }
1136 return fossil_unicode_to_utf8(zUnicode);
 
 
 
 
 
 
1137 #else
1138 return (char *)zUnicode; /* No-op on unix */
1139 #endif
1140 }
1141
@@ -1140,34 +1155,52 @@
1155
1156 /*
1157 ** Translate UTF8 to unicode for use in system calls. Return a pointer to the
1158 ** translated text.. Call fossil_mbcs_free() to deallocate any memory
1159 ** used to store the returned pointer when done.
1160 */
1161 void *fossil_utf8_to_unicode(const char *zUtf8){
1162 #ifdef _WIN32
1163 int nByte = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
1164 wchar_t *zUnicode = sqlite3_malloc( nByte * 2 );
1165 if( zUnicode==0 ){
1166 return 0;
1167 }
1168 MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nByte);
1169
1170 return zUnicode;
1171 #else
1172 return (void *)zUtf8; /* No-op on unix */
1173 #endif
1174 }
1175
1176 /*
1177 ** Translate UTF8 to unicode for use in filename translations.
1178 ** Return a pointer to the translated text.. Call fossil_mbcs_free()
1179 ** to deallocate any memory used to store the returned pointer when done.
1180 **
1181 ** On Windows, characters in the range U+0001 to U+0031 and the
1182 ** characters '"', '*', ':', '<', '>', '?', '|' and '\\' are invalid
1183 ** to be used. Therefore, translated those to characters in the
1184 ** (private use area), in the range U+F001 - U+F07F, so those
1185 ** characters never arrive in any Windows API. The filenames might
1186 ** look strange in Windows explorer, but in the cygwin shell
1187 ** everything looks as expected.
1188 **
1189 ** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
1190 **
1191 */
1192 void *fossil_utf8_to_filename(const char *zUtf8){
1193 #ifdef _WIN32
1194 WCHAR *zUnicode = fossil_utf8_to_unicode(zUtf8);
1195 WCHAR *wUnicode = zUnicode;
1196 /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
1197 if ( file_is_absolute_path(zUtf8) ){
1198 wUnicode += 3;
1199 }
1200 while( *wUnicode != '\0' ){
1201 if ( (*wUnicode < 32) || wcschr(L"\"*<>?|:", *wUnicode) ){
 
 
1202 *wUnicode |= 0xF000;
1203 }
1204 ++wUnicode;
1205 }
1206
@@ -1248,14 +1281,14 @@
1281 ** Like fopen() but always takes a UTF8 argument.
1282 */
1283 FILE *fossil_fopen(const char *zName, const char *zMode){
1284 #ifdef _WIN32
1285 wchar_t *uMode = fossil_utf8_to_unicode(zMode);
1286 wchar_t *uName = fossil_utf8_to_filename(zName);
1287 FILE *f = _wfopen(uName, uMode);
1288 fossil_mbcs_free(uName);
1289 fossil_mbcs_free(uMode);
1290 #else
1291 FILE *f = fopen(zName, zMode);
1292 #endif
1293 return f;
1294 }
1295
+2 -2
--- src/rebuild.c
+++ src/rebuild.c
@@ -833,21 +833,21 @@
833833
Blob aContent; /* content of the just read artifact */
834834
static int nFileRead = 0;
835835
void *zUnicodePath;
836836
char *zUtf8Name;
837837
838
- zUnicodePath = fossil_utf8_to_unicode(zPath);
838
+ zUnicodePath = fossil_utf8_to_filename(zPath);
839839
d = opendir(zUnicodePath);
840840
if( d ){
841841
while( (pEntry=readdir(d))!=0 ){
842842
Blob path;
843843
char *zSubpath;
844844
845845
if( pEntry->d_name[0]=='.' ){
846846
continue;
847847
}
848
- zUtf8Name = fossil_unicode_to_utf8(pEntry->d_name);
848
+ zUtf8Name = fossil_filename_to_utf8(pEntry->d_name);
849849
zSubpath = mprintf("%s/%s", zPath, zUtf8Name);
850850
fossil_mbcs_free(zUtf8Name);
851851
if( file_isdir(zSubpath)==1 ){
852852
recon_read_dir(zSubpath);
853853
}
854854
--- src/rebuild.c
+++ src/rebuild.c
@@ -833,21 +833,21 @@
833 Blob aContent; /* content of the just read artifact */
834 static int nFileRead = 0;
835 void *zUnicodePath;
836 char *zUtf8Name;
837
838 zUnicodePath = fossil_utf8_to_unicode(zPath);
839 d = opendir(zUnicodePath);
840 if( d ){
841 while( (pEntry=readdir(d))!=0 ){
842 Blob path;
843 char *zSubpath;
844
845 if( pEntry->d_name[0]=='.' ){
846 continue;
847 }
848 zUtf8Name = fossil_unicode_to_utf8(pEntry->d_name);
849 zSubpath = mprintf("%s/%s", zPath, zUtf8Name);
850 fossil_mbcs_free(zUtf8Name);
851 if( file_isdir(zSubpath)==1 ){
852 recon_read_dir(zSubpath);
853 }
854
--- src/rebuild.c
+++ src/rebuild.c
@@ -833,21 +833,21 @@
833 Blob aContent; /* content of the just read artifact */
834 static int nFileRead = 0;
835 void *zUnicodePath;
836 char *zUtf8Name;
837
838 zUnicodePath = fossil_utf8_to_filename(zPath);
839 d = opendir(zUnicodePath);
840 if( d ){
841 while( (pEntry=readdir(d))!=0 ){
842 Blob path;
843 char *zSubpath;
844
845 if( pEntry->d_name[0]=='.' ){
846 continue;
847 }
848 zUtf8Name = fossil_filename_to_utf8(pEntry->d_name);
849 zSubpath = mprintf("%s/%s", zPath, zUtf8Name);
850 fossil_mbcs_free(zUtf8Name);
851 if( file_isdir(zSubpath)==1 ){
852 recon_read_dir(zSubpath);
853 }
854
+2 -2
--- src/vfile.c
+++ src/vfile.c
@@ -459,11 +459,11 @@
459459
);
460460
}
461461
depth++;
462462
463463
zDir = blob_str(pPath);
464
- zMbcs = fossil_utf8_to_unicode(zDir);
464
+ zMbcs = fossil_utf8_to_filename(zDir);
465465
d = opendir(zMbcs);
466466
if( d ){
467467
while( (pEntry=readdir(d))!=0 ){
468468
char *zPath;
469469
char *zUtf8;
@@ -470,11 +470,11 @@
470470
if( pEntry->d_name[0]=='.' ){
471471
if( (scanFlags & SCAN_ALL)==0 ) continue;
472472
if( pEntry->d_name[1]==0 ) continue;
473473
if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue;
474474
}
475
- zUtf8 = fossil_unicode_to_utf8(pEntry->d_name);
475
+ zUtf8 = fossil_filename_to_utf8(pEntry->d_name);
476476
blob_appendf(pPath, "/%s", zUtf8);
477477
zPath = blob_str(pPath);
478478
if( glob_match(pIgnore, &zPath[nPrefix+1]) ){
479479
/* do nothing */
480480
}else if( file_wd_isdir(zPath)==1 ){
481481
--- src/vfile.c
+++ src/vfile.c
@@ -459,11 +459,11 @@
459 );
460 }
461 depth++;
462
463 zDir = blob_str(pPath);
464 zMbcs = fossil_utf8_to_unicode(zDir);
465 d = opendir(zMbcs);
466 if( d ){
467 while( (pEntry=readdir(d))!=0 ){
468 char *zPath;
469 char *zUtf8;
@@ -470,11 +470,11 @@
470 if( pEntry->d_name[0]=='.' ){
471 if( (scanFlags & SCAN_ALL)==0 ) continue;
472 if( pEntry->d_name[1]==0 ) continue;
473 if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue;
474 }
475 zUtf8 = fossil_unicode_to_utf8(pEntry->d_name);
476 blob_appendf(pPath, "/%s", zUtf8);
477 zPath = blob_str(pPath);
478 if( glob_match(pIgnore, &zPath[nPrefix+1]) ){
479 /* do nothing */
480 }else if( file_wd_isdir(zPath)==1 ){
481
--- src/vfile.c
+++ src/vfile.c
@@ -459,11 +459,11 @@
459 );
460 }
461 depth++;
462
463 zDir = blob_str(pPath);
464 zMbcs = fossil_utf8_to_filename(zDir);
465 d = opendir(zMbcs);
466 if( d ){
467 while( (pEntry=readdir(d))!=0 ){
468 char *zPath;
469 char *zUtf8;
@@ -470,11 +470,11 @@
470 if( pEntry->d_name[0]=='.' ){
471 if( (scanFlags & SCAN_ALL)==0 ) continue;
472 if( pEntry->d_name[1]==0 ) continue;
473 if( pEntry->d_name[1]=='.' && pEntry->d_name[2]==0 ) continue;
474 }
475 zUtf8 = fossil_filename_to_utf8(pEntry->d_name);
476 blob_appendf(pPath, "/%s", zUtf8);
477 zPath = blob_str(pPath);
478 if( glob_match(pIgnore, &zPath[nPrefix+1]) ){
479 /* do nothing */
480 }else if( file_wd_isdir(zPath)==1 ){
481

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button