Code cleanups.

This commit is contained in:
Kyle Isom 2023-10-10 18:57:43 -07:00
parent 8dba3d27f2
commit bf1ea5e749
10 changed files with 108 additions and 65 deletions

View File

@ -3,8 +3,7 @@
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#if defined(__linux__) #if defined(__posix__) || defined(__linux__) || defined(__APPLE__)
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
@ -66,8 +65,7 @@ Arena::SetAlloc(size_t allocSize)
} }
#if defined(__linux__) #if defined(__posix__) || defined(__linux__) || defined(__APPLE__)
int int
Arena::MemoryMap(int memFileDes, size_t memSize) Arena::MemoryMap(int memFileDes, size_t memSize)
{ {
@ -205,6 +203,7 @@ Arena::Create(const char *path, size_t fileSize)
#endif #endif
bool bool
Arena::CursorInArena(const uint8_t *cursor) Arena::CursorInArena(const uint8_t *cursor)
{ {
@ -249,7 +248,7 @@ Arena::Destroy()
case ArenaType::Alloc: case ArenaType::Alloc:
delete this->store; delete this->store;
break; break;
#if defined(__linux__) #if defined(__posix__) || defined(__linux__) || defined(__APPLE__)
case ArenaType::MemoryMapped: case ArenaType::MemoryMapped:
if (munmap(this->store, this->size) == -1) { if (munmap(this->store, this->size) == -1) {
abort(); abort();
@ -265,7 +264,7 @@ Arena::Destroy()
#endif #endif
default: default:
#if defined(NDEBUG) #if defined(NDEBUG)
return -1; return;
#else #else
abort(); abort();
#endif #endif
@ -297,7 +296,7 @@ operator<<(std::ostream &os, Arena &arena)
case ArenaType::Alloc: case ArenaType::Alloc:
os << "allocated"; os << "allocated";
break; break;
#if defined(__linux__) #if defined(__posix__) || defined(__linux__) || defined(__APPLE__)
case ArenaType::MemoryMapped: case ArenaType::MemoryMapped:
os << "mmap/file"; os << "mmap/file";
break; break;
@ -322,7 +321,7 @@ Arena::Write(const char *path)
FILE *arenaFile = nullptr; FILE *arenaFile = nullptr;
int retc = -1; int retc = -1;
#if defined(__posix__) || defined(__linux__) #if defined(__posix__) || defined(__linux__) || defined(__APPLE__)
arenaFile = fopen(path, "w"); arenaFile = fopen(path, "w");
if (arenaFile == nullptr) { if (arenaFile == nullptr) {
#else #else

View File

@ -96,7 +96,7 @@ public:
/// \param memFileDes File descriptor to map into memory. /// \param memFileDes File descriptor to map into memory.
/// \param memSize The size of memory to map. /// \param memSize The size of memory to map.
/// \return Returns 0 on success and -1 on error. /// \return Returns 0 on success and -1 on error.
#if defined(__linux__) #if defined(__posix__) || defined(__linux__) || defined(__APPLE__)
int MemoryMap(int memFileDes, size_t memSize); int MemoryMap(int memFileDes, size_t memSize);
#else #else
@ -112,7 +112,7 @@ public:
/// \param path The path to the file that should be created. /// \param path The path to the file that should be created.
/// \param fileSize The size of the file to create. /// \param fileSize The size of the file to create.
/// \return Returns 0 on success and -1 on error. /// \return Returns 0 on success and -1 on error.
#if defined(__linux__) #if defined(__posix__) || defined(__linux__) || defined(__APPLE__)
int Create(const char *path, size_t fileSize); int Create(const char *path, size_t fileSize);
#elif defined(__WIN64__) || defined(__WIN32__) || defined(WIN32) #elif defined(__WIN64__) || defined(__WIN32__) || defined(WIN32)
int Create(const char *path, size_t fileSize); int Create(const char *path, size_t fileSize);

View File

@ -275,6 +275,8 @@ Buffer::HexDump(std::ostream &os)
} }
os << std::setw(0) << std::dec; os << std::setw(0) << std::dec;
#else
(void)os;
#endif #endif
} }

View File

@ -10,7 +10,15 @@ set(VERBOSE YES)
if (MSVC) if (MSVC)
add_compile_options("/W4" "$<$<CONFIG:RELEASE>:/O2>") add_compile_options("/W4" "$<$<CONFIG:RELEASE>:/O2>")
else () else ()
add_compile_options("-Wall" "-Wextra" "-Werror" "$<$<CONFIG:RELEASE>:-O3>") # compile options:
# -Wall Default to all errors.
# -Wextra And a few extra.
# -Werror And require them to be fixed to build.
# -Wno-unused-function This is a library. Not every function is used here.
# -Wno-unused-parameter Some functions have parameters defined for compatibility,
# and aren't used in the implementation.
add_compile_options("-Wall" "-Wextra" "-Werror" "-Wno-unused-function" "-Wno-unused-parameter" "$<$<CONFIG:RELEASE>:-O2>")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_compile_options("-stdlib=libc++") add_compile_options("-stdlib=libc++")
else () else ()
@ -33,10 +41,10 @@ set(SOURCE_FILES
Arena.cc Arena.cc
Buffer.cc Buffer.cc
Dictionary.cc Dictionary.cc
Exceptions.cpp Exceptions.cc
Test.cc Test.cc
TLV.cc TLV.cc
Commander.cpp Commander.cc
Commander.h Commander.h
WinHelpers.cc) WinHelpers.cc)

View File

@ -12,8 +12,8 @@ AssertionFailed::AssertionFailed(std::string message) : msg(message)
{ {
} }
char * const char *
AssertionFailed::what() AssertionFailed::what() const throw()
{ {
return const_cast<char *>(this->msg.c_str()); return const_cast<char *>(this->msg.c_str());
} }

View File

@ -22,7 +22,7 @@ public:
explicit NotImplemented(const char *pl) : platform((char *)pl) {} explicit NotImplemented(const char *pl) : platform((char *)pl) {}
/// what returns a message naming the platform. /// what returns a message naming the platform.
char *what() { const char *what() const throw() {
return this->platform; return this->platform;
} }
private: private:
@ -38,7 +38,7 @@ public:
explicit AssertionFailed(std::string message); explicit AssertionFailed(std::string message);
/// what returns a message describing the exception. /// what returns a message describing the exception.
char *what(); const char *what() const throw();
private: private:
std::string msg; std::string msg;

26
Test.cc
View File

@ -5,14 +5,13 @@
#include "Exceptions.h" #include "Exceptions.h"
#include "Test.h" #include "Test.h"
#include <iostream>
#include <cassert> #include <cassert>
#include <iostream>
#include <sstream>
namespace klib { namespace klib {
void void
TestAssert(bool condition, std::string message = "Assertion failed.") TestAssert(bool condition, std::string message = "Assertion failed.")
{ {
@ -29,4 +28,25 @@ TestAssert(bool condition, std::string message = "Assertion failed.")
} }
void
TestAssert(bool condition)
{
#if defined(NDEBUG)
if (condition) {
return;
}
#if defined(KLIB_NO_ASSERT)
std::cerr << "Assertion failed!\n";
#else
std::stringstream msg;
msg << "assertion failed at " << __FILE__ << ":" << __LINE__;
throw AssertionFailed(msg.str());
#endif
#else
assert(condition);
#endif
}
} // namespace klib } // namespace klib

13
Test.h
View File

@ -13,6 +13,17 @@
namespace klib { namespace klib {
/// TestAssert is a variant on the assert macro. This variant is intended to be
/// a drop-in replacement for the cassert macro: even in release mode, the tests
/// should still run.
///
/// If NDEBUG is set, TestAssert will throw an exception if condition is false.
/// Otherwise, it calls assert after printing the message.
///
/// \param condition If true, TestAssert throws an exception.
void TestAssert(bool condition);
/// TestAssert is a variant on the assert macro. /// TestAssert is a variant on the assert macro.
/// ///
/// If NDEBUG is set, TestAssert will throw an exception if condition is false. /// If NDEBUG is set, TestAssert will throw an exception if condition is false.
@ -24,7 +35,7 @@ namespace klib {
/// ///
/// \param condition The condition to assert. /// \param condition The condition to assert.
/// \param message The message that should be displayed if condition is false. /// \param message The message that should be displayed if condition is false.
inline void TestAssert(bool condition, std::string message); void TestAssert(bool condition, std::string message);
} // namespace klib } // namespace klib

View File

@ -1,31 +1,33 @@
#include <cassert>
#include <iostream> #include <iostream>
#include "Arena.h" #include "Arena.h"
#include "Dictionary.h" #include "Dictionary.h"
#include "Test.h"
#include "testFixtures.h" #include "testFixtures.h"
using namespace klib; using namespace klib;
constexpr char TEST_KVSTR1[] = "foo"; constexpr char TEST_KVSTR1[] = "foo";
constexpr uint8_t TEST_KVSTRLEN1 = 3; constexpr uint8_t TEST_KVSTRLEN1 = 3;
constexpr char TEST_KVSTR2[] = "baz"; constexpr char TEST_KVSTR2[] = "baz";
constexpr uint8_t TEST_KVSTRLEN2 = 3; constexpr uint8_t TEST_KVSTRLEN2 = 3;
constexpr char TEST_KVSTR3[] = "quux"; constexpr char TEST_KVSTR3[] = "quux";
constexpr uint8_t TEST_KVSTRLEN3 = 4; constexpr uint8_t TEST_KVSTRLEN3 = 4;
constexpr char TEST_KVSTR4[] = "spam"; constexpr char TEST_KVSTR4[] = "spam";
constexpr uint8_t TEST_KVSTRLEN4 = 4; constexpr uint8_t TEST_KVSTRLEN4 = 4;
constexpr char TEST_KVSTR5[] = "xyzzx"; constexpr char TEST_KVSTR5[] = "xyzzx";
constexpr uint8_t TEST_KVSTRLEN5 = 5; constexpr uint8_t TEST_KVSTRLEN5 = 5;
constexpr char TEST_KVSTR6[] = "corvid"; constexpr char TEST_KVSTR6[] = "corvid";
constexpr uint8_t TEST_KVSTRLEN6 = 6; constexpr uint8_t TEST_KVSTRLEN6 = 6;
static bool static bool
testSetKV(Dictionary &pb, const char *k, uint8_t kl, const char *v, testSetKV(Dictionary &pb, const char *k, uint8_t kl, const char *v,
uint8_t vl) uint8_t vl)
{ {
bool ok; bool ok;
std::cout << "test Set " << k << "->" << v << "\n"; std::cout << "test Set " << k << "->" << v << "\n";
ok = pb.Set(k, kl, v, vl) == 0; ok = pb.Set(k, kl, v, vl) == 0;
std::cout << "\tSet complete\n"; std::cout << "\tSet complete\n";
@ -36,69 +38,70 @@ testSetKV(Dictionary &pb, const char *k, uint8_t kl, const char *v,
int int
main(int argc, const char *argv[]) main(int argc, const char *argv[])
{ {
(void)argc; (void)argv; (void) argc;
(void) argv;
Arena arena; Arena arena;
TLV::Record value; TLV::Record value;
TLV::Record expect; TLV::Record expect;
std::cout << "TESTPROG: " << argv[0] << "\n"; std::cout << "TESTPROG: " << argv[0] << "\n";
#if defined(__linux__) #if defined(__linux__)
if (arena.Create(ARENA_FILE, ARENA_SIZE) == -1) { if (arena.Create(ARENA_FILE, ARENA_SIZE) == -1) {
abort(); abort();
} }
#else #else
if (arena.SetAlloc(ARENA_SIZE) == -1) { if (arena.SetAlloc(ARENA_SIZE) == -1) {
abort(); abort();
} }
#endif #endif
std::cout << arena << "\n"; std::cout << arena << "\n";
TLV::SetRecord(expect, DICTIONARY_TAG_VAL, TEST_KVSTRLEN3, TEST_KVSTR3); TLV::SetRecord(expect, DICTIONARY_TAG_VAL, TEST_KVSTRLEN3, TEST_KVSTR3);
Dictionary dict(arena); Dictionary dict(arena);
assert(!dict.Contains(TEST_KVSTR2, TEST_KVSTRLEN2)); TestAssert(!dict.Contains(TEST_KVSTR2, TEST_KVSTRLEN2));
assert(testSetKV(dict, TEST_KVSTR1, TEST_KVSTRLEN1, TEST_KVSTR3, TestAssert(testSetKV(dict, TEST_KVSTR1, TEST_KVSTRLEN1, TEST_KVSTR3,
TEST_KVSTRLEN3)); TEST_KVSTRLEN3));
std::cout << dict; std::cout << dict;
assert(testSetKV(dict, TEST_KVSTR2, TEST_KVSTRLEN2, TEST_KVSTR3, TestAssert(testSetKV(dict, TEST_KVSTR2, TEST_KVSTRLEN2, TEST_KVSTR3,
TEST_KVSTRLEN3)); TEST_KVSTRLEN3));
std::cout << dict; std::cout << dict;
assert(dict.Contains(TEST_KVSTR2, TEST_KVSTRLEN2)); TestAssert(dict.Contains(TEST_KVSTR2, TEST_KVSTRLEN2));
assert(testSetKV(dict, TEST_KVSTR4, TEST_KVSTRLEN4, TEST_KVSTR5, TestAssert(testSetKV(dict, TEST_KVSTR4, TEST_KVSTRLEN4, TEST_KVSTR5,
TEST_KVSTRLEN5)); TEST_KVSTRLEN5));
std::cout << dict; std::cout << dict;
assert(dict.Lookup(TEST_KVSTR2, TEST_KVSTRLEN2, value)); TestAssert(dict.Lookup(TEST_KVSTR2, TEST_KVSTRLEN2, value));
assert(cmpRecord(value, expect)); TestAssert(cmpRecord(value, expect));
std::cout << "test overwriting key" << "\n"; std::cout << "test overwriting key" << "\n";
assert(testSetKV(dict, TEST_KVSTR2, TEST_KVSTRLEN2, TEST_KVSTR6, TestAssert(testSetKV(dict, TEST_KVSTR2, TEST_KVSTRLEN2, TEST_KVSTR6,
TEST_KVSTRLEN6)); TEST_KVSTRLEN6));
std::cout << dict; std::cout << dict;
TLV::SetRecord(expect, DICTIONARY_TAG_VAL, TEST_KVSTRLEN6, TEST_KVSTR6); TLV::SetRecord(expect, DICTIONARY_TAG_VAL, TEST_KVSTRLEN6, TEST_KVSTR6);
std::cout << "\tlookup" << "\n"; std::cout << "\tlookup" << "\n";
assert(dict.Lookup(TEST_KVSTR2, TEST_KVSTRLEN2, value)); TestAssert(dict.Lookup(TEST_KVSTR2, TEST_KVSTRLEN2, value));
std::cout << "\tcompare records" << "\n"; std::cout << "\tcompare records" << "\n";
assert(cmpRecord(value, expect)); TestAssert(cmpRecord(value, expect));
std::cout << "\tadd new key to dictionary" << "\n"; std::cout << "\tadd new key to dictionary" << "\n";
assert(testSetKV(dict, TEST_KVSTR3, TEST_KVSTRLEN3, TEST_KVSTR5, TestAssert(testSetKV(dict, TEST_KVSTR3, TEST_KVSTRLEN3, TEST_KVSTR5,
TEST_KVSTRLEN5)); TEST_KVSTRLEN5));
std::cout << dict; std::cout << dict;
TLV::SetRecord(expect, DICTIONARY_TAG_VAL, TEST_KVSTRLEN5, TEST_KVSTR5); TLV::SetRecord(expect, DICTIONARY_TAG_VAL, TEST_KVSTRLEN5, TEST_KVSTR5);
assert(dict.Lookup(TEST_KVSTR4, TEST_KVSTRLEN4, value)); TestAssert(dict.Lookup(TEST_KVSTR4, TEST_KVSTRLEN4, value));
assert(cmpRecord(value, expect)); TestAssert(cmpRecord(value, expect));
std::cout << "OK" <<"\n"; std::cout << "OK" << "\n";
// Dump the generated arena for inspection later. // Dump the generated arena for inspection later.
#if defined(__linux__) #if defined(__linux__)
#else #else
dict.DumpToFile(ARENA_FILE); dict.DumpToFile(ARENA_FILE);
#endif #endif
arena.Clear(); arena.Clear();
std::cout << dict; std::cout << dict;