diff --git a/src/olympic/studio/modlib/include/studio/project.hpp b/src/olympic/studio/modlib/include/studio/project.hpp index 9908889a..8efc7bb9 100644 --- a/src/olympic/studio/modlib/include/studio/project.hpp +++ b/src/olympic/studio/modlib/include/studio/project.hpp @@ -36,6 +36,15 @@ constexpr ox::Result fileExt(ox::CRStringView path) noexcept { return substr(path, extStart + 1); } +[[nodiscard]] +constexpr ox::StringView parentDir(ox::StringView path) noexcept { + if (path.len() && path[path.len() - 1] == '/') { + path = substr(path, 0, path.len() - 1); + } + auto const extStart = ox::find(path.crbegin(), path.crend(), '/').offset(); + return substr(path, 0, extStart); +} + class Project { private: keel::Context &m_ctx; @@ -108,6 +117,7 @@ template ox::Error Project::writeObj(ox::CRStringView path, T const&obj, ox::ClawFormat fmt) noexcept { oxRequireM(buff, ox::writeClaw(obj, fmt)); // write to FS + oxReturnError(mkdir(parentDir(path))); oxReturnError(writeBuff(path, buff)); // write type descriptor if (m_typeStore.get().error) { diff --git a/src/olympic/studio/modlib/src/project.cpp b/src/olympic/studio/modlib/src/project.cpp index cd0d2f5f..0a87fd75 100644 --- a/src/olympic/studio/modlib/src/project.cpp +++ b/src/olympic/studio/modlib/src/project.cpp @@ -13,6 +13,11 @@ namespace studio { +static_assert(fileExt("main.c").value == "c"); +static_assert(fileExt("a.b.c").value == "c"); +static_assert(parentDir("/a/b/c") == "/a/b"); +static_assert(parentDir("/a/b/c/") == "/a/b"); + static void generateTypes(ox::TypeStore &ts) noexcept { for (auto const mod : keel::modules()) { for (auto gen : mod->types()) {