1240116Smarcel// Copyright (c) 2007 The NetBSD Foundation, Inc. 2240116Smarcel// All rights reserved. 3240116Smarcel// 4240116Smarcel// Redistribution and use in source and binary forms, with or without 5240116Smarcel// modification, are permitted provided that the following conditions 6240116Smarcel// are met: 7240116Smarcel// 1. Redistributions of source code must retain the above copyright 8240116Smarcel// notice, this list of conditions and the following disclaimer. 9240116Smarcel// 2. Redistributions in binary form must reproduce the above copyright 10240116Smarcel// notice, this list of conditions and the following disclaimer in the 11240116Smarcel// documentation and/or other materials provided with the distribution. 12240116Smarcel// 13240116Smarcel// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 14240116Smarcel// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 15240116Smarcel// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16240116Smarcel// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17240116Smarcel// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 18240116Smarcel// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19240116Smarcel// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 20240116Smarcel// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21240116Smarcel// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 22240116Smarcel// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23240116Smarcel// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 24240116Smarcel// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25240116Smarcel 26275988Sngie#include "atf-c++/detail/text.hpp" 27275988Sngie 28240116Smarcelextern "C" { 29240116Smarcel#include <regex.h> 30240116Smarcel} 31240116Smarcel 32240116Smarcel#include <cctype> 33240116Smarcel#include <cstring> 34240116Smarcel 35240116Smarcelextern "C" { 36275988Sngie#include "atf-c/detail/text.h" 37275988Sngie#include "atf-c/error.h" 38240116Smarcel} 39240116Smarcel 40275988Sngie#include "atf-c++/detail/exceptions.hpp" 41240116Smarcel 42240116Smarcelnamespace impl = atf::text; 43240116Smarcel#define IMPL_NAME "atf::text" 44240116Smarcel 45240116Smarcelchar* 46240116Smarcelimpl::duplicate(const char* str) 47240116Smarcel{ 48240116Smarcel char* copy = new char[std::strlen(str) + 1]; 49240116Smarcel std::strcpy(copy, str); 50240116Smarcel return copy; 51240116Smarcel} 52240116Smarcel 53240116Smarcelbool 54240116Smarcelimpl::match(const std::string& str, const std::string& regex) 55240116Smarcel{ 56240116Smarcel bool found; 57240116Smarcel 58240116Smarcel // Special case: regcomp does not like empty regular expressions. 59240116Smarcel if (regex.empty()) { 60240116Smarcel found = str.empty(); 61240116Smarcel } else { 62240116Smarcel ::regex_t preg; 63240116Smarcel 64240116Smarcel if (::regcomp(&preg, regex.c_str(), REG_EXTENDED) != 0) 65240116Smarcel throw std::runtime_error("Invalid regular expression '" + regex + 66240116Smarcel "'"); 67240116Smarcel 68240116Smarcel const int res = ::regexec(&preg, str.c_str(), 0, NULL, 0); 69240116Smarcel regfree(&preg); 70240116Smarcel if (res != 0 && res != REG_NOMATCH) 71240116Smarcel throw std::runtime_error("Invalid regular expression " + regex); 72240116Smarcel 73240116Smarcel found = res == 0; 74240116Smarcel } 75240116Smarcel 76240116Smarcel return found; 77240116Smarcel} 78240116Smarcel 79240116Smarcelstd::string 80240116Smarcelimpl::to_lower(const std::string& str) 81240116Smarcel{ 82240116Smarcel std::string lc; 83240116Smarcel for (std::string::const_iterator iter = str.begin(); iter != str.end(); 84240116Smarcel iter++) 85240116Smarcel lc += std::tolower(*iter); 86240116Smarcel return lc; 87240116Smarcel} 88240116Smarcel 89240116Smarcelstd::vector< std::string > 90240116Smarcelimpl::split(const std::string& str, const std::string& delim) 91240116Smarcel{ 92240116Smarcel std::vector< std::string > words; 93240116Smarcel 94240116Smarcel std::string::size_type pos = 0, newpos = 0; 95240116Smarcel while (pos < str.length() && newpos != std::string::npos) { 96240116Smarcel newpos = str.find(delim, pos); 97240116Smarcel if (newpos != pos) 98240116Smarcel words.push_back(str.substr(pos, newpos - pos)); 99240116Smarcel pos = newpos + delim.length(); 100240116Smarcel } 101240116Smarcel 102240116Smarcel return words; 103240116Smarcel} 104240116Smarcel 105240116Smarcelstd::string 106240116Smarcelimpl::trim(const std::string& str) 107240116Smarcel{ 108240116Smarcel std::string::size_type pos1 = str.find_first_not_of(" \t"); 109240116Smarcel std::string::size_type pos2 = str.find_last_not_of(" \t"); 110240116Smarcel 111240116Smarcel if (pos1 == std::string::npos && pos2 == std::string::npos) 112240116Smarcel return ""; 113240116Smarcel else if (pos1 == std::string::npos) 114240116Smarcel return str.substr(0, str.length() - pos2); 115240116Smarcel else if (pos2 == std::string::npos) 116240116Smarcel return str.substr(pos1); 117240116Smarcel else 118240116Smarcel return str.substr(pos1, pos2 - pos1 + 1); 119240116Smarcel} 120240116Smarcel 121240116Smarcelbool 122240116Smarcelimpl::to_bool(const std::string& str) 123240116Smarcel{ 124240116Smarcel bool b; 125240116Smarcel 126240116Smarcel atf_error_t err = atf_text_to_bool(str.c_str(), &b); 127240116Smarcel if (atf_is_error(err)) 128240116Smarcel throw_atf_error(err); 129240116Smarcel 130240116Smarcel return b; 131240116Smarcel} 132240116Smarcel 133240116Smarcelint64_t 134240116Smarcelimpl::to_bytes(std::string str) 135240116Smarcel{ 136240116Smarcel if (str.empty()) 137240116Smarcel throw std::runtime_error("Empty value"); 138240116Smarcel 139240116Smarcel const char unit = str[str.length() - 1]; 140240116Smarcel int64_t multiplier; 141240116Smarcel switch (unit) { 142240116Smarcel case 'k': case 'K': multiplier = 1 << 10; break; 143240116Smarcel case 'm': case 'M': multiplier = 1 << 20; break; 144240116Smarcel case 'g': case 'G': multiplier = 1 << 30; break; 145240116Smarcel case 't': case 'T': multiplier = int64_t(1) << 40; break; 146240116Smarcel default: 147240116Smarcel if (!std::isdigit(unit)) 148240116Smarcel throw std::runtime_error(std::string("Unknown size unit '") + unit 149240116Smarcel + "'"); 150240116Smarcel multiplier = 1; 151240116Smarcel } 152240116Smarcel if (multiplier != 1) 153240116Smarcel str.erase(str.length() - 1); 154240116Smarcel 155240116Smarcel return to_type< int64_t >(str) * multiplier; 156240116Smarcel} 157