Commit d3c3a4c58f9bdb9c4907add9144b2df812643774
Committed by
Henry Schreiner
1 parent
b2689445
add validator for ip address and positive number
Showing
2 changed files
with
81 additions
and
0 deletions
include/CLI/Validators.hpp
| @@ -150,6 +150,49 @@ struct NonexistentPathValidator : public Validator { | @@ -150,6 +150,49 @@ struct NonexistentPathValidator : public Validator { | ||
| 150 | }; | 150 | }; |
| 151 | } | 151 | } |
| 152 | }; | 152 | }; |
| 153 | + | ||
| 154 | +/// validate the given string is a legal ipv4 address | ||
| 155 | +struct IPV4Validator : public Validator { | ||
| 156 | + IPV4Validator() { | ||
| 157 | + tname = "IPV4"; | ||
| 158 | + func = [](const std::string &ip_addr) { | ||
| 159 | + auto result = CLI::detail::split(ip_addr, '.'); | ||
| 160 | + if(result.size() != 4) { | ||
| 161 | + return "Invalid IPV4 address must have four parts " + ip_addr; | ||
| 162 | + } | ||
| 163 | + int num; | ||
| 164 | + bool retval = true; | ||
| 165 | + for(const auto &var : result) { | ||
| 166 | + retval &= detail::lexical_cast(var, num); | ||
| 167 | + if(!retval) { | ||
| 168 | + return "Failed parsing number " + var; | ||
| 169 | + } | ||
| 170 | + if(num < 0 || num > 255) { | ||
| 171 | + return "Each IP number must be between 0 and 255 " + var; | ||
| 172 | + } | ||
| 173 | + } | ||
| 174 | + return std::string(); | ||
| 175 | + }; | ||
| 176 | + } | ||
| 177 | +}; | ||
| 178 | + | ||
| 179 | +/// validate the argument is a number and equal greater then 0 | ||
| 180 | +struct PositiveNumber : public Validator { | ||
| 181 | + PositiveNumber() { | ||
| 182 | + tname = "positive number"; | ||
| 183 | + func = [](const std::string &number_str) { | ||
| 184 | + int number; | ||
| 185 | + if(!detail::lexical_cast(number_str, number)) { | ||
| 186 | + return "Failed parsing number " + number_str; | ||
| 187 | + } | ||
| 188 | + if(number < 0) { | ||
| 189 | + return "number less then 0 " + number_str; | ||
| 190 | + } | ||
| 191 | + return std::string(); | ||
| 192 | + }; | ||
| 193 | + } | ||
| 194 | +}; | ||
| 195 | + | ||
| 153 | } // namespace detail | 196 | } // namespace detail |
| 154 | 197 | ||
| 155 | // Static is not needed here, because global const implies static. | 198 | // Static is not needed here, because global const implies static. |
| @@ -166,6 +209,12 @@ const detail::ExistingPathValidator ExistingPath; | @@ -166,6 +209,12 @@ const detail::ExistingPathValidator ExistingPath; | ||
| 166 | /// Check for an non-existing path | 209 | /// Check for an non-existing path |
| 167 | const detail::NonexistentPathValidator NonexistentPath; | 210 | const detail::NonexistentPathValidator NonexistentPath; |
| 168 | 211 | ||
| 212 | +/// Check for an existing path | ||
| 213 | +const detail::IPV4Validator ValidIPV4; | ||
| 214 | + | ||
| 215 | +/// Check for an non-existing path | ||
| 216 | +const detail::PositiveNumber PositiveNumber; | ||
| 217 | + | ||
| 169 | /// Produce a range (factory). Min and max are inclusive. | 218 | /// Produce a range (factory). Min and max are inclusive. |
| 170 | struct Range : public Validator { | 219 | struct Range : public Validator { |
| 171 | /// This produces a range with min and max inclusive. | 220 | /// This produces a range with min and max inclusive. |
tests/HelpersTest.cpp
| @@ -189,6 +189,38 @@ TEST(Validators, PathNotExistsDir) { | @@ -189,6 +189,38 @@ TEST(Validators, PathNotExistsDir) { | ||
| 189 | EXPECT_NE(CLI::ExistingPath(mydir), ""); | 189 | EXPECT_NE(CLI::ExistingPath(mydir), ""); |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | +TEST(Validators, IPValidate1) { | ||
| 193 | + std::string ip = "1.1.1.1"; | ||
| 194 | + EXPECT_TRUE(CLI::ValidIPV4(ip).empty()); | ||
| 195 | + ip = "224.255.0.1"; | ||
| 196 | + EXPECT_TRUE(CLI::ValidIPV4(ip).empty()); | ||
| 197 | + ip = "-1.255.0.1"; | ||
| 198 | + EXPECT_FALSE(CLI::ValidIPV4(ip).empty()); | ||
| 199 | + ip = "1.256.0.1"; | ||
| 200 | + EXPECT_FALSE(CLI::ValidIPV4(ip).empty()); | ||
| 201 | + ip = "1.256.0.1"; | ||
| 202 | + EXPECT_FALSE(CLI::ValidIPV4(ip).empty()); | ||
| 203 | + ip = "aaa"; | ||
| 204 | + EXPECT_FALSE(CLI::ValidIPV4(ip).empty()); | ||
| 205 | + ip = "11.22"; | ||
| 206 | + EXPECT_FALSE(CLI::ValidIPV4(ip).empty()); | ||
| 207 | +} | ||
| 208 | + | ||
| 209 | +TEST(Validators, PositiveValidator) { | ||
| 210 | + std::string num = "1.1.1.1"; | ||
| 211 | + EXPECT_FALSE(CLI::PositiveNumber(num).empty()); | ||
| 212 | + num = "1"; | ||
| 213 | + EXPECT_TRUE(CLI::PositiveNumber(num).empty()); | ||
| 214 | + num = "10000"; | ||
| 215 | + EXPECT_TRUE(CLI::PositiveNumber(num).empty()); | ||
| 216 | + num = "0"; | ||
| 217 | + EXPECT_TRUE(CLI::PositiveNumber(num).empty()); | ||
| 218 | + num = "-1"; | ||
| 219 | + EXPECT_FALSE(CLI::PositiveNumber(num).empty()); | ||
| 220 | + num = "a"; | ||
| 221 | + EXPECT_FALSE(CLI::PositiveNumber(num).empty()); | ||
| 222 | +} | ||
| 223 | + | ||
| 192 | TEST(Validators, CombinedAndRange) { | 224 | TEST(Validators, CombinedAndRange) { |
| 193 | auto crange = CLI::Range(0, 12) & CLI::Range(4, 16); | 225 | auto crange = CLI::Range(0, 12) & CLI::Range(4, 16); |
| 194 | EXPECT_TRUE(crange("4").empty()); | 226 | EXPECT_TRUE(crange("4").empty()); |