Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rely on std::filesystem for file_utils #3042

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from

Conversation

drewejohnson
Copy link
Contributor

Description

file_utils is more like a thin wrapper over std::filesystem primarily because we have a lot of strings describing files being passed around.

First attempt was to remove file_utils in favor of direct calls to things like std::filesystem::exists and
std::filesystem::path::get_extension. However, many places in openmc use strings to store paths to files and directories which would require patterns that previously look like

if (!file_exists(member_string_var_)) {
...
}

where a class stores a string file path at member_string_var_. These would become

std::filesystem::path p(member_string_var_);
if (!std::filesystem::exists(p)) {
...
}

This second pattern would be repeated in a lot of the code base, so keeping file_exists(const std::string&) means less repeated code.

An alternative is to use std::filesystem::path objects to represent paths to files and directories. This would work pretty easily in at least two locations:

  • Library::path_
  • DAGUniverse::filename_

But the primary source of "strings for paths" is due to various settings, e.g., settings::path_input. I don't believe those can be converted to std::filesystem::path objects because they must be more portable to C and, by extension, Python.

Fixes #3041

Checklist

  • I have performed a self-review of my own code
  • I have run clang-format (version 15) on any C++ source files (if applicable)
  • I have followed the style guidelines for Python source files (if applicable)
  • I have made corresponding changes to the documentation (if applicable)
    • All internal so no doc changes needed at this time
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
    • Should be handled by existing tests for things that use file_utils.
    • Happy to add some new tests as requested

First attempt was to remove `file_utils` in favor of direct calls
to things like `std::filesystem::exists` and
``std::filesystem::path::get_extension`. However, many places in
openmc use strings to store paths to files and directories which
would require patterns that previously look like
```cpp
if (!file_exists(member_string_var_)) {
...
}
```
where a class stores a string file path at `member_string_var_`
to change to
```cpp
std::filesystem::path p(member_string_var_);
if (!std::filesystem::exists(p)) {
...
}
```
This second pattern would be repeated in a lot of the code base,
so keeping `file_exists(std::string)` means less repeated code.

An alternative is to use `std::filesystem::path` objects to represent
paths to files and directories. This would work pretty easily in at
least two locations:

- `Library::path_`
- `DAGUniverse::filename_`

But the primary source of "strings for paths" is due to various
settings, e.g., `settings::path_input`. I don't believe those can be
converted to `std::filesystem::path` objects because they must be
more portable to C and, by extension, Python.

Closes openmc-dev#3041
Copy link
Contributor

@gridley gridley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. This revised code is objectively cleaner. Really, shouldn't extern std::string not even work for the C API? If it's working, it's by coincidence. Casting an std::string to char* and using it through a C API may or may not give the right behavior.

Maybe it'd be worth considering changing the global variables to be paths, then altering the C API to work with that, rather than directly manipulating char* variables in the C API. Whoever else reviews this can decide that matter!

Sorry about the weird behavior with the numeric "extensions" not counting as extensions.

Andrew Johnson added 4 commits June 20, 2024 15:21
Always writes an h5 formatted file to the provided
filepath, even if the extension is not .h5
Always writes an h5 formatted file to the
provided filepath, even if the extension is not .h5
@drewejohnson
Copy link
Contributor Author

Thanks @gridley! Regarding

Maybe it'd be worth considering changing the global variables to be paths, then altering the C API to work with that, rather than directly manipulating char* variables in the C API. Whoever else reviews this can decide that matter!

I'm open to the idea as we do a lot of path manipulation off those settings. Things like settings::path_input feel like they should be paths, .e.g.,

src/settings.cpp
278:  std::string filename = settings::path_input + "settings.xml";

src/tallies/tally.cpp
844:  std::string filename = settings::path_input + "tallies.xml";

src/material.cpp
1319:  std::string filename = settings::path_input + "materials.xml";

src/plot.cpp
182:  std::string filename = settings::path_input + "plots.xml";

But, that's also a larger API change that could have more knock on effects that I'm not considering

Andrew Johnson added 2 commits June 20, 2024 16:15
Previous implementation returned the substring up to and including
the final directory separator. This is not consistent with
`std::filesystem::path::parent_path`
Andrew Johnson added 2 commits June 21, 2024 09:30
Avoids needing to modify a user-provided file name in
write_source_point and write_mcnp_source_point
Copy link
Contributor

@paulromano paulromano left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@drewejohnson This looks good to me, but there is a conflict from the recent merging of #3055. Can you merge develop into your branch and resolve the conflict?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Move to C++17 for std::filesystem
3 participants