Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-13 09:06:09

0001 // Copyright (c) 2017-2025, University of Cincinnati, developed by Henry Schreiner
0002 // under NSF AWARD 1414736 and by the respective contributors.
0003 // All rights reserved.
0004 //
0005 // SPDX-License-Identifier: BSD-3-Clause
0006 
0007 #pragma once
0008 
0009 // IWYU pragma: private, include "CLI/CLI.hpp"
0010 #include "../Validators.hpp"
0011 
0012 #include "../Encoding.hpp"
0013 #include "../Macros.hpp"
0014 #include "../StringTools.hpp"
0015 #include "../TypeTools.hpp"
0016 
0017 // [CLI11:public_includes:set]
0018 #include <map>
0019 #include <string>
0020 #include <utility>
0021 // [CLI11:public_includes:end]
0022 
0023 namespace CLI {
0024 // [CLI11:validators_inl_hpp:verbatim]
0025 
0026 CLI11_INLINE std::string Validator::operator()(std::string &str) const {
0027     std::string retstring;
0028     if(active_) {
0029         if(non_modifying_) {
0030             std::string value = str;
0031             retstring = func_(value);
0032         } else {
0033             retstring = func_(str);
0034         }
0035     }
0036     return retstring;
0037 }
0038 
0039 CLI11_NODISCARD CLI11_INLINE Validator Validator::description(std::string validator_desc) const {
0040     Validator newval(*this);
0041     newval.desc_function_ = [validator_desc]() { return validator_desc; };
0042     return newval;
0043 }
0044 
0045 CLI11_INLINE Validator Validator::operator&(const Validator &other) const {
0046     Validator newval;
0047 
0048     newval._merge_description(*this, other, " AND ");
0049 
0050     // Give references (will make a copy in lambda function)
0051     const std::function<std::string(std::string & filename)> &f1 = func_;
0052     const std::function<std::string(std::string & filename)> &f2 = other.func_;
0053 
0054     newval.func_ = [f1, f2](std::string &input) {
0055         std::string s1 = f1(input);
0056         std::string s2 = f2(input);
0057         if(!s1.empty() && !s2.empty())
0058             return std::string("(") + s1 + ") AND (" + s2 + ")";
0059         return s1 + s2;
0060     };
0061 
0062     newval.active_ = active_ && other.active_;
0063     newval.application_index_ = application_index_;
0064     return newval;
0065 }
0066 
0067 CLI11_INLINE Validator Validator::operator|(const Validator &other) const {
0068     Validator newval;
0069 
0070     newval._merge_description(*this, other, " OR ");
0071 
0072     // Give references (will make a copy in lambda function)
0073     const std::function<std::string(std::string &)> &f1 = func_;
0074     const std::function<std::string(std::string &)> &f2 = other.func_;
0075 
0076     newval.func_ = [f1, f2](std::string &input) {
0077         std::string s1 = f1(input);
0078         std::string s2 = f2(input);
0079         if(s1.empty() || s2.empty())
0080             return std::string();
0081 
0082         return std::string("(") + s1 + ") OR (" + s2 + ")";
0083     };
0084     newval.active_ = active_ && other.active_;
0085     newval.application_index_ = application_index_;
0086     return newval;
0087 }
0088 
0089 CLI11_INLINE Validator Validator::operator!() const {
0090     Validator newval;
0091     const std::function<std::string()> &dfunc1 = desc_function_;
0092     newval.desc_function_ = [dfunc1]() {
0093         auto str = dfunc1();
0094         return (!str.empty()) ? std::string("NOT ") + str : std::string{};
0095     };
0096     // Give references (will make a copy in lambda function)
0097     const std::function<std::string(std::string & res)> &f1 = func_;
0098 
0099     newval.func_ = [f1, dfunc1](std::string &test) -> std::string {
0100         std::string s1 = f1(test);
0101         if(s1.empty()) {
0102             return std::string("check ") + dfunc1() + " succeeded improperly";
0103         }
0104         return std::string{};
0105     };
0106     newval.active_ = active_;
0107     newval.application_index_ = application_index_;
0108     return newval;
0109 }
0110 
0111 CLI11_INLINE void
0112 Validator::_merge_description(const Validator &val1, const Validator &val2, const std::string &merger) {
0113 
0114     const std::function<std::string()> &dfunc1 = val1.desc_function_;
0115     const std::function<std::string()> &dfunc2 = val2.desc_function_;
0116 
0117     desc_function_ = [=]() {
0118         std::string f1 = dfunc1();
0119         std::string f2 = dfunc2();
0120         if((f1.empty()) || (f2.empty())) {
0121             return f1 + f2;
0122         }
0123         return std::string(1, '(') + f1 + ')' + merger + '(' + f2 + ')';
0124     };
0125 }
0126 
0127 namespace detail {
0128 
0129 #if defined CLI11_HAS_FILESYSTEM && CLI11_HAS_FILESYSTEM > 0
0130 CLI11_INLINE path_type check_path(const char *file) noexcept {
0131     std::error_code ec;
0132     auto stat = std::filesystem::status(to_path(file), ec);
0133     if(ec) {
0134         return path_type::nonexistent;
0135     }
0136     switch(stat.type()) {
0137     case std::filesystem::file_type::none:  // LCOV_EXCL_LINE
0138     case std::filesystem::file_type::not_found:
0139         return path_type::nonexistent;  // LCOV_EXCL_LINE
0140     case std::filesystem::file_type::directory:
0141         return path_type::directory;
0142     case std::filesystem::file_type::symlink:
0143     case std::filesystem::file_type::block:
0144     case std::filesystem::file_type::character:
0145     case std::filesystem::file_type::fifo:
0146     case std::filesystem::file_type::socket:
0147     case std::filesystem::file_type::regular:
0148     case std::filesystem::file_type::unknown:
0149     default:
0150         return path_type::file;
0151     }
0152 }
0153 #else
0154 CLI11_INLINE path_type check_path(const char *file) noexcept {
0155 #if defined(_MSC_VER)
0156     struct __stat64 buffer;
0157     if(_stat64(file, &buffer) == 0) {
0158         return ((buffer.st_mode & S_IFDIR) != 0) ? path_type::directory : path_type::file;
0159     }
0160 #else
0161     struct stat buffer;
0162     if(stat(file, &buffer) == 0) {
0163         return ((buffer.st_mode & S_IFDIR) != 0) ? path_type::directory : path_type::file;
0164     }
0165 #endif
0166     return path_type::nonexistent;
0167 }
0168 #endif
0169 
0170 CLI11_INLINE ExistingFileValidator::ExistingFileValidator() : Validator("FILE") {
0171     func_ = [](std::string &filename) {
0172         auto path_result = check_path(filename.c_str());
0173         if(path_result == path_type::nonexistent) {
0174             return "File does not exist: " + filename;
0175         }
0176         if(path_result == path_type::directory) {
0177             return "File is actually a directory: " + filename;
0178         }
0179         return std::string();
0180     };
0181 }
0182 
0183 CLI11_INLINE ExistingDirectoryValidator::ExistingDirectoryValidator() : Validator("DIR") {
0184     func_ = [](std::string &filename) {
0185         auto path_result = check_path(filename.c_str());
0186         if(path_result == path_type::nonexistent) {
0187             return "Directory does not exist: " + filename;
0188         }
0189         if(path_result == path_type::file) {
0190             return "Directory is actually a file: " + filename;
0191         }
0192         return std::string();
0193     };
0194 }
0195 
0196 CLI11_INLINE ExistingPathValidator::ExistingPathValidator() : Validator("PATH(existing)") {
0197     func_ = [](std::string &filename) {
0198         auto path_result = check_path(filename.c_str());
0199         if(path_result == path_type::nonexistent) {
0200             return "Path does not exist: " + filename;
0201         }
0202         return std::string();
0203     };
0204 }
0205 
0206 CLI11_INLINE NonexistentPathValidator::NonexistentPathValidator() : Validator("PATH(non-existing)") {
0207     func_ = [](std::string &filename) {
0208         auto path_result = check_path(filename.c_str());
0209         if(path_result != path_type::nonexistent) {
0210             return "Path already exists: " + filename;
0211         }
0212         return std::string();
0213     };
0214 }
0215 
0216 CLI11_INLINE EscapedStringTransformer::EscapedStringTransformer() {
0217     func_ = [](std::string &str) {
0218         try {
0219             if(str.size() > 1 && (str.front() == '\"' || str.front() == '\'' || str.front() == '`') &&
0220                str.front() == str.back()) {
0221                 process_quoted_string(str);
0222             } else if(str.find_first_of('\\') != std::string::npos) {
0223                 if(detail::is_binary_escaped_string(str)) {
0224                     str = detail::extract_binary_string(str);
0225                 } else {
0226                     str = remove_escaped_characters(str);
0227                 }
0228             }
0229             return std::string{};
0230         } catch(const std::invalid_argument &ia) {
0231             return std::string(ia.what());
0232         }
0233     };
0234 }
0235 }  // namespace detail
0236 
0237 CLI11_INLINE FileOnDefaultPath::FileOnDefaultPath(std::string default_path, bool enableErrorReturn)
0238     : Validator("FILE") {
0239     func_ = [default_path, enableErrorReturn](std::string &filename) {
0240         auto path_result = detail::check_path(filename.c_str());
0241         if(path_result == detail::path_type::nonexistent) {
0242             std::string test_file_path = default_path;
0243             if(default_path.back() != '/' && default_path.back() != '\\') {
0244                 // Add folder separator
0245                 test_file_path += '/';
0246             }
0247             test_file_path.append(filename);
0248             path_result = detail::check_path(test_file_path.c_str());
0249             if(path_result == detail::path_type::file) {
0250                 filename = test_file_path;
0251             } else {
0252                 if(enableErrorReturn) {
0253                     return "File does not exist: " + filename;
0254                 }
0255             }
0256         }
0257         return std::string{};
0258     };
0259 }
0260 
0261 namespace detail {
0262 
0263 CLI11_INLINE std::pair<std::string, std::string> split_program_name(std::string commandline) {
0264     // try to determine the programName
0265     std::pair<std::string, std::string> vals;
0266     trim(commandline);
0267     auto esp = commandline.find_first_of(' ', 1);
0268     while(detail::check_path(commandline.substr(0, esp).c_str()) != path_type::file) {
0269         esp = commandline.find_first_of(' ', esp + 1);
0270         if(esp == std::string::npos) {
0271             // if we have reached the end and haven't found a valid file just assume the first argument is the
0272             // program name
0273             if(commandline[0] == '"' || commandline[0] == '\'' || commandline[0] == '`') {
0274                 bool embeddedQuote = false;
0275                 auto keyChar = commandline[0];
0276                 auto end = commandline.find_first_of(keyChar, 1);
0277                 while((end != std::string::npos) && (commandline[end - 1] == '\\')) {  // deal with escaped quotes
0278                     end = commandline.find_first_of(keyChar, end + 1);
0279                     embeddedQuote = true;
0280                 }
0281                 if(end != std::string::npos) {
0282                     vals.first = commandline.substr(1, end - 1);
0283                     esp = end + 1;
0284                     if(embeddedQuote) {
0285                         vals.first = find_and_replace(vals.first, std::string("\\") + keyChar, std::string(1, keyChar));
0286                     }
0287                 } else {
0288                     esp = commandline.find_first_of(' ', 1);
0289                 }
0290             } else {
0291                 esp = commandline.find_first_of(' ', 1);
0292             }
0293 
0294             break;
0295         }
0296     }
0297     if(vals.first.empty()) {
0298         vals.first = commandline.substr(0, esp);
0299         rtrim(vals.first);
0300     }
0301 
0302     // strip the program name
0303     vals.second = (esp < commandline.length() - 1) ? commandline.substr(esp + 1) : std::string{};
0304     ltrim(vals.second);
0305     return vals;
0306 }
0307 
0308 }  // namespace detail
0309 /// @}
0310 
0311 // [CLI11:validators_inl_hpp:end]
0312 }  // namespace CLI