summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--cmake/warnings.cmake82
-rw-r--r--include/fud_assert.hpp2
-rw-r--r--include/fud_c_file.hpp2
-rw-r--r--include/fud_memory.hpp6
-rw-r--r--include/fud_utf8.hpp11
-rw-r--r--include/libfud.hpp9
-rw-r--r--source/fud_directory.cpp16
-rw-r--r--source/fud_sqlite.cpp16
-rw-r--r--source/fud_string.cpp6
-rw-r--r--source/fud_utf8.cpp12
-rwxr-xr-xtools/coverage.sh5
-rwxr-xr-xtools/create-pyenv.sh9
-rwxr-xr-xtools/run-cppcheck.sh46
14 files changed, 165 insertions, 60 deletions
diff --git a/.gitignore b/.gitignore
index 2eece04..b374a73 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,4 +9,5 @@ cppcheck.json
test/fuzztest
dist/
.semgrepignore
-.#* \ No newline at end of file
+.#*
+fudenv/
diff --git a/cmake/warnings.cmake b/cmake/warnings.cmake
index 03d7a32..cd3cdf9 100644
--- a/cmake/warnings.cmake
+++ b/cmake/warnings.cmake
@@ -1,65 +1,93 @@
set(FUD_WARNINGS
+ # baseline
-Werror
- -Wstack-usage=2048
- -Wno-long-long
- -Wno-error=long-long
- -Wno-error=inline
- -Wno-error=mismatched-tags
-Wall
- -Weffc++
+ -Wextra
-pedantic
- -Wsizeof-pointer-memaccess
-pedantic-errors
- -Wextra
+ -Wstack-usage=2048 # GCC specific
+ -Wvla # variable modified types don't play nice in C++
+ # types
+ -Wlong-long
+ -Wlong-long
+ -Winline
+ # memory / data / array / string
+ -Wsizeof-pointer-memaccess
-Wpacked
- -Wshadow
- -Wvla
- -Wnull-dereference
-Wuninitialized
-Wstack-protector
-Warray-bounds
-Woverlength-strings
-Wwrite-strings
- -Wcast-qual
-Wcast-align
- -Wdisabled-optimization
+ -Wchar-subscripts
+ -Wpointer-arith
+ -Wstrict-aliasing
+ -Wstrict-aliasing=2
+ -Wstrict-null-sentinel
+ # classes / initialization
+ -Weffc++
+ -Wmismatched-tags
-Wmissing-field-initializers
- -Wimport
-Winit-self
- -Wchar-subscripts
- -Wcomment
- -Wconversion
- -Wfloat-equal
+ -Wctor-dtor-privacy
+ -Wnon-virtual-dtor
+ -Wsuggest-final-types
+ -Wsuggest-final-methods
+ -Wsuggest-override
+ # format
-Wformat
-Wformat=2
-Wformat-nonliteral
-Wformat-security
-Wformat-y2k
-Wmissing-format-attribute
+ -Wformat-overflow
+ -Wformat-security
+ -Wformat-signedness
+ # floats and signedness
+ -Wfloat-equal
+ -Wsign-compare
+ -Wsign-conversion
+ -Wdouble-promotion
+ # semantics / style
+ -Wshadow
+ -Wnull-dereference
+ -Wimplicit-fallthrough=5
+ -Wduplicated-branches
+ -Wduplicated-cond
+ -Wcast-qual
+ -Wcomment
+ -Wconversion
-Wmissing-braces
-Winvalid-pch
-Wmissing-include-dirs
- -Wmissing-noreturn
-Wparentheses
- -Wpointer-arith
-Wredundant-decls
-Wreturn-type
-Wsequence-point
- -Wsign-compare
- -Wstrict-aliasing
- -Wstrict-aliasing=2
- -Wswitch
- -Wswitch-default
- -Wswitch-enum
-Wtrigraphs
-Wunknown-pragmas
- -Wunreachable-code
-Wunused
-Wunused-function
-Wunused-label
-Wunused-parameter
-Wunused-value
-Wunused-variable
+ -Wswitch
+ -Wswitch-default
+ -Wswitch-enum
+ # this plays badly with clangd
+ # -Wzero-as-null-pointer-constant
+ -Wlogical-op
+ -Wuseless-cast
+ -Wextra-semi
+ -Wredundant-decls
+ -Wmisleading-indentation
+ # optmizations
+ -Wdisabled-optimization
+ -Wmissing-noreturn
-Wvariadic-macros
-Wvolatile-register-var
+ -Wunreachable-code
)
diff --git a/include/fud_assert.hpp b/include/fud_assert.hpp
index 5b63703..fd861ea 100644
--- a/include/fud_assert.hpp
+++ b/include/fud_assert.hpp
@@ -24,7 +24,7 @@ void assertFail(const char* assertion, const char* file, unsigned int line, cons
__attribute__((__noreturn__));
#define fudAssert(expr) \
- (static_cast<bool>(expr) ? static_cast<void>(0) : assertFail(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__))
+ ((expr) ? static_cast<void>(0) : assertFail(#expr, __FILE__, __LINE__, __PRETTY_FUNCTION__))
} // namespace fud
diff --git a/include/fud_c_file.hpp b/include/fud_c_file.hpp
index 3b7d821..0908841 100644
--- a/include/fud_c_file.hpp
+++ b/include/fud_c_file.hpp
@@ -151,7 +151,7 @@ class CFile {
FILE* file()
{
- auto& self = static_cast<Derived&>(*this);
+ const auto& self = static_cast<const Derived&>(*this);
return self.m_file;
}
diff --git a/include/fud_memory.hpp b/include/fud_memory.hpp
index 41393bd..62ff81a 100644
--- a/include/fud_memory.hpp
+++ b/include/fud_memory.hpp
@@ -77,7 +77,7 @@ void copyMem(T& destination, const U& source)
for (size_t idx = 0; idx < Count; ++idx) {
// NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast)
- reinterpret_cast<uint8_t*>(&destination)[idx] = reinterpret_cast<const uint8_t*>(&source)[idx];
+ reinterpret_cast<char*>(&destination)[idx] = reinterpret_cast<const char*>(&source)[idx];
// NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)
}
}
@@ -115,11 +115,13 @@ int compareMem(const T& lhs, U&& rhs)
static_assert(Count <= sizeof(T));
static_assert(Count <= sizeof(U));
+ U uRhs{std::forward<U>(rhs)};
+
int difference = 0;
for (size_t idx = 0; idx < Count; ++idx) {
// NOLINTBEGIN(cppcoreguidelines-pro-type-reinterpret-cast)
difference = reinterpret_cast<const uint8_t*>(&lhs)[idx] -
- reinterpret_cast<const uint8_t*>(&std::forward<U>(rhs))[idx];
+ reinterpret_cast<const uint8_t*>(&uRhs)[idx];
// NOLINTEND(cppcoreguidelines-pro-type-reinterpret-cast)
if (difference != 0) {
break;
diff --git a/include/fud_utf8.hpp b/include/fud_utf8.hpp
index 99766d4..5b84a3a 100644
--- a/include/fud_utf8.hpp
+++ b/include/fud_utf8.hpp
@@ -19,7 +19,6 @@
#define FUD_UTF8_HPP
#include "fud_array.hpp"
-#include "fud_memory.hpp"
#include "fud_status.hpp"
#include "fud_unique_array.hpp"
@@ -62,7 +61,7 @@ constexpr bool validUtf8MB(utf8 code) noexcept
struct Ascii {
Array<utf8, 1> characters;
- constexpr Ascii() noexcept = default;
+ constexpr Ascii() noexcept = default; // cppcheck-suppress uninitMemberVar
constexpr explicit Ascii(utf8 chr) noexcept : characters{{chr}}
{
@@ -252,10 +251,10 @@ struct FudUtf8 {
static constexpr Ascii invalidAsciiCode{Ascii{0xFF}};
static FudUtf8 fromString(const String& fudString, size_t index) noexcept;
- static FudUtf8 fromStringView(StringView&& fudView, size_t index) noexcept;
- static FudUtf8 fromStringView(const StringView& fudView, size_t index) noexcept;
+ static FudUtf8 fromStringView(StringView&& view, size_t index) noexcept;
+ static FudUtf8 fromStringView(const StringView& view, size_t index) noexcept;
- static constexpr FudUtf8 makeUtf8(Array<utf8, 4>& data)
+ static constexpr FudUtf8 makeUtf8(const Array<utf8, 4>& data)
{
FudUtf8 unicode{};
if (Ascii::valid(data[0])) {
@@ -367,10 +366,10 @@ struct FudUtf8 {
[[nodiscard]] constexpr int64_t hash() const noexcept
{
- using fud::Utf8Type;
using fud::Utf82Byte;
using fud::Utf83Byte;
using fud::Utf84Byte;
+ using fud::Utf8Type;
if (!valid()) {
return -1;
diff --git a/include/libfud.hpp b/include/libfud.hpp
index 1e6df5d..271d55b 100644
--- a/include/libfud.hpp
+++ b/include/libfud.hpp
@@ -27,6 +27,15 @@ namespace fud {
/** \brief Fear, unknown, doubt. Call at your own peril. */
void fud();
+/**
+ * \brief Get an environmental variable if it exists.
+ *
+ * \param[in] name The name of the variable to look up.
+ *
+ * \retstmt The value of the string bound to the variable if it exists.
+ * \retcode FudStatus::NullPointer if name is a null pointer.
+ * \retcode FudStatus::NotFound if no binding for the variable exists.
+ */
Result<String, FudStatus> getEnv(const char* name);
template<typename T>
diff --git a/source/fud_directory.cpp b/source/fud_directory.cpp
index 6851158..5772c95 100644
--- a/source/fud_directory.cpp
+++ b/source/fud_directory.cpp
@@ -137,15 +137,15 @@ Result<DirectoryEntry, FudStatus> Directory::info()
return RetType::error(m_status);
}
- Stat statBuffer{};
- auto status = fstat(m_dirFd, &statBuffer);
- if (status == -1) {
+ Stat sBuffer{};
+ auto fStatus = fstat(m_dirFd, &sBuffer);
+ if (fStatus == -1) {
m_errorCode = errno;
m_status = FudStatus::Failure;
return RetType::error(m_status);
}
- auto retValue = DirectoryEntry::fromStat(m_name, statBuffer);
+ auto retValue = DirectoryEntry::fromStat(m_name, sBuffer);
if (retValue.isOkay()) {
m_errorCode = 0;
@@ -187,17 +187,17 @@ Result<std::optional<DirectoryEntry>, FudStatus> Directory::getNextEntry()
m_errorCode = 0;
- Stat statBuffer{};
+ Stat sBuffer{};
auto flags = 0;
- auto status = fstatat(m_dirFd, entryNameCString, &statBuffer, flags);
- if (status == -1) {
+ auto fStatus = fstatat(m_dirFd, entryNameCString, &sBuffer, flags);
+ if (fStatus == -1) {
m_errorCode = errno;
m_status = FudStatus::Failure;
return RetType::error(m_status);
}
auto entryName = String{entryNameCString};
- auto retValue = DirectoryEntry::fromStat(entryName, statBuffer);
+ auto retValue = DirectoryEntry::fromStat(entryName, sBuffer);
if (retValue.isOkay()) {
m_errorCode = 0;
diff --git a/source/fud_sqlite.cpp b/source/fud_sqlite.cpp
index f573f1c..e07523d 100644
--- a/source/fud_sqlite.cpp
+++ b/source/fud_sqlite.cpp
@@ -58,6 +58,8 @@ SqliteDb& SqliteDb::operator=(SqliteDb&& rhs)
m_nameValid = rhs.m_nameValid;
m_dbHandle = rhs.m_dbHandle;
m_errorCode = rhs.m_errorCode;
+ m_mode = rhs.m_mode;
+ m_extraFlags = rhs.m_extraFlags;
rhs.m_nameValid = false;
rhs.m_dbHandle = nullptr;
@@ -94,9 +96,9 @@ FudStatus SqliteDb::exec(
}
char* errorMsgPtr = nullptr;
- char** errorMsgPtrAddress = &errorMsgPtr;
- if (errorMessage == nullptr) {
- errorMsgPtrAddress = nullptr;
+ char** errorMsgPtrAddress = nullptr;
+ if (errorMessage != nullptr) {
+ errorMsgPtrAddress = &errorMsgPtr;
}
m_errorCode = sqlite3_exec(
@@ -106,6 +108,10 @@ FudStatus SqliteDb::exec(
context,
errorMsgPtrAddress);
+ if (errorMessage != nullptr) {
+ *errorMessage = String{errorMsgPtr};
+ }
+
return m_errorCode == SQLITE_OK ? FudStatus::Success : FudStatus::Failure;
}
@@ -126,10 +132,10 @@ int SqliteDb::open()
return sqlite3_open_v2(m_name.c_str(), &m_dbHandle, static_cast<int>(m_mode) | m_extraFlags, nullptr);
}
-Result<SqliteStatement, FudStatus> SqliteDb::prepare(const String& dql)
+Result<SqliteStatement, FudStatus> SqliteDb::prepare(const String& sql)
{
using RetType = Result<SqliteStatement, FudStatus>;
- SqliteStatement preparedStatement{*this, dql};
+ SqliteStatement preparedStatement{*this, sql};
if (!preparedStatement.valid() || preparedStatement.status() != FudStatus::Success) {
m_errorCode = preparedStatement.errorCode();
diff --git a/source/fud_string.cpp b/source/fud_string.cpp
index 10352ad..4cffb60 100644
--- a/source/fud_string.cpp
+++ b/source/fud_string.cpp
@@ -357,12 +357,12 @@ FudStatus String::append(StringView source)
return FudStatus::Aliased;
}
- const auto newLength = length() + source.length();
+ const size_t newLength = length() + source.length();
if (newLength < length()) {
return FudStatus::OperationInvalid;
}
- const auto newSize = newLength + 1;
- if (newSize < newLength) {
+ const size_t newSize = newLength + 1; // cppcheck-suppress knownConditionTrueFalse
+ if (newSize < newLength) { // cppcheck-suppress knownConditionTrueFalse
return FudStatus::OperationInvalid;
}
if (newSize >= m_capacity) {
diff --git a/source/fud_utf8.cpp b/source/fud_utf8.cpp
index 1c23581..50b5d31 100644
--- a/source/fud_utf8.cpp
+++ b/source/fud_utf8.cpp
@@ -41,32 +41,32 @@ FudUtf8 FudUtf8::fromStringView(const StringView& view, size_t index) noexcept
FudUtf8 FudUtf8::fromStringView(StringView&& view, size_t index) noexcept
{
auto len = view.length();
- const auto* data = view.data();
- if (data == nullptr) {
+ const auto* vData = view.data();
+ if (vData == nullptr) {
return invalidAscii();
}
- FudUtf8 localChar{Ascii{data[index]}};
+ FudUtf8 localChar{Ascii{vData[index]}};
if (localChar.valid()) {
return localChar;
}
if (index + 1 < len) {
- localChar.m_variant = Utf82Byte{data[index], data[index + 1]};
+ localChar.m_variant = Utf82Byte{vData[index], vData[index + 1]};
}
if (localChar.valid()) {
return localChar;
}
if (index + 2 < len) {
- localChar.m_variant = Utf83Byte{data[index], data[index + 1], data[index + 2]};
+ localChar.m_variant = Utf83Byte{vData[index], vData[index + 1], vData[index + 2]};
}
if (localChar.valid()) {
return localChar;
}
if (index + 3 < len) {
- localChar.m_variant = Utf84Byte{data[index], data[index + 1], data[index + 2], data[index + 3]};
+ localChar.m_variant = Utf84Byte{vData[index], vData[index + 1], vData[index + 2], vData[index + 3]};
}
if (localChar.valid()) {
return localChar;
diff --git a/tools/coverage.sh b/tools/coverage.sh
new file mode 100755
index 0000000..5caa6f0
--- /dev/null
+++ b/tools/coverage.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+ctest --test-dir build/test -j8
+mkdir -p build/html
+gcovr --exclude-throw-branches --exclude build/_deps/ --exclude test -r source . --html-details build/html/gcovr_report.html
diff --git a/tools/create-pyenv.sh b/tools/create-pyenv.sh
new file mode 100755
index 0000000..64b1fbf
--- /dev/null
+++ b/tools/create-pyenv.sh
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+PROJ_ROOT=$(git rev-parse --show-toplevel)
+cd $PROJ_ROOT
+
+python3 -m venv fudenv
+. fudenv/bin/activate
+pip install cppcheck-codequality
+deactivate
diff --git a/tools/run-cppcheck.sh b/tools/run-cppcheck.sh
new file mode 100755
index 0000000..1f8ee7d
--- /dev/null
+++ b/tools/run-cppcheck.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# libfud
+# Copyright 2024 Dominick Allen
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+PROJ_ROOT=$(git rev-parse --show-toplevel)
+cd $PROJ_ROOT
+
+COMPILE_COMMANDS='build/compile_commands.json'
+
+cppcheck \
+ --verbose \
+ --inline-suppr \
+ --checkers-report=build/cppcheck-checkers-report.log \
+ --suppress=useStlAlgorithm \
+ --suppress=missingIncludeSystem \
+ --suppress=functionStatic \
+ --suppress=functionConst \
+ --suppress=unusedFunction \
+ --enable=all \
+ --inconclusive \
+ --max-ctu-depth=8 \
+ --check-level=exhaustive \
+ -i build/ \
+ --cppcheck-build-dir=build/ \
+ --project="$COMPILE_COMMANDS" \
+ --verbose \
+ --error-exitcode=2 \
+ --xml 2> build/err.xml
+
+cppcheck-htmlreport --file=build/err.xml --report-dir=build/cppcheck_report --source-dir="$PROJ_ROOT"
+. fudenv/bin/activate
+python3 -m cppcheck_codequality --input-file=build/err.xml --base-dir=$PROJ_ROOT --output-file=build/cppcheck.json
+deactivate