Skip to content

Commit

Permalink
refactor file pattern matching for forcing data retrieval
Browse files Browse the repository at this point in the history
  • Loading branch information
JoshCu committed Feb 19, 2025
1 parent 9005062 commit 4486ed0
Showing 1 changed file with 37 additions and 45 deletions.
82 changes: 37 additions & 45 deletions include/realizations/catchment/Formulation_Manager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,54 +517,46 @@ namespace realization {
errMsg = "Received system error number " + std::to_string(errno);
}

// If the directory could be found and opened, we can go ahead and iterate
if (directory != nullptr) {
bool match;
while ((entry = readdir(directory))) {
match = std::regex_match(entry->d_name, pattern);
if( match ) {
// If the entry is a regular file or symlink AND the name matches the pattern,
// we can consider this ready to be interpretted as valid forcing data (even if it isn't)
#ifdef _DIRENT_HAVE_D_TYPE
if ( entry->d_type == DT_REG or entry->d_type == DT_LNK ) {
return forcing_params(
path + entry->d_name,
provider,
simulation_time_config.start_time,
simulation_time_config.end_time,
enable_cache
);
}
else if ( entry->d_type == DT_UNKNOWN )
#endif
{
//dirent is not guaranteed to provide propoer file type identification in d_type
//so if a system returns unknown or it isn't supported, need to use stat to determine if it is a file
struct stat st;
if( stat((path+entry->d_name).c_str(), &st) != 0) {
throw std::runtime_error("Could not stat file "+path+entry->d_name);
}
if( S_ISREG(st.st_mode) ) {
//Sinde we used stat and not lstat, we get the result of the target of links as well
//so this covers both cases we are interested in.
return forcing_params(
path + entry->d_name,
provider,
simulation_time_config.start_time,
simulation_time_config.end_time,
enable_cache
);
}
throw std::runtime_error("Forcing data is path "+path+entry->d_name+" is not a file");
}
} //no match found, try next entry
} // end while iter dir
} //end if directory
else {
// The directory wasn't found or otherwise couldn't be opened; forcing data cannot be retrieved
// If the directory could not be opened, throw an error
if (directory == nullptr) {
errMsg = "Received system error number " + std::to_string(errno);
throw std::runtime_error("Error opening forcing data dir '" + path + "' after " + std::to_string(attemptCount) + " attempts: " + errMsg);
}

// Check if the file pattern is a file itself
std::ifstream possible_file(path + filepattern);
if (possible_file.good()) {
possible_file.close();
closedir(directory);
return forcing_params(
path + filepattern,
provider,
simulation_time_config.start_time,
simulation_time_config.end_time,
enable_cache
);
}

// If that failed, use regex to find the file
bool match;
while ((entry = readdir(directory))) {
match = std::regex_match(entry->d_name, pattern);
if( match ) {
possible_file.open(path + entry->d_name);
if (possible_file.good()) {
possible_file.close();
closedir(directory);
return forcing_params(
path + entry->d_name,
provider,
simulation_time_config.start_time,
simulation_time_config.end_time,
enable_cache
);
}
}
}
possible_file.close();
closedir(directory);

throw std::runtime_error("Forcing data could not be found for '" + identifier + "'");
Expand Down

0 comments on commit 4486ed0

Please sign in to comment.