Fossil SCM

Handle translation between '/' and '\\' on Windows and Cygwin

jan.nijtmans 2013-01-24 12:00 UTC ticket-d17d6e5b17
Commit ba87fb1fecfa54a28922ead0c8e10a8cbc4dc2ed
2 files changed +4 -4 +19 -3
+4 -4
--- src/file.c
+++ src/file.c
@@ -547,12 +547,10 @@
547547
if( (z[++i]&0xc0)!=0x80 ){
548548
/* Invalid second continuation byte */
549549
return 0;
550550
}
551551
}
552
- }else if( c=='\\' ){
553
- return 0;
554552
}
555553
if( c=='/' ){
556554
if( z[i+1]=='/' ) return 0;
557555
if( z[i+1]=='.' ){
558556
if( z[i+2]=='/' || z[i+2]==0 ) return 0;
@@ -792,12 +790,12 @@
792790
}
793791
794792
/*
795793
** Return TRUE if the given filename is canonical.
796794
**
797
-** Canonical names are full pathnames using "/" not "\" and which
798
-** contain no "/./" or "/../" terms.
795
+** Canonical names are full pathnames which contain no "/./" or "/../"
796
+** terms and (On Windows/Cygwin) using "/" not "\".
799797
*/
800798
int file_is_canonical(const char *z){
801799
int i;
802800
if( z[0]!='/'
803801
#if defined(_WIN32)
@@ -804,11 +802,13 @@
804802
&& (z[0]==0 || z[1]!=':' || z[2]!='/')
805803
#endif
806804
) return 0;
807805
808806
for(i=0; z[i]; i++){
807
+#if defined(_WIN32) || defined(__CYGWIN__)
809808
if( z[i]=='\\' ) return 0;
809
+#endif
810810
if( z[i]=='/' ){
811811
if( z[i+1]=='.' ){
812812
if( z[i+2]=='/' || z[i+2]==0 ) return 0;
813813
if( z[i+2]=='.' && (z[i+3]=='/' || z[i+3]==0) ) return 0;
814814
}
815815
--- src/file.c
+++ src/file.c
@@ -547,12 +547,10 @@
547 if( (z[++i]&0xc0)!=0x80 ){
548 /* Invalid second continuation byte */
549 return 0;
550 }
551 }
552 }else if( c=='\\' ){
553 return 0;
554 }
555 if( c=='/' ){
556 if( z[i+1]=='/' ) return 0;
557 if( z[i+1]=='.' ){
558 if( z[i+2]=='/' || z[i+2]==0 ) return 0;
@@ -792,12 +790,12 @@
792 }
793
794 /*
795 ** Return TRUE if the given filename is canonical.
796 **
797 ** Canonical names are full pathnames using "/" not "\" and which
798 ** contain no "/./" or "/../" terms.
799 */
800 int file_is_canonical(const char *z){
801 int i;
802 if( z[0]!='/'
803 #if defined(_WIN32)
@@ -804,11 +802,13 @@
804 && (z[0]==0 || z[1]!=':' || z[2]!='/')
805 #endif
806 ) return 0;
807
808 for(i=0; z[i]; i++){
 
809 if( z[i]=='\\' ) return 0;
 
810 if( z[i]=='/' ){
811 if( z[i+1]=='.' ){
812 if( z[i+2]=='/' || z[i+2]==0 ) return 0;
813 if( z[i+2]=='.' && (z[i+3]=='/' || z[i+3]==0) ) return 0;
814 }
815
--- src/file.c
+++ src/file.c
@@ -547,12 +547,10 @@
547 if( (z[++i]&0xc0)!=0x80 ){
548 /* Invalid second continuation byte */
549 return 0;
550 }
551 }
 
 
552 }
553 if( c=='/' ){
554 if( z[i+1]=='/' ) return 0;
555 if( z[i+1]=='.' ){
556 if( z[i+2]=='/' || z[i+2]==0 ) return 0;
@@ -792,12 +790,12 @@
790 }
791
792 /*
793 ** Return TRUE if the given filename is canonical.
794 **
795 ** Canonical names are full pathnames which contain no "/./" or "/../"
796 ** terms and (On Windows/Cygwin) using "/" not "\".
797 */
798 int file_is_canonical(const char *z){
799 int i;
800 if( z[0]!='/'
801 #if defined(_WIN32)
@@ -804,11 +802,13 @@
802 && (z[0]==0 || z[1]!=':' || z[2]!='/')
803 #endif
804 ) return 0;
805
806 for(i=0; z[i]; i++){
807 #if defined(_WIN32) || defined(__CYGWIN__)
808 if( z[i]=='\\' ) return 0;
809 #endif
810 if( z[i]=='/' ){
811 if( z[i+1]=='.' ){
812 if( z[i+2]=='/' || z[i+2]==0 ) return 0;
813 if( z[i+2]=='.' && (z[i+3]=='/' || z[i+3]==0) ) return 0;
814 }
815
+19 -3
--- src/utf8.c
+++ src/utf8.c
@@ -133,10 +133,14 @@
133133
if( zUtf==0 ){
134134
return 0;
135135
}
136136
WideCharToMultiByte(CP_UTF8, 0, zFilename, -1, zUtf, nByte, 0, 0);
137137
return zUtf;
138
+#elif defined(__CYGWIN__)
139
+ char *zOut;
140
+ zOut = fossil_strdup(zFilename);
141
+ return zOut;
138142
#elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
139143
char *zIn = (char*)zFilename;
140144
char *zOut;
141145
iconv_t cd;
142146
size_t n, x;
@@ -169,11 +173,11 @@
169173
** Translate UTF8 to unicode for use in filename translations.
170174
** Return a pointer to the translated text.. Call fossil_filename_free()
171175
** to deallocate any memory used to store the returned pointer when done.
172176
**
173177
** On Windows, characters in the range U+0001 to U+0031 and the
174
-** characters '"', '*', ':', '<', '>', '?', '|' and '\\' are invalid
178
+** characters '"', '*', ':', '<', '>', '?' and '|' are invalid
175179
** to be used. Therefore, translated those to characters in the
176180
** (private use area), in the range U+F001 - U+F07F, so those
177181
** characters never arrive in any Windows API. The filenames might
178182
** look strange in Windows explorer, but in the cygwin shell
179183
** everything looks as expected.
@@ -186,21 +190,33 @@
186190
WCHAR *zUnicode = fossil_utf8_to_unicode(zUtf8);
187191
WCHAR *wUnicode = zUnicode;
188192
/* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
189193
if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
190194
&& (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
195
+ zUnicode[2] = '\\';
191196
wUnicode += 3;
192197
}
193198
while( *wUnicode != '\0' ){
194199
if ( (*wUnicode < 32) || wcschr(L"\"*<>?|:", *wUnicode) ){
195200
*wUnicode |= 0xF000;
201
+ }else if( *wUnicode == '/' ){
202
+ *wUnicode = '\\';
196203
}
197204
++wUnicode;
198205
}
199206
200207
return zUnicode;
201
-#elif defined(__APPLE__)
208
+#elif defined(__CYGWIN__)
209
+ char *zPath = fossil_strdup(zUtf8);
210
+ char *p = zPath;
211
+ while( (*p = *zUtf8++) != 0){
212
+ if (*p++ == '\\' ) {
213
+ p[-1] = '/';
214
+ }
215
+ }
216
+ return zPath;
217
+#elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
202218
return fossil_strdup(zUtf8);
203219
#else
204220
return (void *)zUtf8; /* No-op on unix */
205221
#endif
206222
}
@@ -210,11 +226,11 @@
210226
** fossil_filename_to_utf8() or fossil_utf8_to_filename().
211227
*/
212228
void fossil_filename_free(void *pOld){
213229
#if defined(_WIN32)
214230
sqlite3_free(pOld);
215
-#elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
231
+#elif (defined(__APPLE__) && !defined(WITHOUT_ICONV)) || defined(__CYGWIN__)
216232
fossil_free(pOld);
217233
#else
218234
/* No-op on all other unix */
219235
#endif
220236
}
221237
--- src/utf8.c
+++ src/utf8.c
@@ -133,10 +133,14 @@
133 if( zUtf==0 ){
134 return 0;
135 }
136 WideCharToMultiByte(CP_UTF8, 0, zFilename, -1, zUtf, nByte, 0, 0);
137 return zUtf;
 
 
 
 
138 #elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
139 char *zIn = (char*)zFilename;
140 char *zOut;
141 iconv_t cd;
142 size_t n, x;
@@ -169,11 +173,11 @@
169 ** Translate UTF8 to unicode for use in filename translations.
170 ** Return a pointer to the translated text.. Call fossil_filename_free()
171 ** to deallocate any memory used to store the returned pointer when done.
172 **
173 ** On Windows, characters in the range U+0001 to U+0031 and the
174 ** characters '"', '*', ':', '<', '>', '?', '|' and '\\' are invalid
175 ** to be used. Therefore, translated those to characters in the
176 ** (private use area), in the range U+F001 - U+F07F, so those
177 ** characters never arrive in any Windows API. The filenames might
178 ** look strange in Windows explorer, but in the cygwin shell
179 ** everything looks as expected.
@@ -186,21 +190,33 @@
186 WCHAR *zUnicode = fossil_utf8_to_unicode(zUtf8);
187 WCHAR *wUnicode = zUnicode;
188 /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
189 if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
190 && (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
 
191 wUnicode += 3;
192 }
193 while( *wUnicode != '\0' ){
194 if ( (*wUnicode < 32) || wcschr(L"\"*<>?|:", *wUnicode) ){
195 *wUnicode |= 0xF000;
 
 
196 }
197 ++wUnicode;
198 }
199
200 return zUnicode;
201 #elif defined(__APPLE__)
 
 
 
 
 
 
 
 
 
202 return fossil_strdup(zUtf8);
203 #else
204 return (void *)zUtf8; /* No-op on unix */
205 #endif
206 }
@@ -210,11 +226,11 @@
210 ** fossil_filename_to_utf8() or fossil_utf8_to_filename().
211 */
212 void fossil_filename_free(void *pOld){
213 #if defined(_WIN32)
214 sqlite3_free(pOld);
215 #elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
216 fossil_free(pOld);
217 #else
218 /* No-op on all other unix */
219 #endif
220 }
221
--- src/utf8.c
+++ src/utf8.c
@@ -133,10 +133,14 @@
133 if( zUtf==0 ){
134 return 0;
135 }
136 WideCharToMultiByte(CP_UTF8, 0, zFilename, -1, zUtf, nByte, 0, 0);
137 return zUtf;
138 #elif defined(__CYGWIN__)
139 char *zOut;
140 zOut = fossil_strdup(zFilename);
141 return zOut;
142 #elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
143 char *zIn = (char*)zFilename;
144 char *zOut;
145 iconv_t cd;
146 size_t n, x;
@@ -169,11 +173,11 @@
173 ** Translate UTF8 to unicode for use in filename translations.
174 ** Return a pointer to the translated text.. Call fossil_filename_free()
175 ** to deallocate any memory used to store the returned pointer when done.
176 **
177 ** On Windows, characters in the range U+0001 to U+0031 and the
178 ** characters '"', '*', ':', '<', '>', '?' and '|' are invalid
179 ** to be used. Therefore, translated those to characters in the
180 ** (private use area), in the range U+F001 - U+F07F, so those
181 ** characters never arrive in any Windows API. The filenames might
182 ** look strange in Windows explorer, but in the cygwin shell
183 ** everything looks as expected.
@@ -186,21 +190,33 @@
190 WCHAR *zUnicode = fossil_utf8_to_unicode(zUtf8);
191 WCHAR *wUnicode = zUnicode;
192 /* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
193 if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
194 && (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
195 zUnicode[2] = '\\';
196 wUnicode += 3;
197 }
198 while( *wUnicode != '\0' ){
199 if ( (*wUnicode < 32) || wcschr(L"\"*<>?|:", *wUnicode) ){
200 *wUnicode |= 0xF000;
201 }else if( *wUnicode == '/' ){
202 *wUnicode = '\\';
203 }
204 ++wUnicode;
205 }
206
207 return zUnicode;
208 #elif defined(__CYGWIN__)
209 char *zPath = fossil_strdup(zUtf8);
210 char *p = zPath;
211 while( (*p = *zUtf8++) != 0){
212 if (*p++ == '\\' ) {
213 p[-1] = '/';
214 }
215 }
216 return zPath;
217 #elif defined(__APPLE__) && !defined(WITHOUT_ICONV)
218 return fossil_strdup(zUtf8);
219 #else
220 return (void *)zUtf8; /* No-op on unix */
221 #endif
222 }
@@ -210,11 +226,11 @@
226 ** fossil_filename_to_utf8() or fossil_utf8_to_filename().
227 */
228 void fossil_filename_free(void *pOld){
229 #if defined(_WIN32)
230 sqlite3_free(pOld);
231 #elif (defined(__APPLE__) && !defined(WITHOUT_ICONV)) || defined(__CYGWIN__)
232 fossil_free(pOld);
233 #else
234 /* No-op on all other unix */
235 #endif
236 }
237

Keyboard Shortcuts

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