summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorDominick Allen <djallen@librehumanitas.org>2025-01-04 09:56:12 -0600
committerDominick Allen <djallen@librehumanitas.org>2025-01-04 09:56:12 -0600
commit0b400af9519444deef4cc6ad2c43c30e2092ab4f (patch)
treee6b0d78a2c292a7df5724f150e123b55d7871819 /source
parent253385f4bca5ccd2fee22fea8333dfe435c0df0a (diff)
Fix bug related to string copying.
Diffstat (limited to 'source')
-rw-r--r--source/fud_string.cpp24
-rw-r--r--source/fud_string_view.cpp115
-rw-r--r--source/libfud.cpp15
3 files changed, 116 insertions, 38 deletions
diff --git a/source/fud_string.cpp b/source/fud_string.cpp
index 2a17201..37a2a4b 100644
--- a/source/fud_string.cpp
+++ b/source/fud_string.cpp
@@ -19,12 +19,11 @@
#include "fud_assert.hpp"
-#include <type_traits>
-
namespace fud {
StringResult String::makeFromCString(const char8_t* cString)
{
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
return makeFromCString(reinterpret_cast<const char*>(cString));
}
@@ -35,6 +34,7 @@ StringResult String::makeFromCString(const char* cString)
StringResult String::makeFromCString(const char8_t* cString, Allocator* allocator)
{
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
return makeFromCString(reinterpret_cast<const char*>(cString), allocator);
}
@@ -61,6 +61,7 @@ StringResult String::makeFromCString(const char* cString, Allocator* allocator)
}
String output{};
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
output.m_allocator = reinterpret_cast<uintptr_t>(allocator);
utf8* outputData{nullptr};
@@ -86,6 +87,7 @@ StringResult String::makeFromCString(const char* cString, Allocator* allocator)
return StringResult::okay(std::move(output));
}
+//NOLINTNEXTLINE(performance-unnecessary-value-param)
StringResult String::from(const String& rhs, Option<Allocator*> allocatorOption)
{
if (!rhs.valid()) {
@@ -98,10 +100,11 @@ StringResult String::from(const String& rhs, Option<Allocator*> allocatorOption)
}
String output{};
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
output.m_allocator = reinterpret_cast<uintptr_t>(allocator);
utf8* outputData{nullptr};
- size_t outputCapacity{0};
- size_t outputLength{0};
+ size_t outputCapacity{rhs.capacity()};
+ size_t outputLength{rhs.length()};
if (rhs.isLarge()) {
auto status = output.makeLarge(outputCapacity, outputLength, outputData);
if (status != FudStatus::Success) {
@@ -132,6 +135,7 @@ StringResult String::from(StringView view, Allocator* allocator)
}
String output{};
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
output.m_allocator = reinterpret_cast<uintptr_t>(allocator);
size_t outputCapacity = view.length() + 1U;
bool isLarge = outputCapacity > SsoBufSize;
@@ -154,7 +158,7 @@ StringResult String::from(StringView view, Allocator* allocator)
return StringResult::okay(std::move(output));
}
-String::String(String&& rhs) noexcept : m_allocator{rhs.m_allocator}, m_repr{std::move(rhs.m_repr)}
+String::String(String&& rhs) noexcept : m_allocator{rhs.m_allocator}, m_repr{rhs.m_repr}
{
rhs.setSmall();
rhs.m_repr.small.length = 0;
@@ -189,6 +193,7 @@ FudStatus String::copy(const String& rhs)
if (allocResult.isError()) {
return allocResult.takeError();
}
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
m_repr.large.data = reinterpret_cast<utf8*>(allocResult.takeOkay());
outputCapacity = m_repr.large.capacity;
outputLength = m_repr.large.length;
@@ -219,7 +224,7 @@ String& String::operator=(String&& rhs) noexcept
cleanup();
m_allocator = rhs.m_allocator;
- m_repr = std::move(rhs.m_repr);
+ m_repr = rhs.m_repr;
if (isLarge()) {
rhs.m_repr.large.data = nullptr;
@@ -232,6 +237,7 @@ void String::cleanup()
{
const auto* allocPtr = allocator();
if (isLarge() && m_repr.large.data != nullptr && allocPtr != nullptr) {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
allocator()->deallocate(reinterpret_cast<std::byte*>(m_repr.large.data), m_repr.large.capacity);
m_repr.large.data = nullptr;
}
@@ -259,6 +265,7 @@ FudStatus String::resize(size_t newCapacity)
auto copyResult = copyMem(dataMut(), temp.size(), temp.data(), len);
fudAssert(copyResult == FudStatus::Success);
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
allocator()->deallocate(reinterpret_cast<std::byte*>(m_repr.large.data), m_repr.large.capacity);
setSmall();
m_repr.small.length = len & smallStringLengthMask;
@@ -272,6 +279,7 @@ FudStatus String::resize(size_t newCapacity)
if (allocResult.isError()) {
return allocResult.takeError();
}
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
auto* newData = reinterpret_cast<utf8*>(allocResult.takeOkay());
fudAssert(newData != nullptr);
@@ -279,6 +287,7 @@ FudStatus String::resize(size_t newCapacity)
fudAssert(copyResult == FudStatus::Success);
if (isLarge()) {
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
allocator()->deallocate(reinterpret_cast<std::byte*>(m_repr.large.data), m_repr.large.capacity);
}
@@ -658,7 +667,7 @@ StringResult String::catenate(const char* rhs) const
if (lenResult < 0 || lenResult >= static_cast<ssize_t>(maxStringLength)) {
return StringResult::error(FudStatus::ArgumentInvalid);
}
- size_t rhsLength = static_cast<size_t>(lenResult);
+ auto rhsLength = static_cast<size_t>(lenResult);
if (maxStringLength - length() < rhsLength) {
return StringResult::error(FudStatus::Failure);
@@ -804,6 +813,7 @@ FudStatus String::makeLarge(size_t cap, size_t len, utf8*& outputData)
if (dataResult.isError()) {
return dataResult.getError();
}
+ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
m_repr.large.data = reinterpret_cast<utf8*>(dataResult.getOkay());
outputData = m_repr.large.data;
setLarge();
diff --git a/source/fud_string_view.cpp b/source/fud_string_view.cpp
index ba88ad4..5c5e623 100644
--- a/source/fud_string_view.cpp
+++ b/source/fud_string_view.cpp
@@ -133,6 +133,96 @@ FudStatus skipWhitespace(StringView& view, size_t& skipIndex)
return FudStatus::Success;
}
+FudStatus fud_string_compare(StringView levo, StringView dextro, int& difference)
+{
+ if (anyAreNull(levo.m_data, dextro.m_data)) {
+ return FudStatus::NullPointer;
+ }
+
+ int diff = 0;
+ size_t index = 0;
+ while (diff == 0 && index < levo.length() && index < dextro.length()) {
+ diff = levo.m_data[index] - dextro.m_data[index];
+ index++;
+ }
+
+ if (diff != 0 || levo.length() == dextro.length()) {
+ /* nothing to do */
+ } else if (levo.length() > dextro.length()) {
+ diff = static_cast<int>(levo.m_data[index]);
+ } else {
+ diff = -static_cast<int>(dextro.m_data[index]);
+ }
+
+ difference = diff;
+ return FudStatus::Success;
+}
+
+bool StringView::operator==(const StringView& rhs) const noexcept
+{
+ if (m_length == rhs.m_length && m_data == rhs.m_data) {
+ return true;
+ }
+ int difference{};
+ auto compareStatus = fud_string_compare(*this, rhs, difference);
+ if (compareStatus != FudStatus::Success) {
+ if (m_data != nullptr && rhs.m_data == nullptr) {
+ return false;
+ }
+ if (m_data == nullptr && rhs.m_data != nullptr) {
+ return false;
+ }
+ fudAssert(m_data == nullptr && rhs.m_data == nullptr);
+ if (m_length > rhs.m_length) {
+ return false;
+ }
+ fudAssert(m_length < rhs.m_length);
+ return false;
+ }
+ if (difference > 0) {
+ return false;
+ }
+ if (difference < 0) {
+ return false;
+ }
+ return true;
+
+}
+
+auto StringView::operator<=>(const StringView& rhs) const noexcept
+{
+ if (this == &rhs) {
+ return std::strong_ordering::equivalent;
+ }
+ if (m_length == rhs.m_length && m_data == rhs.m_data)
+ {
+ return std::strong_ordering::equivalent;
+ }
+ int difference{};
+ auto compareStatus = fud_string_compare(*this, rhs, difference);
+ if (compareStatus != FudStatus::Success) {
+ if (m_data != nullptr && rhs.m_data == nullptr) {
+ return std::strong_ordering::greater;
+ }
+ if (m_data == nullptr && rhs.m_data != nullptr) {
+ return std::strong_ordering::less;
+ }
+ fudAssert(m_data == nullptr && rhs.m_data == nullptr);
+ if (m_length > rhs.m_length) {
+ return std::strong_ordering::greater;
+ }
+ fudAssert(m_length < rhs.m_length);
+ return std::strong_ordering::less;
+ }
+ if (difference > 0) {
+ return std::strong_ordering::greater;
+ }
+ if (difference < 0) {
+ return std::strong_ordering::less;
+ }
+ return std::strong_ordering::equivalent;
+}
+
#if 0
FudStatus fud_string_truncate(ExtBasicString* source, ssize_t newLength)
@@ -226,31 +316,6 @@ FudStatus fud_string_reverse_substring(ExtBasicString* source, StringView subStr
return FudStatus::Success;
}
-FudStatus fud_string_compare(StringView levo, StringView dextro, int* difference)
-{
- if (anyAreNull(difference, levo.data, dextro.data)) {
- return FudStatus::NullPointer;
- }
-
- int diff = 0;
- size_t index = 0;
- while (diff == 0 && index < levo.length && index < dextro.length) {
- diff = levo.data[index] - dextro.data[index];
- index++;
- }
-
- if (diff != 0 || levo.length == dextro.length) {
- /* nothing to do */
- } else if (levo.length > dextro.length) {
- diff = static_cast<int>(levo.data[index]);
- } else {
- diff = -static_cast<int>(dextro.data[index]);
- }
-
- *difference = diff;
- return FudStatus::Success;
-}
-
FudStatus fud_string_chr(StringView extStringView, char character, size_t* index)
{
if (anyAreNull(extStringView.data, index)) {
diff --git a/source/libfud.cpp b/source/libfud.cpp
index be43490..c4e4b5b 100644
--- a/source/libfud.cpp
+++ b/source/libfud.cpp
@@ -35,20 +35,23 @@ FUD fud()
return fudInfo;
}
-Result<String, FudStatus> getEnv(const char* name, Allocator* allocator)
+Result<Option<String>, FudStatus> getEnv(const char* name, Allocator* allocator)
{
- using RetType = Result<String, FudStatus>;
-
if (name == nullptr) {
- return RetType::error(FudStatus::NullPointer);
+ return Error{FudStatus::NullPointer};
}
const char* resultString = getenv(name);
if (resultString == nullptr) {
- return RetType::error(FudStatus::NotFound);
+ return Okay{Option<String>{NullOpt}};
+ }
+
+ auto result{String::makeFromCString(resultString, allocator)};
+ if (result.isError()) {
+ return Error{result.takeError()};
}
- return String::makeFromCString(resultString, allocator);
+ return Okay{Option<String>::take(result.takeOkay())};
}
} // namespace fud