Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3122ed6ac7 | |||
| 184d468b06 | |||
| fa1cb59697 | |||
| a8387f010f | |||
| 00e9bc0f22 | |||
| 567f5f9564 | |||
| b7584b06cc | |||
| a0cd2ca866 | |||
| a0edf915ad |
26
.circleci/config.yml
Normal file
26
.circleci/config.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
# Use the latest 2.1 version of CircleCI pipeline process engine.
|
||||
# See: https://circleci.com/docs/configuration-reference
|
||||
version: 2.1
|
||||
|
||||
# Define a job to be invoked later in a workflow.
|
||||
# See: https://circleci.com/docs/configuration-reference/#jobs
|
||||
jobs:
|
||||
ctest:
|
||||
# Specify the execution environment. You can specify an image from Docker Hub or use one of our convenience images from CircleCI's Developer Hub.
|
||||
# See: https://circleci.com/docs/configuration-reference/#executor-job
|
||||
docker:
|
||||
- image: git.wntrmute.dev/sc/dev:alpine
|
||||
# Add steps to the job
|
||||
# See: https://circleci.com/docs/configuration-reference/#steps
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: Setup cmake build
|
||||
command: setup-cmake.sh
|
||||
|
||||
# Orchestrate jobs using workflows
|
||||
# See: https://circleci.com/docs/configuration-reference/#workflows
|
||||
workflows:
|
||||
ctest:
|
||||
jobs:
|
||||
- ctest
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
project(scsl LANGUAGES CXX
|
||||
VERSION 0.2.4
|
||||
VERSION 0.2.5
|
||||
DESCRIPTION "Shimmering Clarity Standard Library")
|
||||
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
/// PERFORMANCE OF THIS SOFTWARE.
|
||||
///
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <string>
|
||||
@@ -51,7 +52,7 @@ using CommanderFunc = std::function<bool (int, char **)>;
|
||||
class Subcommand {
|
||||
public:
|
||||
/// Status describes the results of running a Subcommand.
|
||||
enum class Status : uint8_t {
|
||||
enum class Status : int8_t {
|
||||
/// The subcommand executed correctly.
|
||||
OK = 0,
|
||||
/// Not enough arguments were supplied to the subcommand.
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
/// PERFORMANCE OF THIS SOFTWARE.
|
||||
///
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
@@ -43,16 +44,13 @@ Dictionary::Lookup(const char *key, uint8_t klen, TLV::Record &res)
|
||||
if ((klen == res.Len) &&
|
||||
(memcmp(res.Val, key, klen) == 0)) {
|
||||
TLV::ReadFromMemory(res, cursor);
|
||||
if (res.Tag != this->vTag) {
|
||||
abort();
|
||||
}
|
||||
return true;
|
||||
assert(res.Tag == this->vTag);
|
||||
return res.Tag == this->vTag;
|
||||
}
|
||||
cursor = TLV::FindTag(this->arena, cursor, res);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -26,9 +26,8 @@
|
||||
namespace scsl {
|
||||
|
||||
|
||||
AssertionFailed::AssertionFailed(std::string message) : msg(message)
|
||||
{
|
||||
}
|
||||
AssertionFailed::AssertionFailed(std::string message) : msg(message) {}
|
||||
|
||||
|
||||
const char *
|
||||
AssertionFailed::what() const throw()
|
||||
@@ -37,6 +36,4 @@ AssertionFailed::what() const throw()
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
36
Flag.h
36
Flag.h
@@ -92,41 +92,43 @@ Flag *NewFlag(std::string fName, FlagType fType, std::string fDescription);
|
||||
///
|
||||
/// A short example program is below:
|
||||
///
|
||||
/// ```c++
|
||||
/// int
|
||||
/// main(int argc, char *argv[])
|
||||
/// {
|
||||
/// std::string server = "service.example.com";
|
||||
/// unsigned int port = 1234;
|
||||
///
|
||||
/// std::string server = "service.example.com";
|
||||
/// unsigned int port = 1234;
|
||||
///
|
||||
/// auto flags = new scsl::Flags("example-client",
|
||||
/// "This interacts with the example.com service.");
|
||||
/// "This interacts with the example.com service.");
|
||||
/// flags->Register("-p", port, "server port");
|
||||
/// flags->Register("-s", server, "hostname to connect to");
|
||||
///
|
||||
///
|
||||
/// auto status = flags->Parse(argc, argv);
|
||||
/// if (status != ParseStatus::OK) {
|
||||
/// std::cerr << "failed to parse flags: "
|
||||
/// << scsl::Flags::ParseStatusToString(status)
|
||||
/// << "\n";
|
||||
/// << scsl::Flags::ParseStatusToString(status)
|
||||
/// << "\n";
|
||||
/// exit(1);
|
||||
/// }
|
||||
///
|
||||
///
|
||||
/// auto wasSet = flags->GetString("-s", server);
|
||||
/// if (wasSet) {
|
||||
/// std::cout << "hostname override: " << server << "\n";
|
||||
/// }
|
||||
///
|
||||
/// if (wasSet) {
|
||||
/// std::cout << "hostname override: " << server << "\n";
|
||||
/// }
|
||||
///
|
||||
/// wasSet = flags->GetUnsignedInteger("-p", port);
|
||||
/// if (wasSet) {
|
||||
/// std::cout << "port override: " << port << "\n";
|
||||
/// }
|
||||
///
|
||||
/// if (wasSet) {
|
||||
/// std::cout << "port override: " << port << "\n";
|
||||
/// }
|
||||
///
|
||||
/// std::cout << "connecting to " << server << ":" << port << "\n";
|
||||
/// for (size_t i = 0; i < flags.NumArgs(); i++) {
|
||||
/// std::cout << "\tExecuting command " << flags.Arg(i) << "\n";
|
||||
/// }
|
||||
/// return 0;
|
||||
/// return 0;
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
class Flags {
|
||||
public:
|
||||
|
||||
57
README.md
Normal file
57
README.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# scsl : The Shimmering Clarity Standard C++ Library
|
||||
|
||||
scsl is a collection of software I found myself needing to use repeatedly.
|
||||
|
||||
Full [Doxygen documentation](https://docs.shimmering-clarity.net/scsl/)
|
||||
is available.
|
||||
|
||||
## Introduction
|
||||
|
||||
This is a collection of C++ code that I find useful in building things.
|
||||
It arose from two main use cases.
|
||||
|
||||
### The modem
|
||||
|
||||
On the one hand, I was building a wireless modem for some Z80 computers I
|
||||
have. I needed to be able to store a phonebook of SSIDs and WPA keys, as
|
||||
well as short names to host:port descriptors. I had a limited amount of
|
||||
persistent NVRAM storage and no SD card or other removeable media, so
|
||||
typical desktop-oriented serialization mechanisms weren't going to really
|
||||
work well. Furthermore, when working with microcontrollers, I prefer not to
|
||||
dynamically allocate memory as much as possible. This led to building out
|
||||
Arena, TLV::Record to store the records, and finally Dictionary to make use
|
||||
of both of them.
|
||||
|
||||
Closely related to this, I've been working on building an ARM-based handheld
|
||||
computer, for which I would also need a memory arena.
|
||||
|
||||
### The text editors
|
||||
|
||||
Some time ago, I wrote a console text editor of my own; then later, started
|
||||
working on a graphical editor. For this, I needed some data structures to
|
||||
manage memory in the editor. Thus, Buffer was born.
|
||||
|
||||
### Finally
|
||||
|
||||
I'd been writing Go professionally for a while, but C was my first love. I
|
||||
recently started a job that is mostly in C++, and the best way for me to
|
||||
learn is to build a bunch of stuff with it. So, I took a bunch of micro-
|
||||
controller stuff I'd been writing and started building out some other stuff.
|
||||
|
||||
|
||||
## License
|
||||
|
||||
Copyright 2023 K. Isom <kyle@imap.cc>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
27
README.rst
27
README.rst
@@ -1,27 +0,0 @@
|
||||
scsl : The Shimmering Clarity Standard C++ Library
|
||||
==================================================
|
||||
|
||||
scsl is a collection of software I found myself needing to use repeatedly.
|
||||
|
||||
Full `Doxygen documentation`_ is available.
|
||||
|
||||
.. _Doxygen documentation: https://docs.shimmering-clarity.net/scsl/
|
||||
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Copyright 2023 K. Isom <kyle@imap.cc>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
15
TLV.cc
15
TLV.cc
@@ -116,8 +116,10 @@ FindTag(Arena &arena, uint8_t *cursor, Record &rec)
|
||||
{
|
||||
cursor = LocateTag(arena, cursor, rec);
|
||||
if (rec.Tag != TAG_EMPTY) {
|
||||
std::cout << "skipping record\n";
|
||||
cursor = SkipRecord(rec, cursor);
|
||||
if (!arena.CursorInArena(cursor)) {
|
||||
cursor = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return cursor;
|
||||
@@ -134,23 +136,24 @@ LocateTag(Arena &arena, uint8_t *cursor, Record &rec)
|
||||
}
|
||||
|
||||
if (cursor == nullptr) {
|
||||
std::cout << "move cursor to arena start\n";
|
||||
cursor = arena.Start();
|
||||
}
|
||||
|
||||
while ((tag = cursor[0]) != rec.Tag) {
|
||||
while (((tag = cursor[0]) != rec.Tag) &&
|
||||
(arena.CursorInArena(cursor))) {
|
||||
assert(arena.CursorInArena(cursor));
|
||||
std::cout << "cursor is in arena\n";
|
||||
len = cursor[1];
|
||||
std::cout << "record length" << len << "\n";
|
||||
if (!spaceAvailable(arena, cursor, len)) {
|
||||
std::cout << "no space available\n";
|
||||
return nullptr;
|
||||
}
|
||||
cursor += len;
|
||||
cursor += 2;
|
||||
}
|
||||
|
||||
if (!arena.CursorInArena(cursor)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (tag != rec.Tag) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
1
Test.cc
1
Test.cc
@@ -23,6 +23,7 @@
|
||||
#include "Exceptions.h"
|
||||
#include "Test.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
|
||||
2
scsl.h
2
scsl.h
@@ -55,7 +55,7 @@ namespace scsl {
|
||||
///
|
||||
/// On the one hand, I was building a wireless modem for some Z80 computers I
|
||||
/// have. I needed to be able to store a phonebook of SSIDs and WPA keys, as
|
||||
/// well as short names to host:port descriptors. I had a limited amount of of
|
||||
/// well as short names to host:port descriptors. I had a limited amount of
|
||||
/// persistent NVRAM storage and no SD card or other removeable media, so
|
||||
/// typical desktop-oriented serialization mechanisms weren't going to really
|
||||
/// work well. Furthermore, when working with microcontrollers, I prefer not to
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
set(SCSL_INCLUDE_DIRS include/scsl)
|
||||
set(SCSL_LIBRARIES libscsl.a)
|
||||
set(SCSL_LIBRARIES libscsl.a)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user