Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.vs/
.vscode/
.idea/
.xmake/
*.db
*.vcxproj.user

Expand Down Expand Up @@ -46,3 +47,4 @@ Caprica/INSTALL.vcxproj.filters
Caprica/cmake_install.cmake

x64/
vs*/
14 changes: 7 additions & 7 deletions Caprica/common/CapricaReportingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ void CapricaReportingContext::breakIfDebugging() {

void CapricaReportingContext::exitIfErrors() {
if (errorCount > 0) {
pushToErrorStream(fmt::format("Compilation of '{}' failed; {} warnings and {} errors were encountered.", filename, warningCount, errorCount));
pushToErrorStream(std::format("Compilation of '{}' failed; {} warnings and {} errors were encountered.", filename, warningCount, errorCount));
throw std::runtime_error("");
}
}
Expand Down Expand Up @@ -63,7 +63,7 @@ size_t CapricaReportingContext::getLocationLine(CapricaFileLocation location, si
}
}
// TODO: Fix line offsets during parsing for reals, remove this hack
// maybePushMessage(this, nullptr, "Warning:", 0, fmt::format("Unable to locate line at offset {}, using last known line {}...", location.startOffset, lineOffsets.size()), true);
// maybePushMessage(this, nullptr, "Warning:", 0, std::format("Unable to locate line at offset {}, using last known line {}...", location.startOffset, lineOffsets.size()), true);
return lineOffsets.size();
// CapricaReportingContext::logicalFatal("Unable to locate line at offset {}.", location.startOffset);
}
Expand All @@ -74,7 +74,7 @@ std::string CapricaReportingContext::formatLocation(CapricaFileLocation loc) {
auto line = getLocationLine(loc);
auto column = loc.startOffset - lineOffsets.at(line - 1) + 1;
auto columnEnd = loc.endOffset - loc.startOffset + column;
return fmt::format("{} ({}, {}:{})", filename, line, column, columnEnd);
return std::format("{} ({}, {}:{})", filename, line, column, columnEnd);
}

void CapricaReportingContext::maybePushMessage(CapricaReportingContext* ctx,
Expand All @@ -87,16 +87,16 @@ void CapricaReportingContext::maybePushMessage(CapricaReportingContext* ctx,
if (ctx->isWarningEnabled(*location, warningNumber)) {
if (ctx->isWarningError(*location, warningNumber)) {
ctx->errorCount++;
pushToErrorStream(fmt::format("{}: Error W{}: {}", ctx->formatLocation(*location), warningNumber, msg), true);
pushToErrorStream(std::format("{}: Error W{}: {}", ctx->formatLocation(*location), warningNumber, msg), true);
} else {
ctx->warningCount++;
pushToErrorStream(fmt::format("{}: Warning W{}: {}", ctx->formatLocation(*location), warningNumber, msg));
pushToErrorStream(std::format("{}: Warning W{}: {}", ctx->formatLocation(*location), warningNumber, msg));
}
}
} else if (location != nullptr) {
pushToErrorStream(fmt::format("{}: {}: {}", ctx->formatLocation(*location), msgType, msg), forceAsError);
pushToErrorStream(std::format("{}: {}: {}", ctx->formatLocation(*location), msgType, msg), forceAsError);
} else {
pushToErrorStream(fmt::format("{}: {}", msgType, msg), forceAsError);
pushToErrorStream(std::format("{}: {}", msgType, msg), forceAsError);
}
}

Expand Down
29 changes: 14 additions & 15 deletions Caprica/common/CapricaReportingContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#include <string_view>
#include <vector>

#include <fmt/format.h>
#include <format>

