Fossil SCM

If "fossil new" or "fossil open"'s argument has an extended path prefix like "\\?\C:\", don't process the '?' and ':' in it as special path characters, only do '/' -> '\' translation. This makes extended paths usable in fossil everywhere (hopefully), for now <260.

jan.nijtmans 2013-12-17 09:32 trunk
Commit 04f4e699d41b7378ce8cb5d4c09bc0756a818fb0
1 file changed +18 -4
+18 -4
--- src/utf8.c
+++ src/utf8.c
@@ -191,22 +191,36 @@
191191
**
192192
*/
193193
void *fossil_utf8_to_filename(const char *zUtf8){
194194
#ifdef _WIN32
195195
int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
196
- wchar_t *zUnicode = sqlite3_malloc( nChar * 2 );
196
+ wchar_t *zUnicode = sqlite3_malloc( nChar * sizeof(wchar_t) );
197197
wchar_t *wUnicode = zUnicode;
198198
if( zUnicode==0 ){
199199
return 0;
200200
}
201
- MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar);
202
- /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
203201
if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
204202
&& (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
205
- zUnicode[2] = '\\';
203
+ /* If path starts with "<drive>:[/\]", don't process the ':' */
204
+ zUnicode[0] = zUtf8[0];
205
+ memcpy(&zUnicode[1], L":\\", 2 * sizeof(wchar_t));
206206
wUnicode += 3;
207
+ MultiByteToWideChar(CP_UTF8, 0, zUtf8+3, -1, wUnicode, nChar-3);
208
+ goto finish;
209
+ }else if( (zUtf8[0]=='\\' || zUtf8[0]=='/') &&
210
+ (zUtf8[1]=='\\' || zUtf8[1]=='/') ) {
211
+ if( zUtf8[2]=='?' && nChar>5 ){
212
+ /* Don't postprocess [?:] in extended path, but do '/' -> '\' */
213
+ memcpy(zUnicode, L"\\\\", 2 * sizeof(wchar_t));
214
+ MultiByteToWideChar(CP_UTF8, 0, zUtf8+2, -1, zUnicode+2, nChar-2);
215
+ if( zUtf8[3]=='/' ) zUnicode[3]='\\';
216
+ wUnicode += 6;
217
+ goto finish;
218
+ }
207219
}
220
+ MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar);
221
+finish:
208222
while( *wUnicode != '\0' ){
209223
if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){
210224
*wUnicode |= 0xF000;
211225
}else if( *wUnicode == '/' ){
212226
*wUnicode = '\\';
213227
--- src/utf8.c
+++ src/utf8.c
@@ -191,22 +191,36 @@
191 **
192 */
193 void *fossil_utf8_to_filename(const char *zUtf8){
194 #ifdef _WIN32
195 int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
196 wchar_t *zUnicode = sqlite3_malloc( nChar * 2 );
197 wchar_t *wUnicode = zUnicode;
198 if( zUnicode==0 ){
199 return 0;
200 }
201 MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar);
202 /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
203 if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
204 && (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
205 zUnicode[2] = '\\';
 
 
206 wUnicode += 3;
 
 
 
 
 
 
 
 
 
 
 
 
207 }
 
 
208 while( *wUnicode != '\0' ){
209 if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){
210 *wUnicode |= 0xF000;
211 }else if( *wUnicode == '/' ){
212 *wUnicode = '\\';
213
--- src/utf8.c
+++ src/utf8.c
@@ -191,22 +191,36 @@
191 **
192 */
193 void *fossil_utf8_to_filename(const char *zUtf8){
194 #ifdef _WIN32
195 int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
196 wchar_t *zUnicode = sqlite3_malloc( nChar * sizeof(wchar_t) );
197 wchar_t *wUnicode = zUnicode;
198 if( zUnicode==0 ){
199 return 0;
200 }
 
 
201 if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
202 && (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
203 /* If path starts with "<drive>:[/\]", don't process the ':' */
204 zUnicode[0] = zUtf8[0];
205 memcpy(&zUnicode[1], L":\\", 2 * sizeof(wchar_t));
206 wUnicode += 3;
207 MultiByteToWideChar(CP_UTF8, 0, zUtf8+3, -1, wUnicode, nChar-3);
208 goto finish;
209 }else if( (zUtf8[0]=='\\' || zUtf8[0]=='/') &&
210 (zUtf8[1]=='\\' || zUtf8[1]=='/') ) {
211 if( zUtf8[2]=='?' && nChar>5 ){
212 /* Don't postprocess [?:] in extended path, but do '/' -> '\' */
213 memcpy(zUnicode, L"\\\\", 2 * sizeof(wchar_t));
214 MultiByteToWideChar(CP_UTF8, 0, zUtf8+2, -1, zUnicode+2, nChar-2);
215 if( zUtf8[3]=='/' ) zUnicode[3]='\\';
216 wUnicode += 6;
217 goto finish;
218 }
219 }
220 MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar);
221 finish:
222 while( *wUnicode != '\0' ){
223 if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){
224 *wUnicode |= 0xF000;
225 }else if( *wUnicode == '/' ){
226 *wUnicode = '\\';
227

Keyboard Shortcuts

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