From 482e237fb9b05fcbbda6ef1fb220c7992494b005 Mon Sep 17 00:00:00 2001 From: Tom Hicks Date: Mon, 24 Apr 2023 22:09:20 -0700 Subject: [PATCH] Adds ToLower to utils. Renames utils functions to match other functions. --- sbf-cpp/Utils.cpp | 66 +++++++++++++------------- sbf-cpp/Utils.h | 39 ++++++++-------- sbf-cpp/Utils_test.cpp | 102 +++++++++++++++++++++++------------------ 3 files changed, 112 insertions(+), 95 deletions(-) diff --git a/sbf-cpp/Utils.cpp b/sbf-cpp/Utils.cpp index 94da1c3..6e421e4 100644 --- a/sbf-cpp/Utils.cpp +++ b/sbf-cpp/Utils.cpp @@ -1,9 +1,10 @@ -#define _XOPEN_SOURCE_EXTENDED +#define _XOPEN_SOURCE_EXTENDED #include "Utils.h" #include #include #include +#include #include #include @@ -12,11 +13,10 @@ using namespace SBF; namespace SBF { namespace { using std::string; -using std::to_string; using std::vector; } // End namespace -vector word_wrap(const string& text, const size_t max_width) { +vector WordWrap(const string& text, const size_t max_width) { vector lines; string output = ""; string thisLine = ""; @@ -30,11 +30,11 @@ vector word_wrap(const string& text, const size_t max_width) { bool done = false; while (!done) { - nextSpace = get_index_of(text, " ", thisLineCurrentPosition); + nextSpace = GetIndexOf(text, " ", thisLineCurrentPosition); if (nextSpace < 0) { nextSpace = textLength; } - nextChunk = get_substring(text, thisLineCurrentPosition, nextSpace - thisLineCurrentPosition); + nextChunk = GetSubstring(text, thisLineCurrentPosition, nextSpace - thisLineCurrentPosition); auto nextChunkLength = nextChunk.size(); if (nextChunkLength > 0) { auto needsSpace = thisLine.size() > 0; @@ -43,12 +43,12 @@ vector word_wrap(const string& text, const size_t max_width) { } thisLineLength = thisLine.size(); if (nextChunkLength > max_width) { - nextChunk = get_substring(text, thisLineCurrentPosition, max_width - thisLineLength); + nextChunk = GetSubstring(text, thisLineCurrentPosition, max_width - thisLineLength); nextSpace = thisLineStartPosition + max_width; thisLine = thisLine + nextChunk; thisLineCurrentPosition = nextSpace; } else if (thisLineLength + nextChunkLength > max_width) { - thisLine = make_fit_l(thisLine, max_width, L' '); + thisLine = MakeFitL(thisLine, max_width, L' '); } else { thisLine = thisLine + nextChunk; thisLineCurrentPosition = nextSpace + 1; @@ -61,7 +61,7 @@ vector word_wrap(const string& text, const size_t max_width) { if (thisLineCurrentPosition > textLength) { done = true; } - thisLine = make_fit_l(thisLine, max_width, L'_'); + thisLine = MakeFitL(thisLine, max_width, L'_'); output += thisLine + (done ? "" : "\n"); lines.push_back(thisLine); thisLine = ""; @@ -73,9 +73,9 @@ vector word_wrap(const string& text, const size_t max_width) { return lines; } -string string_dollar(const size_t length, const char ch) { +string RepeatChar(const size_t length, const char ch) { if (ch == '\0') { - return string_dollar(length, ' '); + return RepeatChar(length, ' '); } string str = ""; @@ -85,11 +85,11 @@ string string_dollar(const size_t length, const char ch) { return str; } -string left(const string& text, const size_t length) { +string Left(const string& text, const size_t length) { return text.substr(0, length); } -string right(const string& text, const size_t length) { +string Right(const string& text, const size_t length) { size_t text_length = text.size(); size_t starting_position = text_length - length; if (text_length >= length) { @@ -99,40 +99,40 @@ string right(const string& text, const size_t length) { } } -string make_fit_c(const string& text, const size_t length, const char pad_character) { +string MakeFitC(const string& text, const size_t length, const char pad_character) { size_t text_length = text.size(); size_t left_pad_length = length >= text_length ? (length - text_length) / 2 : 0; size_t right_pad_length = (length >= text_length + left_pad_length) ? (length - text_length - left_pad_length) : 0; - string left_pad = string_dollar(left_pad_length, pad_character != '\0' ? pad_character : ' '); - string right_pad = string_dollar(right_pad_length, pad_character != '\0' ? pad_character : ' '); + string left_pad = RepeatChar(left_pad_length, pad_character != '\0' ? pad_character : ' '); + string right_pad = RepeatChar(right_pad_length, pad_character != '\0' ? pad_character : ' '); size_t total_chop = (text_length >= length) ? text_length - length : 0; size_t left_chop = total_chop / 2; // + 1 string ret = left_pad + (text == "" ? "" : text.substr(left_chop, length)) + right_pad; return ret; } -std::string make_fit_b(const std::string& prefix, - const std::string& suffix, - const size_t length, - const char pad_character) { - return make_fit_l(make_fit_l(prefix, length - suffix.size(), pad_character != '\0' ? pad_character : ' ') + suffix, - length, - pad_character != '\0' ? pad_character : ' '); +std::string MakeFitB(const std::string& prefix, + const std::string& suffix, + const size_t length, + const char pad_character) { + return MakeFitL(MakeFitL(prefix, length - suffix.size(), pad_character != '\0' ? pad_character : ' ') + suffix, + length, + pad_character != '\0' ? pad_character : ' '); } -string make_fit_l(const string& text, const size_t length, const char pad_character) { - return left(text + string_dollar(length, pad_character != '\0' ? pad_character : ' '), length); +string MakeFitL(const string& text, const size_t length, const char pad_character) { + return Left(text + RepeatChar(length, pad_character != '\0' ? pad_character : ' '), length); } -string make_fit_r(const string& text, const size_t length, const char pad_character) { - return right(string_dollar(length, pad_character != '\0' ? pad_character : ' ') + text, length); +string MakeFitR(const string& text, const size_t length, const char pad_character) { + return Right(RepeatChar(length, pad_character != '\0' ? pad_character : ' ') + text, length); } -string get_substring(const string& text, const size_t start, const size_t length) { +string GetSubstring(const string& text, const size_t start, const size_t length) { return text.substr(std::min(start, text.length()), std::max(length, 0)); } -size_t get_index_of(const string& text, const string& search, const size_t start) { +size_t GetIndexOf(const string& text, const string& search, const size_t start) { return text.find(search, start); } @@ -140,7 +140,7 @@ bool is_whitespace(char ch) { return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '\f' || ch == '\v'; } -string left_trim(const string& text) { +string LeftTrim(const string& text) { if (text == "") { return ""; } @@ -156,7 +156,7 @@ string left_trim(const string& text) { return ""; } -string right_trim(const string& text) { +string RightTrim(const string& text) { if (text == "") { return ""; } @@ -173,7 +173,9 @@ string right_trim(const string& text) { return ""; } -std::string itos(int i) { - return to_string(i); +string ToLower(const string& text) { + ostringstream os; + for_each(text.begin(), text.end(), [&os](unsigned char ch) { os << (char)tolower(ch); }); + return os.str(); } } // End namespace SBF diff --git a/sbf-cpp/Utils.h b/sbf-cpp/Utils.h index 45d52b8..4494f37 100644 --- a/sbf-cpp/Utils.h +++ b/sbf-cpp/Utils.h @@ -21,41 +21,41 @@ namespace SBF { /// @param search The text to search for. /// @param start The position to start searching at. /// @return The position of the string if found and std::npos if not found. -size_t get_index_of(const std::string& text, const std::string& search, const size_t start); +size_t GetIndexOf(const std::string& text, const std::string& search, const size_t start); /// @brief Collapses white space and attempts to word wrap text to a max of max_width columns. /// @param text The text to wrap. /// @param max_width The number of columns to wrap to. /// @return The wrapped text. -std::vector word_wrap(const std::string& text, const size_t max_width); +std::vector WordWrap(const std::string& text, const size_t max_width); /// @brief Gets a substring of another string. /// @param text The text to split. /// @param start The starting position. /// @param length The length of the substring. /// @return The sub string of text. -std::string get_substring(const std::string& text, const size_t start, const size_t length); +std::string GetSubstring(const std::string& text, const size_t start, const size_t length); /// @brief Pads on the right or truncates text to length using pad_character. /// @param text The text to operate on. /// @param length The desired length to make text. /// @param pad_character The character to pad with. /// @return The modified string. -std::string make_fit_l(const std::string& text, const size_t length, const char pad_character = ' '); +std::string MakeFitL(const std::string& text, const size_t length, const char pad_character = ' '); /// @brief Pads on both sides or truncates text to length using pad_character. /// @param text The text to operate on. /// @param length The desired length to make text. /// @param pad_character The character to pad with. /// @return The modified string. -std::string make_fit_c(const std::string& text, const size_t length, const char pad_character = ' '); +std::string MakeFitC(const std::string& text, const size_t length, const char pad_character = ' '); /// @brief Pads on the left or truncates text to length using pad_character. /// @param text The text to operate on. /// @param length The desired length to make text. /// @param pad_character The character to pad with. /// @return The modified string. -std::string make_fit_r(const std::string& text, const size_t length, const char pad_character = ' '); +std::string MakeFitR(const std::string& text, const size_t length, const char pad_character = ' '); /// @brief Pads or truncates the space between two strings. /// @param prefix The text to put on the left. @@ -63,41 +63,42 @@ std::string make_fit_r(const std::string& text, const size_t length, const char /// @param length The desired length to make the result. /// @param pad_character The character to pad with. /// @return The modified string. -std::string make_fit_b(const std::string& prefix, - const std::string& suffix, - const size_t length, - const char pad_character = ' '); +std::string MakeFitB(const std::string& prefix, + const std::string& suffix, + const size_t length, + const char pad_character = ' '); /// @brief Gets the leftmost length characters of text. /// @param text The text to operate on. /// @param length The maximum number of characters to return. /// @return The leftmost n characters of text where n is the lesser of text.size and length. -std::string left(const std::string& text, const size_t length); +std::string Left(const std::string& text, const size_t length); /// @brief Gets the rightmost length of characters of text. /// @param text The text to operate on. /// @param length The maximum number of characters to return. /// @return The rightmost n characters of text where n is the lesser of text.size and length. -std::string right(const std::string& text, const size_t length); +std::string Right(const std::string& text, const size_t length); /// @brief Removes whitespace from the left side of text. /// @param text The text to operate on. -std::string left_trim(const std::string& text); +std::string LeftTrim(const std::string& text); /// @brief Removes whitespace from the right side of text. /// @param text The text to operate on. -std::string right_trim(const std::string& text); +std::string RightTrim(const std::string& text); /// @brief Gets a string made by repeating a character. /// @param length The length of the string to return. /// @param ch The character to repeat. /// @return The repeated string. -std::string string_dollar(const size_t length, const char ch = ' '); +std::string RepeatChar(const size_t length, const char ch = ' '); -/// @brief Converts an int to a string. -/// @param i The int to convert. -/// @return The string representation of i. -std::string itos(int i); +/// @brief Gets the lowercase version of a string. This is a temporary hack until I figure out how to add ICU4C as a +/// bazel dependency. +/// @param text The text to convert. +/// @return The lowercase version of text. Currently this only supports ASCII characters. +std::string ToLower(const std::string& text); } // End namespace SBF /** @}*/ diff --git a/sbf-cpp/Utils_test.cpp b/sbf-cpp/Utils_test.cpp index a7e02d8..f38f016 100644 --- a/sbf-cpp/Utils_test.cpp +++ b/sbf-cpp/Utils_test.cpp @@ -13,7 +13,7 @@ using namespace Test; using namespace std; } // End namespace -TestResults test_get_index_of() { +TestResults test_GetIndexOf() { string long_text = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's " "standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to " @@ -22,8 +22,8 @@ TestResults test_get_index_of() { "sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker " "including versions of Lorem Ipsum."; return execute_suite(make_test_suite( - "SBF::Utils::get_index_of", - get_index_of, + "SBF::Utils::GetIndexOf(const std::string &text, const std::string &search, const size_t start)", + GetIndexOf, vector>({ make_test( "should get 0 for the first word in a string", 0, make_tuple(long_text, string("Lorem"), size_t(0))), @@ -54,10 +54,10 @@ TestResults test_get_index_of() { }))); } -TestResults test_get_substring() { +TestResults test_GetSubstring() { return execute_suite(make_test_suite( - "SBF::Utils::get_substring", - get_substring, + "SBF::Utils::GetSubstring(const std::string &text, const size_t start, const size_t length)", + GetSubstring, vector>({ make_test( "should get an empty string if start is too big", "", make_tuple(string("asdf"), size_t(6), size_t(2))), @@ -77,10 +77,10 @@ TestResults test_get_substring() { }))); } -TestResults test_left() { +TestResults test_Left() { return execute_suite(make_test_suite( - "SBF::Utils::left", - SBF::left, + "SBF::Utils::Left(const std::string& text, const size_t length)", + Left, vector>({ make_test( "should get a substring", "Micro", make_tuple(string("Microsoft QBasic"), size_t(5))), @@ -97,10 +97,10 @@ TestResults test_left() { }))); } -TestResults test_right() { +TestResults test_Right() { return execute_suite(make_test_suite( - "SBF::Utils::right", - SBF::right, + "SBF::Utils::Right(const std::string& text, const size_t length)", + Right, vector>({ make_test( "should get a substring", "Basic", make_tuple(string("Microsoft QBasic"), size_t(5))), @@ -117,10 +117,15 @@ TestResults test_right() { }))); } -TestResults test_make_fit_c() { +TestResults test_MakeFitB() { + return TestResults().skip( + "SBF::Utils::MakeFitB(const std::string &prefix, const std::string &suffix, const size_t length)"); +} + +TestResults test_MakeFitC() { return execute_suite(make_test_suite( - "SBF::Utils::make_fit_c", - make_fit_c, + "SBF::Utils::MakeFitC(const std::string &text, const size_t length)", + MakeFitC, vector>({ make_test( "should truncate a string that is too long", "soft ", make_tuple(string("Microsoft QBasic"), 5, 'A')), @@ -136,10 +141,10 @@ TestResults test_make_fit_c() { }))); } -TestResults test_make_fit_l() { +TestResults test_MakeFitL() { return execute_suite(make_test_suite( - "SBF::Utils::make_fit_l", - make_fit_l, + "SBF::Utils::MakeFitL(const std::string &text, const size_t length)", + MakeFitL, vector>({ make_test( "should truncate a string that is too long", "Micro", make_tuple(string("Microsoft QBasic"), 5, 'A')), @@ -155,10 +160,10 @@ TestResults test_make_fit_l() { }))); } -TestResults test_make_fit_r() { +TestResults test_MakeFitR() { return execute_suite(make_test_suite( - "SBF::Utils::make_fit_r", - make_fit_r, + "SBF::Utils::MakeFitR(const std::string &text, const size_t length)", + MakeFitR, vector>({ make_test( "should truncate a string that is too long", "Basic", make_tuple(string("Microsoft QBasic"), 5, 'A')), @@ -174,10 +179,10 @@ TestResults test_make_fit_r() { }))); } -TestResults test_left_trim() { +TestResults test_LeftTrim() { return execute_suite(make_test_suite( - "SBF::Utils::left_trim", - left_trim, + "SBF::Utils::LeftTrim(const std::string &text)", + LeftTrim, vector>({ make_test("should trim a string with spaces", "this is a string with spaces on either end ", @@ -205,10 +210,10 @@ TestResults test_left_trim() { }))); } -TestResults test_right_trim() { +TestResults test_RightTrim() { return execute_suite(make_test_suite( - "SBF::Utils::right_trim", - right_trim, + "SBF::Utils::RightTrim(const std::string &text)", + RightTrim, vector>({ make_test("should trim a string with spaces", " this is a string with spaces on either end", @@ -236,10 +241,10 @@ TestResults test_right_trim() { }))); } -TestResults test_string_dollar() { +TestResults test_RepeatChar() { return execute_suite(make_test_suite( - "SBF::Utils::string_dollar", - string_dollar, + "SBF::Utils::RepeatChar(const size_t length, const char ch)", + RepeatChar, vector>({ make_test("should make a string", "YYYYY", make_tuple(size_t(5), 'Y')), make_test( @@ -248,12 +253,20 @@ TestResults test_string_dollar() { }))); } -TestResults test_word_wrap() { +TestResults test_RegexReplace() { + return TestResults() + .skip( + "SBF::Utils::RegexReplace(const string& text, const string& pattern, const string& replace) // TODO: Fill " + "this in.") + .skip("SBF::Utils::RegexReplace(const string& text, regex regex, const string& replace) // TODO: Fill this in."); +} + +TestResults test_WordWrap() { // TODO: Treat newlines and tabs in text as spaces. auto fnToTest = [](string text, int32_t column_width, vector expected) -> string { ostringstream error_message; try { - vector actual = word_wrap(text, column_width); + vector actual = WordWrap(text, column_width); compare(error_message, expected, actual); } catch (const exception& ex) { error_message << ex.what(); @@ -267,7 +280,7 @@ TestResults test_word_wrap() { return "no errors"; }; return execute_suite>(make_test_suite( - "SBF::Utils::word_wrap", + "SBF::Utils::WordWrap(const std::string &text, const size_t max_width)", fnToTest, vector>>({ make_test>("should return the string if it is shorter than max_width", @@ -301,17 +314,18 @@ TestResults test_word_wrap() { int main(int argc, char* argv[]) { TestResults results; - results += test_get_index_of(); - results += test_get_substring(); - results += test_left(); - results += test_left_trim(); - results += test_make_fit_c(); - results += test_make_fit_l(); - results += test_make_fit_r(); - results += test_right(); - results += test_right_trim(); - results += test_string_dollar(); - results += test_word_wrap(); + results += test_GetIndexOf(); + results += test_GetSubstring(); + results += test_Left(); + results += test_LeftTrim(); + results += test_MakeFitC(); + results += test_MakeFitL(); + results += test_MakeFitR(); + results += test_RegexReplace(); + results += test_Right(); + results += test_RightTrim(); + results += test_RepeatChar(); + results += test_WordWrap(); PrintResults(cout, results);