diff options
author | Remko Tronçon <git@el-tramo.be> | 2009-06-03 21:52:05 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2009-06-09 18:18:53 (GMT) |
commit | fd89da91d12b270d56f60544cad6f1ddc809af28 (patch) | |
tree | 77bebb89221cc8023b22efaa0b707cdcd0759b3b /3rdParty/Boost/libs/regex/src/cregex.cpp | |
parent | 3de4268ade36c9292a88b1da7604748a87c65777 (diff) | |
download | swift-contrib-fd89da91d12b270d56f60544cad6f1ddc809af28.zip swift-contrib-fd89da91d12b270d56f60544cad6f1ddc809af28.tar.bz2 |
Added Boost.regex.
Diffstat (limited to '3rdParty/Boost/libs/regex/src/cregex.cpp')
-rw-r--r-- | 3rdParty/Boost/libs/regex/src/cregex.cpp | 648 |
1 files changed, 648 insertions, 0 deletions
diff --git a/3rdParty/Boost/libs/regex/src/cregex.cpp b/3rdParty/Boost/libs/regex/src/cregex.cpp new file mode 100644 index 0000000..fb12373 --- /dev/null +++ b/3rdParty/Boost/libs/regex/src/cregex.cpp @@ -0,0 +1,648 @@ +/* + * + * Copyright (c) 1998-2002 + * John Maddock + * + * Use, modification and distribution are subject to the + * Boost Software License, Version 1.0. (See accompanying file + * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + * + */ + + /* + * LOCATION: see http://www.boost.org for most recent version. + * FILE: cregex.cpp + * VERSION: see <boost/version.hpp> + * DESCRIPTION: Implements high level class boost::RexEx + */ + + +#define BOOST_REGEX_SOURCE + +#include <boost/regex.hpp> +#include <boost/cregex.hpp> +#if !defined(BOOST_NO_STD_STRING) +#include <map> +#include <list> +#include <boost/regex/v4/fileiter.hpp> +typedef boost::match_flag_type match_flag_type; +#include <cstdio> + +#ifdef BOOST_MSVC +#pragma warning(disable:4309) +#endif + +namespace boost{ + +#ifdef __BORLANDC__ +#if __BORLANDC__ < 0x530 +// +// we need to instantiate the vector classes we use +// since declaring a reference to type doesn't seem to +// do the job... +std::vector<std::size_t> inst1; +std::vector<std::string> inst2; +#endif +#endif + +namespace{ + +template <class iterator> +std::string to_string(iterator i, iterator j) +{ + std::string s; + while(i != j) + { + s.append(1, *i); + ++i; + } + return s; +} + +inline std::string to_string(const char* i, const char* j) +{ + return std::string(i, j); +} + +} +namespace re_detail{ + +class RegExData +{ +public: + enum type + { + type_pc, + type_pf, + type_copy + }; + regex e; + cmatch m; +#ifndef BOOST_REGEX_NO_FILEITER + match_results<mapfile::iterator> fm; +#endif + type t; + const char* pbase; +#ifndef BOOST_REGEX_NO_FILEITER + mapfile::iterator fbase; +#endif + std::map<int, std::string, std::less<int> > strings; + std::map<int, std::ptrdiff_t, std::less<int> > positions; + void update(); + void clean(); + RegExData() : e(), m(), +#ifndef BOOST_REGEX_NO_FILEITER + fm(), +#endif + t(type_copy), pbase(0), +#ifndef BOOST_REGEX_NO_FILEITER + fbase(), +#endif + strings(), positions() {} +}; + +void RegExData::update() +{ + strings.erase(strings.begin(), strings.end()); + positions.erase(positions.begin(), positions.end()); + if(t == type_pc) + { + for(unsigned int i = 0; i < m.size(); ++i) + { + if(m[i].matched) strings[i] = std::string(m[i].first, m[i].second); + positions[i] = m[i].matched ? m[i].first - pbase : -1; + } + } +#ifndef BOOST_REGEX_NO_FILEITER + else + { + for(unsigned int i = 0; i < fm.size(); ++i) + { + if(fm[i].matched) strings[i] = to_string(fm[i].first, fm[i].second); + positions[i] = fm[i].matched ? fm[i].first - fbase : -1; + } + } +#endif + t = type_copy; +} + +void RegExData::clean() +{ +#ifndef BOOST_REGEX_NO_FILEITER + fbase = mapfile::iterator(); + fm = match_results<mapfile::iterator>(); +#endif +} + +} // namespace + +RegEx::RegEx() +{ + pdata = new re_detail::RegExData(); +} + +RegEx::RegEx(const RegEx& o) +{ + pdata = new re_detail::RegExData(*(o.pdata)); +} + +RegEx::~RegEx() +{ + delete pdata; +} + +RegEx::RegEx(const char* c, bool icase) +{ + pdata = new re_detail::RegExData(); + SetExpression(c, icase); +} + +RegEx::RegEx(const std::string& s, bool icase) +{ + pdata = new re_detail::RegExData(); + SetExpression(s.c_str(), icase); +} + +RegEx& RegEx::operator=(const RegEx& o) +{ + *pdata = *(o.pdata); + return *this; +} + +RegEx& RegEx::operator=(const char* p) +{ + SetExpression(p, false); + return *this; +} + +unsigned int RegEx::SetExpression(const char* p, bool icase) +{ + boost::uint_fast32_t f = icase ? regex::normal | regex::icase : regex::normal; + return pdata->e.set_expression(p, f); +} + +unsigned int RegEx::error_code()const +{ + return pdata->e.error_code(); +} + + +std::string RegEx::Expression()const +{ + return pdata->e.expression(); +} + +// +// now matching operators: +// +bool RegEx::Match(const char* p, match_flag_type flags) +{ + pdata->t = re_detail::RegExData::type_pc; + pdata->pbase = p; + const char* end = p; + while(*end)++end; + + if(regex_match(p, end, pdata->m, pdata->e, flags)) + { + pdata->update(); + return true; + } + return false; +} + +bool RegEx::Search(const char* p, match_flag_type flags) +{ + pdata->t = re_detail::RegExData::type_pc; + pdata->pbase = p; + const char* end = p; + while(*end)++end; + + if(regex_search(p, end, pdata->m, pdata->e, flags)) + { + pdata->update(); + return true; + } + return false; +} +namespace re_detail{ +struct pred1 +{ + GrepCallback cb; + RegEx* pe; + pred1(GrepCallback c, RegEx* i) : cb(c), pe(i) {} + bool operator()(const cmatch& m) + { + pe->pdata->m = m; + return cb(*pe); + } +}; +} +unsigned int RegEx::Grep(GrepCallback cb, const char* p, match_flag_type flags) +{ + pdata->t = re_detail::RegExData::type_pc; + pdata->pbase = p; + const char* end = p; + while(*end)++end; + + unsigned int result = regex_grep(re_detail::pred1(cb, this), p, end, pdata->e, flags); + if(result) + pdata->update(); + return result; +} +namespace re_detail{ +struct pred2 +{ + std::vector<std::string>& v; + RegEx* pe; + pred2(std::vector<std::string>& o, RegEx* e) : v(o), pe(e) {} + bool operator()(const cmatch& m) + { + pe->pdata->m = m; + v.push_back(std::string(m[0].first, m[0].second)); + return true; + } +private: + pred2& operator=(const pred2&); +}; +} + +unsigned int RegEx::Grep(std::vector<std::string>& v, const char* p, match_flag_type flags) +{ + pdata->t = re_detail::RegExData::type_pc; + pdata->pbase = p; + const char* end = p; + while(*end)++end; + + unsigned int result = regex_grep(re_detail::pred2(v, this), p, end, pdata->e, flags); + if(result) + pdata->update(); + return result; +} +namespace re_detail{ +struct pred3 +{ + std::vector<std::size_t>& v; + const char* base; + RegEx* pe; + pred3(std::vector<std::size_t>& o, const char* pb, RegEx* p) : v(o), base(pb), pe(p) {} + bool operator()(const cmatch& m) + { + pe->pdata->m = m; + v.push_back(static_cast<std::size_t>(m[0].first - base)); + return true; + } +private: + pred3& operator=(const pred3&); +}; +} +unsigned int RegEx::Grep(std::vector<std::size_t>& v, const char* p, match_flag_type flags) +{ + pdata->t = re_detail::RegExData::type_pc; + pdata->pbase = p; + const char* end = p; + while(*end)++end; + + unsigned int result = regex_grep(re_detail::pred3(v, p, this), p, end, pdata->e, flags); + if(result) + pdata->update(); + return result; +} +#ifndef BOOST_REGEX_NO_FILEITER +namespace re_detail{ +struct pred4 +{ + GrepFileCallback cb; + RegEx* pe; + const char* file; + bool ok; + pred4(GrepFileCallback c, RegEx* i, const char* f) : cb(c), pe(i), file(f), ok(true) {} + bool operator()(const match_results<mapfile::iterator>& m) + { + pe->pdata->t = RegExData::type_pf; + pe->pdata->fm = m; + pe->pdata->update(); + ok = cb(file, *pe); + return ok; + } +}; +} +namespace{ +void BuildFileList(std::list<std::string>* pl, const char* files, bool recurse) +{ + file_iterator start(files); + file_iterator end; + if(recurse) + { + // go through sub directories: + char buf[MAX_PATH]; + re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(buf, MAX_PATH, start.root())); + if(*buf == 0) + { + re_detail::overflow_error_if_not_zero(re_detail::strcpy_s(buf, MAX_PATH, ".")); + re_detail::overflow_error_if_not_zero(re_detail::strcat_s(buf, MAX_PATH, directory_iterator::separator())); + re_detail::overflow_error_if_not_zero(re_detail::strcat_s(buf, MAX_PATH, "*")); + } + else + { + re_detail::overflow_error_if_not_zero(re_detail::strcat_s(buf, MAX_PATH, directory_iterator::separator())); + re_detail::overflow_error_if_not_zero(re_detail::strcat_s(buf, MAX_PATH, "*")); + } + directory_iterator dstart(buf); + directory_iterator dend; + + // now get the file mask bit of "files": + const char* ptr = files; + while(*ptr) ++ptr; + while((ptr != files) && (*ptr != *directory_iterator::separator()) && (*ptr != '/'))--ptr; + if(ptr != files) ++ptr; + + while(dstart != dend) + { +#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE) + (::sprintf_s)(buf, sizeof(buf), "%s%s%s", dstart.path(), directory_iterator::separator(), ptr); +#else + (std::sprintf)(buf, "%s%s%s", dstart.path(), directory_iterator::separator(), ptr); +#endif + BuildFileList(pl, buf, recurse); + ++dstart; + } + } + while(start != end) + { + pl->push_back(*start); + ++start; + } +} +} + +unsigned int RegEx::GrepFiles(GrepFileCallback cb, const char* files, bool recurse, match_flag_type flags) +{ + unsigned int result = 0; + std::list<std::string> file_list; + BuildFileList(&file_list, files, recurse); + std::list<std::string>::iterator start, end; + start = file_list.begin(); + end = file_list.end(); + + while(start != end) + { + mapfile map((*start).c_str()); + pdata->t = re_detail::RegExData::type_pf; + pdata->fbase = map.begin(); + re_detail::pred4 pred(cb, this, (*start).c_str()); + int r = regex_grep(pred, map.begin(), map.end(), pdata->e, flags); + result += r; + ++start; + pdata->clean(); + if(pred.ok == false) + return result; + } + + return result; +} + + +unsigned int RegEx::FindFiles(FindFilesCallback cb, const char* files, bool recurse, match_flag_type flags) +{ + unsigned int result = 0; + std::list<std::string> file_list; + BuildFileList(&file_list, files, recurse); + std::list<std::string>::iterator start, end; + start = file_list.begin(); + end = file_list.end(); + + while(start != end) + { + mapfile map((*start).c_str()); + pdata->t = re_detail::RegExData::type_pf; + pdata->fbase = map.begin(); + + if(regex_search(map.begin(), map.end(), pdata->fm, pdata->e, flags)) + { + ++result; + if(false == cb((*start).c_str())) + return result; + } + //pdata->update(); + ++start; + //pdata->clean(); + } + + return result; +} +#endif + +#ifdef BOOST_REGEX_V3 +#define regex_replace regex_merge +#endif + +std::string RegEx::Merge(const std::string& in, const std::string& fmt, + bool copy, match_flag_type flags) +{ + std::string result; + re_detail::string_out_iterator<std::string> i(result); + if(!copy) flags |= format_no_copy; + regex_replace(i, in.begin(), in.end(), pdata->e, fmt.c_str(), flags); + return result; +} + +std::string RegEx::Merge(const char* in, const char* fmt, + bool copy, match_flag_type flags) +{ + std::string result; + if(!copy) flags |= format_no_copy; + re_detail::string_out_iterator<std::string> i(result); + regex_replace(i, in, in + std::strlen(in), pdata->e, fmt, flags); + return result; +} + +std::size_t RegEx::Split(std::vector<std::string>& v, + std::string& s, + match_flag_type flags, + unsigned max_count) +{ + return regex_split(std::back_inserter(v), s, pdata->e, flags, max_count); +} + + + +// +// now operators for returning what matched in more detail: +// +std::size_t RegEx::Position(int i)const +{ + switch(pdata->t) + { + case re_detail::RegExData::type_pc: + return pdata->m[i].matched ? pdata->m[i].first - pdata->pbase : RegEx::npos; +#ifndef BOOST_REGEX_NO_FILEITER + case re_detail::RegExData::type_pf: + return pdata->fm[i].matched ? pdata->fm[i].first - pdata->fbase : RegEx::npos; +#endif + case re_detail::RegExData::type_copy: + { + std::map<int, std::ptrdiff_t, std::less<int> >::iterator pos = pdata->positions.find(i); + if(pos == pdata->positions.end()) + return RegEx::npos; + return (*pos).second; + } + } + return RegEx::npos; +} + +std::size_t RegEx::Marks()const +{ + return pdata->e.mark_count(); +} + + +std::size_t RegEx::Length(int i)const +{ + switch(pdata->t) + { + case re_detail::RegExData::type_pc: + return pdata->m[i].matched ? pdata->m[i].second - pdata->m[i].first : RegEx::npos; +#ifndef BOOST_REGEX_NO_FILEITER + case re_detail::RegExData::type_pf: + return pdata->fm[i].matched ? pdata->fm[i].second - pdata->fm[i].first : RegEx::npos; +#endif + case re_detail::RegExData::type_copy: + { + std::map<int, std::string, std::less<int> >::iterator pos = pdata->strings.find(i); + if(pos == pdata->strings.end()) + return RegEx::npos; + return (*pos).second.size(); + } + } + return RegEx::npos; +} + +bool RegEx::Matched(int i)const +{ + switch(pdata->t) + { + case re_detail::RegExData::type_pc: + return pdata->m[i].matched; +#ifndef BOOST_REGEX_NO_FILEITER + case re_detail::RegExData::type_pf: + return pdata->fm[i].matched; +#endif + case re_detail::RegExData::type_copy: + { + std::map<int, std::string, std::less<int> >::iterator pos = pdata->strings.find(i); + if(pos == pdata->strings.end()) + return false; + return true; + } + } + return false; +} + + +std::string RegEx::What(int i)const +{ + std::string result; + switch(pdata->t) + { + case re_detail::RegExData::type_pc: + if(pdata->m[i].matched) + result.assign(pdata->m[i].first, pdata->m[i].second); + break; + case re_detail::RegExData::type_pf: + if(pdata->m[i].matched) + result.assign(to_string(pdata->m[i].first, pdata->m[i].second)); + break; + case re_detail::RegExData::type_copy: + { + std::map<int, std::string, std::less<int> >::iterator pos = pdata->strings.find(i); + if(pos != pdata->strings.end()) + result = (*pos).second; + break; + } + } + return result; +} + +#ifdef BOOST_HAS_LONG_LONG +const std::size_t RegEx::npos = static_cast<std::size_t>(~0ULL); +#else +const std::size_t RegEx::npos = static_cast<std::size_t>(~0UL); +#endif + +} // namespace boost + +#if defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) && (__BORLANDC__ <= 0x551) && !defined(_RWSTD_COMPILE_INSTANTIATE) +// +// this is an ugly hack to work around an ugly problem: +// by default this file will produce unresolved externals during +// linking unless _RWSTD_COMPILE_INSTANTIATE is defined (Borland bug). +// However if _RWSTD_COMPILE_INSTANTIATE is defined then we get separate +// copies of basic_string's static data in the RTL and this DLL, this messes +// with basic_string's memory management and results in run-time crashes, +// Oh sweet joy of Catch 22.... +// +namespace std{ +template<> template<> +basic_string<char>& BOOST_REGEX_DECL +basic_string<char>::replace<const char*>(char* f1, char* f2, const char* i1, const char* i2) +{ + unsigned insert_pos = f1 - begin(); + unsigned remove_len = f2 - f1; + unsigned insert_len = i2 - i1; + unsigned org_size = size(); + if(insert_len > remove_len) + { + append(insert_len-remove_len, ' '); + std::copy_backward(begin() + insert_pos + remove_len, begin() + org_size, end()); + std::copy(i1, i2, begin() + insert_pos); + } + else + { + std::copy(begin() + insert_pos + remove_len, begin() + org_size, begin() + insert_pos + insert_len); + std::copy(i1, i2, begin() + insert_pos); + erase(size() + insert_len - remove_len); + } + return *this; +} +template<> template<> +basic_string<wchar_t>& BOOST_REGEX_DECL +basic_string<wchar_t>::replace<const wchar_t*>(wchar_t* f1, wchar_t* f2, const wchar_t* i1, const wchar_t* i2) +{ + unsigned insert_pos = f1 - begin(); + unsigned remove_len = f2 - f1; + unsigned insert_len = i2 - i1; + unsigned org_size = size(); + if(insert_len > remove_len) + { + append(insert_len-remove_len, ' '); + std::copy_backward(begin() + insert_pos + remove_len, begin() + org_size, end()); + std::copy(i1, i2, begin() + insert_pos); + } + else + { + std::copy(begin() + insert_pos + remove_len, begin() + org_size, begin() + insert_pos + insert_len); + std::copy(i1, i2, begin() + insert_pos); + erase(size() + insert_len - remove_len); + } + return *this; +} +} // namespace std +#endif + +#endif + + + + + + + + + + + + + + + + |