// Charlemagne Package Manager // // Douglas Thrift // // $Id$ /* Menes - C++ High-Level Utility Library * Copyright (C) 2003-2005 Jay Freeman (saurik) */ /* * 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. * 3. The name of the author may not be used to endorse * or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. */ #include #include #include "regex.hpp" #include "truck.hpp" namespace Pcre { Error::Error(int code) { std::ostringstream message; message << _B("Pcre[#") << code << _B("] "); switch (code) { case PCRE_ERROR_NOMATCH: message << _B("PCRE_ERROR_NOMATCH"); break; case PCRE_ERROR_NULL: message << _B("PCRE_ERROR_NULL"); break; case PCRE_ERROR_BADOPTION: message << _B("PCRE_ERROR_BADOPTION"); break; case PCRE_ERROR_BADMAGIC: message << _B("PCRE_ERROR_BADMAGIC"); break; case PCRE_ERROR_UNKNOWN_NODE: message << _B("PCRE_ERROR_UNKNOWN_NODE"); break; case PCRE_ERROR_NOMEMORY: message << _B("PCRE_ERROR_NOMEMORY"); break; case PCRE_ERROR_NOSUBSTRING: message << _B("PCRE_ERROR_NOSUBSTRING"); break; case PCRE_ERROR_MATCHLIMIT: message << _B("PCRE_ERROR_MATCHLIMIT"); break; case PCRE_ERROR_CALLOUT: message << _B("PCRE_ERROR_CALLOUT"); break; case PCRE_ERROR_BADUTF8: message << _B("PCRE_ERROR_BADUTF8"); break; case PCRE_ERROR_BADUTF8_OFFSET: message << _B("PCRE_ERROR_BADUTF8_OFFSET"); break; default: message << _B("Unknown Error"); } this->message = message.str(); } RegEx::Match::Match(const std::string &data, std::vector &substrings) : data(data) { std::swap(this->substrings, substrings); } RegEx::Match::Match() {} RegEx::Match::operator bool() const { return !substrings.empty(); } std::string RegEx::Match::operator [](size_t substring) const { size_t index(substring * 2); if (index >= substrings.size()) return std::string(); return std::string(data.begin() + substrings[index], data.begin() + substrings[index + 1]); } RegEx::RegEx(const std::string &pattern) : code(NULL), study(NULL), capture(-1) { const char *error; int offset; code = ::pcre_compile(pattern.c_str(), PCRE_DOTALL | PCRE_DOLLAR_ENDONLY, &error, &offset, NULL); int err(::pcre_fullinfo(code, study, PCRE_INFO_CAPTURECOUNT, &capture)); if (err != 0) { assert(err < 0); throw Error(err); } assert(capture >= 0); } RegEx::~RegEx() { ::pcre_free(code); } RegEx::Match RegEx::operator ()(const std::string &data) const { std::vector substrings((capture + 1) * 3); int err(::pcre_exec(code, study, data.c_str(), data.size(), 0, 0, &substrings.front(), substrings.size())); assert(err != 0); if (err == PCRE_ERROR_NOMATCH) err = 0; if (err < 0) throw Error(err); substrings.resize(err * 2); return Match(data, substrings); } }