diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/fud_assert.cpp | 63 | ||||
-rw-r--r-- | source/fud_format.cpp | 64 |
2 files changed, 104 insertions, 23 deletions
diff --git a/source/fud_assert.cpp b/source/fud_assert.cpp index 8811464..0c4d7cf 100644 --- a/source/fud_assert.cpp +++ b/source/fud_assert.cpp @@ -1,39 +1,56 @@ #include "fud_assert.hpp" -// #include "fud_array.hpp" -// #include "fud_format.hpp" +#include "fud_format.hpp" +#include "fud_string.hpp" #include <climits> #include <cstdio> #include <exception> -// #include <format> namespace fud { -// constexpr std::size_t BITS_PER_OCTAL = 3; -// constexpr auto MAX_LINE_CHARS = BITS_PER_OCTAL * sizeof(decltype(std::source_location{}.line())) + 3; +struct BufferSink { + DrainResult drain(StringView source); +}; -[[noreturn]] void assertFail(const char* assertion, const std::source_location sourceLocation) +DrainResult BufferSink::drain(StringView source) +{ + DrainResult result{0, FudStatus::Success}; + if (source.m_data == nullptr) { + result.status = FudStatus::NullPointer; + return result; + } + if (source.m_length == 0) { + result.status = FudStatus::Success; + return result; + } + result.bytesWritten = fwrite(reinterpret_cast<const char*>(source.m_data), 1, source.m_length, stderr); + if (result.bytesWritten != source.m_length) { + result.status = FudStatus::Full; + } + return result; +} + +namespace impl { +void assertFailMessage(const char* assertion, const std::source_location sourceLocation) { - const char* file_name = sourceLocation.file_name(); - if (file_name == nullptr) { - fputs("Unknown file", stderr); - } else { - fputs(file_name, stderr); + BufferSink sink; + const char* fileName = sourceLocation.file_name(); + if (fileName == nullptr) { + fileName = "Unknown file"; + } + const char* functionName = sourceLocation.function_name(); + if (functionName == nullptr) { + functionName = "Unknown Function"; } + format(sink, FormatCharMode::Unchecked, "{}:{}:{}: {}\n", fileName, functionName, sourceLocation.line(), assertion); +} - /* - constexpr std::size_t assertMsgSize = MAX_LINE_CHARS + 3; - Array<char, assertMsgSize> buffer{}; - static_cast<void>(std::format_to_n(buffer.data(), buffer.size() - 1U, ":{}:", sourceLocation.line())); - buffer[buffer.size() - 1] = '\0'; - fputs(buffer.data(), stderr); - */ - - fputs(sourceLocation.function_name(), stderr); - fputs(": ", stderr); - fputs(assertion, stderr); - fputc('\n', stderr); +} // namespace impl + +[[noreturn]] void assertFail(const char* assertion, const std::source_location sourceLocation) +{ + impl::assertFailMessage(assertion, sourceLocation); std::terminate(); } diff --git a/source/fud_format.cpp b/source/fud_format.cpp index 6bd5aae..f3e6894 100644 --- a/source/fud_format.cpp +++ b/source/fud_format.cpp @@ -507,6 +507,70 @@ FudStatus getFormatSign(StringView& formatView, FormatSpec& spec) return FudStatus::Success; } +size_t findSpec(StringView scanView) +{ + size_t index = 0; + bool foundBracket = false; + while (index < scanView.length()) { + auto letter = scanView[index]; + if (letter == FormatSpec::openBracket && not foundBracket) { + foundBracket = true; + } else if (letter == FormatSpec::openBracket && foundBracket) { + foundBracket = false; + } else if (foundBracket) { + index--; + break; + } + index++; + } + + return index; +} + +FudStatus fillUnsignedBuffer( + Array<utf8, maxIntCharCount>& buffer, + uint64_t value, + uint8_t& bufferLength, + Radix radix, + bool uppercase) +{ + static_assert(maxIntCharCount < std::numeric_limits<uint8_t>::max()); + bufferLength = 0; + + constexpr Array<uint8_t, static_cast<size_t>(Radix::Hexadecimal)> lower{ + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}}; + constexpr Array<uint8_t, static_cast<size_t>(Radix::Hexadecimal)> upper{ + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}}; + const auto& lookup = uppercase ? upper : lower; + + if (value == 0) { + buffer[0] = '0'; + bufferLength = 1; + return FudStatus::Success; + } + + static_assert(std::is_same_v<std::underlying_type_t<Radix>, uint8_t>); + auto radixValue = static_cast<uint8_t>(radix); + while (value > 0 && bufferLength < maxIntCharCount) { + auto digit = static_cast<uint8_t>(value % radixValue); + buffer[bufferLength] = lookup[digit]; + value /= radixValue; + bufferLength++; + } + + if (value > 0 || bufferLength > maxIntCharCount) { + return FudStatus::Failure; + } + + // TODO: implement fud_algorithm reverse + for (size_t idx = 0; idx < bufferLength / 2; ++idx) { + auto rhsIndex = bufferLength - idx - 1; + std::swap(buffer[idx], buffer[rhsIndex]); + } + + return FudStatus::Success; +} + } // namespace impl } // namespace fud |