Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0071b84ab5 |
8
.idea/klib.iml
generated
8
.idea/klib.iml
generated
@@ -1,8 +1,2 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module classpath="CMake" type="CPP_MODULE" version="4">
|
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
||||||
<component name="FacetManager">
|
|
||||||
<facet type="Python" name="Python facet">
|
|
||||||
<configuration sdkName="Python 3.10 (scsl)" />
|
|
||||||
</facet>
|
|
||||||
</component>
|
|
||||||
</module>
|
|
||||||
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@@ -1,7 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="Black">
|
|
||||||
<option name="sdkName" value="Python 3.10 (scsl)" />
|
|
||||||
</component>
|
|
||||||
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||||
</project>
|
</project>
|
||||||
30
Arena.cc
30
Arena.cc
@@ -1,37 +1,19 @@
|
|||||||
///
|
#include <cassert>
|
||||||
/// \file Arena.cc
|
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
|
||||||
/// \date 2023-10-06
|
|
||||||
/// \brief Memory management using an arena.
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
|
||||||
#if defined(__posix__) || defined(__linux__) || defined(__APPLE__)
|
#if defined(__posix__) || defined(__linux__) || defined(__APPLE__)
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define PROT_RW (PROT_WRITE|PROT_READ)
|
#define PROT_RW (PROT_WRITE|PROT_READ)
|
||||||
|
#elif defined(__WIN64__) || defined(__WIN32__) || defined(WIN32)
|
||||||
|
#include "WinHelpers.h"
|
||||||
|
#pragma comment(lib, "advapi32.lib")
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <ios>
|
#include <ios>
|
||||||
@@ -264,7 +246,7 @@ Arena::Destroy()
|
|||||||
case ArenaType::Static:
|
case ArenaType::Static:
|
||||||
break;
|
break;
|
||||||
case ArenaType::Alloc:
|
case ArenaType::Alloc:
|
||||||
delete[] this->store;
|
delete this->store;
|
||||||
break;
|
break;
|
||||||
#if defined(__posix__) || defined(__linux__) || defined(__APPLE__)
|
#if defined(__posix__) || defined(__linux__) || defined(__APPLE__)
|
||||||
case ArenaType::MemoryMapped:
|
case ArenaType::MemoryMapped:
|
||||||
|
|||||||
26
Arena.h
26
Arena.h
@@ -1,26 +1,11 @@
|
|||||||
///
|
///
|
||||||
/// \file Arena.h
|
/// \file Arena.h
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
/// \author K. Isom
|
||||||
/// \date 2023-10-06
|
/// \date 2023-10-06
|
||||||
/// \brief Memory management using an arena.
|
/// \brief Memory management using an arena.
|
||||||
///
|
///
|
||||||
/// Arena defines a memory management backend for pre-allocating memory.
|
/// Arena defines a memory management backend for pre-allocating memory.
|
||||||
///
|
///
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
/// \section PLATFORM SUPPORT
|
/// \section PLATFORM SUPPORT
|
||||||
///
|
///
|
||||||
/// Arena will build on the major platforms, but memory-mapped files are only
|
/// Arena will build on the major platforms, but memory-mapped files are only
|
||||||
@@ -32,10 +17,10 @@
|
|||||||
#define KIMODEM_ARENA_H
|
#define KIMODEM_ARENA_H
|
||||||
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
#include "Exceptions.h"
|
#include "Exceptions.h"
|
||||||
|
|
||||||
@@ -127,7 +112,12 @@ 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(__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)
|
||||||
|
int Create(const char *path, size_t fileSize);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/// Open reads a file into the arena; the file must already exist. On
|
/// Open reads a file into the arena; the file must already exist. On
|
||||||
/// Unix-based platforms, the arena will be backed by a memory via
|
/// Unix-based platforms, the arena will be backed by a memory via
|
||||||
|
|||||||
18
Buffer.cc
18
Buffer.cc
@@ -2,28 +2,14 @@
|
|||||||
/// \file Buffer.cc
|
/// \file Buffer.cc
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
/// \author K. Isom <kyle@imap.cc>
|
||||||
/// \date 2023-10-09
|
/// \date 2023-10-09
|
||||||
/// \brief Buffer implements basic line buffers.
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ios>
|
#include <ios>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
#include "Buffer.h"
|
#include "Buffer.h"
|
||||||
|
|
||||||
|
|||||||
17
Buffer.h
17
Buffer.h
@@ -8,27 +8,12 @@
|
|||||||
/// editing. It allocates memory in powers of two, and will grow or shrink
|
/// editing. It allocates memory in powers of two, and will grow or shrink
|
||||||
/// as needed.
|
/// as needed.
|
||||||
///
|
///
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
|
|
||||||
#ifndef KGE_BUFFER_H
|
#ifndef KGE_BUFFER_H
|
||||||
#define KGE_BUFFER_H
|
#define KGE_BUFFER_H
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
|
||||||
namespace scsl {
|
namespace scsl {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ find_package(Doxygen)
|
|||||||
if (${DOXYGEN_FOUND})
|
if (${DOXYGEN_FOUND})
|
||||||
set(DOXYGEN_GENERATE_MAN YES)
|
set(DOXYGEN_GENERATE_MAN YES)
|
||||||
set(DOXYGEN_GENERATE_LATEX YES)
|
set(DOXYGEN_GENERATE_LATEX YES)
|
||||||
set(DOXYGEN_EXTRACT_ALL YES)
|
#set(DOXYGEN_EXTRACT_ALL YES)
|
||||||
message(STATUS "Doxygen found, building docs.")
|
message(STATUS "Doxygen found, building docs.")
|
||||||
|
|
||||||
doxygen_add_docs(scsl_docs
|
doxygen_add_docs(scsl_docs
|
||||||
@@ -1,61 +1,64 @@
|
|||||||
cmake_minimum_required(VERSION 3.22)
|
cmake_minimum_required(VERSION 3.22)
|
||||||
project(scsl LANGUAGES CXX
|
project(scsl LANGUAGES CXX
|
||||||
VERSION 0.2.4
|
VERSION 0.1.1
|
||||||
DESCRIPTION "Shimmering Clarity Standard Library")
|
DESCRIPTION "Shimmering Clarity Standard Library")
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
set(CMAKE_VERBOSE_MAKEFILES TRUE)
|
set(CMAKE_VERBOSE_MAKEFILES TRUE)
|
||||||
set(VERBOSE YES)
|
set(VERBOSE YES)
|
||||||
|
|
||||||
# compile options:
|
if (MSVC)
|
||||||
# -Wall Default to all errors.
|
add_compile_options("/W4" "$<$<CONFIG:RELEASE>:/O2>")
|
||||||
# -Wextra And a few extra.
|
else ()
|
||||||
# -Werror And require them to be fixed to build.
|
# compile options:
|
||||||
# -Wno-unused-function This is a library. Not every function is used here.
|
# -Wall Default to all errors.
|
||||||
# -Wno-unused-parameter Some functions have parameters defined for compatibility,
|
# -Wextra And a few extra.
|
||||||
# and aren't used in the implementation.
|
# -Werror And require them to be fixed to build.
|
||||||
add_compile_options(
|
# -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(
|
||||||
"-static"
|
"-static"
|
||||||
"-Wall"
|
"-Wall"
|
||||||
"-Wextra"
|
"-Wextra"
|
||||||
"-Werror"
|
"-Werror"
|
||||||
"-Wno-unused-function"
|
"-Wno-unused-function"
|
||||||
"-Wno-unused-parameter"
|
"-Wno-unused-parameter"
|
||||||
"-g"
|
|
||||||
"$<$<CONFIG:RELEASE>:-O2>"
|
"$<$<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 ()
|
||||||
# nothing special for gcc at the moment
|
# nothing special for gcc at the moment
|
||||||
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
|
|
||||||
add_compile_definitions(SCSL_DESKTOP_BUILD)
|
add_compile_definitions(SCSL_DESKTOP_BUILD)
|
||||||
add_compile_definitions(SCSL_VERSION=${PROJECT_VERSION})
|
add_compile_definitions(SCSL_VERSION=${PROJECT_VERSION})
|
||||||
|
|
||||||
set(HEADER_FILES scsl.h
|
set(HEADER_FILES scsl.h
|
||||||
Arena.h
|
Arena.h
|
||||||
Buffer.h
|
Buffer.h
|
||||||
Commander.h
|
|
||||||
Dictionary.h
|
Dictionary.h
|
||||||
Exceptions.h
|
Exceptions.h
|
||||||
Flag.h
|
Flag.h
|
||||||
StringUtil.h
|
StringUtil.h
|
||||||
TLV.h
|
TLV.h
|
||||||
Test.h
|
Test.h
|
||||||
)
|
WinHelpers.h)
|
||||||
|
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
Arena.cc
|
Arena.cc
|
||||||
Buffer.cc
|
Buffer.cc
|
||||||
Commander.cc
|
Commander.cc
|
||||||
|
Commander.h
|
||||||
Dictionary.cc
|
Dictionary.cc
|
||||||
Exceptions.cc
|
Exceptions.cc
|
||||||
Flag.cc
|
Flag.cc
|
||||||
StringUtil.cc
|
StringUtil.cc
|
||||||
TLV.cc
|
TLV.cc
|
||||||
Test.cc
|
Test.cc
|
||||||
)
|
WinHelpers.cc)
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
add_library(scsl
|
add_library(scsl
|
||||||
@@ -116,6 +119,6 @@ install(FILES ${HEADER_FILES} DESTINATION include/scsl)
|
|||||||
install(FILES scslConfig.cmake DESTINATION share/scsl/cmake)
|
install(FILES scslConfig.cmake DESTINATION share/scsl/cmake)
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/scsl.pc DESTINATION lib/pkgconfig)
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/scsl.pc DESTINATION lib/pkgconfig)
|
||||||
|
|
||||||
include(cmake/packaging.cmake)
|
include(CMakePack.txt)
|
||||||
include(cmake/docs.cmake)
|
include(CMakeDocs.txt)
|
||||||
endif()
|
endif()
|
||||||
|
|||||||
@@ -7,9 +7,6 @@ set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
|
|||||||
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
|
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
|
||||||
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
|
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
|
||||||
|
|
||||||
set(CPACK_PACKAGE_FILE_NAME
|
|
||||||
${PROJECT_NAME}-${PROJECT_VERSION}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_ARCH}${CMAKE_HOST_SYSTEM_PROCESSOR})
|
|
||||||
|
|
||||||
# Debian settings
|
# Debian settings
|
||||||
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Shimmering Clarity")
|
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Shimmering Clarity")
|
||||||
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The Shimmering Clarity standard C++ library")
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The Shimmering Clarity standard C++ library")
|
||||||
@@ -38,3 +35,4 @@ set(CPACK_SOURCE_IGNORE_FILES
|
|||||||
|
|
||||||
include (CPack)
|
include (CPack)
|
||||||
add_custom_target(package_docs DEPENDS SCSL_docs package package_source)
|
add_custom_target(package_docs DEPENDS SCSL_docs package package_source)
|
||||||
|
|
||||||
22
Commander.cc
22
Commander.cc
@@ -1,30 +1,12 @@
|
|||||||
///
|
///
|
||||||
/// \file Commander.cc
|
/// \file Commander.cc
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
/// \author kyle
|
||||||
/// \date 2023-10-10
|
/// \date 2023-10-10
|
||||||
/// \brief Subprogram tooling.
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
///
|
///
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "Commander.h"
|
#include "Commander.h"
|
||||||
|
|
||||||
|
|
||||||
namespace scsl {
|
namespace scsl {
|
||||||
|
|
||||||
|
|
||||||
@@ -75,4 +57,4 @@ Commander::Run(std::string command, int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace scsl
|
} // scsl
|
||||||
22
Commander.h
22
Commander.h
@@ -12,24 +12,9 @@
|
|||||||
/// $ some_tool subcommand args...
|
/// $ some_tool subcommand args...
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <functional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -43,7 +28,7 @@ namespace scsl {
|
|||||||
/// CommanderFunc describes a function that can be run in Commander.
|
/// CommanderFunc describes a function that can be run in Commander.
|
||||||
///
|
///
|
||||||
/// It expects an argument count and a list of arguments.
|
/// It expects an argument count and a list of arguments.
|
||||||
using CommanderFunc = std::function<bool (int, char **)>;
|
typedef std::function<bool(int, char **)> CommanderFunc;
|
||||||
|
|
||||||
|
|
||||||
/// Subcommands are the individual commands for the program. A Subcommand
|
/// Subcommands are the individual commands for the program. A Subcommand
|
||||||
@@ -119,8 +104,7 @@ private:
|
|||||||
std::map<std::string, Subcommand *> cmap;
|
std::map<std::string, Subcommand *> cmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
} // scsl
|
||||||
} // namespace scsl
|
|
||||||
|
|
||||||
|
|
||||||
#endif //SCSL_COMMANDER_H
|
#endif //SCSL_COMMANDER_H
|
||||||
|
|||||||
@@ -1,28 +1,5 @@
|
|||||||
///
|
|
||||||
/// \file Dictionary.cc
|
|
||||||
/// \author K.Isom <kyle@imap.cc>
|
|
||||||
/// \date 2023-10-05
|
|
||||||
/// \brief Key-value store built on top of Arena and TLV.
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cstdlib>
|
||||||
#include "Dictionary.h"
|
#include "Dictionary.h"
|
||||||
|
|
||||||
#if defined(SCSL_DESKTOP_BUILD)
|
#if defined(SCSL_DESKTOP_BUILD)
|
||||||
|
|||||||
31
Dictionary.h
31
Dictionary.h
@@ -1,24 +1,7 @@
|
|||||||
///
|
///
|
||||||
/// \file Dictionary.h
|
/// \file scsl.h
|
||||||
/// \author kyle (kyle@imap.cc)
|
/// \author kyle
|
||||||
/// \date 2023-10-12
|
/// \date 2023-10-06
|
||||||
/// \brief Key-value store built on top of Arena and TLV.
|
|
||||||
///
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
@@ -26,8 +9,6 @@
|
|||||||
#define SCSL_DICTIONARY_H
|
#define SCSL_DICTIONARY_H
|
||||||
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
#include "Arena.h"
|
#include "Arena.h"
|
||||||
#include "TLV.h"
|
#include "TLV.h"
|
||||||
|
|
||||||
@@ -45,6 +26,12 @@ namespace scsl {
|
|||||||
*/
|
*/
|
||||||
/// Dictionary implements a key-value store on top of Arena and TLV::Record.
|
/// Dictionary implements a key-value store on top of Arena and TLV::Record.
|
||||||
///
|
///
|
||||||
|
/// phonebook of SSIDs and WPA keys on a microcontroller. This phonebook had to
|
||||||
|
/// be stored in persistent NVRAM storage, preëmpting the use of std::map or
|
||||||
|
/// similar. The hardware in use was also not conducive to more expensive
|
||||||
|
/// options. It was originally named Phonebook until it was adapted to a more
|
||||||
|
/// general-purpose data structure.
|
||||||
|
///
|
||||||
/// Keys and vales are stored as sequential pairs of TLV records; they are
|
/// Keys and vales are stored as sequential pairs of TLV records; they are
|
||||||
/// expected to contain string values but this isn't necessarily the case. The
|
/// expected to contain string values but this isn't necessarily the case. The
|
||||||
/// tag values default to a tag of DICTIONARY_TAG_KEY, and values to a tag of
|
/// tag values default to a tag of DICTIONARY_TAG_KEY, and values to a tag of
|
||||||
|
|||||||
@@ -1,24 +1,6 @@
|
|||||||
///
|
//
|
||||||
/// \file Exceptions.cc
|
// Created by kyle on 2023-10-10.
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
//
|
||||||
/// \date 2023-10-10
|
|
||||||
/// \brief Custom exceptions used in writing test programs.
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
|
|
||||||
#include "Exceptions.h"
|
#include "Exceptions.h"
|
||||||
|
|
||||||
|
|||||||
26
Exceptions.h
26
Exceptions.h
@@ -1,24 +1,7 @@
|
|||||||
///
|
//
|
||||||
/// \file Exceptions.h
|
// Created by kyle on 2023-10-10.
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
//
|
||||||
/// \date 2023-10-10
|
|
||||||
/// \brief Custom exceptions for use in SCSL used in writing test programs.
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
#ifndef SCSL_EXCEPTIONS_H
|
#ifndef SCSL_EXCEPTIONS_H
|
||||||
#define SCSL_EXCEPTIONS_H
|
#define SCSL_EXCEPTIONS_H
|
||||||
|
|
||||||
@@ -26,7 +9,6 @@
|
|||||||
#include <exception>
|
#include <exception>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
namespace scsl {
|
namespace scsl {
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
112
Flag.cc
112
Flag.cc
@@ -1,9 +1,11 @@
|
|||||||
///
|
///
|
||||||
/// \file Flag.cc
|
/// \file Flag.h
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
/// \author kyle
|
||||||
/// \date 2023-10-12
|
/// \created 2023-10-12
|
||||||
/// \brief Flag defines a command-line flag parser.
|
/// \brief Flag defines a command-line flag parser.
|
||||||
///
|
///
|
||||||
|
/// \section COPYRIGHT
|
||||||
|
///
|
||||||
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
||||||
///
|
///
|
||||||
/// Permission to use, copy, modify, and/or distribute this software for
|
/// Permission to use, copy, modify, and/or distribute this software for
|
||||||
@@ -21,7 +23,9 @@
|
|||||||
///
|
///
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -36,7 +40,7 @@ static const std::regex isFlag("^--?[a-zA-Z0-9][a-zA-Z0-9-_]*$",
|
|||||||
std::regex_constants::nosubs);
|
std::regex_constants::nosubs);
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
Flags::ParseStatusToString(ParseStatus status)
|
ParseStatusToString(ParseStatus status)
|
||||||
{
|
{
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case ParseStatus::OK:
|
case ParseStatus::OK:
|
||||||
@@ -54,7 +58,7 @@ Flags::ParseStatusToString(ParseStatus status)
|
|||||||
|
|
||||||
|
|
||||||
Flag *
|
Flag *
|
||||||
NewFlag(std::string fName, FlagType fType, std::string fDescription)
|
NewFlag(FlagType fType, std::string fName, std::string fDescription)
|
||||||
{
|
{
|
||||||
auto flag = new Flag;
|
auto flag = new Flag;
|
||||||
|
|
||||||
@@ -80,21 +84,10 @@ Flags::Flags(std::string fName, std::string fDescription)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Flags::~Flags()
|
|
||||||
{
|
|
||||||
for (auto flag : this->flags) {
|
|
||||||
if (flag.second->Type == FlagType::String) {
|
|
||||||
delete flag.second->Value.s;
|
|
||||||
}
|
|
||||||
delete flag.second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Flags::Register(std::string fName, FlagType fType, std::string fDescription)
|
Flags::Register(std::string fName, FlagType fType, std::string fDescription)
|
||||||
{
|
{
|
||||||
if (!std::regex_search(fName, isFlag) || fName == "-h") {
|
if (!std::regex_search(fName, isFlag)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +95,7 @@ Flags::Register(std::string fName, FlagType fType, std::string fDescription)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto flag = NewFlag(fName, fType, fDescription);
|
auto flag = NewFlag(fType, fName, fDescription);
|
||||||
this->flags[fName] = flag;
|
this->flags[fName] = flag;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -198,10 +191,12 @@ Flags::ValueOf(std::string fName, FlagValue &value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Flags::ParseStatus
|
|
||||||
|
ParseStatus
|
||||||
Flags::parseArg(int argc, char **argv, int &index)
|
Flags::parseArg(int argc, char **argv, int &index)
|
||||||
{
|
{
|
||||||
std::string arg(argv[index]);
|
std::string arg(argv[index]);
|
||||||
|
|
||||||
U::S::TrimWhitespace(arg);
|
U::S::TrimWhitespace(arg);
|
||||||
|
|
||||||
index++;
|
index++;
|
||||||
@@ -210,17 +205,10 @@ Flags::parseArg(int argc, char **argv, int &index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this->flags.count(arg) == 0) {
|
if (this->flags.count(arg) == 0) {
|
||||||
if (arg == "-h" || arg == "--help") {
|
|
||||||
Usage(std::cout, 0);
|
|
||||||
}
|
|
||||||
return ParseStatus::NotRegistered;
|
return ParseStatus::NotRegistered;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto flag = flags[arg];
|
auto flag = flags[arg];
|
||||||
if ((flag->Type != FlagType::Boolean) && index == argc) {
|
|
||||||
return ParseStatus::NotEnoughArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (flag->Type) {
|
switch (flag->Type) {
|
||||||
case FlagType::Boolean:
|
case FlagType::Boolean:
|
||||||
flag->WasSet = true;
|
flag->WasSet = true;
|
||||||
@@ -254,13 +242,10 @@ Flags::parseArg(int argc, char **argv, int &index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Flags::ParseStatus
|
ParseStatus
|
||||||
Flags::Parse(int argc, char **argv, bool skipFirst)
|
Flags::Parse(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 1;
|
||||||
if (skipFirst) {
|
|
||||||
index = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (index != argc) {
|
while (index != argc) {
|
||||||
auto result = this->parseArg(argc, argv, index);
|
auto result = this->parseArg(argc, argv, index);
|
||||||
@@ -292,55 +277,6 @@ Flags::Parse(int argc, char **argv, bool skipFirst)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Flags::Usage(std::ostream &os, int exitCode)
|
|
||||||
{
|
|
||||||
os << this->name << ":\t";
|
|
||||||
auto indent = this->name.size() + 7;
|
|
||||||
|
|
||||||
U::S::WriteTabIndented(os, description, 72 - indent, indent / 8, false);
|
|
||||||
os << "\n\n";
|
|
||||||
|
|
||||||
for (const auto &pair : this->flags) {
|
|
||||||
auto argLine = "\t" + pair.first;
|
|
||||||
switch (pair.second->Type) {
|
|
||||||
case FlagType::Boolean:
|
|
||||||
argLine += "\t\t";
|
|
||||||
break;
|
|
||||||
case FlagType::Integer:
|
|
||||||
argLine += "int\t\t";
|
|
||||||
break;
|
|
||||||
case FlagType::UnsignedInteger:
|
|
||||||
argLine += "uint\t\t";
|
|
||||||
break;
|
|
||||||
case FlagType::SizeT:
|
|
||||||
argLine += "size_t\t";
|
|
||||||
break;
|
|
||||||
case FlagType::String:
|
|
||||||
argLine += "string\t";
|
|
||||||
break;
|
|
||||||
case FlagType::Unknown:
|
|
||||||
// fallthrough
|
|
||||||
default:
|
|
||||||
#ifdef SCSL_NOEXCEPT
|
|
||||||
abort();
|
|
||||||
#else
|
|
||||||
throw std::runtime_error("unhandled parsing error - this is a bug");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
os << argLine;
|
|
||||||
indent = argLine.size();
|
|
||||||
U::S::WriteTabIndented(os, pair.second->Description,
|
|
||||||
72-indent, (indent/8)+2, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
os << "\n";
|
|
||||||
exit(exitCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
Flags::NumArgs()
|
Flags::NumArgs()
|
||||||
{
|
{
|
||||||
@@ -355,17 +291,6 @@ Flags::Args()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string
|
|
||||||
Flags::Arg(size_t i)
|
|
||||||
{
|
|
||||||
if (i >= this->args.size()) {
|
|
||||||
throw std::out_of_range("index is out of range");
|
|
||||||
}
|
|
||||||
|
|
||||||
return this->args[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Flag *
|
Flag *
|
||||||
Flags::checkGetArg(std::string fName, FlagType eType)
|
Flags::checkGetArg(std::string fName, FlagType eType)
|
||||||
{
|
{
|
||||||
@@ -416,6 +341,7 @@ Flags::GetUnsignedInteger(std::string fName, unsigned int &flagValue)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Flags::GetSizeT(std::string fName, std::size_t &flagValue)
|
Flags::GetSizeT(std::string fName, std::size_t &flagValue)
|
||||||
{
|
{
|
||||||
|
|||||||
275
Flag.h
275
Flag.h
@@ -1,9 +1,11 @@
|
|||||||
///
|
///
|
||||||
/// \file Flag.h
|
/// \file Flag.h
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
/// \author kyle
|
||||||
/// \date 2023-10-12
|
/// \created 2023-10-12
|
||||||
/// \brief Flag declares a command-line flag parser.
|
/// \brief Flag declares a command-line flag parser.
|
||||||
///
|
///
|
||||||
|
/// \section COPYRIGHT
|
||||||
|
///
|
||||||
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
||||||
///
|
///
|
||||||
/// Permission to use, copy, modify, and/or distribute this software for
|
/// Permission to use, copy, modify, and/or distribute this software for
|
||||||
@@ -33,298 +35,91 @@ namespace scsl {
|
|||||||
|
|
||||||
|
|
||||||
/// FlagType indicates the value held in a FlagValue.
|
/// FlagType indicates the value held in a FlagValue.
|
||||||
///
|
|
||||||
/// \todo When C++17 support is more common, switch to `std::variant`.
|
|
||||||
enum class FlagType : uint8_t {
|
enum class FlagType : uint8_t {
|
||||||
Unknown = 0, ///< Unsupported value type.
|
Unknown = 0,
|
||||||
Boolean = 1, ///< bool
|
Boolean = 1,
|
||||||
Integer = 2, ///< int32_t
|
Integer = 2, ///< int32_t
|
||||||
UnsignedInteger = 3, ///< uint32_t
|
UnsignedInteger = 3, ///< uint32_t
|
||||||
SizeT = 4, ///< size_t
|
SizeT = 4, ///< size_t
|
||||||
String = 5, ///< std::string
|
String = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// FlagValue holds the value of a command line flag.
|
enum class ParseStatus : uint8_t {
|
||||||
|
Unknown = 0,
|
||||||
|
OK = 1,
|
||||||
|
EndOfFlags = 2,
|
||||||
|
NotRegistered = 3,
|
||||||
|
NotEnoughArgs = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string
|
||||||
|
ParseStatusToString(ParseStatus status);
|
||||||
|
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
unsigned int u; ///< FlagType::UnsignedInteger
|
unsigned int u;
|
||||||
int i; ///< FlagType::Integer
|
int i;
|
||||||
std::size_t size; ///< FlagType::SizeT
|
std::size_t size;
|
||||||
std::string *s; ///< FlagType::String
|
std::string *s;
|
||||||
bool b; ///< FlagType::Boolean
|
bool b;
|
||||||
} FlagValue;
|
} FlagValue;
|
||||||
|
|
||||||
|
|
||||||
/// Flag describes an individual command-line flag.
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FlagType Type; ///< The type of the value in the flag.
|
FlagType Type;
|
||||||
bool WasSet; ///< The flag was set on the command-line.
|
bool WasSet;
|
||||||
std::string Name; ///< The name of the flag.
|
std::string Name;
|
||||||
std::string Description; ///< A description of the flag.
|
std::string Description;
|
||||||
FlagValue Value; ///< The flag's value.
|
FlagValue Value;
|
||||||
} Flag;
|
} Flag;
|
||||||
|
|
||||||
/// NewFlag is a helper function for constructing a new flag.
|
Flag *
|
||||||
///
|
NewFlag(FlagType fType, std::string fName, std::string fDescription);
|
||||||
/// \param fName The name of the flag.
|
|
||||||
/// \param fType The type of the flag.
|
|
||||||
/// \param fDescription A description of the flag.
|
|
||||||
/// \return A pointer to a flag.
|
|
||||||
Flag *NewFlag(std::string fName, FlagType fType, std::string fDescription);
|
|
||||||
|
|
||||||
/// Flags provides a basic facility for processing command line flags.
|
|
||||||
///
|
|
||||||
/// Any remaining arguments after the args are added to the parser as
|
|
||||||
/// arguments that can be accessed with NumArgs, Args, and Arg.
|
|
||||||
///
|
|
||||||
/// \note The parser automatically handles the -h and --help flags by
|
|
||||||
/// calling Usage(std::cout, 0). The user can override this flag
|
|
||||||
/// and handle providing help on their own.
|
|
||||||
///
|
|
||||||
/// \details
|
|
||||||
///
|
|
||||||
/// Arguments are named with their leading dash, e.g. "-f". For example,
|
|
||||||
///
|
|
||||||
/// ```c++
|
|
||||||
/// flags.Register("-f", FlagType::String, "Path to a configuration file.");
|
|
||||||
/// ```
|
|
||||||
/// \section Usage
|
|
||||||
///
|
|
||||||
/// A short example program is below:
|
|
||||||
///
|
|
||||||
/// int
|
|
||||||
/// main(int argc, char *argv[])
|
|
||||||
/// {
|
|
||||||
/// std::string server = "service.example.com";
|
|
||||||
/// unsigned int port = 1234;
|
|
||||||
///
|
|
||||||
/// auto flags = new scsl::Flags("example-client",
|
|
||||||
/// "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";
|
|
||||||
/// exit(1);
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// auto wasSet = flags->GetString("-s", server);
|
|
||||||
/// if (wasSet) {
|
|
||||||
/// std::cout << "hostname override: " << server << "\n";
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// wasSet = flags->GetUnsignedInteger("-p", port);
|
|
||||||
/// 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;
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
class Flags {
|
class Flags {
|
||||||
public:
|
public:
|
||||||
/// ParseStatus describes the result of parsing command-line
|
|
||||||
/// arguments.
|
|
||||||
enum class ParseStatus : uint8_t {
|
|
||||||
/// An unknown parsing error occurred. This is a bug,
|
|
||||||
/// and users should never see this.
|
|
||||||
Unknown = 0,
|
|
||||||
|
|
||||||
/// Parsing succeeded.
|
|
||||||
OK = 1,
|
|
||||||
|
|
||||||
/// This is an internal status marking the end of
|
|
||||||
/// command line flags.
|
|
||||||
EndOfFlags = 2,
|
|
||||||
|
|
||||||
/// The command line flag provided isn't registered.
|
|
||||||
NotRegistered = 3,
|
|
||||||
|
|
||||||
/// Not enough arguments were provided to a flag that
|
|
||||||
/// takes an argument. For example, if "-p" expects
|
|
||||||
/// a number, and the program was called with just
|
|
||||||
/// `./program -p`, this error will be reported.
|
|
||||||
NotEnoughArgs = 4,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// ParseStatusToString returns a string message describing the
|
|
||||||
/// result of parsing command line args.
|
|
||||||
static std::string ParseStatusToString(ParseStatus status);
|
|
||||||
|
|
||||||
/// Create a new flags parser for the named program.
|
|
||||||
///
|
|
||||||
/// \param fName The program name,
|
|
||||||
Flags(std::string fName);
|
Flags(std::string fName);
|
||||||
|
|
||||||
/// Create a new flags parser for the named program.
|
|
||||||
///
|
|
||||||
/// \param fName The program name.
|
|
||||||
/// \param fDescription A short description of the program.
|
|
||||||
Flags(std::string fName, std::string fDescription);
|
Flags(std::string fName, std::string fDescription);
|
||||||
|
|
||||||
~Flags();
|
|
||||||
|
|
||||||
/// Register a new command line flag.
|
|
||||||
///
|
|
||||||
/// \param fName The name of the flag, including a leading dash.
|
|
||||||
/// \param fType The type of the argument to parse.
|
|
||||||
/// \param fDescription A description of the flag.
|
|
||||||
/// \return True if the flag was registered, false if the flag could
|
|
||||||
/// not be registered (e.g. a duplicate flag was registered).
|
|
||||||
bool Register(std::string fName,
|
bool Register(std::string fName,
|
||||||
FlagType fType,
|
FlagType fType,
|
||||||
std::string fDescription);
|
std::string fDescription);
|
||||||
|
|
||||||
/// Register a new boolean command line flag with a default value.
|
|
||||||
///
|
|
||||||
/// \note For booleans, it only makes sense to pass a false default
|
|
||||||
/// value, as there is no way to set a boolean flag to false.
|
|
||||||
/// This form is provided for compatibility with the other
|
|
||||||
/// variants on this method.
|
|
||||||
///
|
|
||||||
/// \param fName The name of the flag, including a leading dash.
|
|
||||||
/// \param defaultValue The default value for the flag.
|
|
||||||
/// \param fDescription A short description of the flag.
|
|
||||||
/// \return True if the flag was registered, false if the flag could
|
|
||||||
/// not be registered (e.g. a duplicate flag was registered).
|
|
||||||
bool Register(std::string fName,
|
bool Register(std::string fName,
|
||||||
bool defaultValue,
|
bool defaultValue,
|
||||||
std::string fDescription);
|
std::string fDescription);
|
||||||
|
|
||||||
/// Register a new integer command line flag with a default value.
|
|
||||||
///
|
|
||||||
/// \param fName The name of the flag, including a leading dash.
|
|
||||||
/// \param defaultValue The default value for the flag.
|
|
||||||
/// \param fDescription A short description of the flag.
|
|
||||||
/// \return True if the flag was registered, false if the flag could
|
|
||||||
/// not be registered (e.g. a duplicate flag was registered).
|
|
||||||
bool Register(std::string fName,
|
bool Register(std::string fName,
|
||||||
int defaultValue,
|
int defaultValue,
|
||||||
std::string fDescription);
|
std::string fDescription);
|
||||||
|
|
||||||
/// Register a new unsigned integer command line flag with a default
|
|
||||||
/// value.
|
|
||||||
///
|
|
||||||
/// \param fName The name of the flag, including a leading dash.
|
|
||||||
/// \param defaultValue The default value for the flag.
|
|
||||||
/// \param fDescription A short description of the flag.
|
|
||||||
/// \return True if the flag was registered, false if the flag could
|
|
||||||
/// not be registered (e.g. a duplicate flag was registered).
|
|
||||||
bool Register(std::string fName,
|
bool Register(std::string fName,
|
||||||
unsigned int defaultValue,
|
unsigned int defaultValue,
|
||||||
std::string fDescription);
|
std::string fDescription);
|
||||||
|
|
||||||
/// Register a new size_t command line flag with a default value.
|
|
||||||
///
|
|
||||||
/// \param fName The name of the flag, including a leading dash.
|
|
||||||
/// \param defaultValue The default value for the flag.
|
|
||||||
/// \param fDescription A short description of the flag.
|
|
||||||
/// \return True if the flag was registered, false if the flag could
|
|
||||||
/// not be registered (e.g. a duplicate flag was registered).
|
|
||||||
bool Register(std::string fName,
|
bool Register(std::string fName,
|
||||||
size_t defaultValue,
|
size_t defaultValue,
|
||||||
std::string fDescription);
|
std::string fDescription);
|
||||||
|
|
||||||
/// Register a new string command line flag with a default value.
|
|
||||||
///
|
|
||||||
/// \param fName The name of the flag, including a leading dash.
|
|
||||||
/// \param defaultValue The default value for the flag.
|
|
||||||
/// \param fDescription A short description of the flag.
|
|
||||||
/// \return True if the flag was registered, false if the flag could
|
|
||||||
/// not be registered (e.g. a duplicate flag was registered).
|
|
||||||
bool Register(std::string fName,
|
bool Register(std::string fName,
|
||||||
std::string defaultValue,
|
std::string defaultValue,
|
||||||
std::string fDescription);
|
std::string fDescription);
|
||||||
|
|
||||||
/// Return the number of registered flags.
|
|
||||||
size_t Size();
|
size_t Size();
|
||||||
|
|
||||||
/// Lookup a flag.
|
|
||||||
///
|
|
||||||
/// \param fName The flag name.
|
|
||||||
/// \return A pointer to flag if registered, or nullptr if the flag
|
|
||||||
/// wasn't registered.
|
|
||||||
Flag *Lookup(std::string fName);
|
Flag *Lookup(std::string fName);
|
||||||
|
|
||||||
/// ValueOf returns the value of the flag in the
|
|
||||||
bool ValueOf(std::string fName, FlagValue &value);
|
bool ValueOf(std::string fName, FlagValue &value);
|
||||||
|
|
||||||
/// Process a list of arguments into flags.
|
ParseStatus Parse(int argc, char **argv);
|
||||||
///
|
|
||||||
/// \param argc The number of arguments.
|
|
||||||
/// \param argv The arguments passed to the program.
|
|
||||||
/// \param skipFirst Flags expects to receive arguments directly
|
|
||||||
/// from those passed to `main`, and defaults to skipping
|
|
||||||
/// the first argument. Set to false if this is not the
|
|
||||||
/// case.
|
|
||||||
/// \return
|
|
||||||
ParseStatus Parse(int argc, char **argv, bool skipFirst=true);
|
|
||||||
|
|
||||||
/// Print a usage message to the output stream.
|
|
||||||
void Usage(std::ostream &os, int exitCode);
|
void Usage(std::ostream &os, int exitCode);
|
||||||
|
|
||||||
/// Return the number of arguments processed. These are any
|
|
||||||
/// remaining elements in argv that are not flags.
|
|
||||||
size_t NumArgs();
|
size_t NumArgs();
|
||||||
|
|
||||||
/// Return the arguments as a vector.
|
|
||||||
std::vector<std::string> Args();
|
std::vector<std::string> Args();
|
||||||
|
std::string Arg(int index);
|
||||||
|
|
||||||
/// Return a particular argument.
|
|
||||||
///
|
|
||||||
/// \param index The argument number to extract.
|
|
||||||
/// \return The argument at index i. If the index is greater than
|
|
||||||
/// the number of arguments present, an out_of_range
|
|
||||||
/// exception is thrown.
|
|
||||||
std::string Arg(size_t index);
|
|
||||||
|
|
||||||
/// Retrieve the state of a boolean flag.
|
|
||||||
///
|
|
||||||
/// \param fName The flag to look up.
|
|
||||||
/// \param flagValue The value to store.
|
|
||||||
/// \return True if the value was set, or false if the value isn't
|
|
||||||
/// a boolean or if it wasn't set.
|
|
||||||
bool GetBool(std::string fName, bool &flagValue);
|
bool GetBool(std::string fName, bool &flagValue);
|
||||||
|
|
||||||
/// Retrieve the value of an unsigned integer flag.
|
|
||||||
///
|
|
||||||
/// \param fName The flag to look up.
|
|
||||||
/// \param flagValue The value to store.
|
|
||||||
/// \return True if the value was set, or false if the value isn't
|
|
||||||
/// an unsigned integer or if it wasn't set.
|
|
||||||
bool GetUnsignedInteger(std::string fName, unsigned int &flagValue);
|
bool GetUnsignedInteger(std::string fName, unsigned int &flagValue);
|
||||||
|
|
||||||
/// Retrieve the value of an integer flag.
|
|
||||||
///
|
|
||||||
/// \param fName The flag to look up.
|
|
||||||
/// \param flagValue The value to store.
|
|
||||||
/// \return True if the value was set, or false if the value isn't
|
|
||||||
/// an integer or if it wasn't set.
|
|
||||||
bool GetInteger(std::string fName, int &flagValue);
|
bool GetInteger(std::string fName, int &flagValue);
|
||||||
|
|
||||||
/// Retrieve the value of a string flag.
|
|
||||||
///
|
|
||||||
/// \param fName The flag to look up.
|
|
||||||
/// \param flagValue The value to store.
|
|
||||||
/// \return True if the value was set, or false if the value isn't
|
|
||||||
/// a string or if it wasn't set.
|
|
||||||
bool GetString(std::string fName, std::string &flagValue);
|
bool GetString(std::string fName, std::string &flagValue);
|
||||||
|
|
||||||
/// Retrieve the value of a size_t flag.
|
|
||||||
///
|
|
||||||
/// \param fName The flag to look up.
|
|
||||||
/// \param flagValue The value to store.
|
|
||||||
/// \return True if the value was set, or false if the value isn't
|
|
||||||
/// a size_t or if it wasn't set.
|
|
||||||
bool GetSizeT(std::string fName, std::size_t &flagValue);
|
bool GetSizeT(std::string fName, std::size_t &flagValue);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ParseStatus parseArg(int argc, char **argv, int &index);
|
ParseStatus parseArg(int argc, char **argv, int &index);
|
||||||
Flag *checkGetArg(std::string fName, FlagType eType);
|
Flag *checkGetArg(std::string fName, FlagType eType);
|
||||||
|
|||||||
13
LICENSE
13
LICENSE
@@ -1,13 +0,0 @@
|
|||||||
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.
|
|
||||||
75
Makefile
75
Makefile
@@ -1,59 +1,39 @@
|
|||||||
HEADERS := scsl.h \
|
TARGET := klib.a
|
||||||
Arena.h \
|
TESTS := tlv_test dictionary_test
|
||||||
Buffer.h \
|
HEADERS := $(wildcard *.h)
|
||||||
Commander.h \
|
SOURCES := $(wildcard *.cc)
|
||||||
Dictionary.h \
|
OBJS := Arena.o Dictionary.o TLV.o
|
||||||
Exceptions.h \
|
|
||||||
Flag.h \
|
|
||||||
StringUtil.h \
|
|
||||||
Test.h \
|
|
||||||
TLV.h \
|
|
||||||
WinHelpers.h
|
|
||||||
|
|
||||||
SOURCES := Arena.cc \
|
|
||||||
Buffer.cc \
|
|
||||||
Commander.cc \
|
|
||||||
Dictionary.cc \
|
|
||||||
Exceptions.cc \
|
|
||||||
Flag.cc \
|
|
||||||
StringUtil.cc \
|
|
||||||
Test.cc \
|
|
||||||
TLV.cc \
|
|
||||||
WinHelpers.cc
|
|
||||||
|
|
||||||
BUILD := DEBUG
|
|
||||||
OBJS := $(patsubst %.cc,%.o,$(SOURCES))
|
|
||||||
LIBS := libscsl.a
|
|
||||||
|
|
||||||
TARGETS := $(LIBS) phonebook
|
|
||||||
TESTS := bufferTest dictionaryTest flagTest tlvTest
|
|
||||||
CXX := clang++
|
CXX := clang++
|
||||||
CXXFLAGS := -std=c++14 -Werror -Wall -Wextra -DSCSL_DESKTOP_BUILD \
|
CXXFLAGS := -g -std=c++14 -Werror -Wall -DSCSL_DESKTOP_BUILD
|
||||||
-DSCSL_BUILD_TYPE=${BUILD}
|
|
||||||
ifeq ($(BUILD),DEBUG)
|
|
||||||
CXXFLAGS += -g -fsanitize=address
|
|
||||||
else
|
|
||||||
CXXFLAGS += -O2
|
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: $(TARGETS) $(TESTS) tags run-tests
|
all: $(TARGET) $(TESTS) tags run-tests
|
||||||
|
|
||||||
tags: $(HEADERS) $(SOURCES)
|
tags: $(HEADERS) $(SOURCES)
|
||||||
ctags $(HEADERS) $(SOURCES)
|
ctags $(HEADERS) $(SOURCES)
|
||||||
|
|
||||||
libscsl.a: $(OBJS)
|
$(TARGET): $(OBJS)
|
||||||
$(AR) rcs $@ $(OBJS)
|
$(AR) rcs $@ $(OBJS)
|
||||||
|
|
||||||
|
tlv_test: tlvTest.o $(TARGET)
|
||||||
|
$(CXX) -o $@ $(CXXFLAGS) tlvTest.o $(TARGET)
|
||||||
|
|
||||||
|
dictionary_test: dictionaryTest.o $(TARGET)
|
||||||
|
$(CXX) -o $@ $(CXXFLAGS) dictionaryTest.o $(TARGET)
|
||||||
|
|
||||||
.PHONY: print-%
|
.PHONY: print-%
|
||||||
print-%: ; @echo '$(subst ','\'',$*=$($*))'
|
print-%: ; @echo '$(subst ','\'',$*=$($*))'
|
||||||
|
|
||||||
klib.a: $(OBJS)
|
klib.a: $(OBJS)
|
||||||
|
|
||||||
|
%.o: %.cc
|
||||||
|
$(CXX) -o $@ -c $(CXXFLAGS) $<
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
# build outputs
|
# build outputs
|
||||||
rm -f $(TARGETS) $(TESTS) *.o
|
rm -f $(TARGET) $(TESTS) *.o
|
||||||
|
|
||||||
# test miscellaneous
|
# test miscellaneous
|
||||||
rm -f core core.* tags arena_test.bin
|
rm -f core core.* tags arena_test.bin
|
||||||
@@ -65,22 +45,3 @@ run-tests: $(TESTS)
|
|||||||
echo "./$${testbin}" ; \
|
echo "./$${testbin}" ; \
|
||||||
./$${testbin}; \
|
./$${testbin}; \
|
||||||
done
|
done
|
||||||
|
|
||||||
phonebook: phonebook.o $(LIBS)
|
|
||||||
$(CXX) -o $@ $(CXXFLAGS) $@.o $(LIBS)
|
|
||||||
|
|
||||||
bufferTest: bufferTest.o $(LIBS)
|
|
||||||
$(CXX) -o $@ $(CXXFLAGS) $@.o $(LIBS)
|
|
||||||
|
|
||||||
dictionaryTest: dictionaryTest.o $(LIBS)
|
|
||||||
$(CXX) -o $@ $(CXXFLAGS) $@.o $(LIBS)
|
|
||||||
|
|
||||||
flagTest: flagTest.o $(LIBS)
|
|
||||||
$(CXX) -o $@ $(CXXFLAGS) $@.o $(LIBS)
|
|
||||||
|
|
||||||
tlvTest: tlvTest.o $(LIBS)
|
|
||||||
$(CXX) -o $@ $(CXXFLAGS) $@.o $(LIBS)
|
|
||||||
|
|
||||||
%.o: %.cc
|
|
||||||
$(CXX) -o $@ -c $(CXXFLAGS) $<
|
|
||||||
|
|
||||||
|
|||||||
122
StringUtil.cc
122
StringUtil.cc
@@ -1,26 +1,3 @@
|
|||||||
///
|
|
||||||
/// \file StringUtil.cc
|
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
|
||||||
/// \date 2023-10-12
|
|
||||||
/// \brief Utilities for working with strings.
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@@ -35,21 +12,22 @@ namespace U {
|
|||||||
namespace S {
|
namespace S {
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
SplitKeyValuePair(std::string line, std::string delimiter)
|
SplitKeyValuePair(std::string line, std::string delimiter)
|
||||||
{
|
{
|
||||||
auto pair = SplitN(line, delimiter, 2);
|
std::string key;
|
||||||
|
std::string val;
|
||||||
|
|
||||||
if (pair.size() == 0) {
|
auto pos = line.find(delimiter);
|
||||||
return {"", ""};
|
if (pos == std::string::npos) {
|
||||||
} else if (pair.size() == 1) {
|
key = line;
|
||||||
return {pair[0], ""};
|
val = "";
|
||||||
|
} else {
|
||||||
|
key = line.substr(0, pos);
|
||||||
|
val = line.substr(pos + 1, line.size() - pos - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(pair.size() == 2);
|
|
||||||
auto key = pair[0];
|
|
||||||
auto val = pair[1];
|
|
||||||
|
|
||||||
TrimWhitespace(key);
|
TrimWhitespace(key);
|
||||||
TrimWhitespace(val);
|
TrimWhitespace(val);
|
||||||
return {key, val};
|
return {key, val};
|
||||||
@@ -59,11 +37,23 @@ SplitKeyValuePair(std::string line, std::string delimiter)
|
|||||||
std::vector<std::string>
|
std::vector<std::string>
|
||||||
SplitKeyValuePair(std::string line, char delimiter)
|
SplitKeyValuePair(std::string line, char delimiter)
|
||||||
{
|
{
|
||||||
std::string sDelim;
|
std::string key;
|
||||||
|
std::string val;
|
||||||
|
|
||||||
sDelim.push_back(delimiter);
|
auto pos = line.find(delimiter);
|
||||||
return SplitKeyValuePair(line, sDelim);
|
if (pos == std::string::npos) {
|
||||||
|
key = line;
|
||||||
|
val = "";
|
||||||
|
} else {
|
||||||
|
key = line.substr(0, pos);
|
||||||
|
val = line.substr(pos + 1, line.size() - pos - 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
TrimWhitespace(key);
|
||||||
|
TrimWhitespace(val);
|
||||||
|
return {key, val};
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -142,66 +132,6 @@ SplitN(std::string s, std::string delim, size_t maxCount)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::string>
|
|
||||||
WrapText(std::string line, size_t lineLength)
|
|
||||||
{
|
|
||||||
std::vector<std::string> wrapped;
|
|
||||||
auto parts = SplitN(line, " ", 0);
|
|
||||||
|
|
||||||
for (auto &part: parts) {
|
|
||||||
TrimWhitespace(part);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string wLine;
|
|
||||||
for (auto word: parts) {
|
|
||||||
if (word.size() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((wLine.size() + word.size() + 1) > lineLength) {
|
|
||||||
wrapped.push_back(wLine);
|
|
||||||
wLine.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wLine.size() > 0) {
|
|
||||||
wLine += " ";
|
|
||||||
}
|
|
||||||
wLine += word;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wLine.size() > 0) {
|
|
||||||
wrapped.push_back(wLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
return wrapped;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
WriteTabIndented(std::ostream &os, std::vector<std::string> lines,
|
|
||||||
int tabStop, bool indentFirst)
|
|
||||||
{
|
|
||||||
std::string indent(tabStop, '\t');
|
|
||||||
|
|
||||||
for (size_t i = 0; i < lines.size(); i++) {
|
|
||||||
if (i > 0 || indentFirst) {
|
|
||||||
os << indent;
|
|
||||||
}
|
|
||||||
os << lines[i] << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
WriteTabIndented(std::ostream &os, std::string line, size_t maxLength,
|
|
||||||
int tabStop, bool indentFirst)
|
|
||||||
{
|
|
||||||
auto lines = WrapText(line, maxLength);
|
|
||||||
WriteTabIndented(os, lines, tabStop, indentFirst);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::ostream &
|
std::ostream &
|
||||||
VectorToString(std::ostream &os, const std::vector<std::string> &svec)
|
VectorToString(std::ostream &os, const std::vector<std::string> &svec)
|
||||||
{
|
{
|
||||||
@@ -211,7 +141,7 @@ VectorToString(std::ostream &os, const std::vector<std::string> &svec)
|
|||||||
os << "{";
|
os << "{";
|
||||||
|
|
||||||
for (size_t i = 0; i < svec.size(); i++) {
|
for (size_t i = 0; i < svec.size(); i++) {
|
||||||
if (i > 0) { os << ", "; }
|
if (i > 0) os << ", ";
|
||||||
os << svec[i];
|
os << svec[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
StringUtil.h
42
StringUtil.h
@@ -1,9 +1,10 @@
|
|||||||
///
|
///
|
||||||
/// \file StringUtil.h
|
/// \file StringUtil.h
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
/// \author kyle (kyle@midgard)
|
||||||
/// \date 2023-10-14
|
/// \created 2023-10-14
|
||||||
/// \brief Utilities for working with strings.
|
/// \brief StringUtil contains string utilities.
|
||||||
///
|
///
|
||||||
|
/// \section COPYRIGHT
|
||||||
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
||||||
///
|
///
|
||||||
/// Permission to use, copy, modify, and/or distribute this software for
|
/// Permission to use, copy, modify, and/or distribute this software for
|
||||||
@@ -84,44 +85,17 @@ std::vector<std::string> SplitKeyValuePair(std::string line, char delimiter);
|
|||||||
|
|
||||||
/// Split a string into parts based on the delimiter.
|
/// Split a string into parts based on the delimiter.
|
||||||
///
|
///
|
||||||
/// \param s The string that should be split.
|
|
||||||
/// \param delimiter The string that delimits the parts of the string.
|
/// \param delimiter The string that delimits the parts of the string.
|
||||||
/// \param maxCount The maximum number of parts to split. If 0, there is no
|
/// \param maxCount The maximum number of parts to split. If 0, there is no limit
|
||||||
/// limit to the number of parts.
|
/// to the number of parts.
|
||||||
/// \return A vector containing all the parts of the string.
|
/// \return A vector containing all the parts of the string.
|
||||||
std::vector<std::string> SplitN(std::string, std::string delimiter, size_t maxCount=0);
|
std::vector<std::string> SplitN(std::string, std::string delimiter, size_t maxCount=0);
|
||||||
|
|
||||||
/// WrapText is a very simple wrapping function that breaks the line into
|
//std::vector<std::string> SplitN(std::string, char delimiter, size_t size_t maxCount=0);
|
||||||
/// lines of at most lineLength characters. It does this by breaking the
|
|
||||||
/// line into individual words (splitting on whitespace).
|
|
||||||
std::vector<std::string> WrapText(std::string line, size_t lineLength);
|
|
||||||
|
|
||||||
/// Write out a vector of lines indented with tabs.
|
|
||||||
///
|
|
||||||
/// \param os The output stream to write to.
|
|
||||||
/// \param lines The lines of text to write.
|
|
||||||
/// \param tabStop The number of tabs to indent.
|
|
||||||
/// \param indentFirst Whether the first line should be indented.
|
|
||||||
void WriteTabIndented(std::ostream &os, std::vector<std::string> lines,
|
|
||||||
int tabStop, bool indentFirst);
|
|
||||||
|
|
||||||
/// Wrap a line, then output it to a stream.
|
|
||||||
///
|
|
||||||
/// \param os The output stream to write to.
|
|
||||||
/// \param line The line to wrap and output.
|
|
||||||
/// \param maxLength The maximum length of each section of text.
|
|
||||||
/// \param tabStop The number of tabs to indent.
|
|
||||||
/// \param indentFirst Whether the first line should be indented.
|
|
||||||
void WriteTabIndented(std::ostream &os, std::string line, size_t maxLength,
|
|
||||||
int tabStop, bool indentFirst);
|
|
||||||
|
|
||||||
|
|
||||||
/// Write a string vector to the output stream in the same format as
|
/// Return a string represention of a string vector in the form [size]{"foo", "bar", ...}.
|
||||||
/// VectorToString.
|
|
||||||
std::ostream &VectorToString(std::ostream &os, const std::vector<std::string> &svec);
|
std::ostream &VectorToString(std::ostream &os, const std::vector<std::string> &svec);
|
||||||
|
|
||||||
/// Return a string represention of a string vector in the form
|
|
||||||
/// [size]{"foo", "bar", ...}.
|
|
||||||
std::string VectorToString(const std::vector<std::string> &svec);
|
std::string VectorToString(const std::vector<std::string> &svec);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
36
TLV.cc
36
TLV.cc
@@ -1,35 +1,9 @@
|
|||||||
///
|
|
||||||
/// \file TLV.cc
|
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
|
||||||
/// \date 2023-10-06
|
|
||||||
/// \brief Tag-Length-Value records built on Arena.
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "TLV.h"
|
#include "TLV.h"
|
||||||
|
|
||||||
using namespace scsl;
|
using namespace scsl;
|
||||||
|
|
||||||
|
|
||||||
/// REC_SIZE calculates the total length of a TLV record, including the
|
|
||||||
/// two byte header.
|
|
||||||
#define REC_SIZE(x) ((std::size_t)x.Len + 2)
|
#define REC_SIZE(x) ((std::size_t)x.Len + 2)
|
||||||
|
|
||||||
|
|
||||||
@@ -116,7 +90,6 @@ FindTag(Arena &arena, uint8_t *cursor, Record &rec)
|
|||||||
{
|
{
|
||||||
cursor = LocateTag(arena, cursor, rec);
|
cursor = LocateTag(arena, cursor, rec);
|
||||||
if (rec.Tag != TAG_EMPTY) {
|
if (rec.Tag != TAG_EMPTY) {
|
||||||
std::cout << "skipping record\n";
|
|
||||||
cursor = SkipRecord(rec, cursor);
|
cursor = SkipRecord(rec, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,22 +102,13 @@ LocateTag(Arena &arena, uint8_t *cursor, Record &rec)
|
|||||||
{
|
{
|
||||||
uint8_t tag, len;
|
uint8_t tag, len;
|
||||||
|
|
||||||
if (!arena.CursorInArena(cursor)) {
|
|
||||||
cursor = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cursor == nullptr) {
|
if (cursor == nullptr) {
|
||||||
std::cout << "move cursor to arena start\n";
|
|
||||||
cursor = arena.Start();
|
cursor = arena.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((tag = cursor[0]) != rec.Tag) {
|
while ((tag = cursor[0]) != rec.Tag) {
|
||||||
assert(arena.CursorInArena(cursor));
|
|
||||||
std::cout << "cursor is in arena\n";
|
|
||||||
len = cursor[1];
|
len = cursor[1];
|
||||||
std::cout << "record length" << len << "\n";
|
|
||||||
if (!spaceAvailable(arena, cursor, len)) {
|
if (!spaceAvailable(arena, cursor, len)) {
|
||||||
std::cout << "no space available\n";
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
cursor += len;
|
cursor += len;
|
||||||
|
|||||||
3
TLV.h
3
TLV.h
@@ -14,8 +14,8 @@
|
|||||||
#ifndef KIMODEM_TLV_H
|
#ifndef KIMODEM_TLV_H
|
||||||
#define KIMODEM_TLV_H
|
#define KIMODEM_TLV_H
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include "Arena.h"
|
#include "Arena.h"
|
||||||
|
|
||||||
@@ -23,7 +23,6 @@
|
|||||||
namespace scsl {
|
namespace scsl {
|
||||||
namespace TLV {
|
namespace TLV {
|
||||||
|
|
||||||
|
|
||||||
#ifndef TLV_MAX_LEN
|
#ifndef TLV_MAX_LEN
|
||||||
static constexpr size_t TLV_MAX_LEN = 253;
|
static constexpr size_t TLV_MAX_LEN = 253;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
25
Test.cc
25
Test.cc
@@ -1,28 +1,11 @@
|
|||||||
///
|
//
|
||||||
/// \file Test.cc
|
// Created by kyle on 2023-10-09.
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
//
|
||||||
/// \date 2023-10-09
|
|
||||||
/// \brief Tooling to assist in building test programs..
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
|
|
||||||
#include "Exceptions.h"
|
#include "Exceptions.h"
|
||||||
#include "Test.h"
|
#include "Test.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
|||||||
19
Test.h
19
Test.h
@@ -2,28 +2,11 @@
|
|||||||
/// \file Test.h
|
/// \file Test.h
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
/// \author K. Isom <kyle@imap.cc>
|
||||||
/// \date 2023-10-09
|
/// \date 2023-10-09
|
||||||
/// \brief Tooling to assist in building test programs..
|
/// \brief Test.h implements basic testing tools.
|
||||||
///
|
///
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
|
|
||||||
#ifndef SCSL_TEST_H
|
#ifndef SCSL_TEST_H
|
||||||
#define SCSL_TEST_H
|
#define SCSL_TEST_H
|
||||||
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
10
flagTest.cc
10
flagTest.cc
@@ -20,19 +20,18 @@ main(int argc, char *argv[])
|
|||||||
int testInteger = 0;
|
int testInteger = 0;
|
||||||
std::string testString;
|
std::string testString;
|
||||||
|
|
||||||
auto flags = new Flags("flag_test", "this is a test of the flag functionality. This line is particularly long to make sure the wrapping works.");
|
auto flags = new Flags("flag_test", "this is a test of the flag functionality.");
|
||||||
flags->Register("-b", FlagType::Boolean, "test boolean");
|
flags->Register("-b", FlagType::Boolean, "test boolean");
|
||||||
flags->Register("-s", FlagType::String, "test string");
|
flags->Register("-s", FlagType::String, "test string");
|
||||||
flags->Register("-u", (unsigned int)42, "test unsigned integer with a long description line. This should trigger multiline text-wrapping.");
|
flags->Register("-u", (unsigned int)42, "test unsigned integer");
|
||||||
flags->Register("-i", -42, "test integer");
|
flags->Register("-i", -42, "test integer");
|
||||||
flags->Register("-size", FlagType::SizeT, "test size_t");
|
flags->Register("-size", FlagType::SizeT, "test size_t");
|
||||||
TestAssert(flags->Size() == 5, "flags weren't registered");
|
TestAssert(flags->Size() == 5, "flags weren't registered");
|
||||||
|
|
||||||
auto status = flags->Parse(argc, argv);
|
auto status = flags->Parse(argc, argv);
|
||||||
|
|
||||||
if (status != Flags::ParseStatus::OK) {
|
if (status != ParseStatus::OK) {
|
||||||
std::cerr << "failed to parse flags: "
|
std::cerr << "failed to parse flags: " << ParseStatusToString(status) << "\n";
|
||||||
<< Flags::ParseStatusToString(status) << "\n";
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,6 +55,5 @@ main(int argc, char *argv[])
|
|||||||
std::cout << "(string) test flag was set: " << wasSet << "\n";
|
std::cout << "(string) test flag was set: " << wasSet << "\n";
|
||||||
std::cout << "(string) test flag value: " << testString << "\n";
|
std::cout << "(string) test flag value: " << testString << "\n";
|
||||||
|
|
||||||
delete flags;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
25
phonebook.cc
25
phonebook.cc
@@ -1,24 +1,6 @@
|
|||||||
///
|
//
|
||||||
/// \file phonebook.cc
|
// Created by kyle on 2023-10-10.
|
||||||
/// \author K. Isom <kyle@imap.cc>
|
//
|
||||||
/// \date 2023-10-10
|
|
||||||
/// \brief Commandline tools for interacting with dictionary data file.
|
|
||||||
///
|
|
||||||
/// 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.
|
|
||||||
///
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -27,7 +9,6 @@ using namespace std;
|
|||||||
#include "Arena.h"
|
#include "Arena.h"
|
||||||
#include "Commander.h"
|
#include "Commander.h"
|
||||||
#include "Dictionary.h"
|
#include "Dictionary.h"
|
||||||
#include "Flag.h"
|
|
||||||
using namespace scsl;
|
using namespace scsl;
|
||||||
|
|
||||||
static const char *defaultPhonebook = "pb.dat";
|
static const char *defaultPhonebook = "pb.dat";
|
||||||
|
|||||||
22
scsl.h
22
scsl.h
@@ -1,13 +1,10 @@
|
|||||||
///
|
///
|
||||||
/// \file scsl.h
|
/// \file scsl.h
|
||||||
/// \author kyle (kyle@imap.cc)
|
/// \author kyle
|
||||||
/// \date 2023-10-10
|
/// \created 2023-10-10
|
||||||
/// \brief scsl is my collection of C++ data structures and code.
|
/// \brief scsl is my collection of C++ data structures and code.
|
||||||
///
|
///
|
||||||
/// scsl.h is a utility header that includes all of SCSL.
|
|
||||||
///
|
|
||||||
/// \section COPYRIGHT
|
/// \section COPYRIGHT
|
||||||
///
|
|
||||||
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
||||||
///
|
///
|
||||||
/// Permission to use, copy, modify, and/or distribute this software for
|
/// Permission to use, copy, modify, and/or distribute this software for
|
||||||
@@ -28,15 +25,12 @@
|
|||||||
#define SCSL_SCSL_H
|
#define SCSL_SCSL_H
|
||||||
|
|
||||||
|
|
||||||
#include <scsl/Arena.h>
|
#include <klib/Arena.h>
|
||||||
#include <scsl/Buffer.h>
|
#include <klib/Buffer.h>
|
||||||
#include <scsl/Commander.h>
|
#include <klib/Dictionary.h>
|
||||||
#include <scsl/Dictionary.h>
|
#include <klib/Exceptions.h>
|
||||||
#include <scsl/Exceptions.h>
|
#include <klib/TLV.h>
|
||||||
#include <scsl/Flag.h>
|
#include <klib/Test.h>
|
||||||
#include <scsl/StringUtil.h>
|
|
||||||
#include <scsl/TLV.h>
|
|
||||||
#include <scsl/Test.h>
|
|
||||||
|
|
||||||
|
|
||||||
/// scsl is the top-level namespace containing all the code in this library.
|
/// scsl is the top-level namespace containing all the code in this library.
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
///
|
///
|
||||||
/// \file stringutil_test.cc
|
/// \file stringutil_test.cc
|
||||||
/// \author kyle
|
/// \author kyle
|
||||||
/// \date 10/14/23
|
/// \created 10/14/23
|
||||||
/// \brief Ensure the stringutil functions work.
|
/// \brief Ensure the stringutil functions work.
|
||||||
///
|
///
|
||||||
|
/// \section COPYRIGHT
|
||||||
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
/// Copyright 2023 K. Isom <kyle@imap.cc>
|
||||||
///
|
///
|
||||||
/// Permission to use, copy, modify, and/or distribute this software for
|
/// Permission to use, copy, modify, and/or distribute this software for
|
||||||
@@ -26,8 +27,6 @@
|
|||||||
|
|
||||||
#include "StringUtil.h"
|
#include "StringUtil.h"
|
||||||
#include "Test.h"
|
#include "Test.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace scsl;
|
using namespace scsl;
|
||||||
|
|
||||||
|
|
||||||
@@ -77,7 +76,7 @@ vec2string(std::vector<std::string> v)
|
|||||||
ss << "{";
|
ss << "{";
|
||||||
|
|
||||||
for (size_t i = 0; i < v.size(); i++) {
|
for (size_t i = 0; i < v.size(); i++) {
|
||||||
if (i > 0) { ss << ", "; }
|
if (i > 0) ss << ", ";
|
||||||
ss << v[i];
|
ss << v[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,36 +100,6 @@ TestSplit(std::string line, std::string delim, size_t maxCount, std::vector<std:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
|
||||||
TestWrapping()
|
|
||||||
{
|
|
||||||
std::string testLine = "A much longer line, something that can be tested with WrapText. ";
|
|
||||||
testLine += "Does it handle puncuation? I hope so.";
|
|
||||||
|
|
||||||
std::vector<std::string> expected{
|
|
||||||
"A much longer",
|
|
||||||
"line, something",
|
|
||||||
"that can be",
|
|
||||||
"tested with",
|
|
||||||
"WrapText. Does",
|
|
||||||
"it handle",
|
|
||||||
"puncuation? I",
|
|
||||||
"hope so.",
|
|
||||||
};
|
|
||||||
|
|
||||||
auto wrapped = U::S::WrapText(testLine, 16);
|
|
||||||
TestAssert(wrapped.size() == expected.size(),
|
|
||||||
U::S::VectorToString(wrapped) + " != " + U::S::VectorToString(expected));
|
|
||||||
|
|
||||||
for (size_t i = 0; i < wrapped.size(); i++) {
|
|
||||||
TestAssert(wrapped[i] == expected[i],
|
|
||||||
"\"" + wrapped[i] + "\" != \"" + expected[i] + "\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
U::S::WriteTabIndented(std::cout, wrapped, 4, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
@@ -147,6 +116,4 @@ main()
|
|||||||
std::vector<std::string>{"abc:def:ghij:klm"});
|
std::vector<std::string>{"abc:def:ghij:klm"});
|
||||||
TestSplit("abc::def:ghi", ":", 0,
|
TestSplit("abc::def:ghi", ":", 0,
|
||||||
std::vector<std::string>{"abc", "", "def", "ghi"});
|
std::vector<std::string>{"abc", "", "def", "ghi"});
|
||||||
|
|
||||||
TestWrapping();
|
|
||||||
}
|
}
|
||||||
@@ -48,16 +48,13 @@ tlvTestSuite(Arena &backend)
|
|||||||
assert(cursor != nullptr);
|
assert(cursor != nullptr);
|
||||||
assert(cmpRecord(rec3, rec4));
|
assert(cmpRecord(rec3, rec4));
|
||||||
|
|
||||||
std::cout << "\tSetRecord 1\n";
|
|
||||||
TLV::SetRecord(rec4, 3, TEST_STRLEN3, TEST_STR3);
|
TLV::SetRecord(rec4, 3, TEST_STRLEN3, TEST_STR3);
|
||||||
assert(TLV::WriteToMemory(backend, nullptr, rec4));
|
assert(TLV::WriteToMemory(backend, nullptr, rec4));
|
||||||
|
|
||||||
std::cout << "FindTag 3\n";
|
|
||||||
rec4.Tag = 2;
|
rec4.Tag = 2;
|
||||||
cursor = TLV::FindTag(backend, nullptr, rec4);
|
cursor = TLV::FindTag(backend, nullptr, rec4);
|
||||||
assert(cursor != nullptr);
|
assert(cursor != nullptr);
|
||||||
|
|
||||||
std::cout << "DeleteRecord\n";
|
|
||||||
TLV::DeleteRecord(backend, cursor);
|
TLV::DeleteRecord(backend, cursor);
|
||||||
assert(cursor[0] == 3);
|
assert(cursor[0] == 3);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user