Path: blob/main/contrib/atf/atf-c++/detail/text.cpp
39563 views
// Copyright (c) 2007 The NetBSD Foundation, Inc.1// All rights reserved.2//3// Redistribution and use in source and binary forms, with or without4// modification, are permitted provided that the following conditions5// are met:6// 1. Redistributions of source code must retain the above copyright7// notice, this list of conditions and the following disclaimer.8// 2. Redistributions in binary form must reproduce the above copyright9// notice, this list of conditions and the following disclaimer in the10// documentation and/or other materials provided with the distribution.11//12// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND13// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,14// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF15// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.16// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY17// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL18// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE19// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS20// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER21// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR22// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN23// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.2425#include "atf-c++/detail/text.hpp"2627extern "C" {28#include <regex.h>29}3031#include <cctype>32#include <cstring>3334extern "C" {35#include "atf-c/detail/text.h"36#include "atf-c/error.h"37}3839#include "atf-c++/detail/exceptions.hpp"4041namespace impl = atf::text;42#define IMPL_NAME "atf::text"4344char*45impl::duplicate(const char* str)46{47char* copy = new char[std::strlen(str) + 1];48std::strcpy(copy, str);49return copy;50}5152bool53impl::match(const std::string& str, const std::string& regex)54{55bool found;5657// Special case: regcomp does not like empty regular expressions.58if (regex.empty()) {59found = str.empty();60} else {61::regex_t preg;6263if (::regcomp(&preg, regex.c_str(), REG_EXTENDED) != 0)64throw std::runtime_error("Invalid regular expression '" + regex +65"'");6667const int res = ::regexec(&preg, str.c_str(), 0, NULL, 0);68regfree(&preg);69if (res != 0 && res != REG_NOMATCH)70throw std::runtime_error("Invalid regular expression " + regex);7172found = res == 0;73}7475return found;76}7778std::string79impl::to_lower(const std::string& str)80{81std::string lc;82for (std::string::const_iterator iter = str.begin(); iter != str.end();83iter++)84lc += std::tolower(*iter);85return lc;86}8788std::vector< std::string >89impl::split(const std::string& str, const std::string& delim)90{91std::vector< std::string > words;9293std::string::size_type pos = 0, newpos = 0;94while (pos < str.length() && newpos != std::string::npos) {95newpos = str.find(delim, pos);96if (newpos != pos)97words.push_back(str.substr(pos, newpos - pos));98pos = newpos + delim.length();99}100101return words;102}103104std::string105impl::trim(const std::string& str)106{107std::string::size_type pos1 = str.find_first_not_of(" \t");108std::string::size_type pos2 = str.find_last_not_of(" \t");109110if (pos1 == std::string::npos && pos2 == std::string::npos)111return "";112else if (pos1 == std::string::npos)113return str.substr(0, str.length() - pos2);114else if (pos2 == std::string::npos)115return str.substr(pos1);116else117return str.substr(pos1, pos2 - pos1 + 1);118}119120bool121impl::to_bool(const std::string& str)122{123bool b;124125atf_error_t err = atf_text_to_bool(str.c_str(), &b);126if (atf_is_error(err))127throw_atf_error(err);128129return b;130}131132int64_t133impl::to_bytes(std::string str)134{135if (str.empty())136throw std::runtime_error("Empty value");137138const char unit = str[str.length() - 1];139int64_t multiplier;140switch (unit) {141case 'k': case 'K': multiplier = 1 << 10; break;142case 'm': case 'M': multiplier = 1 << 20; break;143case 'g': case 'G': multiplier = 1 << 30; break;144case 't': case 'T': multiplier = int64_t(1) << 40; break;145default:146if (!std::isdigit(unit))147throw std::runtime_error(std::string("Unknown size unit '") + unit148+ "'");149multiplier = 1;150}151if (multiplier != 1)152str.erase(str.length() - 1);153154return to_type< int64_t >(str) * multiplier;155}156157158