text.cpp revision 1.2
1//
2// Automated Testing Framework (atf)
3//
4// Copyright (c) 2007, 2008, 2010 The NetBSD Foundation, Inc.
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions
9// are met:
10// 1. Redistributions of source code must retain the above copyright
11//    notice, this list of conditions and the following disclaimer.
12// 2. Redistributions in binary form must reproduce the above copyright
13//    notice, this list of conditions and the following disclaimer in the
14//    documentation and/or other materials provided with the distribution.
15//
16// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28//
29
30extern "C" {
31#include <regex.h>
32}
33
34#include <cctype>
35#include <cstring>
36#include <cstdlib>
37
38extern "C" {
39#include "../../atf-c/error.h"
40
41#include "../../atf-c/detail/text.h"
42}
43
44#include "exceptions.hpp"
45#include "text.hpp"
46
47namespace impl = atf::text;
48#define IMPL_NAME "atf::text"
49
50char*
51impl::duplicate(const char* str)
52{
53    char* copy = new char[std::strlen(str) + 1];
54    std::strcpy(copy, str);
55    return copy;
56}
57
58bool
59impl::match(const std::string& str, const std::string& regex)
60{
61    bool found;
62
63    // Special case: regcomp does not like empty regular expressions.
64    if (regex.empty()) {
65        found = str.empty();
66    } else {
67        ::regex_t preg;
68
69        if (::regcomp(&preg, regex.c_str(), REG_EXTENDED) != 0)
70            throw std::runtime_error("Invalid regular expression '" + regex +
71                                     "'");
72
73        const int res = ::regexec(&preg, str.c_str(), 0, NULL, 0);
74        regfree(&preg);
75        if (res != 0 && res != REG_NOMATCH)
76            throw std::runtime_error("Invalid regular expression " + regex);
77
78        found = res == 0;
79    }
80
81    return found;
82}
83
84std::string
85impl::to_lower(const std::string& str)
86{
87    std::string lc;
88    for (std::string::const_iterator iter = str.begin(); iter != str.end();
89         iter++)
90        lc += std::tolower(*iter);
91    return lc;
92}
93
94std::vector< std::string >
95impl::split(const std::string& str, const std::string& delim)
96{
97    std::vector< std::string > words;
98
99    std::string::size_type pos = 0, newpos = 0;
100    while (pos < str.length() && newpos != std::string::npos) {
101        newpos = str.find(delim, pos);
102        if (newpos != pos)
103            words.push_back(str.substr(pos, newpos - pos));
104        pos = newpos + delim.length();
105    }
106
107    return words;
108}
109
110std::string
111impl::trim(const std::string& str)
112{
113    std::string::size_type pos1 = str.find_first_not_of(" \t");
114    std::string::size_type pos2 = str.find_last_not_of(" \t");
115
116    if (pos1 == std::string::npos && pos2 == std::string::npos)
117        return "";
118    else if (pos1 == std::string::npos)
119        return str.substr(0, str.length() - pos2);
120    else if (pos2 == std::string::npos)
121        return str.substr(pos1);
122    else
123        return str.substr(pos1, pos2 - pos1 + 1);
124}
125
126bool
127impl::to_bool(const std::string& str)
128{
129    bool b;
130
131    atf_error_t err = atf_text_to_bool(str.c_str(), &b);
132    if (atf_is_error(err))
133        throw_atf_error(err);
134
135    return b;
136}
137
138int64_t
139impl::to_number(const std::string& str)
140{
141	int64_t num;
142	::dehumanize_number(str.c_str(), &num);
143	return num;
144}
145
146