Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Handle win32 extended path prefix everywhere: Just strip it in the function file_simplify_name(), and only add it back when needed (just before feeding it to a win32 function when >260 chars). Includes additional test-cases. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA1: |
95f004b1c535c545941ebe7512d7684f |
| User & Date: | jan.nijtmans 2014-02-28 13:46:25.028 |
References
|
2014-03-18
| ||
| 15:59 | Since file_simplify_name() already was modified to handle the extended path prefix correctly [95f004b1c535c545], this special Cygwin handling is no longer necessary. check-in: e35dbea1e3 user: jan.nijtmans tags: trunk | |
Context
|
2014-02-28
| ||
| 15:46 | Fix to check-in [81162e791f] so that it does not require non-standard modifications to the SQLite "shell.c" source file. Sorry, but this doesn't work! Compiling this with Makefile.mingw.mistachkin gives: wbld/shell.o:shell.c:(.text+0x3463): undefined reference to `__imp_win32_access' wbld/shell.o:shell.c:(.text+0x59ac): undefined reference to `__imp_win32_access' /usr/lib/gcc/x86_64-w64-mingw32/4.8.2/../../../../x86_64-w64-mingw32/bin/ld: wbld/shell.o: bad reloc address 0x0 in section `.data' collect2: error: ld returned 1 exit status win/Makefile.mingw.mistachkin:698: recipe for target 'fossil.exe' failed check-in: 99dca38314 user: drh tags: trunk | |
| 13:46 | Handle win32 extended path prefix everywhere: Just strip it in the function file_simplify_name(), and only add it back when needed (just before feeding it to a win32 function when >260 chars). Includes additional test-cases. check-in: 95f004b1c5 user: jan.nijtmans tags: trunk | |
| 10:34 | Remove unnecessary spaces at end-of-lines. No change in functionality. check-in: 3df526ca41 user: jan.nijtmans tags: trunk | |
|
2014-02-26
| ||
| 10:42 | Add support for extended UNC paths as well, and add Windows/Cygwin-specific test-cases for it. Closed-Leaf check-in: ebb42b530e user: jan.nijtmans tags: extended-path-prefix | |
Changes
Changes to src/file.c.
| ︙ | ︙ | |||
694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 |
*pJ = i-1;
return 1;
}
/*
** Simplify a filename by
**
** * Convert all \ into / on windows and cygwin
** * removing any trailing and duplicate /
** * removing /./
** * removing /A/../
**
** Changes are made in-place. Return the new name length.
** If the slash parameter is non-zero, the trailing slash, if any,
** is retained.
*/
int file_simplify_name(char *z, int n, int slash){
| > | | > | | > > > > > > > > > | | 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 |
*pJ = i-1;
return 1;
}
/*
** Simplify a filename by
**
** * Remove extended path prefix on windows and cygwin
** * Convert all \ into / on windows and cygwin
** * removing any trailing and duplicate /
** * removing /./
** * removing /A/../
**
** Changes are made in-place. Return the new name length.
** If the slash parameter is non-zero, the trailing slash, if any,
** is retained.
*/
int file_simplify_name(char *z, int n, int slash){
int i = 1, j;
if( n<0 ) n = strlen(z);
/* On windows and cygwin convert all \ characters to /
* and remove extended path prefix if present */
#if defined(_WIN32) || defined(__CYGWIN__)
for(j=0; j<n; j++){
if( z[j]=='\\' ) z[j] = '/';
}
if( n>3 && !memcmp(z, "//?/", 4) ){
if( fossil_strnicmp(z+4,"UNC", 3) ){
i += 4;
z[0] = z[4];
}else{
i += 6;
z[0] = '/';
}
}
#endif
/* Removing trailing "/" characters */
if( !slash ){
while( n>1 && z[n-1]=='/' ){ n--; }
}
/* Remove duplicate '/' characters. Except, two // at the beginning
** of a pathname is allowed since this is important on windows. */
for(j=1; i<n; i++){
z[j++] = z[i];
while( z[i]=='/' && i<n-1 && z[i+1]=='/' ) i++;
}
n = j;
/* Skip over zero or more initial "./" sequences */
for(i=0; i<n-1 && z[i]=='.' && z[i+1]=='/'; i+=2){}
|
| ︙ | ︙ |
Changes to src/utf8.c.
| ︙ | ︙ | |||
188 189 190 191 192 193 194 |
**
** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
**
*/
void *fossil_utf8_to_filename(const char *zUtf8){
#ifdef _WIN32
int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
| > | > > > > > > > > > > > > > > | | | < < > > > > > > | 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
**
** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
**
*/
void *fossil_utf8_to_filename(const char *zUtf8){
#ifdef _WIN32
int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
/* Overallocate 6 chars, making some room for extended paths */
wchar_t *zUnicode = sqlite3_malloc( (nChar+6) * sizeof(wchar_t) );
wchar_t *wUnicode = zUnicode;
if( zUnicode==0 ){
return 0;
}
MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zUnicode, nChar);
/*
** If path starts with "//?/" or "\\?\" (extended path), translate
** any slashes to backslashes but leave the '?' intact
*/
if( (zUtf8[0]=='\\' || zUtf8[0]=='/') && (zUtf8[1]=='\\' || zUtf8[1]=='/')
&& zUtf8[2]=='?' && (zUtf8[3]=='\\' || zUtf8[3]=='/')) {
wUnicode[0] = wUnicode[1] = wUnicode[3] = '\\';
zUtf8 += 4;
wUnicode += 4;
}
/*
** If there is no "\\?\" prefix but there is a drive or UNC
** path prefix and the path is larger than MAX_PATH chars,
** no Win32 API function can handle that unless it is
** prefixed with the extended path prefix. See:
** <http://msdn.microsoft.com/en-us/library/aa365247(VS.85).aspx#maxpath>
**/
if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
&& (zUtf8[2]=='\\' || zUtf8[2]=='/') ){
if( wUnicode==zUnicode && nChar>MAX_PATH){
memmove(wUnicode+4, wUnicode, nChar*sizeof(wchar_t));
memcpy(wUnicode, L"\\\\?\\", 4*sizeof(wchar_t));
wUnicode += 4;
}
/*
** If (remainder of) path starts with "<drive>:/" or "<drive>:\",
** leave the ':' intact but translate the backslash to a slash.
*/
wUnicode[2] = '\\';
wUnicode += 3;
}else if( wUnicode==zUnicode && nChar>MAX_PATH
&& (zUtf8[0]=='\\' || zUtf8[0]=='/')
&& (zUtf8[1]=='\\' || zUtf8[1]=='/') && zUtf8[2]!='?'){
memmove(wUnicode+6, wUnicode, nChar*sizeof(wchar_t));
memcpy(wUnicode, L"\\\\?\\UNC", 7*sizeof(wchar_t));
wUnicode += 7;
}
/*
** In the remainder of the path, translate invalid characters to
** characters in the Unicode private use area. This is what makes
** Win32 fossil.exe work well in a Cygwin environment even when a
** filename contains characters which are invalid for Win32.
*/
|
| ︙ | ︙ |
Changes to test/file1.test.
| ︙ | ︙ | |||
31 32 33 34 35 36 37 |
simplify-name 101 {} {} / / ///////// / ././././ .
simplify-name 102 x x /x /x ///x //x
simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b
simplify-name 104 a/b/../c/ a/c /a/b/../c /a/c /a/b//../c /a/c /a/b/..///c /a/c
simplify-name 105 a/b/../../x/y x/y /a/b/../../x/y /x/y
simplify-name 106 a/b/../../../x/y ../x/y /a/b/../../../x/y /../x/y
simplify-name 107 a/./b/.././../x/y x/y a//.//b//..//.//..//x//y/// x/y
| > > > > > | 31 32 33 34 35 36 37 38 39 40 41 42 |
simplify-name 101 {} {} / / ///////// / ././././ .
simplify-name 102 x x /x /x ///x //x
simplify-name 103 a/b a/b /a/b /a/b a///b a/b ///a///b///// //a/b
simplify-name 104 a/b/../c/ a/c /a/b/../c /a/c /a/b//../c /a/c /a/b/..///c /a/c
simplify-name 105 a/b/../../x/y x/y /a/b/../../x/y /x/y
simplify-name 106 a/b/../../../x/y ../x/y /a/b/../../../x/y /../x/y
simplify-name 107 a/./b/.././../x/y x/y a//.//b//..//.//..//x//y/// x/y
if {$::tcl_platform(os)=="Windows NT"} {
simplify-name 108 //?/a:/a/b a:/a/b //?/UNC/a/b //a/b //?/ {}
simplify-name 109 \\\\?\\a:\\a\\b a:/a/b \\\\?\\UNC\\a\\b //a/b \\\\?\\ {}
}
|