cppcheck cleanups and additional docs+testing.

This commit is contained in:
Kyle Isom 2023-10-21 23:33:22 -07:00
parent 9faed6a95b
commit 9a8dc08a4f
8 changed files with 191 additions and 76 deletions

View File

@ -47,99 +47,116 @@ namespace scsl {
/// memory if possible, but only if #AutoTrimIsEnabled (it is by default). /// memory if possible, but only if #AutoTrimIsEnabled (it is by default).
class Buffer { class Buffer {
public: public:
/// A Buffer can be constructed empty, with no memory allocated (yet). /// \brief Construct an empty buffer with no memory allocated.
Buffer(); Buffer();
/// A Buffer can be constructed with an explicit capacity. /// \buffer Constructor with explicit memory capacity.
/// ///
/// \param initialCapacity The initial allocation size for the buffer. /// \param initialCapacity The initial allocation size for the
/// buffer.
explicit Buffer(size_t initialCapacity); explicit Buffer(size_t initialCapacity);
/// A Buffer can be initialized with a starting C-style string. /// \brief Construct with a C-style string.
explicit Buffer(const char *s); explicit Buffer(const char *s);
/// A Buffer can be initialized with a starting string. /// \buffer Construct with an initial string.
explicit Buffer(const std::string s); explicit Buffer(const std::string& s);
~Buffer() ~Buffer();
{ this->Reclaim(); }
/// Contents returns the Buffer's contents. /// \brief Retrieve the buffer's contents.
uint8_t *Contents() const uint8_t *Contents() const;
{ return this->contents; }
/// Length returns the length of the data currently stored in the std::string ToString() const;
/// buffer.
size_t Length() const
{ return this->length; };
/// Capacity returns the amount of memory allocated to the Buffer. /// \brief The length of data stored in the buffer.
size_t Capacity() const ///
{ return this->capacity; } /// \return The number of bytes stored in the Buffer.
size_t Length() const;
/// Append copies in a C-style string to the end of the buffer. /// \brief Return the amount of memory allocated for the
/// Buffer.
size_t Capacity() const;
/// \brief Append a C-style string to the end of the buffer.
/// ///
/// \param s The string to append. /// \param s The string to append.
/// \return True if the Buffer was resized. /// \return True if the Buffer was resized.
bool Append(const char *s); bool Append(const char *s);
/// Append copies in a string to the end of the buffer. /// Append Append a string to the end of the buffer.
/// ///
/// \param s The string to append. /// \param s The string to append.
/// \return True if the Buffer was resized. /// \return True if the Buffer was resized.
bool Append(const std::string s); bool Append(const std::string &s);
/// Append copies in a byte buffer to the end of the buffer. /// \brief Append a byte buffer to the end of the buffer.
/// ///
/// \param data The byte buffer to insert. /// \param data The byte buffer to insert.
/// \param datalen The length of the byte buffer. /// \param datalen The length of the byte buffer.
/// \return True if the Buffer was resized. /// \return True if the Buffer was resized.
bool Append(const uint8_t *data, const size_t datalen); bool Append(const uint8_t *data, const size_t datalen);
/// Append copies a single character to the end of the buffer. /// \brief Append a single character to the end of the buffer.
/// ///
/// \param c The character to append. /// \param c The character to append.
/// \return True if the Buffer was resized. /// \return True if the Buffer was resized.
bool Append(const uint8_t c); bool Append(const uint8_t c);
/// Insert copies a C-style string into the buffer At index. /// \brief Insert a C-style string into the buffer at index.
/// ///
/// \param index The index to insert the string At. /// \note As this is intended for use in text editing, an
/// insert into a buffer after the length will insert
/// spaces before the content.
///
/// \param index The index to insert the string at.
/// \param s The string to insert. /// \param s The string to insert.
/// \return True if the Buffer was resized. /// \return True if the Buffer was resized.
bool Insert(const size_t index, const char *s); bool Insert(const size_t index, const char *s);
/// Insert copies a string into the buffer At index. /// \brief Insert a string into the buffer at index.
/// ///
/// \param index The index the string should be inserted At. /// \note As this is intended for use in text editing, an
/// insert into a buffer after the length will insert
/// spaces before the content.
///
/// \param index The index the string should be inserted at.
/// \param s The string to insert. /// \param s The string to insert.
/// \return True if the Buffer was resized. /// \return True if the Buffer was resized.
bool Insert(const size_t index, const std::string s); bool Insert(const size_t index, const std::string &s);
/// Insert copies a uint8_t buffer into the buffer At index. /// \brief Insert a uint8_t buffer into the buffer at index.
/// ///
/// \param index The index to insert the buffer At. /// \note As this is intended for use in text editing, an
/// insert into a buffer after the length will insert
/// spaces before the content.
///
/// \param index The index to insert the buffer at.
/// \param data The buffer to insert. /// \param data The buffer to insert.
/// \param datalen The size of the data buffer. /// \param datalen The size of the data buffer.
/// \return True if the Buffer was resized. /// \return True if the Buffer was resized.
bool bool
Insert(const size_t index, const uint8_t *data, const size_t datalen); Insert(const size_t index, const uint8_t *data, const size_t datalen);
/// Insert copies a character into the buffer At index. /// \brief Insert a character into the buffer at index.
/// ///
/// \param index The index to insert the character At. /// \note As this is intended for use in text editing, an
/// insert into a buffer after the length will insert
/// spaces before the content.
///
/// \param index The index to insert the character at.
/// \param c The character to insert. /// \param c The character to insert.
/// \return True if the Buffer was resized. /// \return True if the Buffer was resized.
bool Insert(const size_t index, const uint8_t c); bool Insert(const size_t index, const uint8_t c);
/// Remove removes `count` bytes from the buffer At `index`. /// \brief Remove `count` bytes from the buffer at `index`.
/// ///
/// \param index The starting index to remove bytes from. /// \param index The starting index to remove bytes from.
/// \param count The number of bytes to remove. /// \param count The number of bytes to remove.
/// \return True if the Buffer was resized. /// \return True if the Buffer was resized.
bool Remove(const size_t index, const size_t count); bool Remove(const size_t index, const size_t count);
/// Remove removes a single byte from the buffer. /// \brief Remove removes a single byte from the buffer.
/// ///
/// \param index The index pointing to the byte to be removed. /// \param index The index pointing to the byte to be removed.
/// \return True if the Buffer was resized. /// \return True if the Buffer was resized.
@ -147,7 +164,7 @@ public:
/* memory management */ /* memory management */
/// Resize changes the capacity of the buffer to `newCapacity`. /// \brief Changes the capacity of the buffer to `newCapacity`.
/// ///
/// If newCapacity is less than the length of the Buffer, it /// If newCapacity is less than the length of the Buffer, it
/// will remove enough bytes from the end to make this happen. /// will remove enough bytes from the end to make this happen.
@ -155,27 +172,23 @@ public:
/// \param newCapacity The new capacity for the Buffer. /// \param newCapacity The new capacity for the Buffer.
void Resize(size_t newCapacity); void Resize(size_t newCapacity);
/// Trim will resize the Buffer to an appropriate size based on /// \brief Resize the Buffer capacity based on its length.
/// its length.
/// ///
/// \return The new capacity of the Buffer. /// \return The new capacity of the Buffer.
size_t Trim(); size_t Trim();
/// DisableAutoTrim prevents the #Buffer from automatically /// DisableAutoTrim prevents the #Buffer from automatically
/// trimming memory after a call to #Remove. /// trimming memory after a call to #Remove.
void DisableAutoTrim() void DisableAutoTrim();
{ this->autoTrim = false; }
/// EnableAutoTrim enables automatically trimming memory after /// EnableAutoTrim enables automatically trimming memory after
/// calls to #Remove. /// calls to #Remove.
void EnableAutoTrim() void EnableAutoTrim();
{ this->autoTrim = true; }
/// AutoTrimIsEnabled returns true if autotrim is enabled. /// AutoTrimIsEnabled returns true if autotrim is enabled.
/// ///
/// \return #Remove will call Trim. /// \return #Remove will call Trim.
bool AutoTrimIsEnabled() bool AutoTrimIsEnabled();
{ return this->autoTrim; }
/// Clear removes the data stored in the buffer. It will not /// Clear removes the data stored in the buffer. It will not
/// call #Trim; the capacity of the buffer will not be altered. /// call #Trim; the capacity of the buffer will not be altered.

View File

@ -186,27 +186,25 @@ main(int argc, char *argv[])
auto args = flags->Args(); auto args = flags->Args();
args.erase(args.begin()); args.erase(args.begin());
auto result = commander.Run(command, args); auto result = commander.Run(command, args);
delete flags;
switch (result) { switch (result) {
case Subcommand::Status::OK: case Subcommand::Status::OK:
std::cout << "[+] OK\n"; std::cout << "[+] OK\n";
retc = 0; retc = 0;
break; break;
case Subcommand::Status::NotEnoughArgs: case Subcommand::Status::NotEnoughArgs:
delete flags;
usage(cerr, 1); usage(cerr, 1);
break; break;
case Subcommand::Status::Failed: case Subcommand::Status::Failed:
cerr << "[!] '"<< command << "' failed\n"; cerr << "[!] '"<< command << "' failed\n";
break; break;
case Subcommand::Status::CommandNotRegistered: case Subcommand::Status::CommandNotRegistered:
delete flags;
cerr << "[!] '" << command << "' not registered.\n"; cerr << "[!] '" << command << "' not registered.\n";
usage(cerr, 1); usage(cerr, 1);
break; break;
default: default:
delete flags;
abort(); abort();
} }

View File

@ -20,24 +20,19 @@
/// PERFORMANCE OF THIS SOFTWARE. /// PERFORMANCE OF THIS SOFTWARE.
/// ///
#include <cstdio>
#include <cstdlib>
#include <cstring>
#if defined(__posix__) || defined(__linux__) || defined(__APPLE__)
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <cstdio>
#define PROT_RW (PROT_WRITE|PROT_READ) #include <cstdlib>
#endif #include <cstring>
#include <ios> #include <ios>
#include <scsl/Arena.h> #include <scsl/Arena.h>
#define PROT_RW (PROT_WRITE|PROT_READ)
namespace scsl { namespace scsl {
@ -74,9 +69,6 @@ Arena::SetAlloc(size_t allocSize)
this->arenaType = ArenaType::Alloc; this->arenaType = ArenaType::Alloc;
this->size = allocSize; this->size = allocSize;
this->store = new uint8_t[allocSize]; this->store = new uint8_t[allocSize];
if (this->store == nullptr) {
return -1;
}
this->Clear(); this->Clear();
return 0; return 0;
@ -221,16 +213,15 @@ Arena::Destroy()
this->arenaType = ArenaType::Uninit; this->arenaType = ArenaType::Uninit;
this->size = 0; this->size = 0;
this->store = nullptr; this->store = nullptr;
return;
} }
std::ostream & std::ostream &
operator<<(std::ostream &os, Arena &arena) operator<<(std::ostream &os, Arena &arena)
{ {
auto cursor = arena.Start(); auto *cursor = arena.Start();
char cursorString[33] = {0}; char cursorString[33] = {0};
snprintf(cursorString, 32, "%#016llx", snprintf(cursorString, 32, "%#016llx",
(long long unsigned int) cursor); (long long unsigned int)(cursor));
os << "Arena<"; os << "Arena<";
switch (arena.Type()) { switch (arena.Type()) {
@ -250,7 +241,7 @@ operator<<(std::ostream &os, Arena &arena)
os << "unknown (this is a bug)"; os << "unknown (this is a bug)";
} }
os << ">@0x"; os << ">@0x";
os << std::hex << (uintptr_t) &arena; os << std::hex << static_cast<void *>(&arena);
os << std::dec; os << std::dec;
os << ",store<" << arena.Size() << "B>@"; os << ",store<" << arena.Size() << "B>@";
os << std::hex << cursorString; os << std::hex << cursorString;

View File

@ -83,13 +83,46 @@ Buffer::Buffer(const char *data)
} }
Buffer::Buffer(const std::string s) Buffer::Buffer(const std::string& s)
: contents(nullptr), length(0), capacity(0), autoTrim(true) : contents(nullptr), length(0), capacity(0), autoTrim(true)
{ {
this->Append(s); this->Append(s);
} }
Buffer::~Buffer()
{
this->Reclaim();
}
uint8_t *
Buffer::Contents() const
{
return this->contents;
}
std::string
Buffer::ToString() const
{
return std::string((const char *)(this->contents));
}
size_t
Buffer::Length() const
{
return this->length;
}
size_t
Buffer::Capacity() const
{
return this->capacity;
}
bool bool
Buffer::Append(const char *s) Buffer::Append(const char *s)
{ {
@ -100,7 +133,7 @@ Buffer::Append(const char *s)
bool bool
Buffer::Append(const std::string s) Buffer::Append(const std::string &s)
{ {
return this->Append((const uint8_t *) s.c_str(), s.size()); return this->Append((const uint8_t *) s.c_str(), s.size());
} }
@ -156,7 +189,7 @@ Buffer::Insert(const size_t index, const char *s)
bool bool
Buffer::Insert(const size_t index, const std::string s) Buffer::Insert(const size_t index, const std::string &s)
{ {
return this->Insert(index, (const uint8_t *) s.c_str(), s.size()); return this->Insert(index, (const uint8_t *) s.c_str(), s.size());
} }
@ -240,6 +273,28 @@ Buffer::Trim()
return 0; return 0;
} }
void
Buffer::DisableAutoTrim()
{
this->autoTrim = false;
}
void
Buffer::EnableAutoTrim()
{
this->autoTrim = true;
}
bool
Buffer::AutoTrimIsEnabled()
{
return this->autoTrim;
}
void void
Buffer::Clear() Buffer::Clear()
{ {
@ -328,7 +383,11 @@ Buffer::shiftRight(size_t offset, size_t delta)
resized = true; resized = true;
} }
if (this->length == 0) return 0; if (this->length < offset) {
for (size_t i = this->length; i < offset; i++) {
this->contents[i] = ' ';
}
}
memmove(this->contents + (offset + delta), this->contents + offset, memmove(this->contents + (offset + delta), this->contents + offset,

View File

@ -46,7 +46,6 @@ Subcommand::Run(std::vector<std::string> args)
} }
Commander::Commander() Commander::Commander()
: cmap()
{ {
this->cmap.clear(); this->cmap.clear();
} }
@ -72,7 +71,7 @@ Commander::Run(std::string command, std::vector<std::string> args)
} }
auto scmd = this->cmap[command]; auto scmd = this->cmap[command];
return scmd->Run(args); return scmd->Run(std::move(args));
} }

