Created
January 6, 2019 00:31
-
-
Save lukem/693f03e4d0ece63e16c05ca218612d7f to your computer and use it in GitHub Desktop.
boost 1.56 changed Boost.Filesystem recursive_directory_iterator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Workaround Boost.Filesystem V3 behaviour change in boost 1.56. | |
* See original at http://thisthread.blogspot.com/2011/07/using-recursivedirectoryiterator.html | |
*/ | |
void plainListTree(boost::filesystem::path path) // 1. | |
{ | |
dump(path, 0); | |
boost::filesystem::recursive_directory_iterator it = createRIterator(path); | |
boost::filesystem::recursive_directory_iterator end; | |
while(it != end) // 2. | |
{ | |
const std::string curPath(it->path().string()); | |
dump(*it, it.level()); // 3. | |
if(boost::filesystem::is_directory(*it) && boost::filesystem::is_symlink(*it)) // 4. | |
it.no_push(); | |
// advance it | |
try | |
{ | |
++it; // 5. | |
} | |
catch (boost::filesystem::filesystem_error & e) | |
{ | |
std::cout << "warn: " << curPath << ": " << e.what() << std::endl; | |
/* | |
* boost 1.56 changed the behaviour of the recursive_directory_iterator in two ways: | |
* 1. The iterator is advanced before the error is raised (exception thrown), | |
* so the no_push() workaround isn't required. If that workaround is used, | |
* the next path is incorrectly skipped. | |
* 2. Because of (1), accessing it->path().string() in error handling | |
* prints the _next_ path, not the erroneous one. | |
* Handle the older behaviour below. | |
*/ | |
#if BOOST_VERSION < 105600 | |
try | |
{ | |
it.no_push(); // 6. | |
++it; | |
} | |
catch (boost::filesystem::filesystem_error & e) | |
{ | |
std::cout << "fatal error: " << curPath << ": " << e.what() << std::endl; | |
throw; | |
} | |
#endif // BOOST_VERSION < 105600 | |
} | |
} | |
} |
I have put a link to this gist in the blog. Thank you, Luke!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Background
The original code was in http://thisthread.blogspot.com.au/2011/07/using-recursivedirectoryiterator.html
The pattern worked fine with boost 1.41 (Boost.Filesystem V2) on CentOS 6. However, I experienced a behaviour change when using boost 1.64 (Boost.Filesystem V3) on macOS 10.12.
After a lot of debugging, it appears that boost 1.56 changed the behaviour of the recursive_directory_iterator in two ways, one of which directly affects the pattern: (Boost.Filesystem V3 was made the default in boost 1.46, and this behaviour change wasn't made until 1.56):
Fix