From 87be1a3e389f80452886237d1e487195600db6e0 Mon Sep 17 00:00:00 2001 From: Henry Fredrick Schreiner Date: Tue, 31 Jan 2017 18:50:15 -0500 Subject: [PATCH] Adding nicer name splitter --- include/CLI.hpp | 54 +++++++++++++++++++++++++++++++++++++++++++++ tests/SmallTest.cpp | 19 ++++++++++++++++ 2 files changed, 73 insertions(+) diff --git a/include/CLI.hpp b/include/CLI.hpp index 502abe66..37c2cd4a 100644 --- a/include/CLI.hpp +++ b/include/CLI.hpp @@ -23,6 +23,8 @@ #include #include +#include + // GCC 4.7 and 4.8 have an non-working implementation of regex #include #if __cplusplus >= 201103L \ @@ -227,6 +229,58 @@ inline std::vector split_names(std::string current) { } +template +bool valid_first_char(T c) { + return std::isalpha(c) || c=='_'; +} + +template +bool valid_later_char(T c) { + return std::isalnum(c) || c=='_' || c=='.' || c=='-'; +} + +inline bool valid_name_string(const std::string &str) { + if(str.size()<1 || !valid_first_char(str[0])) + return false; + for(auto c : str.substr(1)) + if(!valid_later_char(c)) + return false; + return true; +} + +inline std::tuple,std::vector> get_names(const std::vector &input) { + std::vector short_names; + std::vector long_names; + + for(std::string name : input) { + if(name.length() == 0) + continue; + else if(name.length() == 1) + if(valid_first_char(name[0])) + short_names.push_back(name); + else + throw BadNameString("Invalid one char name: "+name); + else if(name.length() == 2 && name[0] == '-' && name[1] != '-') { + if(valid_first_char(name[1])) + short_names.push_back(std::string(1,name[1])); + else + throw BadNameString("Invalid one char name: "+name); + } else { + + if(name.substr(0,2) == "--") + name = name.substr(2); + if(valid_name_string(name)) + long_names.push_back(name); + else + throw BadNameString("Bad long name"+name); + + } + } + + return {short_names, long_names}; + +} + // Currently just throws an error if name is incorrect. May clean later. inline void cleanup_names(const std::vector &input) { diff --git a/tests/SmallTest.cpp b/tests/SmallTest.cpp index 092c434a..69cbf789 100644 --- a/tests/SmallTest.cpp +++ b/tests/SmallTest.cpp @@ -120,3 +120,22 @@ TEST(RegEx, Longs) { EXPECT_FALSE(CLI::split_long("--", name, value)); } + +TEST(Regex, SplittingNew) { + + std::vector shorts; + std::vector longs; + + EXPECT_NO_THROW(std::tie(shorts, longs) = CLI::get_names({"--long", "s", "-q", "also-long"})); + EXPECT_EQ(std::vector({"long", "also-long"}), longs); + EXPECT_EQ(std::vector({"s", "q"}), shorts); + + EXPECT_NO_THROW(std::tie(shorts, longs) = CLI::get_names({"--long", "", "s", "-q", "", "also-long"})); + EXPECT_EQ(std::vector({"long", "also-long"}), longs); + EXPECT_EQ(std::vector({"s", "q"}), shorts); + + EXPECT_THROW(std::tie(shorts, longs) = CLI::get_names({"-"}), CLI::BadNameString); + EXPECT_THROW(std::tie(shorts, longs) = CLI::get_names({"--"}), CLI::BadNameString); + EXPECT_THROW(std::tie(shorts, longs) = CLI::get_names({"-hi"}), CLI::BadNameString); + +}