File indexing completed on 2026-05-08 08:37:03
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009
0010 #include "../ExtraValidators.hpp"
0011
0012 #if (defined(CLI11_ENABLE_EXTRA_VALIDATORS) && CLI11_ENABLE_EXTRA_VALIDATORS == 1) || \
0013 (!defined(CLI11_DISABLE_EXTRA_VALIDATORS) || CLI11_DISABLE_EXTRA_VALIDATORS == 0)
0014
0015 #include "../Encoding.hpp"
0016 #include "../Macros.hpp"
0017 #include "../StringTools.hpp"
0018 #include "../TypeTools.hpp"
0019
0020
0021 #include <algorithm>
0022 #include <fstream>
0023 #include <map>
0024 #include <string>
0025 #include <utility>
0026
0027
0028 namespace CLI {
0029
0030
0031 namespace detail {
0032
0033 CLI11_INLINE IPV4Validator::IPV4Validator() : Validator("IPV4") {
0034 func_ = [](std::string &ip_addr) {
0035 auto cdot = std::count(ip_addr.begin(), ip_addr.end(), '.');
0036 if(cdot != 3u) {
0037 return std::string("Invalid IPV4 address: must have 3 separators");
0038 }
0039 auto result = CLI::detail::split(ip_addr, '.');
0040 if(result.size() != 4) {
0041 return std::string("Invalid IPV4 address: must have four parts (") + ip_addr + ')';
0042 }
0043 int num = 0;
0044 for(const auto &var : result) {
0045 using CLI::detail::lexical_cast;
0046 bool retval = lexical_cast(var, num);
0047 if(!retval) {
0048 return std::string("Failed parsing number (") + var + ')';
0049 }
0050 if(num < 0 || num > 255) {
0051 return std::string("Each IP number must be between 0 and 255 ") + var;
0052 }
0053 }
0054 return std::string{};
0055 };
0056 }
0057
0058 }
0059
0060 CLI11_INLINE AsSizeValue::AsSizeValue(bool kb_is_1000) : AsNumberWithUnit(get_mapping(kb_is_1000)) {
0061 if(kb_is_1000) {
0062 description("SIZE [b, kb(=1000b), kib(=1024b), ...]");
0063 } else {
0064 description("SIZE [b, kb(=1024b), ...]");
0065 }
0066 }
0067
0068 CLI11_INLINE std::map<std::string, AsSizeValue::result_t> AsSizeValue::init_mapping(bool kb_is_1000) {
0069 std::map<std::string, result_t> m;
0070 result_t k_factor = kb_is_1000 ? 1000 : 1024;
0071 result_t ki_factor = 1024;
0072 result_t k = 1;
0073 result_t ki = 1;
0074 m["b"] = 1;
0075 for(std::string p : {"k", "m", "g", "t", "p", "e"}) {
0076 k *= k_factor;
0077 ki *= ki_factor;
0078 m[p] = k;
0079 m[p + "b"] = k;
0080 m[p + "i"] = ki;
0081 m[p + "ib"] = ki;
0082 }
0083 return m;
0084 }
0085
0086 CLI11_INLINE std::map<std::string, AsSizeValue::result_t> AsSizeValue::get_mapping(bool kb_is_1000) {
0087 if(kb_is_1000) {
0088 static auto m = init_mapping(true);
0089 return m;
0090 }
0091 static auto m = init_mapping(false);
0092 return m;
0093 }
0094
0095 namespace detail {}
0096
0097
0098 #if defined(CLI11_ENABLE_EXTRA_VALIDATORS) && CLI11_ENABLE_EXTRA_VALIDATORS != 0
0099
0100 namespace detail {
0101
0102 #if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0
0103 CLI11_INLINE PermissionValidator::PermissionValidator(Permission permission) {
0104 std::filesystem::perms permission_code = std::filesystem::perms::none;
0105 std::string permission_name;
0106 switch(permission) {
0107 case Permission::read:
0108 permission_code = std::filesystem::perms::owner_read | std::filesystem::perms::group_read |
0109 std::filesystem::perms::others_read;
0110 permission_name = "read";
0111 break;
0112 case Permission::write:
0113 permission_code = std::filesystem::perms::owner_write | std::filesystem::perms::group_write |
0114 std::filesystem::perms::others_write;
0115 permission_name = "write";
0116 break;
0117 case Permission::exec:
0118 permission_code = std::filesystem::perms::owner_exec | std::filesystem::perms::group_exec |
0119 std::filesystem::perms::others_exec;
0120 permission_name = "exec";
0121 break;
0122 case Permission::none:
0123 default:
0124 permission_code = std::filesystem::perms::none;
0125 break;
0126 }
0127 func_ = [permission_code](std::string &path) {
0128 std::error_code ec;
0129 auto p = std::filesystem::path(path);
0130 if(!std::filesystem::exists(p, ec)) {
0131 return std::string("Path does not exist: ") + path;
0132 }
0133 if(ec) {
0134 return std::string("Error checking path: ") + ec.message();
0135 }
0136 if(permission_code == std::filesystem::perms::none) {
0137 return std::string{};
0138 }
0139 auto perms = std::filesystem::status(p, ec).permissions();
0140 if(ec) {
0141 return std::string("Error checking path status: ") + ec.message();
0142 }
0143 if((perms & permission_code) == std::filesystem::perms::none) {
0144 return std::string("Path does not have required permissions: ") + path;
0145 }
0146 return std::string{};
0147 };
0148 description("Path with " + permission_name + " permission");
0149 }
0150 #endif
0151
0152 }
0153 #endif
0154
0155 }
0156
0157 #endif