| | @@ -20,13 +20,12 @@ |
| 20 | 20 | * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR |
| 21 | 21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
| 22 | 22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR |
| 23 | 23 | * OTHER DEALINGS IN THE SOFTWARE. |
| 24 | 24 | * |
| 25 | | - * Aug 30, 2012, Jan Nijtmans |
| 26 | | - * Remove rewinddir() (not necessary for fossil) |
| 27 | | - * Replace everything with its wide-character variant. |
| 25 | + * Sept 12, 2012, Jan Nijtmans |
| 26 | + * Switchable wide-character variant. |
| 28 | 27 | * |
| 29 | 28 | * Mar 15, 2011, Toni Ronkko |
| 30 | 29 | * Defined FILE_ATTRIBUTE_DEVICE for MSVC 6.0. |
| 31 | 30 | * |
| 32 | 31 | * Aug 11, 2010, Toni Ronkko |
| | @@ -149,27 +148,26 @@ |
| 149 | 148 | #define S_ISLNK(mode) (((mode) & S_IFMT) == S_IFLNK) |
| 150 | 149 | #define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK) |
| 151 | 150 | #define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR) |
| 152 | 151 | #define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK) |
| 153 | 152 | |
| 154 | | -#ifdef __cplusplus |
| 155 | | -extern "C" { |
| 156 | | -#endif |
| 157 | | - |
| 158 | 153 | #ifdef UNICODE |
| 159 | 154 | # define dirent _wdirent |
| 160 | 155 | # define opendir _wopendir |
| 161 | 156 | # define readdir _wreaddir |
| 162 | 157 | # define closedir _wclosedir |
| 158 | +# define rewinddir _wrewinddir |
| 163 | 159 | # define DIR _WDIR |
| 164 | | -#else |
| 165 | | -# define wchar_t char |
| 160 | +#endif |
| 161 | + |
| 162 | +#ifdef __cplusplus |
| 163 | +extern "C" { |
| 166 | 164 | #endif |
| 167 | 165 | |
| 168 | 166 | typedef struct dirent |
| 169 | 167 | { |
| 170 | | - wchar_t d_name[MAX_PATH + 1]; /* File name */ |
| 168 | + TCHAR d_name[MAX_PATH + 1]; /* File name */ |
| 171 | 169 | size_t d_namlen; /* Length of name without \0 */ |
| 172 | 170 | int d_type; /* File type */ |
| 173 | 171 | } dirent; |
| 174 | 172 | |
| 175 | 173 | |
| | @@ -177,18 +175,19 @@ |
| 177 | 175 | { |
| 178 | 176 | dirent curentry; /* Current directory entry */ |
| 179 | 177 | WIN32_FIND_DATA find_data; /* Private file data */ |
| 180 | 178 | int cached; /* True if data is valid */ |
| 181 | 179 | HANDLE search_handle; /* Win32 search handle */ |
| 182 | | - wchar_t patt[MAX_PATH + 3]; /* Initial directory name */ |
| 180 | + TCHAR patt[MAX_PATH + 3]; /* Initial directory name */ |
| 183 | 181 | } DIR; |
| 184 | 182 | |
| 185 | 183 | |
| 186 | 184 | /* Forward declarations */ |
| 187 | | -static DIR *opendir(const wchar_t *dirname); |
| 185 | +static DIR *opendir(const TCHAR *dirname); |
| 188 | 186 | static struct dirent *readdir(DIR *dirp); |
| 189 | 187 | static int closedir(DIR *dirp); |
| 188 | +static void rewinddir(DIR* dirp); |
| 190 | 189 | |
| 191 | 190 | |
| 192 | 191 | /* Use the new safe string functions introduced in Visual Studio 2005 */ |
| 193 | 192 | #if defined(_MSC_VER) && _MSC_VER >= 1400 |
| 194 | 193 | # define DIRENT_STRNCPY(dest,src,size) _tcsncpy_s((dest),(size),(src),_TRUNCATE) |
| | @@ -207,11 +206,11 @@ |
| 207 | 206 | /***************************************************************************** |
| 208 | 207 | * Open directory stream DIRNAME for read and return a pointer to the |
| 209 | 208 | * internal working area that is used to retrieve individual directory |
| 210 | 209 | * entries. |
| 211 | 210 | */ |
| 212 | | -static DIR *opendir(const wchar_t *dirname) |
| 211 | +static DIR *opendir(const TCHAR *dirname) |
| 213 | 212 | { |
| 214 | 213 | DIR *dirp; |
| 215 | 214 | |
| 216 | 215 | /* ensure that the resulting search pattern will be a valid file name */ |
| 217 | 216 | if (dirname == NULL) { |
| | @@ -232,11 +231,11 @@ |
| 232 | 231 | * Convert relative directory name to an absolute one. This |
| 233 | 232 | * allows rewinddir() to function correctly when the current working |
| 234 | 233 | * directory is changed between opendir() and rewinddir(). |
| 235 | 234 | */ |
| 236 | 235 | if (GetFullPathName (dirname, MAX_PATH, dirp->patt, NULL)) { |
| 237 | | - wchar_t *p; |
| 236 | + TCHAR *p; |
| 238 | 237 | |
| 239 | 238 | /* append the search pattern "\\*\0" to the directory name */ |
| 240 | 239 | p = _tcschr (dirp->patt, '\0'); |
| 241 | 240 | if (dirp->patt < p && *(p-1) != '\\' && *(p-1) != ':') { |
| 242 | 241 | *p++ = '\\'; |
| | @@ -302,14 +301,14 @@ |
| 302 | 301 | dirp->search_handle = INVALID_HANDLE_VALUE; |
| 303 | 302 | return NULL; |
| 304 | 303 | } |
| 305 | 304 | } |
| 306 | 305 | |
| 307 | | - /* copy as a unicode character string */ |
| 306 | + /* copy as a multibyte/unicode character string */ |
| 308 | 307 | DIRENT_STRNCPY ( dirp->curentry.d_name, |
| 309 | 308 | dirp->find_data.cFileName, |
| 310 | | - sizeof(dirp->curentry.d_name)/sizeof(dirp->curentry.d_name[0]) ); |
| 309 | + sizeof(dirp->curentry.d_name)/sizeof(TCHAR) ); |
| 311 | 310 | dirp->curentry.d_name[MAX_PATH] = '\0'; |
| 312 | 311 | |
| 313 | 312 | /* compute the length of name */ |
| 314 | 313 | dirp->curentry.d_namlen = _tcslen (dirp->curentry.d_name); |
| 315 | 314 | |
| | @@ -347,20 +346,45 @@ |
| 347 | 346 | |
| 348 | 347 | /* release directory structure */ |
| 349 | 348 | free (dirp); |
| 350 | 349 | return 0; |
| 351 | 350 | } |
| 351 | + |
| 352 | +/***************************************************************************** |
| 353 | + * Resets the position of the directory stream to which dirp refers to the |
| 354 | + * beginning of the directory. It also causes the directory stream to refer |
| 355 | + * to the current state of the corresponding directory, as a call to opendir() |
| 356 | + * would have done. If dirp does not refer to a directory stream, the effect |
| 357 | + * is undefined. |
| 358 | + */ |
| 359 | +static void rewinddir(DIR* dirp) |
| 360 | +{ |
| 361 | + if (dirp != NULL) { |
| 362 | + /* release search handle */ |
| 363 | + if (dirp->search_handle != INVALID_HANDLE_VALUE) { |
| 364 | + FindClose (dirp->search_handle); |
| 365 | + } |
| 366 | + |
| 367 | + /* open new search handle and retrieve the first entry */ |
| 368 | + dirp->search_handle = FindFirstFile (dirp->patt, &dirp->find_data); |
| 369 | + if (dirp->search_handle != INVALID_HANDLE_VALUE) { |
| 370 | + /* a directory entry is now waiting in memory */ |
| 371 | + dirp->cached = 1; |
| 372 | + } else { |
| 373 | + /* failed to re-open directory: no directory entry in memory */ |
| 374 | + dirp->cached = 0; |
| 375 | + } |
| 376 | + } |
| 377 | +} |
| 352 | 378 | |
| 353 | 379 | #ifdef UNICODE |
| 354 | 380 | # undef dirent |
| 355 | 381 | # undef opendir |
| 356 | 382 | # undef readdir |
| 357 | 383 | # undef closedir |
| 358 | 384 | # undef DIR |
| 359 | | -#else |
| 360 | | -# undef wchar_t |
| 361 | 385 | #endif |
| 362 | 386 | |
| 363 | 387 | #ifdef __cplusplus |
| 364 | 388 | } |
| 365 | 389 | #endif |
| 366 | 390 | #endif /*DIRENT_H*/ |
| 367 | 391 | |