diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc index e5599fbb6..2beab3c97 100644 --- a/rtengine/dfmanager.cc +++ b/rtengine/dfmanager.cc @@ -263,13 +263,21 @@ void dfInfo::updateBadPixelList( RawImage *df ) void DFManager::init( Glib::ustring pathname ) { std::vector names; - Glib::RefPtr dir = Gio::File::create_for_path (pathname); - if( dir && !dir->query_exists()) { + auto dir = Gio::File::create_for_path (pathname); + if (!dir || !dir->query_exists()) { return; } - safe_build_file_list (dir, names, pathname); + try { + + auto enumerator = dir->enumerate_children (); + + while (auto file = enumerator->next_file ()) { + names.emplace_back (Glib::build_filename (pathname, file->get_name ())); + } + + } catch (Glib::Exception&) {} dfList.clear(); bpList.clear(); diff --git a/rtengine/ffmanager.cc b/rtengine/ffmanager.cc index 13cb20475..6810465c6 100644 --- a/rtengine/ffmanager.cc +++ b/rtengine/ffmanager.cc @@ -209,13 +209,21 @@ void ffInfo::updateRawImage() void FFManager::init( Glib::ustring pathname ) { std::vector names; - Glib::RefPtr dir = Gio::File::create_for_path (pathname); - if( dir && !dir->query_exists()) { + auto dir = Gio::File::create_for_path (pathname); + if (!dir || !dir->query_exists()) { return; } - safe_build_file_list (dir, names, pathname); + try { + + auto enumerator = dir->enumerate_children (); + + while (auto file = enumerator->next_file ()) { + names.emplace_back (Glib::build_filename (pathname, file->get_name ())); + } + + } catch (Glib::Exception&) {} ffList.clear(); diff --git a/rtengine/safegtk.cc b/rtengine/safegtk.cc index c37d25aa0..6e6ac99ae 100644 --- a/rtengine/safegtk.cc +++ b/rtengine/safegtk.cc @@ -31,85 +31,6 @@ #include #endif -Glib::RefPtr safe_next_file (Glib::RefPtr &dirList) -{ - Glib::RefPtr info; - - bool retry; - Glib::ustring last_error = ""; - - do { - retry = false; - - try { - info = dirList->next_file(); - } catch (Glib::Exception& ex) { - printf ("%s\n", ex.what().c_str()); - // API problem: not possible to differ between error looking at particular entry or - // general error scanning the directory. We do a hack by retrying and see if the - // error changes, if it does we can assume it's about the current filename and we - // should look at the next. More likely if a single file error is that the next - // retry is okay of course. - retry = (ex.what() != last_error); - last_error = ex.what(); - } - } while (retry); - - return info; -} - -# define SAFE_ENUMERATOR_CODE_START(attributes) \ - do{try { if ((dirList = dir->enumerate_children ((attributes)))) \ - for (Glib::RefPtr info = safe_next_file(dirList); info; info = safe_next_file(dirList)) { - -# define SAFE_ENUMERATOR_CODE_END \ - }} catch (Glib::Exception& ex) { printf ("%s\n", ex.what().c_str()); }}while(0) - -/* - * safe_build_file_list can now filter out at the source all files that don't have the extensions specified (if provided) - */ -void safe_build_file_list (Glib::RefPtr &dir, std::vector &names, const Glib::ustring &directory, const std::vector *extensions) -{ - Glib::RefPtr dirList; - - if (dir) { - if (!extensions) { - SAFE_ENUMERATOR_CODE_START("standard::name") - names.push_back (Glib::build_filename (directory, info->get_name())); - SAFE_ENUMERATOR_CODE_END; - } else { - // convert extensions to lowercase in a new vector list - std::vector lcExtensions; - - for (unsigned int i = 0; i < extensions->size(); i++) { - lcExtensions.push_back ((*extensions)[i].lowercase()); - } - - SAFE_ENUMERATOR_CODE_START("standard::name") - // convert the current filename to lowercase in a new ustring - Glib::ustring fname = Glib::ustring(info->get_name()).lowercase(); - - size_t pos = fname.find_last_of('.'); - - if (pos < (fname.length() - 1)) { - // there is an extension to the filename - - Glib::ustring lcFileExt = fname.substr(pos + 1).lowercase(); - - // look out if it has one of the retained extensions - for (size_t i = 0; i < lcExtensions.size(); i++) { - if (lcFileExt == lcExtensions[i]) { - names.push_back (Glib::build_filename (directory, info->get_name())); - break; - } - } - } - - SAFE_ENUMERATOR_CODE_END; - } - } -} - /* * For an unknown reason, Glib::filename_to_utf8 doesn't work on Windows, so we're using * Glib::filename_to_utf8 for Linux/Apple and Glib::locale_to_utf8 for Windows diff --git a/rtengine/safegtk.h b/rtengine/safegtk.h index 6a205be9e..07553632c 100644 --- a/rtengine/safegtk.h +++ b/rtengine/safegtk.h @@ -5,8 +5,6 @@ #include #include -void safe_build_file_list (Glib::RefPtr &dir, std::vector &names, const Glib::ustring &directory = "", const std::vector *extensions = NULL); - bool safe_spawn_command_line_async (const Glib::ustring& cmd_utf8); bool safe_spawn_command_line_sync (const Glib::ustring& cmd_utf8); diff --git a/rtgui/batchqueue.cc b/rtgui/batchqueue.cc index 7e9659ef0..6c9b791e2 100644 --- a/rtgui/batchqueue.cc +++ b/rtgui/batchqueue.cc @@ -676,22 +676,31 @@ rtengine::ProcessingJob* BatchQueue::imageReady (rtengine::IImage16* img) if (saveBatchQueue ()) { ::g_remove (processedParams.c_str ()); - // Delete all files in directory \batch when finished, just to be sure to remove zombies - // Not sure that locking is necessary, but it should be safer - MYREADERLOCK(l, entryRW); + // Delete all files in directory batch when finished, just to be sure to remove zombies + auto isEmpty = false; - if( fd.empty() ) { - MYREADERLOCK_RELEASE(l); + { +#if PROTECT_VECTORS + MYREADERLOCK(l, entryRW); +#endif + isEmpty = fd.empty(); + } - std::vector names; - Glib::ustring batchdir = Glib::build_filename(options.rtdir, "batch"); - Glib::RefPtr dir = Gio::File::create_for_path (batchdir); - safe_build_file_list (dir, names, batchdir); + if (isEmpty) { - for (auto iter = names.begin (); iter != names.end (); ++iter) { - ::g_remove (iter->c_str ()); - } + const auto batchdir = Glib::build_filename (options.rtdir, "batch"); + + try { + + auto dir = Gio::File::create_for_path (batchdir); + auto enumerator = dir->enumerate_children ("standard::name"); + + while (auto file = enumerator->next_file ()) { + ::g_remove (Glib::build_filename (batchdir, file->get_name ()).c_str ()); + } + + } catch (Glib::Exception&) {} } } diff --git a/rtgui/filecatalog.cc b/rtgui/filecatalog.cc index 05689fda1..10ecdaaf7 100644 --- a/rtgui/filecatalog.cc +++ b/rtgui/filecatalog.cc @@ -542,11 +542,44 @@ void FileCatalog::closeDir () std::vector FileCatalog::getFileList () { - std::vector names; - Glib::RefPtr dir = Gio::File::create_for_path (selectedDirectory); - safe_build_file_list (dir, names, selectedDirectory, &(options.parsedExtensions)); -// Issue 2406 std::sort (names.begin(), names.end()); + + std::set extensions; + for (const auto& parsedExt : options.parsedExtensions) { + extensions.emplace (parsedExt.lowercase ()); + } + + try { + + auto dir = Gio::File::create_for_path (selectedDirectory); + + auto enumerator = dir->enumerate_children (); + + while (auto file = enumerator->next_file ()) { + + const Glib::ustring fname = file->get_name (); + + auto lastdot = fname.find_last_of ('.'); + if (lastdot >= fname.length () - 1) { + continue; + } + + const auto fext = fname.substr (lastdot + 1).lowercase (); + if (extensions.count (fext) == 0) { + continue; + } + + names.emplace_back (Glib::build_filename (selectedDirectory, fname)); + } + + } catch (Glib::Exception& exception) { + + if (options.rtSettings.verbose) { + std::cerr << "Failed to list directory \"" << selectedDirectory << "\": " << exception.what() << std::endl; + } + + } + return names; } diff --git a/rtgui/main.cc b/rtgui/main.cc index dce1b1103..7342a2c84 100644 --- a/rtgui/main.cc +++ b/rtgui/main.cc @@ -497,39 +497,54 @@ int processLineParams( int argc, char **argv ) break; case 'c': // MUST be last option - while( iArg + 1 < argc ) { + while (iArg + 1 < argc) { iArg++; - if( !safe_file_test( safe_filename_to_utf8(argv[iArg]), Glib::FILE_TEST_EXISTS )) { - std::cerr << argv[iArg] << " doesn't exist." << std::endl; + const auto argument = safe_filename_to_utf8 (argv[iArg]); + + if (Glib::file_test (argument, Glib::FILE_TEST_IS_REGULAR)) { + inputFiles.emplace_back (argument); continue; } - if( safe_file_test( safe_filename_to_utf8(argv[iArg]), Glib::FILE_TEST_IS_DIR )) { - std::vector names; - Glib::RefPtr dir = Gio::File::create_for_path ( argv[iArg] ); - safe_build_file_list (dir, names, argv[iArg] ); + if (Glib::file_test (argument, Glib::FILE_TEST_IS_DIR)) { - for(size_t iFile = 0; iFile < names.size(); iFile++ ) { - if( !safe_file_test( names[iFile] , Glib::FILE_TEST_IS_DIR)) { - // skip files without extension and without sidecar files - Glib::ustring s(names[iFile]); - Glib::ustring::size_type ext = s.find_last_of('.'); - - if( Glib::ustring::npos == ext ) { - continue; - } - - if( ! s.substr(ext).compare( paramFileExtension )) { - continue; - } - - inputFiles.push_back( names[iFile] ); - } + auto dir = Gio::File::create_for_path (argument); + if (!dir || !dir->query_exists()) { + continue; } - } else { - inputFiles.push_back( safe_filename_to_utf8 (argv[iArg]) ); + + try { + + auto enumerator = dir->enumerate_children (); + + while (auto file = enumerator->next_file ()) { + + const auto fileName = Glib::build_filename (argument, file->get_name ()); + + if (Glib::file_test (fileName, Glib::FILE_TEST_IS_DIR)) { + continue; + } + + // skip files without extension and sidecar files + auto lastdot = fileName.find_last_of('.'); + if (lastdot == Glib::ustring::npos) { + continue; + } + + if (fileName.substr (lastdot).compare (paramFileExtension) == 0) { + continue; + } + + inputFiles.emplace_back (fileName); + } + + } catch (Glib::Exception&) {} + + continue; } + + std::cerr << "\"" << argument << "\" is neither a regular file nor a directory." << std::endl; } break;