CLI11
C++11 Command Line Interface Parser
Loading...
Searching...
No Matches
ExtraValidators_inl.hpp
1// Copyright (c) 2017-2026, University of Cincinnati, developed by Henry Schreiner
2// under NSF AWARD 1414736 and by the respective contributors.
3// All rights reserved.
4//
5// SPDX-License-Identifier: BSD-3-Clause
6
7#pragma once
8
9// IWYU pragma: private, include "CLI/CLI.hpp"
10#include "../ExtraValidators.hpp"
11
12#if (defined(CLI11_ENABLE_EXTRA_VALIDATORS) && CLI11_ENABLE_EXTRA_VALIDATORS == 1) || \
13 (!defined(CLI11_DISABLE_EXTRA_VALIDATORS) || CLI11_DISABLE_EXTRA_VALIDATORS == 0)
14
15#include "../Encoding.hpp"
16#include "../Macros.hpp"
17#include "../StringTools.hpp"
18#include "../TypeTools.hpp"
19
20// [CLI11:public_includes:set]
21#include <algorithm>
22#include <fstream>
23#include <map>
24#include <string>
25#include <utility>
26// [CLI11:public_includes:end]
27
28namespace CLI {
29// [CLI11:extra_validators_inl_hpp:verbatim]
30
31namespace detail {
32
33CLI11_INLINE IPV4Validator::IPV4Validator() : Validator("IPV4") {
34 func_ = [](std::string &ip_addr) {
35 auto cdot = std::count(ip_addr.begin(), ip_addr.end(), '.');
36 if(cdot != 3u) {
37 return std::string("Invalid IPV4 address: must have 3 separators");
38 }
39 auto result = CLI::detail::split(ip_addr, '.');
40 if(result.size() != 4) {
41 return std::string("Invalid IPV4 address: must have four parts (") + ip_addr + ')';
42 }
43 int num = 0;
44 for(const auto &var : result) {
45 using CLI::detail::lexical_cast;
46 bool retval = lexical_cast(var, num);
47 if(!retval) {
48 return std::string("Failed parsing number (") + var + ')';
49 }
50 if(num < 0 || num > 255) {
51 return std::string("Each IP number must be between 0 and 255 ") + var;
52 }
53 }
54 return std::string{};
55 };
56}
57
58} // namespace detail
59
60CLI11_INLINE AsSizeValue::AsSizeValue(bool kb_is_1000) : AsNumberWithUnit(get_mapping(kb_is_1000)) {
61 if(kb_is_1000) {
62 description("SIZE [b, kb(=1000b), kib(=1024b), ...]");
63 } else {
64 description("SIZE [b, kb(=1024b), ...]");
65 }
66}
67
68CLI11_INLINE std::map<std::string, AsSizeValue::result_t> AsSizeValue::init_mapping(bool kb_is_1000) {
69 std::map<std::string, result_t> m;
70 result_t k_factor = kb_is_1000 ? 1000 : 1024;
71 result_t ki_factor = 1024;
72 result_t k = 1;
73 result_t ki = 1;
74 m["b"] = 1;
75 for(std::string p : {"k", "m", "g", "t", "p", "e"}) {
76 k *= k_factor;
77 ki *= ki_factor;
78 m[p] = k;
79 m[p + "b"] = k;
80 m[p + "i"] = ki;
81 m[p + "ib"] = ki;
82 }
83 return m;
84}
85
86CLI11_INLINE std::map<std::string, AsSizeValue::result_t> AsSizeValue::get_mapping(bool kb_is_1000) {
87 if(kb_is_1000) {
88 static auto m = init_mapping(true);
89 return m;
90 }
91 static auto m = init_mapping(false);
92 return m;
93}
94
95#if defined(CLI11_ENABLE_EXTRA_VALIDATORS) && CLI11_ENABLE_EXTRA_VALIDATORS != 0
96// new extra validators
97
98#if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0
99namespace detail {
100CLI11_INLINE PermissionValidator::PermissionValidator(Permission permission) {
101 std::filesystem::perms permission_code = std::filesystem::perms::none;
102 std::string permission_name;
103 switch(permission) {
104 case Permission::read:
105 permission_code = std::filesystem::perms::owner_read | std::filesystem::perms::group_read |
106 std::filesystem::perms::others_read;
107 permission_name = "read";
108 break;
109 case Permission::write:
110 permission_code = std::filesystem::perms::owner_write | std::filesystem::perms::group_write |
111 std::filesystem::perms::others_write;
112 permission_name = "write";
113 break;
114 case Permission::exec:
115 permission_code = std::filesystem::perms::owner_exec | std::filesystem::perms::group_exec |
116 std::filesystem::perms::others_exec;
117 permission_name = "exec";
118 break;
119 case Permission::none:
120 default:
121 permission_code = std::filesystem::perms::none;
122 break;
123 }
124 func_ = [permission_code](std::string &path) {
125 std::error_code ec;
126 auto p = std::filesystem::path(path);
127 if(!std::filesystem::exists(p, ec)) {
128 return std::string("Path does not exist: ") + path;
129 }
130 if(ec) {
131 return std::string("Error checking path: ") + ec.message(); // LCOV_EXCL_LINE
132 }
133 if(permission_code == std::filesystem::perms::none) {
134 return std::string{};
135 }
136 auto perms = std::filesystem::status(p, ec).permissions();
137 if(ec) {
138 return std::string("Error checking path status: ") + ec.message(); // LCOV_EXCL_LINE
139 }
140 if((perms & permission_code) == std::filesystem::perms::none) {
141 return std::string("Path does not have required permissions: ") + path;
142 }
143 return std::string{};
144 };
145 description("Path with " + permission_name + " permission");
146}
147} // namespace detail
148
149CLI11_INLINE FileSizeValidator::FileSizeValidator(std::uint64_t min_size, std::uint64_t max_size) {
150 std::string desc;
151 if(max_size == 0) {
152 desc = "File size at least " + std::to_string(min_size) + " bytes";
153 } else {
154 desc = "File size between " + std::to_string(min_size) + " and " + std::to_string(max_size) + " bytes";
155 }
156 description(desc);
157 func_ = [min_size, max_size](std::string &path) {
158 std::error_code ec;
159 auto p = std::filesystem::path(path);
160 if(!std::filesystem::exists(p, ec)) {
161 return std::string("File does not exist: ") + path;
162 }
163 if(ec) {
164 return std::string("Error checking file: ") + ec.message(); // LCOV_EXCL_LINE
165 }
166 auto size = std::filesystem::file_size(p, ec);
167 if(ec) {
168 return std::string("Error getting file size: ") + ec.message(); // LCOV_EXCL_LINE
169 }
170 if(size < min_size) {
171 return std::string("File size ") + std::to_string(size) + " bytes is less than minimum " +
172 std::to_string(min_size) + " bytes";
173 }
174 if(max_size > 0 && size > max_size) {
175 return std::string("File size ") + std::to_string(size) + " bytes exceeds maximum " +
176 std::to_string(max_size) + " bytes";
177 }
178 return std::string{};
179 };
180}
181#endif
182
183#endif
184// [CLI11:extra_validators_inl_hpp:end]
185} // namespace CLI
186
187#endif
Definition ExtraValidators.hpp:429
Validator & description(std::string validator_desc)
Specify the type string.
Definition Validators.hpp:99