From a87fe4f4977a918b1be6ee1e01994a3f972ef7d4 Mon Sep 17 00:00:00 2001 From: Ventsy Velev Date: Fri, 17 Nov 2023 10:50:38 -0500 Subject: [PATCH 1/5] Closes the output stream in the safeConfig function --- src/Expander.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Expander.cpp b/src/Expander.cpp index 5bae237..22abc07 100755 --- a/src/Expander.cpp +++ b/src/Expander.cpp @@ -510,4 +510,6 @@ void Expander::saveConfig(const std::string& filePath) out << L"group.end " << getGroupEnd() << endl; out << L"quote " << getQuote() << endl; + out.close(); + } From 73e81318e67b90fa07beb8bb8da0240b82a21619 Mon Sep 17 00:00:00 2001 From: Ventsy Velev Date: Fri, 17 Nov 2023 10:51:18 -0500 Subject: [PATCH 2/5] Adds config command line option with various sub-arguments --- src/main.cpp | 70 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ebbe525..8f9e018 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,10 +3,13 @@ #include #include #include +#include #include "Expander.h" using namespace std; +const string DEFAULT_CONFIG_FILE_NAME = ".pathexpconfig"; + void run_command(int argc, char *argv[]) { wstring pattern; @@ -56,16 +59,63 @@ void run_command(int argc, char *argv[]) } } +void setConfig(int argc, char *argv[], const string& filePath) +{ + PatternExpander::Expander exp; + std::wstring_convert> wcu8; + int i = 2; + while (i < argc) + { + string option(argv[i++]); + if (i >= argc) + { + cerr << "Skipping option '" << option << "' - no value provided" << endl; + return; + } + string temp(argv[i++]); + wstring val = wcu8.from_bytes(temp); + if (val.length() != 1) + { + cerr << "Skipping option '" << option << "' due to invalid value '" << temp << "'. Values are single characters only." << endl; + continue; + } + + std::transform(option.begin(), option.end(), option.begin(), + ::tolower); + if (option == "-q" || option == "--quote") + exp.setQuote(val[0]); + else if (option == "-e" || option == "--esc") + exp.setEscChar(val[0]); + else if (option == "-b" || option == "--group_begin" ) + exp.setGroupBegin(val[0]); + else if (option == "-n" || option == "--group_end") + exp.setGroupEnd(val[0]); + else if (option == "-r" || option == "range") + exp.setRangeChar(val[0]); + else + cout << "Skipping unknown option: "<< option << endl; + + exp.saveConfig(filePath); + + } +} + int main(int argc, char *argv[]) { std::setlocale(LC_CTYPE, "C.UTF8"); - wstring usage = LR"(usage: patexp [-h | --help] [] + string usage = R"(usage: patexp [-h | --help] [] commands: run [ .. ] | : Generates strings from a list of patterns validate [ .. ] | : Validates if the patterns provided are syntaxically correct - configure: Sets the various configuration options)"; + configure: Sets the various configuration options + -b, --group_begin : Sets the group begin symbol. Default: '[' + -e, --esc : Sets the escape symbol. Default: '/' + -q, --quote : Sets the quote symbols. Default: '"' + -n, --group_end : Sets the group end symbol. Default: ']' + -r, --range : Sets the range symbol. Default: '-' +)"; if (argc > 1) { @@ -74,7 +124,7 @@ int main(int argc, char *argv[]) ::tolower); if (command == "-h" || command == "--help") { - wcout << usage << endl; + cout << usage << endl; exit(0); } else if (command == "run" || command == "validate") @@ -84,21 +134,23 @@ int main(int argc, char *argv[]) } else if (command == "config" || command == "configure") { - wcout << "Configure is currently not implemented" << endl; - exit(1); + filesystem::path path(getenv("HOME")); + path.append(DEFAULT_CONFIG_FILE_NAME); + + setConfig(argc, argv, path); } else { - wcerr << "Error: unknown command" << endl; - wcout << usage << endl; + cerr << "Error: unknown command" << endl; + cout << usage << endl; } } else { // command not provided - wcerr << "Error: no command was provided" << endl; - wcout << usage << endl; + cerr << "Error: no command was provided" << endl; + cout << usage << endl; } return 0; From f6887ec111b1b4859c1b2734202b7f5472d7ddd2 Mon Sep 17 00:00:00 2001 From: Ventsy Velev Date: Fri, 17 Nov 2023 11:06:01 -0500 Subject: [PATCH 3/5] Extracting main helper functions into a separate file --- Makefile | 2 +- src/Helpers.cpp | 108 ++++++++++++++++++++++++++++++++++++++++++++++++ src/Helpers.h | 19 +++++++++ src/main.cpp | 90 +--------------------------------------- 4 files changed, 129 insertions(+), 90 deletions(-) create mode 100644 src/Helpers.cpp create mode 100644 src/Helpers.h diff --git a/Makefile b/Makefile index 8dc5c97..1389ae2 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ EXE_FILE:=patexp SRC_FILES:= Expander.o -MAIN_FILE:= main.o +MAIN_FILE:= main.o Helpers.o TEST_FILES:= TestExpander.o # Build directories - allows for separate release and debug executables diff --git a/src/Helpers.cpp b/src/Helpers.cpp new file mode 100644 index 0000000..f055315 --- /dev/null +++ b/src/Helpers.cpp @@ -0,0 +1,108 @@ +/* + * Helpers.cpp + * + * Created on: Nov 17, 2023 + * Author: ventsyv + */ + +#include +#include +#include +#include +#include +#include "Expander.h" +#include "Helpers.h" + +using namespace std; + + + +void run_command(int argc, char *argv[]) +{ + wstring pattern; + PatternExpander::Expander exp; + std::wstring_convert> wcu8; + + string command(argv[1]); + std::transform(command.begin(), command.end(), command.begin(), ::tolower); + + if (argc > 2) + { + for (int currentParam = 2; currentParam < argc; currentParam++) + { + pattern = wcu8.from_bytes(argv[currentParam]); + if (command == "validate") + { + exp.validate(pattern); + wcerr << exp.output.str(); + } + else if (command == "run") + { + exp.generate(pattern); + } + + } + // Validate will not produce any data output + wcout << exp; + } + else + { + string temp; + while (cin >> temp) + { + pattern = wcu8.from_bytes(temp); + if (command == "validate") + { + exp.validate(pattern); + wcerr << exp.output.str(); + } + else if (command == "run") + { + exp.generate(pattern); + } + } + // Validate will not produce any data output + wcout << exp; + } +} + +void setConfig(int argc, char *argv[], const string& filePath) +{ + PatternExpander::Expander exp; + std::wstring_convert> wcu8; + int i = 2; + while (i < argc) + { + string option(argv[i++]); + if (i >= argc) + { + cerr << "Skipping option '" << option << "' - no value provided" << endl; + return; + } + string temp(argv[i++]); + wstring val = wcu8.from_bytes(temp); + if (val.length() != 1) + { + cerr << "Skipping option '" << option << "' due to invalid value '" << temp << "'. Values are single characters only." << endl; + continue; + } + + std::transform(option.begin(), option.end(), option.begin(), + ::tolower); + if (option == "-q" || option == "--quote") + exp.setQuote(val[0]); + else if (option == "-e" || option == "--esc") + exp.setEscChar(val[0]); + else if (option == "-b" || option == "--group_begin" ) + exp.setGroupBegin(val[0]); + else if (option == "-n" || option == "--group_end") + exp.setGroupEnd(val[0]); + else if (option == "-r" || option == "range") + exp.setRangeChar(val[0]); + else + cout << "Skipping unknown option: "<< option << endl; + + exp.saveConfig(filePath); + + } +} diff --git a/src/Helpers.h b/src/Helpers.h new file mode 100644 index 0000000..ac77bc0 --- /dev/null +++ b/src/Helpers.h @@ -0,0 +1,19 @@ +/* + * helpers.h + * + * Created on: Nov 17, 2023 + * Author: ventsyv + */ + +#ifndef SRC_HELPERS_H_ +#define SRC_HELPERS_H_ + +#include + +void run_command(int argc, char *argv[]); + +void setConfig(int argc, char *argv[], const std::string& filePath); + + + +#endif /* SRC_HELPERS_H_ */ diff --git a/src/main.cpp b/src/main.cpp index 8f9e018..dc4df8d 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,101 +4,13 @@ #include #include #include +#include "Helpers.h" #include "Expander.h" using namespace std; const string DEFAULT_CONFIG_FILE_NAME = ".pathexpconfig"; -void run_command(int argc, char *argv[]) -{ - wstring pattern; - PatternExpander::Expander exp; - std::wstring_convert> wcu8; - - string command(argv[1]); - std::transform(command.begin(), command.end(), command.begin(), ::tolower); - - if (argc > 2) - { - for (int currentParam = 2; currentParam < argc; currentParam++) - { - pattern = wcu8.from_bytes(argv[currentParam]); - if (command == "validate") - { - exp.validate(pattern); - wcerr << exp.output.str(); - } - else if (command == "run") - { - exp.generate(pattern); - } - - } - // Validate will not produce any data output - wcout << exp; - } - else - { - string temp; - while (cin >> temp) - { - pattern = wcu8.from_bytes(temp); - if (command == "validate") - { - exp.validate(pattern); - wcerr << exp.output.str(); - } - else if (command == "run") - { - exp.generate(pattern); - } - } - // Validate will not produce any data output - wcout << exp; - } -} - -void setConfig(int argc, char *argv[], const string& filePath) -{ - PatternExpander::Expander exp; - std::wstring_convert> wcu8; - int i = 2; - while (i < argc) - { - string option(argv[i++]); - if (i >= argc) - { - cerr << "Skipping option '" << option << "' - no value provided" << endl; - return; - } - string temp(argv[i++]); - wstring val = wcu8.from_bytes(temp); - if (val.length() != 1) - { - cerr << "Skipping option '" << option << "' due to invalid value '" << temp << "'. Values are single characters only." << endl; - continue; - } - - std::transform(option.begin(), option.end(), option.begin(), - ::tolower); - if (option == "-q" || option == "--quote") - exp.setQuote(val[0]); - else if (option == "-e" || option == "--esc") - exp.setEscChar(val[0]); - else if (option == "-b" || option == "--group_begin" ) - exp.setGroupBegin(val[0]); - else if (option == "-n" || option == "--group_end") - exp.setGroupEnd(val[0]); - else if (option == "-r" || option == "range") - exp.setRangeChar(val[0]); - else - cout << "Skipping unknown option: "<< option << endl; - - exp.saveConfig(filePath); - - } -} int main(int argc, char *argv[]) { From 89fced41022a5c462fa464f00471d8814b0c3e92 Mon Sep 17 00:00:00 2001 From: Ventsy Velev Date: Fri, 17 Nov 2023 11:56:41 -0500 Subject: [PATCH 4/5] String exe name from arguments passed to the helper functions --- src/Helpers.cpp | 12 +++++------- src/main.cpp | 9 ++++++--- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/Helpers.cpp b/src/Helpers.cpp index f055315..bb8eba5 100644 --- a/src/Helpers.cpp +++ b/src/Helpers.cpp @@ -23,12 +23,12 @@ void run_command(int argc, char *argv[]) PatternExpander::Expander exp; std::wstring_convert> wcu8; - string command(argv[1]); + string command(argv[0]); std::transform(command.begin(), command.end(), command.begin(), ::tolower); - if (argc > 2) + if (argc > 1) { - for (int currentParam = 2; currentParam < argc; currentParam++) + for (int currentParam = 1; currentParam < argc; currentParam++) { pattern = wcu8.from_bytes(argv[currentParam]); if (command == "validate") @@ -70,7 +70,7 @@ void setConfig(int argc, char *argv[], const string& filePath) { PatternExpander::Expander exp; std::wstring_convert> wcu8; - int i = 2; + int i = 0; while (i < argc) { string option(argv[i++]); @@ -101,8 +101,6 @@ void setConfig(int argc, char *argv[], const string& filePath) exp.setRangeChar(val[0]); else cout << "Skipping unknown option: "<< option << endl; - - exp.saveConfig(filePath); - } + exp.saveConfig(filePath); } diff --git a/src/main.cpp b/src/main.cpp index dc4df8d..5cbdf77 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -41,15 +41,18 @@ int main(int argc, char *argv[]) } else if (command == "run" || command == "validate") { - run_command(argc, argv); - + //The first arg is the name of the executable so start at the one after + run_command(argc - 1, argv + 1); } else if (command == "config" || command == "configure") { filesystem::path path(getenv("HOME")); path.append(DEFAULT_CONFIG_FILE_NAME); - setConfig(argc, argv, path); + //The first arg is the name of the executable + //The second argument is the name of the command (in this case "config") + //We need to skip both of those + setConfig(argc - 2, argv + 2, path); } else { From 6bd75ba72f8dd61914fb13d273a54f7a64c307f8 Mon Sep 17 00:00:00 2001 From: Ventsy Velev Date: Fri, 17 Nov 2023 11:57:07 -0500 Subject: [PATCH 5/5] Adds an unit test for the setConfig helper function --- Makefile | 4 ++-- test/TestExpander.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 1389ae2..c6fb70f 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ EXE_FILE:=patexp -SRC_FILES:= Expander.o -MAIN_FILE:= main.o Helpers.o +SRC_FILES:= Expander.o Helpers.o +MAIN_FILE:= main.o TEST_FILES:= TestExpander.o # Build directories - allows for separate release and debug executables diff --git a/test/TestExpander.cpp b/test/TestExpander.cpp index cca7bcc..b60c7b5 100644 --- a/test/TestExpander.cpp +++ b/test/TestExpander.cpp @@ -4,6 +4,7 @@ #include #include "Expander.h" +#include "Helpers.h" using namespace ::testing; using namespace std; @@ -902,6 +903,45 @@ TEST_F(TestExpander, testSaveConfig) } +TEST_F(TestExpander, testSetConfig) +{ + string configFileName = std::tmpnam(nullptr); + + string args = R"(-e # -r > -b { -n } -q ^)"; + stringstream ss(args); + vector temp; + string item; + while (ss >> item) + temp.push_back(item); + + char** argv = new char*[temp.size()]; + for (size_t i = 0; i < temp.size(); i++) + { + argv[i] = new char[temp[i].length()]; + strcpy(argv[i], temp[i].c_str()); + } + + setConfig(temp.size(), argv, configFileName); + + //Load the alt config file. All settings will change + underTest.loadConfig(configFileName); + + ASSERT_EQ(underTest.getEscChar(), L'#'); + ASSERT_EQ(underTest.getGroupBegin(), L'{'); + ASSERT_EQ(underTest.getGroupEnd(), L'}'); + ASSERT_EQ(underTest.getRangeChar(), L'>'); + ASSERT_EQ(underTest.getQuote(), L'^'); + + + for (size_t i = 0; i < temp.size(); i++) + { + delete argv[i]; + } + delete [] argv; + + +} + int main(int argc, char **argv)