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 | 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 | 196 | } // namespace detail |
| 154 | 197 | |
| 155 | 198 | // Static is not needed here, because global const implies static. |
| ... | ... | @@ -166,6 +209,12 @@ const detail::ExistingPathValidator ExistingPath; |
| 166 | 209 | /// Check for an non-existing path |
| 167 | 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 | 218 | /// Produce a range (factory). Min and max are inclusive. |
| 170 | 219 | struct Range : public Validator { |
| 171 | 220 | /// This produces a range with min and max inclusive. | ... | ... |
tests/HelpersTest.cpp
| ... | ... | @@ -189,6 +189,38 @@ TEST(Validators, PathNotExistsDir) { |
| 189 | 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 | 224 | TEST(Validators, CombinedAndRange) { |
| 193 | 225 | auto crange = CLI::Range(0, 12) & CLI::Range(4, 16); |
| 194 | 226 | EXPECT_TRUE(crange("4").empty()); | ... | ... |