diff --git a/source/mijin/debug/stacktrace.cpp b/source/mijin/debug/stacktrace.cpp index 461af41..e230211 100644 --- a/source/mijin/debug/stacktrace.cpp +++ b/source/mijin/debug/stacktrace.cpp @@ -53,7 +53,7 @@ int backtraceFullCallback(void* data, std::uintptr_t programCounter, const char* { BacktraceData& btData = *static_cast(data); btData.stackframes.push_back({ - .address = reinterpret_cast(programCounter), + .address = reinterpret_cast(programCounter), // NOLINT(performance-no-int-to-ptr) .filename = filename ? filename : "", .function = function ? function : "", .lineNumber = lineno @@ -121,7 +121,7 @@ using cxa_rethrow_type = void (*)(); cxa_throw_type orig_cxa_throw = nullptr; // Address of the original __cxa_throw // cxa_rethrow_type orig_cxa_rethrow = nullptr; // Address of the original __cxa_rethrow -extern "C" void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*)) +extern "C" void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*)) // NOLINT(bugprone-reserved-identifier,cert-dcl37-c,cert-dcl51-cpp) { if (!orig_cxa_throw) { orig_cxa_throw = reinterpret_cast(dlsym(RTLD_NEXT, "__cxa_throw")); diff --git a/source/mijin/io/process.cpp b/source/mijin/io/process.cpp index 1e0fde2..5bca5cc 100644 --- a/source/mijin/io/process.cpp +++ b/source/mijin/io/process.cpp @@ -4,7 +4,7 @@ #include #include #include "../detect.hpp" -#include "../util/iterators.hpp" +#include "../debug/assert.hpp" #include "../util/string.hpp" #if MIJIN_TARGET_OS == MIJIN_OS_LINUX || MIJIN_TARGET_OS == MIJIN_OS_OSX @@ -34,10 +34,10 @@ StreamError ProcessStream::open(const char* command, FileOpenMode mode_) modeStr = "rw"; break; default: - assert(!"Unsupported mode for ProcessStream::open()"); + MIJIN_ERROR("Unsupported mode for ProcessStream::open()"); return StreamError::NOT_SUPPORTED; } - handle = popen(command, modeStr); // NOLINT(cppcoreguidelines-owning-memory) + handle = popen(command, modeStr); // NOLINT(cppcoreguidelines-owning-memory,cert-env33-c) if (!handle) { return StreamError::IO_ERROR; } @@ -47,7 +47,7 @@ StreamError ProcessStream::open(const char* command, FileOpenMode mode_) int ProcessStream::close() { - assert(handle); + MIJIN_ASSERT(handle != nullptr, "Process stream has not been opened."); const int result = pclose(handle); handle = nullptr; return result; @@ -55,10 +55,10 @@ int ProcessStream::close() StreamError ProcessStream::readRaw(std::span buffer, const ReadOptions& options, std::size_t* outBytesRead) { - assert(handle); - assert(mode == FileOpenMode::READ || mode == FileOpenMode::READ_WRITE); + MIJIN_ASSERT(handle != nullptr, "Process stream has not been openend."); + MIJIN_ASSERT(mode == FileOpenMode::READ || mode == FileOpenMode::READ_WRITE, "Cannot read from this process stream."); - if (bufferedChar >= 0 && buffer.size() > 0) + if (bufferedChar >= 0 && !buffer.empty()) { buffer[0] = static_cast(bufferedChar); } @@ -80,8 +80,8 @@ StreamError ProcessStream::readRaw(std::span buffer, const ReadOpt StreamError ProcessStream::writeRaw(std::span buffer) { - assert(handle); - assert(mode == FileOpenMode::WRITE || mode == FileOpenMode::READ_WRITE); + MIJIN_ASSERT(handle != nullptr, "Process stream has not been opened."); + MIJIN_ASSERT(mode == FileOpenMode::WRITE || mode == FileOpenMode::READ_WRITE, "Cannot write to this process stream."); const std::size_t written = std::fwrite(buffer.data(), 1, buffer.size(), handle); if (written != buffer.size() || std::ferror(handle)) { @@ -93,7 +93,7 @@ StreamError ProcessStream::writeRaw(std::span buffer) std::size_t ProcessStream::tell() { - assert(handle); + MIJIN_ASSERT(handle != nullptr, "Process stream has not been opened."); return std::ftell(handle); // TODO: does this work? } @@ -108,22 +108,19 @@ StreamError ProcessStream::seek(std::intptr_t pos, SeekMode seekMode) void ProcessStream::flush() { const int result = std::fflush(handle); - assert(result == 0); + MIJIN_ASSERT(result == 0, "Error flushing process stream."); } bool ProcessStream::isAtEnd() { - assert(handle); + MIJIN_ASSERT(handle != nullptr, "Process stream has not been opened."); if (bufferedChar >= 0) { return false; } bufferedChar = std::fgetc(handle); - if (std::feof(handle)) { - return true; - } - return false; + return static_cast(std::feof(handle)); } StreamFeatures ProcessStream::getFeatures() @@ -161,6 +158,7 @@ std::string shellEscape(const std::string& arg) noexcept case '$': oss << '\\'; break; + default: break; } oss << chr; } diff --git a/source/mijin/io/process.hpp b/source/mijin/io/process.hpp index 260a086..896fdc7 100644 --- a/source/mijin/io/process.hpp +++ b/source/mijin/io/process.hpp @@ -26,7 +26,7 @@ public: [[nodiscard]] inline bool isOpen() const { return handle != nullptr; } // Stream overrides - StreamError readRaw(std::span buffer, const ReadOptions& options = {}, std::size_t* outBytesRead = nullptr) override; + StreamError readRaw(std::span buffer, const ReadOptions& options, std::size_t* outBytesRead) override; StreamError writeRaw(std::span buffer) override; std::size_t tell() override; StreamError seek(std::intptr_t pos, SeekMode seekMode = SeekMode::ABSOLUTE) override; diff --git a/source/mijin/io/stream.cpp b/source/mijin/io/stream.cpp index 6498ad0..2d9ea34 100644 --- a/source/mijin/io/stream.cpp +++ b/source/mijin/io/stream.cpp @@ -75,7 +75,7 @@ StreamError Stream::writeBinaryString(std::string_view str) { MIJIN_ASSERT(str.length() <= std::numeric_limits::max(), "Binary string is too long."); const std::uint32_t length = static_cast(str.length()); - StreamError error = write(length); + const StreamError error = write(length); if (error != StreamError::SUCCESS) { return error; } @@ -118,12 +118,12 @@ StreamError Stream::getTotalLength(std::size_t& outLength) return StreamError::NOT_SUPPORTED; } const std::size_t origPos = tell(); - if (StreamError error = seek(0, SeekMode::RELATIVE_TO_END); error != StreamError::SUCCESS) + if (const StreamError error = seek(0, SeekMode::RELATIVE_TO_END); error != StreamError::SUCCESS) { return error; } outLength = tell(); - if (StreamError error = seek(static_cast(origPos)); error != StreamError::SUCCESS) + if (const StreamError error = seek(static_cast(origPos)); error != StreamError::SUCCESS) { return error; } @@ -134,12 +134,12 @@ StreamError Stream::readRest(TypelessBuffer& outBuffer) { // first try to allocate everything at once std::size_t length = 0; - if (StreamError lengthError = getTotalLength(length); lengthError == StreamError::SUCCESS) + if (const StreamError lengthError = getTotalLength(length); lengthError == StreamError::SUCCESS) { MIJIN_ASSERT(getFeatures().tell, "How did you find the length if you cannot tell()?"); length -= tell(); outBuffer.resize(length); - if (StreamError error = readRaw(outBuffer.data(), length); error != StreamError::SUCCESS) + if (const StreamError error = readRaw(outBuffer.data(), length); error != StreamError::SUCCESS) { return error; } @@ -153,13 +153,13 @@ StreamError Stream::readRest(TypelessBuffer& outBuffer) while (!isAtEnd()) { std::size_t bytesRead = 0; - if (StreamError error = readRaw(chunk, {.partial = true}, &bytesRead); error != StreamError::SUCCESS) + if (const StreamError error = readRaw(chunk, {.partial = true}, &bytesRead); error != StreamError::SUCCESS) { return error; } outBuffer.resize(outBuffer.byteSize() + bytesRead); - std::span bufferBytes = outBuffer.makeSpan(); + const std::span bufferBytes = outBuffer.makeSpan(); std::copy_n(chunk.begin(), bytesRead, bufferBytes.end() - static_cast(bytesRead)); } return StreamError::SUCCESS; @@ -213,14 +213,14 @@ StreamError Stream::readLine(std::string& outString) { // read into the buffer std::size_t bytesRead = 0; - if (StreamError error = readRaw(buffer, {.partial = true, .peek = true}, &bytesRead); error != StreamError::SUCCESS) + if (const StreamError error = readRaw(buffer, {.partial = true, .peek = true}, &bytesRead); error != StreamError::SUCCESS) { return error; } // try to find a \n - auto begin = buffer.begin(); - auto end = buffer.begin() + bytesRead; - auto newline = std::find(begin, end, '\n'); + auto begin = buffer.begin(); // NOLINT(readability-qualified-auto) + auto end = buffer.begin() + bytesRead; // NOLINT(readability-qualified-auto) + auto newline = std::find(begin, end, '\n'); // NOLINT(readability-qualified-auto) if (newline != end) { @@ -235,7 +235,7 @@ StreamError Stream::readLine(std::string& outString) } // read again, this time to skip - if (StreamError error = readSpan(begin, end); error != StreamError::SUCCESS) + if (const StreamError error = readSpan(begin, end); error != StreamError::SUCCESS) { return error; } @@ -262,9 +262,9 @@ mijin::Task Stream::c_readLine(std::string& outString) co_return error; } // try to find a \n - auto begin = buffer.begin(); - auto end = buffer.begin() + bytesRead; - auto newline = std::find(begin, end, '\n'); + auto begin = buffer.begin(); // NOLINT(readability-qualified-auto) + auto end = buffer.begin() + bytesRead; // NOLINT(readability-qualified-auto) + auto newline = std::find(begin, end, '\n'); // NOLINT(readability-qualified-auto) if (newline != end) { @@ -359,7 +359,7 @@ StreamError FileStream::readRaw(std::span buffer, const ReadOption } if (options.peek) { - if (StreamError error = seek(-static_cast(readBytes), SeekMode::RELATIVE); error != StreamError::SUCCESS) + if (const StreamError error = seek(-static_cast(readBytes), SeekMode::RELATIVE); error != StreamError::SUCCESS) { return error; } diff --git a/source/mijin/types/name.cpp b/source/mijin/types/name.cpp index d475999..d78d0fe 100644 --- a/source/mijin/types/name.cpp +++ b/source/mijin/types/name.cpp @@ -82,7 +82,7 @@ static std::size_t getOrCreateStringID(std::string_view string) // 3. copy global state and check local again { - std::shared_lock lock(getGlobalNamesMutex()); + const std::shared_lock lock(getGlobalNamesMutex()); copyNamesToLocal(); } @@ -96,7 +96,7 @@ static std::size_t getOrCreateStringID(std::string_view string) } // 4. insert a new ID - std::unique_lock lock(getGlobalNamesMutex()); + const std::unique_lock lock(getGlobalNamesMutex()); const std::size_t idx = getGlobalNames().size(); getGlobalNames().emplace_back(string); copyNamesToLocal(); diff --git a/source/mijin/util/os.cpp b/source/mijin/util/os.cpp index 997b0d0..21ef754 100644 --- a/source/mijin/util/os.cpp +++ b/source/mijin/util/os.cpp @@ -4,6 +4,7 @@ #include #if MIJIN_TARGET_OS == MIJIN_OS_LINUX + #include #include #include #elif MIJIN_TARGET_OS == MIJIN_OS_WINDOWS @@ -31,6 +32,13 @@ namespace mijin // internal variables // +#if MIJIN_TARGET_OS == MIJIN_OS_LINUX +namespace +{ +std::mutex gDlErrorMutex; // dlerror may not be thread-safe +} +#endif // MIJIN_TARGET_OS == MIJIN_OS_LINUX + // // internal functions // @@ -42,6 +50,7 @@ namespace mijin Result openSharedLibrary(std::string_view libraryFile) noexcept { #if MIJIN_TARGET_OS == MIJIN_OS_LINUX + const std::unique_lock dlErrorLock(gDlErrorMutex); dlerror(); const fs::path libraryPath = fs::absolute(libraryFile); diff --git a/source/mijin/virtual_filesystem/filesystem.cpp b/source/mijin/virtual_filesystem/filesystem.cpp index acf3072..758f739 100644 --- a/source/mijin/virtual_filesystem/filesystem.cpp +++ b/source/mijin/virtual_filesystem/filesystem.cpp @@ -44,7 +44,7 @@ std::vector OSFileSystemAdapter::listFiles(const fs::path& folder) { std::vector entries; std::error_code err; - fs::directory_iterator iterator(folder, fs::directory_options::skip_permission_denied, err); + const fs::directory_iterator iterator(folder, fs::directory_options::skip_permission_denied, err); if (err) { return {}; // TODO: propagate? } diff --git a/source/mijin/virtual_filesystem/stacked.cpp b/source/mijin/virtual_filesystem/stacked.cpp index f01d2f3..b588433 100644 --- a/source/mijin/virtual_filesystem/stacked.cpp +++ b/source/mijin/virtual_filesystem/stacked.cpp @@ -107,7 +107,7 @@ StreamError StackedFileSystemAdapter::open(const fs::path& path, FileOpenMode mo { for (auto& adapter : adapters_) { - FileInfo fileInfo = adapter->getFileInfo(path); + const FileInfo fileInfo = adapter->getFileInfo(path); if (fileInfo.exists) { return adapter->open(path, mode, outStream); }