View File

@ -208,11 +208,11 @@ Flags::parseArg(int argc, char **argv, int &index)
std::string arg(argv[index]); std::string arg(argv[index]);
string::TrimWhitespace(arg); string::TrimWhitespace(arg);
index++;
if (!std::regex_search(arg, isFlag)) { if (!std::regex_search(arg, isFlag)) {
return ParseStatus::EndOfFlags; return ParseStatus::EndOfFlags;
} }
index++;
if (this->flags.count(arg) == 0) { if (this->flags.count(arg) == 0) {
if (arg == "-h" || arg == "--help") { if (arg == "-h" || arg == "--help") {
Usage(std::cout, 0); Usage(std::cout, 0);

View File

@ -61,11 +61,6 @@ bufferTest()
SCTEST_CHECK_EQ(buffer.Capacity(), 0); SCTEST_CHECK_EQ(buffer.Capacity(), 0);
buffer.Append("and now for something completely different..."); buffer.Append("and now for something completely different...");
buffer.Resize(128);
SCTEST_CHECK_EQ(buffer.Capacity(), 128);
buffer.Trim();
SCTEST_CHECK_EQ(buffer.Capacity(), 64);
Buffer buffer2("and now for something completely different..."); Buffer buffer2("and now for something completely different...");
SCTEST_CHECK_EQ(buffer, buffer2); SCTEST_CHECK_EQ(buffer, buffer2);
@ -76,6 +71,63 @@ bufferTest()
} }
bool
testBufferTrimming()
{
const std::string contents = "and now for something completely different...";
Buffer buffer(contents);
buffer.Resize(128);
SCTEST_CHECK_EQ(buffer.Capacity(), 128);
buffer.Trim();
SCTEST_CHECK_EQ(buffer.Capacity(), 64);
buffer.DisableAutoTrim();
buffer.Resize(128);
SCTEST_CHECK_EQ(buffer.Capacity(), 128);
buffer.Remove(buffer.Length() - 1);
SCTEST_CHECK_EQ(buffer.Capacity(), 128);
buffer.Append('.');
SCTEST_CHECK_EQ(buffer.Capacity(), 128);
buffer.EnableAutoTrim();
buffer.Remove(buffer.Length() - 1);
SCTEST_CHECK_EQ(buffer.Capacity(), 64);
return true;
}
bool
testInserts()
{
const std::string contents = "and now for something completely different...";
const std::string expected1 = " and now for something completely different...";
const std::string hello = "hello";
const std::string world = "world";
const std::string helloWorld = "hello world";
Buffer buffer(64);
// Insert shouldn't resize the buffer.
SCTEST_CHECK_FALSE(buffer.Insert(5, contents));
SCTEST_CHECK_EQ(buffer.ToString(), expected1);
buffer.Clear();
SCTEST_CHECK_EQ(buffer.Length(), 0);
buffer.Append(hello);
SCTEST_CHECK_EQ(buffer.ToString(), hello);
buffer.Insert(7, world);
SCTEST_CHECK_EQ(buffer.ToString(), helloWorld);
return true;
}
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
@ -101,6 +153,8 @@ main(int argc, char *argv[])
} }
suite.AddTest("bufferTest", bufferTest); suite.AddTest("bufferTest", bufferTest);
suite.AddTest("trimTest", testBufferTrimming);
suite.AddTest("insertTest", testInserts);
delete flags; delete flags;
auto result = suite.Run(); auto result = suite.Run();

View File

@ -103,6 +103,7 @@ dictionaryTest()
SCTEST_CHECK(dict.Lookup(TEST_KVSTR4, TEST_KVSTRLEN4, value)); SCTEST_CHECK(dict.Lookup(TEST_KVSTR4, TEST_KVSTRLEN4, value));
SCTEST_CHECK(cmpRecord(value, expect)); SCTEST_CHECK(cmpRecord(value, expect));
arena.Write("pb.dat");
arena.Clear(); arena.Clear();
return true; return true;
} }