Start StringUtils, update build, add CLion config for code style.
This commit is contained in:
parent
b28199553f
commit
dd696e2c1f
|
@ -1,4 +1,3 @@
|
||||||
.idea
|
|
||||||
.trunk
|
.trunk
|
||||||
.vc
|
.vc
|
||||||
.vscode
|
.vscode
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Default ignored files
|
||||||
|
/shelf/
|
||||||
|
/workspace.xml
|
||||||
|
# Editor-based HTTP Client requests
|
||||||
|
/httpRequests/
|
||||||
|
# Datasource local storage ignored files
|
||||||
|
/dataSources/
|
||||||
|
/dataSources.local.xml
|
|
@ -0,0 +1,42 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<code_scheme name="Project" version="173">
|
||||||
|
<Objective-C>
|
||||||
|
<option name="INDENT_NAMESPACE_MEMBERS" value="0" />
|
||||||
|
<option name="INDENT_C_STRUCT_MEMBERS" value="8" />
|
||||||
|
<option name="INDENT_CLASS_MEMBERS" value="8" />
|
||||||
|
<option name="FUNCTION_BRACE_PLACEMENT" value="2" />
|
||||||
|
<option name="FUNCTION_TOP_AFTER_RETURN_TYPE_WRAP" value="2" />
|
||||||
|
</Objective-C>
|
||||||
|
<files>
|
||||||
|
<extensions>
|
||||||
|
<pair source="cc" header="h" fileNamingConvention="PASCAL_CASE" />
|
||||||
|
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||||
|
<pair source="cu" header="cuh" fileNamingConvention="NONE" />
|
||||||
|
<pair source="ixx" header="" fileNamingConvention="NONE" />
|
||||||
|
<pair source="mxx" header="" fileNamingConvention="NONE" />
|
||||||
|
<pair source="cppm" header="" fileNamingConvention="NONE" />
|
||||||
|
<pair source="ccm" header="" fileNamingConvention="NONE" />
|
||||||
|
<pair source="cxxm" header="" fileNamingConvention="NONE" />
|
||||||
|
<pair source="c++m" header="" fileNamingConvention="NONE" />
|
||||||
|
</extensions>
|
||||||
|
</files>
|
||||||
|
<codeStyleSettings language="ObjectiveC">
|
||||||
|
<option name="BLANK_LINES_BEFORE_IMPORTS" value="2" />
|
||||||
|
<option name="BLANK_LINES_AFTER_IMPORTS" value="2" />
|
||||||
|
<option name="BLANK_LINES_AROUND_METHOD" value="0" />
|
||||||
|
<option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0" />
|
||||||
|
<option name="INDENT_CASE_FROM_SWITCH" value="false" />
|
||||||
|
<option name="ALIGN_GROUP_FIELD_DECLARATIONS" value="true" />
|
||||||
|
<option name="IF_BRACE_FORCE" value="3" />
|
||||||
|
<option name="DOWHILE_BRACE_FORCE" value="3" />
|
||||||
|
<option name="WHILE_BRACE_FORCE" value="3" />
|
||||||
|
<option name="FOR_BRACE_FORCE" value="3" />
|
||||||
|
<indentOptions>
|
||||||
|
<option name="INDENT_SIZE" value="8" />
|
||||||
|
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||||
|
<option name="TAB_SIZE" value="8" />
|
||||||
|
<option name="USE_TAB_CHARACTER" value="true" />
|
||||||
|
</indentOptions>
|
||||||
|
</codeStyleSettings>
|
||||||
|
</code_scheme>
|
||||||
|
</component>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||||
|
</state>
|
||||||
|
</component>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<component name="CopyrightManager">
|
||||||
|
<copyright>
|
||||||
|
<option name="notice" value="Copyright &#36;today.year 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. " />
|
||||||
|
<option name="myName" value="ISC" />
|
||||||
|
</copyright>
|
||||||
|
</component>
|
|
@ -0,0 +1,11 @@
|
||||||
|
<component name="InspectionProjectProfileManager">
|
||||||
|
<profile version="1.0">
|
||||||
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
|
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
||||||
|
<option name="processCode" value="true" />
|
||||||
|
<option name="processLiterals" value="true" />
|
||||||
|
<option name="processComments" value="true" />
|
||||||
|
</inspection_tool>
|
||||||
|
</profile>
|
||||||
|
</component>
|
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
|
@ -0,0 +1,4 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CMakeWorkspace" PROJECT_DIR="$PROJECT_DIR$" />
|
||||||
|
</project>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/klib.iml" filepath="$PROJECT_DIR$/.idea/klib.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
2
Arena.cc
2
Arena.cc
|
@ -346,7 +346,7 @@ uint8_t &
|
||||||
Arena::operator[](size_t index)
|
Arena::operator[](size_t index)
|
||||||
{
|
{
|
||||||
if (index > this->size) {
|
if (index > this->size) {
|
||||||
#if defined(DESKTOP_BUILD) and !defined(KLIB_NO_ASSERT)
|
#if defined(KLIB_DESKTOP_BUILD) and !defined(KLIB_NO_ASSERT)
|
||||||
throw std::range_error("index out of range");
|
throw std::range_error("index out of range");
|
||||||
#else
|
#else
|
||||||
abort();
|
abort();
|
||||||
|
|
|
@ -330,7 +330,7 @@ uint8_t &
|
||||||
Buffer::operator[](size_t index)
|
Buffer::operator[](size_t index)
|
||||||
{
|
{
|
||||||
if (index > this->length) {
|
if (index > this->length) {
|
||||||
#if defined(DESKTOP_BUILD) and !defined(KLIB_NO_ASSERT)
|
#if defined(KLIB_DESKTOP_BUILD) and !defined(KLIB_NO_ASSERT)
|
||||||
throw std::range_error("array index out of bounds");
|
throw std::range_error("array index out of bounds");
|
||||||
#else
|
#else
|
||||||
abort();
|
abort();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
cmake_minimum_required(VERSION 3.25)
|
cmake_minimum_required(VERSION 3.25)
|
||||||
project(klib LANGUAGES CXX
|
project(klib LANGUAGES CXX
|
||||||
VERSION 0.0.1
|
VERSION 0.1.0
|
||||||
DESCRIPTION "Kyle's C++ library")
|
DESCRIPTION "Kyle's C++ library")
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 14)
|
set(CMAKE_CXX_STANDARD 14)
|
||||||
|
@ -25,27 +25,29 @@ else ()
|
||||||
# nothing special for gcc at the moment
|
# nothing special for gcc at the moment
|
||||||
endif ()
|
endif ()
|
||||||
endif ()
|
endif ()
|
||||||
add_compile_options("-DDESKTOP_BUILD")
|
add_compile_definitions(DKLIB_DESKTOP_BUILD)
|
||||||
|
add_compile_definitions(KLIB_VERSION=${PROJECT_VERSION})
|
||||||
|
|
||||||
set(HEADER_FILES
|
set(HEADER_FILES klib.h
|
||||||
klib.h
|
|
||||||
Arena.h
|
Arena.h
|
||||||
Buffer.h
|
Buffer.h
|
||||||
Dictionary.h
|
Dictionary.h
|
||||||
Exceptions.h
|
Exceptions.h
|
||||||
Test.h
|
StringUtil.h
|
||||||
TLV.h
|
TLV.h
|
||||||
|
Test.h
|
||||||
WinHelpers.h)
|
WinHelpers.h)
|
||||||
|
|
||||||
set(SOURCE_FILES
|
set(SOURCE_FILES
|
||||||
Arena.cc
|
Arena.cc
|
||||||
Buffer.cc
|
Buffer.cc
|
||||||
Dictionary.cc
|
|
||||||
Exceptions.cc
|
|
||||||
Test.cc
|
|
||||||
TLV.cc
|
|
||||||
Commander.cc
|
Commander.cc
|
||||||
Commander.h
|
Commander.h
|
||||||
|
Dictionary.cc
|
||||||
|
Exceptions.cc
|
||||||
|
StringUtil.cc
|
||||||
|
TLV.cc
|
||||||
|
Test.cc
|
||||||
WinHelpers.cc)
|
WinHelpers.cc)
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
|
@ -76,6 +78,10 @@ add_executable(buffer_test bufferTest.cc)
|
||||||
target_link_libraries(buffer_test klib)
|
target_link_libraries(buffer_test klib)
|
||||||
add_test(bufferTest buffer_test)
|
add_test(bufferTest buffer_test)
|
||||||
|
|
||||||
|
add_executable(stringutil_test stringutil_test.cc)
|
||||||
|
target_link_libraries(stringutil_test klib)
|
||||||
|
add_test(stringutilTest stringutil_test)
|
||||||
|
|
||||||
include(CMakePackageConfigHelpers)
|
include(CMakePackageConfigHelpers)
|
||||||
write_basic_package_version_file(
|
write_basic_package_version_file(
|
||||||
klibConfig.cmake
|
klibConfig.cmake
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include "Dictionary.h"
|
#include "Dictionary.h"
|
||||||
|
|
||||||
#if defined(DESKTOP_BUILD)
|
#if defined(KLIB_DESKTOP_BUILD)
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ Dictionary::spaceAvailable(uint8_t klen, uint8_t vlen)
|
||||||
std::ostream &
|
std::ostream &
|
||||||
operator<<(std::ostream &os, const Dictionary &dictionary)
|
operator<<(std::ostream &os, const Dictionary &dictionary)
|
||||||
{
|
{
|
||||||
#if defined(DESKTOP_BUILD)
|
#if defined(KLIB_DESKTOP_BUILD)
|
||||||
uint8_t *cursor = (dictionary.arena).NewCursor();
|
uint8_t *cursor = (dictionary.arena).NewCursor();
|
||||||
TLV::Record rec;
|
TLV::Record rec;
|
||||||
|
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -5,7 +5,7 @@ SOURCES := $(wildcard *.cc)
|
||||||
OBJS := Arena.o Dictionary.o TLV.o
|
OBJS := Arena.o Dictionary.o TLV.o
|
||||||
|
|
||||||
CXX := clang++
|
CXX := clang++
|
||||||
CXXFLAGS := -g -std=c++14 -Werror -Wall -DDESKTOP_BUILD
|
CXXFLAGS := -g -std=c++14 -Werror -Wall -DKLIB_DESKTOP_BUILD
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: $(TARGET) $(TESTS) tags run-tests
|
all: $(TARGET) $(TESTS) tags run-tests
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "StringUtil.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace klib {
|
||||||
|
/// namespace U contains utilities.
|
||||||
|
namespace U {
|
||||||
|
|
||||||
|
/// namespace S contains string-related functions.
|
||||||
|
namespace S {
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
std::vector<std::string>
|
||||||
|
SplitKeyValuePair(std::string line, std::string delimiter)
|
||||||
|
{
|
||||||
|
std::string key;
|
||||||
|
std::string val;
|
||||||
|
|
||||||
|
auto pos = line.find(delimiter);
|
||||||
|
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};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<std::string>
|
||||||
|
SplitKeyValuePair(std::string line, char delimiter)
|
||||||
|
{
|
||||||
|
std::string key;
|
||||||
|
std::string val;
|
||||||
|
|
||||||
|
auto pos = line.find(delimiter);
|
||||||
|
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
|
||||||
|
TrimLeadingWhitespace(std::string &s)
|
||||||
|
{
|
||||||
|
s.erase(s.begin(),
|
||||||
|
std::find_if(s.begin(), s.end(),
|
||||||
|
[](unsigned char ch) {
|
||||||
|
return !std::isspace(ch);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrimTrailingWhitespace(std::string &s)
|
||||||
|
{
|
||||||
|
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
|
||||||
|
return !std::isspace(ch);
|
||||||
|
}).base(), s.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrimWhitespace(std::string &s)
|
||||||
|
{
|
||||||
|
TrimLeadingWhitespace(s);
|
||||||
|
TrimTrailingWhitespace(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string
|
||||||
|
TrimLeadingWhitespaceDup(std::string s)
|
||||||
|
{
|
||||||
|
TrimLeadingWhitespace(s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string
|
||||||
|
TrimTrailingWhitespaceDup(std::string s)
|
||||||
|
{
|
||||||
|
TrimTrailingWhitespace(s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string
|
||||||
|
TrimWhitespaceDup(std::string s)
|
||||||
|
{
|
||||||
|
TrimWhitespace(s);
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<std::string>
|
||||||
|
SplitN(std::string s, std::string delim, size_t maxCount)
|
||||||
|
{
|
||||||
|
std::vector<std::string> parts;
|
||||||
|
size_t ss = 0;
|
||||||
|
size_t se = 0;
|
||||||
|
|
||||||
|
for (ss = 0; s.size() != 0 && ss < s.size(); ss++) {
|
||||||
|
se = s.find(delim, ss);
|
||||||
|
if ((maxCount > 0) && (parts.size() == maxCount - 1)) {
|
||||||
|
se = s.size();
|
||||||
|
} else if (se == std::string::npos) {
|
||||||
|
se = s.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto length = se - ss;
|
||||||
|
parts.push_back(s.substr(ss, length));
|
||||||
|
ss = se;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream &
|
||||||
|
VectorToString(std::ostream &os, const std::vector<std::string> &svec)
|
||||||
|
{
|
||||||
|
os << "(";
|
||||||
|
os << svec.size();
|
||||||
|
os << ")";
|
||||||
|
os << "{";
|
||||||
|
|
||||||
|
for (size_t i = 0; i < svec.size(); i++) {
|
||||||
|
if (i > 0) os << ", ";
|
||||||
|
os << svec[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "}";
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string
|
||||||
|
VectorToString(const std::vector<std::string> &svec)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
VectorToString(ss, svec);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace S
|
||||||
|
} // namespace U
|
||||||
|
} // namespace klib
|
|
@ -0,0 +1,105 @@
|
||||||
|
///
|
||||||
|
/// \file StringUtil.h
|
||||||
|
/// \author kyle (kyle@midgard)
|
||||||
|
/// \created 2023-10-14
|
||||||
|
/// \brief StringUtil contains string utilities.
|
||||||
|
///
|
||||||
|
/// \section COPYRIGHT
|
||||||
|
/// 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 <algorithm>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef STRINGUTIL_H
|
||||||
|
#define STRINGUTIL_H
|
||||||
|
|
||||||
|
|
||||||
|
namespace klib {
|
||||||
|
/// namespace U contains utilities.
|
||||||
|
|
||||||
|
namespace U {
|
||||||
|
|
||||||
|
/// namespace S contains string-related functions.
|
||||||
|
namespace S {
|
||||||
|
|
||||||
|
|
||||||
|
/// Remove any whitespace at the beginning of the string. The string
|
||||||
|
/// is modified in-place.
|
||||||
|
void TrimLeadingWhitespace(std::string &s);
|
||||||
|
|
||||||
|
/// Remove any whitespace at the end of the string. The string is
|
||||||
|
/// modified in-place.
|
||||||
|
void TrimTrailingWhitespace(std::string &s);
|
||||||
|
|
||||||
|
/// Remove any whitespace at the beginning and end of the string. The
|
||||||
|
/// string is modified in-place.
|
||||||
|
void TrimWhitespace(std::string &s);
|
||||||
|
|
||||||
|
/// Remove any whitespace at the beginning of the string. The original
|
||||||
|
/// string isn't modified, and a copy is returned.
|
||||||
|
std::string TrimLeadingWhitespaceDup(std::string s);
|
||||||
|
|
||||||
|
/// Remove any whitespace at the end of the string. The original string
|
||||||
|
/// isn't modified, and a copy is returned.
|
||||||
|
std::string TrimTrailingWhitespaceDup(std::string s);
|
||||||
|
|
||||||
|
/// Remove any whitespace at the beginning and end of the string. The
|
||||||
|
/// original string isn't modified, and a copy is returned.
|
||||||
|
std::string TrimWhitespaceDup(std::string s);
|
||||||
|
|
||||||
|
|
||||||
|
/// Split a line into key and value pairs. If the delimiter isn't found,
|
||||||
|
/// the line is returned as the first element in the pair, and the second
|
||||||
|
/// element will be empty.
|
||||||
|
///
|
||||||
|
/// \param line A string representing a line in a file.
|
||||||
|
/// \param delimiter The string delimiter between the key and value.
|
||||||
|
/// \return The key and value, or {line, ""}.
|
||||||
|
std::vector<std::string> SplitKeyValuePair(std::string line, std::string delimiter);
|
||||||
|
|
||||||
|
/// Split a line into key and value pairs. If the delimiter isn't found,
|
||||||
|
/// the line is returned as the first element in the pair, and the second
|
||||||
|
/// element will be empty.
|
||||||
|
///
|
||||||
|
/// \param line A string representing a line in a file.
|
||||||
|
/// \param delimiter The character delimiter between the key and value.
|
||||||
|
/// \return The key and value.
|
||||||
|
std::vector<std::string> SplitKeyValuePair(std::string line, char delimiter);
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<std::string> Split(std::string, std::string delimiter);
|
||||||
|
std::vector<std::string> Split(std::string, char delimiter);
|
||||||
|
|
||||||
|
std::vector<std::string> SplitN(std::string, std::string delimiter, size_t maxCount=0);
|
||||||
|
//std::vector<std::string> SplitN(std::string, char delimiter, size_t size_t maxCount=0);
|
||||||
|
|
||||||
|
|
||||||
|
std::ostream &VectorToString(std::ostream &os, const std::vector<std::string> &svec);
|
||||||
|
std::string VectorToString(const std::vector<std::string> &svec);
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace S
|
||||||
|
} // namespace U
|
||||||
|
} // namespace klib
|
||||||
|
|
||||||
|
|
||||||
|
#endif // STRINGUTIL_H
|
||||||
|
|
||||||
|
|
2
Test.cc
2
Test.cc
|
@ -13,7 +13,7 @@
|
||||||
namespace klib {
|
namespace klib {
|
||||||
|
|
||||||
void
|
void
|
||||||
TestAssert(bool condition, std::string message = "Assertion failed.")
|
TestAssert(bool condition, std::string message)
|
||||||
{
|
{
|
||||||
#if defined(NDEBUG) || defined(KLIB_NO_ASSERT)
|
#if defined(NDEBUG) || defined(KLIB_NO_ASSERT)
|
||||||
if (!condition) {
|
if (!condition) {
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
///
|
||||||
|
/// \file stringutil_test.cc
|
||||||
|
/// \author kyle
|
||||||
|
/// \created 10/14/23
|
||||||
|
/// \brief Ensure the stringutil functions work.
|
||||||
|
///
|
||||||
|
/// \section COPYRIGHT
|
||||||
|
/// 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 <sstream>
|
||||||
|
|
||||||
|
#include "StringUtil.h"
|
||||||
|
#include "Test.h"
|
||||||
|
using namespace klib;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
TestTrimming(std::string line, std::string lExpected, std::string rExpected, std::string expected)
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
std::string message;
|
||||||
|
|
||||||
|
result = U::S::TrimLeadingWhitespaceDup(line);
|
||||||
|
message = "TrimLeadingDup(\"" + line + "\"): '" + result + "'";
|
||||||
|
TestAssert(result == lExpected, message);
|
||||||
|
|
||||||
|
result = U::S::TrimTrailingWhitespaceDup(line);
|
||||||
|
message = "TrimTrailingDup(\"" + line + "\"): '" + result + "'";
|
||||||
|
TestAssert(result == rExpected, message);
|
||||||
|
|
||||||
|
result = U::S::TrimWhitespaceDup(line);
|
||||||
|
message = "TrimDup(\"" + line + "\"): '" + result + "'";
|
||||||
|
TestAssert(result == expected, message);
|
||||||
|
|
||||||
|
result = line;
|
||||||
|
U::S::TrimLeadingWhitespace(result);
|
||||||
|
message = "TrimLeadingDup(\"" + line + "\"): '" + result + "'";
|
||||||
|
TestAssert(result == lExpected, message);
|
||||||
|
|
||||||
|
result = line;
|
||||||
|
U::S::TrimTrailingWhitespace(result);
|
||||||
|
message = "TrimTrailingDup(\"" + line + "\"): '" + result + "'";
|
||||||
|
TestAssert(result == rExpected, message);
|
||||||
|
|
||||||
|
result = line;
|
||||||
|
U::S::TrimWhitespace(result);
|
||||||
|
message = "TrimDup(\"" + line + "\"): '" + result + "'";
|
||||||
|
TestAssert(result == expected, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static std::string
|
||||||
|
vec2string(std::vector<std::string> v)
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << "(";
|
||||||
|
ss << v.size();
|
||||||
|
ss << ")";
|
||||||
|
ss << "{";
|
||||||
|
|
||||||
|
for (size_t i = 0; i < v.size(); i++) {
|
||||||
|
if (i > 0) ss << ", ";
|
||||||
|
ss << v[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
ss << "}";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
TestSplit(std::string line, std::string delim, size_t maxCount, std::vector<std::string> expected)
|
||||||
|
{
|
||||||
|
std::cout << "test split\n";
|
||||||
|
std::cout << "\t line: \"" << line << "\"\n";
|
||||||
|
std::cout << "\t delim: \"" << delim << "\"\n";
|
||||||
|
std::cout << "\t count: " << maxCount << "\n";
|
||||||
|
std::cout << "\texpect: " << vec2string(expected) << "\n";
|
||||||
|
auto result = U::S::SplitN(line, delim, maxCount);
|
||||||
|
std::cout << "\tresult: " << U::S::VectorToString(result) << "\n";
|
||||||
|
TestAssert(result == expected, U::S::VectorToString(result));
|
||||||
|
std::cout << "OK!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main()
|
||||||
|
{
|
||||||
|
TestTrimming(" foo\t ", "foo\t ", " foo", "foo");
|
||||||
|
TestTrimming(" foo\tbar ", "foo\tbar ", " foo\tbar", "foo\tbar");
|
||||||
|
|
||||||
|
TestSplit("abc:def:ghij:klm", ":", 0,
|
||||||
|
std::vector<std::string>{"abc", "def", "ghij", "klm"});
|
||||||
|
TestSplit("abc:def:ghij:klm", ":", 3,
|
||||||
|
std::vector<std::string>{"abc", "def", "ghij:klm"});
|
||||||
|
TestSplit("abc:def:ghij:klm", ":", 2,
|
||||||
|
std::vector<std::string>{"abc", "def:ghij:klm"});
|
||||||
|
TestSplit("abc:def:ghij:klm", ":", 1,
|
||||||
|
std::vector<std::string>{"abc:def:ghij:klm"});
|
||||||
|
}
|
Loading…
Reference in New Issue