diff options
| author | Marcel Moolenaar <marcel@FreeBSD.org> | 2012-09-04 23:07:32 +0000 | 
|---|---|---|
| committer | Marcel Moolenaar <marcel@FreeBSD.org> | 2012-09-04 23:07:32 +0000 | 
| commit | 679bf1899d7d81eaa5b2e95cba72d5db6f7491a3 (patch) | |
| tree | 748bcc46e1493df6fa88441f5e3783a5e2266e13 /atf-c++/detail/text.cpp | |
Diffstat (limited to 'atf-c++/detail/text.cpp')
| -rw-r--r-- | atf-c++/detail/text.cpp | 160 | 
1 files changed, 160 insertions, 0 deletions
diff --git a/atf-c++/detail/text.cpp b/atf-c++/detail/text.cpp new file mode 100644 index 000000000000..66eebf0a77e7 --- /dev/null +++ b/atf-c++/detail/text.cpp @@ -0,0 +1,160 @@ +// +// Automated Testing Framework (atf) +// +// Copyright (c) 2007 The NetBSD Foundation, Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +//    notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +//    notice, this list of conditions and the following disclaimer in the +//    documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND +// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, +// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY +// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// + +extern "C" { +#include <regex.h> +} + +#include <cctype> +#include <cstring> + +extern "C" { +#include "../../atf-c/error.h" + +#include "../../atf-c/detail/text.h" +} + +#include "exceptions.hpp" +#include "text.hpp" + +namespace impl = atf::text; +#define IMPL_NAME "atf::text" + +char* +impl::duplicate(const char* str) +{ +    char* copy = new char[std::strlen(str) + 1]; +    std::strcpy(copy, str); +    return copy; +} + +bool +impl::match(const std::string& str, const std::string& regex) +{ +    bool found; + +    // Special case: regcomp does not like empty regular expressions. +    if (regex.empty()) { +        found = str.empty(); +    } else { +        ::regex_t preg; + +        if (::regcomp(&preg, regex.c_str(), REG_EXTENDED) != 0) +            throw std::runtime_error("Invalid regular expression '" + regex + +                                     "'"); + +        const int res = ::regexec(&preg, str.c_str(), 0, NULL, 0); +        regfree(&preg); +        if (res != 0 && res != REG_NOMATCH) +            throw std::runtime_error("Invalid regular expression " + regex); + +        found = res == 0; +    } + +    return found; +} + +std::string +impl::to_lower(const std::string& str) +{ +    std::string lc; +    for (std::string::const_iterator iter = str.begin(); iter != str.end(); +         iter++) +        lc += std::tolower(*iter); +    return lc; +} + +std::vector< std::string > +impl::split(const std::string& str, const std::string& delim) +{ +    std::vector< std::string > words; + +    std::string::size_type pos = 0, newpos = 0; +    while (pos < str.length() && newpos != std::string::npos) { +        newpos = str.find(delim, pos); +        if (newpos != pos) +            words.push_back(str.substr(pos, newpos - pos)); +        pos = newpos + delim.length(); +    } + +    return words; +} + +std::string +impl::trim(const std::string& str) +{ +    std::string::size_type pos1 = str.find_first_not_of(" \t"); +    std::string::size_type pos2 = str.find_last_not_of(" \t"); + +    if (pos1 == std::string::npos && pos2 == std::string::npos) +        return ""; +    else if (pos1 == std::string::npos) +        return str.substr(0, str.length() - pos2); +    else if (pos2 == std::string::npos) +        return str.substr(pos1); +    else +        return str.substr(pos1, pos2 - pos1 + 1); +} + +bool +impl::to_bool(const std::string& str) +{ +    bool b; + +    atf_error_t err = atf_text_to_bool(str.c_str(), &b); +    if (atf_is_error(err)) +        throw_atf_error(err); + +    return b; +} + +int64_t +impl::to_bytes(std::string str) +{ +    if (str.empty()) +        throw std::runtime_error("Empty value"); + +    const char unit = str[str.length() - 1]; +    int64_t multiplier; +    switch (unit) { +    case 'k': case 'K': multiplier = 1 << 10; break; +    case 'm': case 'M': multiplier = 1 << 20; break; +    case 'g': case 'G': multiplier = 1 << 30; break; +    case 't': case 'T': multiplier = int64_t(1) << 40; break; +    default: +        if (!std::isdigit(unit)) +            throw std::runtime_error(std::string("Unknown size unit '") + unit +                                     + "'"); +        multiplier = 1; +    } +    if (multiplier != 1) +        str.erase(str.length() - 1); + +    return to_type< int64_t >(str) * multiplier; +}  | 