#include <common/allocators/FileOffsetPool.h>
#include <common/CapricaFileLocation.h>
Expand Down Expand Up @@ -42,24 +42,31 @@ struct CapricaReportingContext final {
void exitIfErrors();

template <typename... Args>
NEVER_INLINE void error(CapricaFileLocation location, fmt::format_string<Args...> msg, Args&&... args) {
ALWAYS_INLINE void warning(CapricaFileLocation location, size_t warningNumber, std::string_view msg, Args&&... args) {
Copy link
Owner

Choose a reason for hiding this comment

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

This shift means we no longer have the ability to get compile-time checking of format strings for warnings and errors :( Is it really worth losing that just to shift to std::format?

Copy link
Author

@qudix qudix Apr 28, 2025

Choose a reason for hiding this comment

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

I didn't work on it for too long, but switching over to std::format_string<Args...> resulted in a compile time error I couldn't quite figure out from the macros.

error C7595: 'std::basic_format_string<char,caprica::identifier_ref &>::basic_format_string': call to immediate function is not a constant expression

I would say that in the short term it's not really a big deal, and it results in one less third-party dependency. Regardless I'll look into it some more.

Copy link
Author

Choose a reason for hiding this comment

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

Actually thinking on it more using string_view and passing that to vformat as I did here does at least do compile time argument checking, but not compile time format checking because that's not a thing until c++26.

// TODO: fix Imports hack
if (!m_QuietWarnings)
maybePushMessage(this, &location, "", warningNumber, std::vformat(msg, std::make_format_args(args...)));
}

template <typename... Args>
NEVER_INLINE void error(CapricaFileLocation location, std::string_view msg, Args&&... args) {
errorCount++;
maybePushMessage(this, &location, "Error", 0, fmt::format(msg, std::forward<Args>(args)...), true);
maybePushMessage(this, &location, "Error", 0, std::vformat(msg, std::make_format_args(args...)), true);
breakIfDebugging();
}

template <typename... Args>
[[noreturn]] NEVER_INLINE void fatal(CapricaFileLocation location, fmt::format_string<Args...> msg, Args&&... args) {
maybePushMessage(this, &location, "Fatal Error", 0, fmt::format(msg, std::forward<Args>(args)...), true);
[[noreturn]] NEVER_INLINE void fatal(CapricaFileLocation location, std::string_view msg, Args&&... args) {
maybePushMessage(this, &location, "Fatal Error", 0, std::vformat(msg, std::make_format_args(args...)), true);
throw std::runtime_error("");
}

// The difference between this and fatal is that this is intended for places
// where the logic of Caprica itself has failed, and a location in a source
// file is likely not available.
template <typename... Args>
[[noreturn]] NEVER_INLINE static void logicalFatal(fmt::format_string<Args...> msg, Args&&... args) {
maybePushMessage(nullptr, nullptr, "Fatal Error", 0, fmt::format(msg, std::forward<Args>(args)...), true);
[[noreturn]] NEVER_INLINE static void logicalFatal(std::string_view msg, Args&&... args) {
maybePushMessage(nullptr, nullptr, "Fatal Error", 0, std::vformat(msg, std::make_format_args(args...)), true);
throw std::runtime_error("");
}

Expand Down Expand Up @@ -334,14 +341,6 @@ struct CapricaReportingContext final {
size_t warnNum,
const std::string& msg,
bool forceAsError = false);

template <typename... Args>
ALWAYS_INLINE void
warning(CapricaFileLocation location, size_t warningNumber, fmt::format_string<Args...> msg, Args&&... args) {
// TODO: fix Imports hack
if (!m_QuietWarnings)
maybePushMessage(this, &location, "", warningNumber, fmt::format(msg, std::forward<Args>(args)...));
}
};

}
12 changes: 6 additions & 6 deletions Caprica/common/identifier_ref.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#include <string>
#include <string_view>

#include <fmt/format.h>
#include <format>

#include <common/UtilMacros.h>

Expand Down Expand Up @@ -97,18 +97,18 @@ bool operator!=(const char* x, const identifier_ref& y);

}

namespace fmt {
template <>
struct formatter<caprica::identifier_ref> {
constexpr auto parse(format_parse_context& ctx) {
struct std::formatter<caprica::identifier_ref>
{
template <class ParseContext>
constexpr auto parse(ParseContext& ctx) {
if (ctx.begin() != ctx.end())
throw format_error("invalid format");
return ctx.end();
}

template <class FormatContext>
auto format(const caprica::identifier_ref& str, FormatContext& ctx) const {
return fmt::format_to(ctx.out(), "{}", str.to_string_view());
return std::format_to(ctx.out(), "{}", str.to_string_view());
}
};
}
8 changes: 3 additions & 5 deletions Caprica/papyrus/PapyrusIdentifier.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include <string>
#include <string_view>

#include <fmt/format.h>
#include <format>

#include <common/CapricaFileLocation.h>
#include <common/CapricaReportingContext.h>
Expand Down Expand Up @@ -176,9 +176,8 @@ struct PapyrusIdentifier final {

}}

namespace fmt {
template <>
struct formatter<caprica::papyrus::PapyrusIdentifierType> {
struct std::formatter<caprica::papyrus::PapyrusIdentifierType> {
constexpr auto parse(format_parse_context& ctx) {
if (ctx.begin() != ctx.end())
throw format_error("invalid format");
Expand All @@ -187,7 +186,6 @@ struct formatter<caprica::papyrus::PapyrusIdentifierType> {

template <class FormatContext>
auto format(const caprica::papyrus::PapyrusIdentifierType& tp, FormatContext& ctx) const {
return fmt::format_to(ctx.out(), "{}", caprica::papyrus::PapyrusIdentifier::prettyTypeString(tp));
return std::format_to(ctx.out(), "{}", caprica::papyrus::PapyrusIdentifier::prettyTypeString(tp));
}
};
}
8 changes: 3 additions & 5 deletions Caprica/papyrus/PapyrusType.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <memory>
#include <string>

#include <fmt/format.h>
#include <format>

#include <common/CapricaFileLocation.h>
#include <common/CapricaReportingContext.h>
Expand Down Expand Up @@ -152,9 +152,8 @@ inline auto& operator|=(PapyrusType::PoisonKind& a, PapyrusType::PoisonKind b) {

}}

namespace fmt {
template <>
struct formatter<caprica::papyrus::PapyrusType> {
struct std::formatter<caprica::papyrus::PapyrusType> {
constexpr auto parse(format_parse_context& ctx) {
if (ctx.begin() != ctx.end())
throw format_error("invalid format");
Expand All @@ -163,7 +162,6 @@ struct formatter<caprica::papyrus::PapyrusType> {

template <class FormatContext>
auto format(const caprica::papyrus::PapyrusType& tp, FormatContext& ctx) const {
return fmt::format_to(ctx.out(), "{}", tp.prettyString());
return std::format_to(ctx.out(), "{}", tp.prettyString());
}
};
}
36 changes: 36 additions & 0 deletions xmake.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
-- set minimum xmake version
set_xmakever("2.9.8")

-- set project
set_project("caprica")
set_languages("c++23")
set_license("MIT")
set_version("0.3.0")

-- require packages
add_requires("boost", { configs = { filesystem = true, program_options = true, container = true } })
add_requires("pugixml")

namespace("caprica", function()
-- define targets
target("caprica", function()
set_kind("$(kind)")

-- bind package dependencies
add_packages("boost", "pugixml", { public = true })

-- add all source files
add_files("caprica/**/**.cpp")

if is_kind("binary") then
add_files("caprica/**.cpp")
end

-- add all header files
add_includedirs("caprica", { public = true })
add_headerfiles("(caprica/**.h)")

-- add flags
add_cxxflags("cl::/Zc:inline", "cl::/bigobj")
end)
end)
Loading