Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-09-28 07:02:18

0001 // Copyright (c) 2017-2020, 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 // [CLI11:public_includes:set]
0010 #include <string>
0011 #include <tuple>
0012 #include <utility>
0013 #include <vector>
0014 // [CLI11:public_includes:end]
0015 
0016 #include "Error.hpp"
0017 #include "StringTools.hpp"
0018 
0019 namespace CLI {
0020 // [CLI11:split_hpp:verbatim]
0021 
0022 namespace detail {
0023 
0024 // Returns false if not a short option. Otherwise, sets opt name and rest and returns true
0025 inline bool split_short(const std::string &current, std::string &name, std::string &rest) {
0026     if(current.size() > 1 && current[0] == '-' && valid_first_char(current[1])) {
0027         name = current.substr(1, 1);
0028         rest = current.substr(2);
0029         return true;
0030     }
0031     return false;
0032 }
0033 
0034 // Returns false if not a long option. Otherwise, sets opt name and other side of = and returns true
0035 inline bool split_long(const std::string &current, std::string &name, std::string &value) {
0036     if(current.size() > 2 && current.substr(0, 2) == "--" && valid_first_char(current[2])) {
0037         auto loc = current.find_first_of('=');
0038         if(loc != std::string::npos) {
0039             name = current.substr(2, loc - 2);
0040             value = current.substr(loc + 1);
0041         } else {
0042             name = current.substr(2);
0043             value = "";
0044         }
0045         return true;
0046     }
0047     return false;
0048 }
0049 
0050 // Returns false if not a windows style option. Otherwise, sets opt name and value and returns true
0051 inline bool split_windows_style(const std::string &current, std::string &name, std::string &value) {
0052     if(current.size() > 1 && current[0] == '/' && valid_first_char(current[1])) {
0053         auto loc = current.find_first_of(':');
0054         if(loc != std::string::npos) {
0055             name = current.substr(1, loc - 1);
0056             value = current.substr(loc + 1);
0057         } else {
0058             name = current.substr(1);
0059             value = "";
0060         }
0061         return true;
0062     }
0063     return false;
0064 }
0065 
0066 // Splits a string into multiple long and short names
0067 inline std::vector<std::string> split_names(std::string current) {
0068     std::vector<std::string> output;
0069     std::size_t val;
0070     while((val = current.find(",")) != std::string::npos) {
0071         output.push_back(trim_copy(current.substr(0, val)));
0072         current = current.substr(val + 1);
0073     }
0074     output.push_back(trim_copy(current));
0075     return output;
0076 }
0077 
0078 /// extract default flag values either {def} or starting with a !
0079 inline std::vector<std::pair<std::string, std::string>> get_default_flag_values(const std::string &str) {
0080     std::vector<std::string> flags = split_names(str);
0081     flags.erase(std::remove_if(flags.begin(),
0082                                flags.end(),
0083                                [](const std::string &name) {
0084                                    return ((name.empty()) || (!(((name.find_first_of('{') != std::string::npos) &&
0085                                                                  (name.back() == '}')) ||
0086                                                                 (name[0] == '!'))));
0087                                }),
0088                 flags.end());
0089     std::vector<std::pair<std::string, std::string>> output;
0090     output.reserve(flags.size());
0091     for(auto &flag : flags) {
0092         auto def_start = flag.find_first_of('{');
0093         std::string defval = "false";
0094         if((def_start != std::string::npos) && (flag.back() == '}')) {
0095             defval = flag.substr(def_start + 1);
0096             defval.pop_back();
0097             flag.erase(def_start, std::string::npos);
0098         }
0099         flag.erase(0, flag.find_first_not_of("-!"));
0100         output.emplace_back(flag, defval);
0101     }
0102     return output;
0103 }
0104 
0105 /// Get a vector of short names, one of long names, and a single name
0106 inline std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>
0107 get_names(const std::vector<std::string> &input) {
0108 
0109     std::vector<std::string> short_names;
0110     std::vector<std::string> long_names;
0111     std::string pos_name;
0112 
0113     for(std::string name : input) {
0114         if(name.length() == 0) {
0115             continue;
0116         }
0117         if(name.length() > 1 && name[0] == '-' && name[1] != '-') {
0118             if(name.length() == 2 && valid_first_char(name[1]))
0119                 short_names.emplace_back(1, name[1]);
0120             else
0121                 throw BadNameString::OneCharName(name);
0122         } else if(name.length() > 2 && name.substr(0, 2) == "--") {
0123             name = name.substr(2);
0124             if(valid_name_string(name))
0125                 long_names.push_back(name);
0126             else
0127                 throw BadNameString::BadLongName(name);
0128         } else if(name == "-" || name == "--") {
0129             throw BadNameString::DashesOnly(name);
0130         } else {
0131             if(pos_name.length() > 0)
0132                 throw BadNameString::MultiPositionalNames(name);
0133             pos_name = name;
0134         }
0135     }
0136 
0137     return std::tuple<std::vector<std::string>, std::vector<std::string>, std::string>(
0138         short_names, long_names, pos_name);
0139 }
0140 
0141 }  // namespace detail
0142 // [CLI11:split_hpp:end]
0143 }  // namespace CLI