Line data Source code
1 : // Copyright (c) 2006-2024 Made to Order Software Corp. All Rights Reserved 2 : // 3 : // https://snapwebsites.org/project/advgetopt 4 : // contact@m2osw.com 5 : // 6 : // This program is free software; you can redistribute it and/or modify 7 : // it under the terms of the GNU General Public License as published by 8 : // the Free Software Foundation; either version 2 of the License, or 9 : // (at your option) any later version. 10 : // 11 : // This program is distributed in the hope that it will be useful, 12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of 13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 : // GNU General Public License for more details. 15 : // 16 : // You should have received a copy of the GNU General Public License along 17 : // with this program; if not, write to the Free Software Foundation, Inc., 18 : // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 : 20 : /** \file 21 : * \brief Implementation of the regular expression validator. 22 : * 23 : * The regular expression validator allows us to check pretty much any type 24 : * of value. 25 : * 26 : * This validator does not offer a convertor since a regular expression 27 : * does not really offer such a feature. 28 : */ 29 : 30 : // self 31 : // 32 : #include "advgetopt/validator_regex.h" 33 : 34 : 35 : // cppthread 36 : // 37 : #include <cppthread/log.h> 38 : 39 : 40 : // last include 41 : // 42 : #include <snapdev/poison.h> 43 : 44 : 45 : 46 : 47 : namespace advgetopt 48 : { 49 : 50 : 51 : 52 : namespace 53 : { 54 : 55 : 56 : 57 : class validator_regex_factory 58 : : public validator_factory 59 : { 60 : public: 61 2 : validator_regex_factory() 62 2 : { 63 2 : validator::register_validator(*this); 64 2 : } 65 : 66 4 : virtual std::string get_name() const override 67 : { 68 4 : return std::string("regex"); 69 : } 70 : 71 28 : virtual std::shared_ptr<validator> create(string_list_t const & data) const override 72 : { 73 28 : return std::make_shared<validator_regex>(data); 74 : } 75 : }; 76 : 77 : validator_regex_factory g_validator_regex_factory; 78 : 79 : 80 : 81 : } // no name namespace 82 : 83 : 84 : 85 : 86 : 87 28 : validator_regex::validator_regex(string_list_t const & regex_list) 88 : { 89 28 : if(regex_list.size() > 1) 90 : { 91 10 : cppthread::log << cppthread::log_level_t::error 92 5 : << "validator_regex() only supports one parameter; " 93 10 : << regex_list.size() 94 5 : << " were supplied; single or double quotation may be required?" 95 15 : << cppthread::end; 96 5 : return; 97 : } 98 : 99 23 : std::string regex; 100 23 : if(!regex_list.empty()) 101 : { 102 23 : regex = regex_list[0]; 103 : } 104 23 : std::regex::flag_type flags = std::regex_constants::extended; 105 23 : if(regex.length() >= 2 106 23 : && regex[0] == '/') 107 : { 108 17 : auto it(regex.end()); 109 39 : for(--it; it != regex.begin(); --it) 110 : { 111 38 : if(*it == '/') 112 : { 113 16 : break; 114 : } 115 22 : switch(*it) 116 : { 117 7 : case 'i': 118 7 : flags |= std::regex_constants::icase; 119 7 : break; 120 : 121 15 : default: 122 30 : cppthread::log << cppthread::log_level_t::error 123 15 : << "unsupported regex flag " 124 15 : << *it 125 15 : << " in regular expression \"" 126 15 : << regex 127 15 : << "\"." 128 30 : << cppthread::end; 129 15 : break; 130 : 131 : } 132 : } 133 17 : if(it == regex.begin()) 134 : { 135 2 : cppthread::log << cppthread::log_level_t::error 136 1 : << "invalid regex definition, ending / is missing in \"" 137 1 : << regex 138 1 : << "\"." 139 2 : << cppthread::end; 140 : 141 1 : f_regex = std::regex(std::string(regex.begin() + 1, regex.end()), flags); 142 : } 143 : else 144 : { 145 16 : f_regex = std::regex(std::string(regex.begin() + 1, it), flags); 146 : } 147 : } 148 : else 149 : { 150 6 : f_regex = std::regex(regex, flags); 151 : } 152 23 : } 153 : 154 : 155 : /** \brief Return the name of this validator. 156 : * 157 : * This function returns "regex". 158 : * 159 : * \return "regex". 160 : */ 161 11 : std::string validator_regex::name() const 162 : { 163 11 : return std::string("regex"); 164 : } 165 : 166 : 167 : /** \brief Check the value against a regular expression. 168 : * 169 : * This function is used to match the value of an argument against a 170 : * regular expression. It returns true when it does match. 171 : * 172 : * \param[in] value The value to be validated. 173 : * 174 : * \return true on a match. 175 : */ 176 83 : bool validator_regex::validate(std::string const & value) const 177 : { 178 83 : std::smatch info; 179 166 : return std::regex_match(value, info, f_regex); 180 83 : } 181 : 182 : 183 : 184 : } // namespace advgetopt 185 : // vim: ts=4 sw=4 et