36 #if ((defined _UNICODE) && !(defined UNICODE)) 40 #if ((defined UNICODE) && !(defined _UNICODE)) 48 # define WIN32_LEAN_AND_MEAN 51 # pragma warning(push) 52 # pragma warning (disable : 4996) 56 # include <sys/stat.h> 67 #if defined _MSC_VER || defined __MINGW32__ 68 #define _tinydir_char_t TCHAR 69 #define TINYDIR_STRING(s) _TEXT(s) 70 #define _tinydir_strlen _tcslen 71 #define _tinydir_strcpy _tcscpy 72 #define _tinydir_strcat _tcscat 73 #define _tinydir_strcmp _tcscmp 74 #define _tinydir_strrchr _tcsrchr 75 #define _tinydir_strncmp _tcsncmp 77 #define _tinydir_char_t char 78 #define TINYDIR_STRING(s) s 79 #define _tinydir_strlen strlen 80 #define _tinydir_strcpy strcpy 81 #define _tinydir_strcat strcat 82 #define _tinydir_strcmp strcmp 83 #define _tinydir_strrchr strrchr 84 #define _tinydir_strncmp strncmp 87 #if (defined _MSC_VER || defined __MINGW32__) 89 #define _TINYDIR_PATH_MAX MAX_PATH 90 #elif defined __linux__ 91 #include <linux/limits.h> 92 #define _TINYDIR_PATH_MAX PATH_MAX 94 #define _TINYDIR_PATH_MAX 4096 99 # define _TINYDIR_PATH_EXTRA 2 101 # define _TINYDIR_PATH_EXTRA 0 104 #define _TINYDIR_FILENAME_MAX 256 106 #if (defined _MSC_VER || defined __MINGW32__) 107 #define _TINYDIR_DRIVE_MAX 3 111 # define _TINYDIR_FUNC static __inline 112 #elif !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L 113 # define _TINYDIR_FUNC static __inline__ 115 # define _TINYDIR_FUNC static inline 119 #ifdef TINYDIR_USE_READDIR_R 123 #if _POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _BSD_SOURCE || _SVID_SOURCE ||\ 125 # define _TINYDIR_HAS_READDIR_R 127 #if _POSIX_C_SOURCE >= 200112L 128 # define _TINYDIR_HAS_FPATHCONF 131 #if _BSD_SOURCE || _SVID_SOURCE || \ 132 (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700) 133 # define _TINYDIR_HAS_DIRFD 134 # include <sys/types.h> 136 #if defined _TINYDIR_HAS_FPATHCONF && defined _TINYDIR_HAS_DIRFD &&\ 138 # define _TINYDIR_USE_FPATHCONF 140 #if defined __MINGW32__ || !defined _TINYDIR_HAS_READDIR_R ||\ 141 !(defined _TINYDIR_USE_FPATHCONF || defined NAME_MAX) 142 # define _TINYDIR_USE_READDIR 147 # define _TINYDIR_USE_READDIR 152 #if (defined __MINGW32__) && (defined _UNICODE) 153 #define _TINYDIR_DIR _WDIR 154 #define _tinydir_dirent _wdirent 155 #define _tinydir_opendir _wopendir 156 #define _tinydir_readdir _wreaddir 157 #define _tinydir_closedir _wclosedir 159 #define _TINYDIR_DIR DIR 160 #define _tinydir_dirent dirent 161 #define _tinydir_opendir opendir 162 #define _tinydir_readdir readdir 163 #define _tinydir_closedir closedir 168 #if defined(_TINYDIR_MALLOC) && defined(_TINYDIR_FREE) 169 #elif !defined(_TINYDIR_MALLOC) && !defined(_TINYDIR_FREE) 171 #error "Either define both alloc and free or none of them!" 174 #if !defined(_TINYDIR_MALLOC) 175 #define _TINYDIR_MALLOC(_size) malloc(_size) 176 #define _TINYDIR_FREE(_ptr) free(_ptr) 181 _tinydir_char_t path[_TINYDIR_PATH_MAX];
182 _tinydir_char_t name[_TINYDIR_FILENAME_MAX];
183 _tinydir_char_t *extension;
198 _tinydir_char_t path[_TINYDIR_PATH_MAX];
202 tinydir_file *_files;
208 struct _tinydir_dirent *_e;
209 #ifndef _TINYDIR_USE_READDIR 210 struct _tinydir_dirent *_ep;
219 int tinydir_open(
tinydir_dir *dir,
const _tinydir_char_t *path);
221 int tinydir_open_sorted(
tinydir_dir *dir,
const _tinydir_char_t *path);
228 int tinydir_readfile(
const tinydir_dir *dir, tinydir_file *file);
230 int tinydir_readfile_n(
const tinydir_dir *dir, tinydir_file *file,
size_t i);
232 int tinydir_open_subdir_n(
tinydir_dir *dir,
size_t i);
235 int tinydir_file_open(tinydir_file *file,
const _tinydir_char_t *path);
237 void _tinydir_get_ext(tinydir_file *file);
239 int _tinydir_file_cmp(
const void *a,
const void *b);
241 #ifndef _TINYDIR_USE_READDIR 243 size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp);
251 int tinydir_open(
tinydir_dir *dir,
const _tinydir_char_t *path)
254 #ifndef _TINYDIR_USE_READDIR 259 _tinydir_char_t path_buf[_TINYDIR_PATH_MAX];
261 _tinydir_char_t *pathp;
263 if (dir == NULL || path == NULL || _tinydir_strlen(path) == 0)
268 if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
270 errno = ENAMETOOLONG;
277 dir->_h = INVALID_HANDLE_VALUE;
280 #ifndef _TINYDIR_USE_READDIR 286 _tinydir_strcpy(dir->path, path);
288 pathp = &dir->path[_tinydir_strlen(dir->path) - 1];
289 while (pathp != dir->path && (*pathp == TINYDIR_STRING(
'\\') || *pathp == TINYDIR_STRING(
'/')))
291 *pathp = TINYDIR_STRING(
'\0');
295 _tinydir_strcpy(path_buf, dir->path);
296 _tinydir_strcat(path_buf, TINYDIR_STRING(
"\\*"));
297 #if (defined WINAPI_FAMILY) && (WINAPI_FAMILY != WINAPI_FAMILY_DESKTOP_APP) 298 dir->_h = FindFirstFileEx(path_buf, FindExInfoStandard, &dir->_f, FindExSearchNameMatch, NULL, 0);
300 dir->_h = FindFirstFile(path_buf, &dir->_f);
302 if (dir->_h == INVALID_HANDLE_VALUE)
306 dir->_d = _tinydir_opendir(path);
316 #ifdef _TINYDIR_USE_READDIR 317 dir->_e = _tinydir_readdir(dir->_d);
320 size = _tinydir_dirent_buf_size(dir->_d);
321 if (size == -1)
return -1;
322 dir->_ep = (
struct _tinydir_dirent*)_TINYDIR_MALLOC(size);
323 if (dir->_ep == NULL)
return -1;
325 error = readdir_r(dir->_d, dir->_ep, &dir->_e);
326 if (error != 0)
return -1;
342 int tinydir_open_sorted(
tinydir_dir *dir,
const _tinydir_char_t *path)
346 if (tinydir_open(dir, path) == -1)
350 while (dir->has_next)
353 if (tinydir_next(dir) == -1)
360 if (tinydir_open(dir, path) == -1)
366 dir->_files = (tinydir_file *)_TINYDIR_MALLOC(
sizeof *dir->_files * n_files);
367 if (dir->_files == NULL)
371 while (dir->has_next)
373 tinydir_file *p_file;
376 p_file = &dir->_files[dir->n_files - 1];
377 if (tinydir_readfile(dir, p_file) == -1)
382 if (tinydir_next(dir) == -1)
389 if (dir->n_files == n_files)
395 qsort(dir->_files, dir->n_files,
sizeof(tinydir_file), _tinydir_file_cmp);
412 memset(dir->path, 0,
sizeof(dir->path));
415 _TINYDIR_FREE(dir->_files);
418 if (dir->_h != INVALID_HANDLE_VALUE)
422 dir->_h = INVALID_HANDLE_VALUE;
426 _tinydir_closedir(dir->_d);
430 #ifndef _TINYDIR_USE_READDIR 431 _TINYDIR_FREE(dir->_ep);
452 if (FindNextFile(dir->_h, &dir->_f) == 0)
454 #ifdef _TINYDIR_USE_READDIR 455 dir->_e = _tinydir_readdir(dir->_d);
457 if (dir->_ep == NULL)
461 if (readdir_r(dir->_d, dir->_ep, &dir->_e) != 0)
471 if (GetLastError() != ERROR_SUCCESS &&
472 GetLastError() != ERROR_NO_MORE_FILES)
485 int tinydir_readfile(
const tinydir_dir *dir, tinydir_file *file)
487 if (dir == NULL || file == NULL)
493 if (dir->_h == INVALID_HANDLE_VALUE)
501 if (_tinydir_strlen(dir->path) +
508 ) + 1 + _TINYDIR_PATH_EXTRA >=
512 errno = ENAMETOOLONG;
521 ) >= _TINYDIR_FILENAME_MAX)
523 errno = ENAMETOOLONG;
527 _tinydir_strcpy(file->path, dir->path);
528 _tinydir_strcat(file->path, TINYDIR_STRING(
"/"));
529 _tinydir_strcpy(file->name,
536 _tinydir_strcat(file->path, file->name);
543 file->path, &file->_s) == -1)
548 _tinydir_get_ext(file);
552 !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
558 !!(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) ||
560 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DEVICE) &&
561 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
562 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) &&
563 #ifdef FILE_ATTRIBUTE_INTEGRITY_STREAM 564 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_INTEGRITY_STREAM) &&
566 #ifdef FILE_ATTRIBUTE_NO_SCRUB_DATA
567 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_NO_SCRUB_DATA) &&
569 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) &&
570 !(dir->_f.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY));
579 int tinydir_readfile_n(
const tinydir_dir *dir, tinydir_file *file,
size_t i)
581 if (dir == NULL || file == NULL)
586 if (i >= dir->n_files)
592 memcpy(file, &dir->_files[i],
sizeof(tinydir_file));
593 _tinydir_get_ext(file);
599 int tinydir_open_subdir_n(
tinydir_dir *dir,
size_t i)
601 _tinydir_char_t path[_TINYDIR_PATH_MAX];
607 if (i >= dir->n_files || !dir->_files[i].is_dir)
613 _tinydir_strcpy(path, dir->_files[i].path);
615 if (tinydir_open_sorted(dir, path) == -1)
625 int tinydir_file_open(tinydir_file *file,
const _tinydir_char_t *path)
630 _tinydir_char_t dir_name_buf[_TINYDIR_PATH_MAX];
631 _tinydir_char_t file_name_buf[_TINYDIR_FILENAME_MAX];
632 _tinydir_char_t *dir_name;
633 _tinydir_char_t *base_name;
634 #if (defined _MSC_VER || defined __MINGW32__) 635 _tinydir_char_t drive_buf[_TINYDIR_PATH_MAX];
636 _tinydir_char_t ext_buf[_TINYDIR_FILENAME_MAX];
639 if (file == NULL || path == NULL || _tinydir_strlen(path) == 0)
644 if (_tinydir_strlen(path) + _TINYDIR_PATH_EXTRA >= _TINYDIR_PATH_MAX)
646 errno = ENAMETOOLONG;
651 #if (defined _MSC_VER || defined __MINGW32__) 652 #if ((defined _MSC_VER) && (_MSC_VER >= 1400)) 655 drive_buf, _TINYDIR_DRIVE_MAX,
656 dir_name_buf, _TINYDIR_FILENAME_MAX,
657 file_name_buf, _TINYDIR_FILENAME_MAX,
658 ext_buf, _TINYDIR_FILENAME_MAX);
670 if (drive_buf[0] == L
'\xFEFE')
672 if (dir_name_buf[0] == L
'\xFEFE')
673 dir_name_buf[0] =
'\0';
683 if (drive_buf[0] ==
'\0' && dir_name_buf[0] ==
'\0')
685 _tinydir_strcpy(dir_name_buf, TINYDIR_STRING(
"."));
688 _tinydir_strcat(drive_buf, dir_name_buf);
689 dir_name = drive_buf;
691 _tinydir_strcat(file_name_buf, ext_buf);
692 base_name = file_name_buf;
694 _tinydir_strcpy(dir_name_buf, path);
695 dir_name = dirname(dir_name_buf);
696 _tinydir_strcpy(file_name_buf, path);
697 base_name =basename(file_name_buf);
701 if (tinydir_open(&dir, dir_name) == -1)
709 if (tinydir_readfile(&dir, file) == -1)
714 if (_tinydir_strcmp(file->name, base_name) == 0)
734 void _tinydir_get_ext(tinydir_file *file)
736 _tinydir_char_t *period = _tinydir_strrchr(file->name, TINYDIR_STRING(
'.'));
739 file->extension = &(file->name[_tinydir_strlen(file->name)]);
743 file->extension = period + 1;
748 int _tinydir_file_cmp(
const void *a,
const void *b)
750 const tinydir_file *fa = (
const tinydir_file *)a;
751 const tinydir_file *fb = (
const tinydir_file *)b;
752 if (fa->is_dir != fb->is_dir)
754 return -(fa->is_dir - fb->is_dir);
756 return _tinydir_strncmp(fa->name, fb->name, _TINYDIR_FILENAME_MAX);
760 #ifndef _TINYDIR_USE_READDIR 773 size_t _tinydir_dirent_buf_size(_TINYDIR_DIR *dirp)
780 #if defined _TINYDIR_USE_FPATHCONF 781 name_max = fpathconf(dirfd(dirp), _PC_NAME_MAX);
783 #if defined(NAME_MAX) 784 name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
788 #elif defined(NAME_MAX) 789 name_max = (NAME_MAX > 255) ? NAME_MAX : 255;
791 #error "buffer size for readdir_r cannot be determined" 793 name_end = (size_t)offsetof(
struct _tinydir_dirent, d_name) + name_max + 1;
794 return (name_end >
sizeof(
struct _tinydir_dirent) ?
795 name_end :
sizeof(
struct _tinydir_dirent));
804 # if defined (_MSC_VER) 805 # pragma warning(pop) char d_name[255+1]
Name of file.
This file is a posix/stdc wrapper for lwip/errno.h.
mode_t st_mode
Mode of file.