* Calls the specified callback for each file in the specified directory * or any of its child directories if the file name matches the specified * pattern. * * @param path The path. * @param pattern The pattern. * @param callback The callback which is invoked for each matching file. * @param type The file type (a combination of GlobFile and GlobDirectory) */
| 554 | * @param type The file type (a combination of GlobFile and GlobDirectory) |
| 555 | */ |
| 556 | bool Utility::GlobRecursive(const String& path, const String& pattern, const std::function<void (const String&)>& callback, int type) |
| 557 | { |
| 558 | std::vector<String> files, dirs, alldirs; |
| 559 | |
| 560 | #ifdef _WIN32 |
| 561 | HANDLE handle; |
| 562 | WIN32_FIND_DATA wfd; |
| 563 | |
| 564 | String pathSpec = path + "/*"; |
| 565 | |
| 566 | handle = FindFirstFile(pathSpec.CStr(), &wfd); |
| 567 | |
| 568 | if (handle == INVALID_HANDLE_VALUE) { |
| 569 | DWORD errorCode = GetLastError(); |
| 570 | |
| 571 | if (errorCode == ERROR_FILE_NOT_FOUND) |
| 572 | return false; |
| 573 | |
| 574 | BOOST_THROW_EXCEPTION(win32_error() |
| 575 | << boost::errinfo_api_function("FindFirstFile") |
| 576 | << errinfo_win32_error(errorCode) |
| 577 | << boost::errinfo_file_name(pathSpec)); |
| 578 | } |
| 579 | |
| 580 | do { |
| 581 | if (strcmp(wfd.cFileName, ".") == 0 || strcmp(wfd.cFileName, "..") == 0) |
| 582 | continue; |
| 583 | |
| 584 | String cpath = path + "/" + wfd.cFileName; |
| 585 | |
| 586 | if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) |
| 587 | alldirs.push_back(cpath); |
| 588 | |
| 589 | if (!Utility::Match(pattern, wfd.cFileName)) |
| 590 | continue; |
| 591 | |
| 592 | if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (type & GlobFile)) |
| 593 | files.push_back(cpath); |
| 594 | |
| 595 | if ((wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (type & GlobDirectory)) |
| 596 | dirs.push_back(cpath); |
| 597 | } while (FindNextFile(handle, &wfd)); |
| 598 | |
| 599 | if (!FindClose(handle)) { |
| 600 | BOOST_THROW_EXCEPTION(win32_error() |
| 601 | << boost::errinfo_api_function("FindClose") |
| 602 | << errinfo_win32_error(GetLastError())); |
| 603 | } |
| 604 | #else /* _WIN32 */ |
| 605 | DIR *dirp; |
| 606 | |
| 607 | dirp = opendir(path.CStr()); |
| 608 | |
| 609 | if (!dirp) |
| 610 | BOOST_THROW_EXCEPTION(posix_error() |
| 611 | << boost::errinfo_api_function("opendir") |
| 612 | << boost::errinfo_errno(errno) |
| 613 | << boost::errinfo_file_name(path)); |
nothing calls this directly
no test coverage detected