Files
boost_regex/src/wide_posix_api.cpp
T

313 lines
7.3 KiB
C++
Raw Normal View History

2000-09-26 11:48:28 +00:00
/*
*
* Copyright (c) 1998-2002
2005-01-21 17:28:42 +00:00
* John Maddock
2000-09-26 11:48:28 +00:00
*
2003-10-04 11:29:20 +00:00
* Use, modification and distribution are subject to the
2003-09-30 13:02:51 +00:00
* Boost Software License, Version 1.0. (See accompanying file
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
2000-09-26 11:48:28 +00:00
*
*/
/*
* LOCATION: see http://www.boost.org for most recent version.
* FILE: wide_posix_api.cpp
* VERSION: see <boost/version.hpp>
2000-09-26 11:48:28 +00:00
* DESCRIPTION: Implements the wide character POSIX API wrappers.
*/
#define BOOST_REGEX_SOURCE
2000-09-26 11:48:28 +00:00
#include <boost/regex/config.hpp>
#ifndef BOOST_NO_WREGEX
2000-09-26 11:48:28 +00:00
#include <boost/regex.hpp>
#include <boost/cregex.hpp>
2000-09-26 11:48:28 +00:00
#include <cwchar>
#include <cstring>
#include <cstdio>
#ifdef BOOST_INTEL
#pragma warning(disable:981)
#endif
2009-01-01 10:23:10 +00:00
#if defined(BOOST_NO_STDC_NAMESPACE) || defined(__NetBSD__)
2005-01-13 17:06:21 +00:00
namespace std{
# ifndef BOOST_NO_SWPRINTF
using ::swprintf;
# endif
}
#endif
2000-09-26 11:48:28 +00:00
namespace boost{
namespace {
unsigned int wmagic_value = 28631;
2005-12-11 17:34:32 +00:00
const wchar_t* wnames[] = {
L"REG_NOERROR",
L"REG_NOMATCH",
L"REG_BADPAT",
L"REG_ECOLLATE",
L"REG_ECTYPE",
L"REG_EESCAPE",
L"REG_ESUBREG",
L"REG_EBRACK",
L"REG_EPAREN",
L"REG_EBRACE",
L"REG_BADBR",
L"REG_ERANGE",
L"REG_ESPACE",
L"REG_BADRPT",
L"REG_EEND",
L"REG_ESIZE",
L"REG_ERPAREN",
L"REG_EMPTY",
L"REG_ECOMPLEXITY",
L"REG_ESTACK",
L"REG_E_PERL",
2005-12-11 17:34:32 +00:00
L"REG_E_UNKNOWN",
};
2000-09-26 11:48:28 +00:00
}
typedef boost::basic_regex<wchar_t, c_regex_traits<wchar_t> > wc_regex_type;
BOOST_REGEX_DECL int BOOST_REGEX_CCALL regcompW(regex_tW* expression, const wchar_t* ptr, int f)
2000-09-26 11:48:28 +00:00
{
#ifndef BOOST_NO_EXCEPTIONS
try{
#endif
expression->guts = new wc_regex_type();
#ifndef BOOST_NO_EXCEPTIONS
} catch(...)
{
expression->guts = 0;
return REG_ESPACE;
2000-09-26 11:48:28 +00:00
}
#else
if(0 == expression->guts)
return REG_E_MEMORY;
#endif
2000-09-26 11:48:28 +00:00
// set default flags:
2005-01-13 17:06:21 +00:00
boost::uint_fast32_t flags = (f & REG_PERLEX) ? 0 : ((f & REG_EXTENDED) ? wregex::extended : wregex::basic);
2003-05-17 11:45:48 +00:00
expression->eflags = (f & REG_NEWLINE) ? match_not_dot_newline : match_default;
2000-09-26 11:48:28 +00:00
// and translate those that are actually set:
if(f & REG_NOCOLLATE)
2003-05-17 11:45:48 +00:00
{
flags |= wregex::nocollate;
#ifndef BOOST_REGEX_V3
2003-05-17 11:45:48 +00:00
flags &= ~wregex::collate;
#endif
2003-05-17 11:45:48 +00:00
}
2000-09-26 11:48:28 +00:00
if(f & REG_NOSUB)
2005-01-13 17:06:21 +00:00
{
//expression->eflags |= match_any;
flags |= wregex::nosubs;
}
2000-09-26 11:48:28 +00:00
if(f & REG_NOSPEC)
2003-05-17 11:45:48 +00:00
flags |= wregex::literal;
2000-09-26 11:48:28 +00:00
if(f & REG_ICASE)
2003-05-17 11:45:48 +00:00
flags |= wregex::icase;
2000-09-26 11:48:28 +00:00
if(f & REG_ESCAPE_IN_LISTS)
2005-01-13 17:06:21 +00:00
flags &= ~wregex::no_escape_in_lists;
2000-09-26 11:48:28 +00:00
if(f & REG_NEWLINE_ALT)
2003-05-17 11:45:48 +00:00
flags |= wregex::newline_alt;
2000-09-26 11:48:28 +00:00
const wchar_t* p2;
if(f & REG_PEND)
p2 = expression->re_endp;
else p2 = ptr + std::wcslen(ptr);
int result;
#ifndef BOOST_NO_EXCEPTIONS
2000-09-26 11:48:28 +00:00
try{
#endif
2000-09-26 11:48:28 +00:00
expression->re_magic = wmagic_value;
static_cast<wc_regex_type*>(expression->guts)->set_expression(ptr, p2, flags);
expression->re_nsub = static_cast<wc_regex_type*>(expression->guts)->mark_count();
result = static_cast<wc_regex_type*>(expression->guts)->error_code();
#ifndef BOOST_NO_EXCEPTIONS
2005-01-13 17:06:21 +00:00
}
catch(const boost::regex_error& be)
{
result = be.code();
}
catch(...)
2000-09-26 11:48:28 +00:00
{
result = REG_E_UNKNOWN;
}
#endif
2000-09-26 11:48:28 +00:00
if(result)
regfreeW(expression);
return result;
}
2002-03-19 11:31:52 +00:00
BOOST_REGEX_DECL regsize_t BOOST_REGEX_CCALL regerrorW(int code, const regex_tW* e, wchar_t* buf, regsize_t buf_size)
2000-09-26 11:48:28 +00:00
{
2002-03-19 11:31:52 +00:00
std::size_t result = 0;
2000-09-26 11:48:28 +00:00
if(code & REG_ITOA)
{
code &= ~REG_ITOA;
2005-01-13 17:06:21 +00:00
if((code <= (int)REG_E_UNKNOWN) && (code >= 0))
2000-09-26 11:48:28 +00:00
{
result = std::wcslen(wnames[code]) + 1;
if(buf_size >= result)
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE)
::wcscpy_s(buf, buf_size, wnames[code]);
#else
2000-09-26 11:48:28 +00:00
std::wcscpy(buf, wnames[code]);
#endif
2000-09-26 11:48:28 +00:00
return result;
}
return result;
}
#if !defined(BOOST_NO_SWPRINTF)
2000-09-26 11:48:28 +00:00
if(code == REG_ATOI)
{
wchar_t localbuf[5];
if(e == 0)
return 0;
2005-01-13 17:06:21 +00:00
for(int i = 0; i <= (int)REG_E_UNKNOWN; ++i)
2000-09-26 11:48:28 +00:00
{
if(std::wcscmp(e->re_endp, wnames[i]) == 0)
{
#if defined(_WIN32_WCE) && !defined(UNDER_CE)
2007-11-17 12:17:05 +00:00
(std::swprintf)(localbuf, L"%d", i);
#else
2005-01-13 17:06:21 +00:00
(std::swprintf)(localbuf, 5, L"%d", i);
2007-11-17 12:17:05 +00:00
#endif
2000-09-26 11:48:28 +00:00
if(std::wcslen(localbuf) < buf_size)
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE)
::wcscpy_s(buf, buf_size, localbuf);
#else
2000-09-26 11:48:28 +00:00
std::wcscpy(buf, localbuf);
#endif
2000-09-26 11:48:28 +00:00
return std::wcslen(localbuf) + 1;
}
}
#if defined(_WIN32_WCE) && !defined(UNDER_CE)
2007-11-17 12:17:05 +00:00
(std::swprintf)(localbuf, L"%d", 0);
#else
2005-01-13 17:06:21 +00:00
(std::swprintf)(localbuf, 5, L"%d", 0);
2007-11-17 12:17:05 +00:00
#endif
2000-09-26 11:48:28 +00:00
if(std::wcslen(localbuf) < buf_size)
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) && !defined(_WIN32_WCE) && !defined(UNDER_CE)
::wcscpy_s(buf, buf_size, localbuf);
#else
2000-09-26 11:48:28 +00:00
std::wcscpy(buf, localbuf);
#endif
2000-09-26 11:48:28 +00:00
return std::wcslen(localbuf) + 1;
}
#endif
2005-01-13 17:06:21 +00:00
if(code <= (int)REG_E_UNKNOWN)
2000-09-26 11:48:28 +00:00
{
2005-01-13 17:06:21 +00:00
std::string p;
if((e) && (e->re_magic == wmagic_value))
p = static_cast<wc_regex_type*>(e->guts)->get_traits().error_string(static_cast< ::boost::regex_constants::error_type>(code));
2005-01-13 17:06:21 +00:00
else
{
2015-04-04 19:10:37 +01:00
p = BOOST_REGEX_DETAIL_NS::get_default_error_string(static_cast< ::boost::regex_constants::error_type>(code));
2005-01-13 17:06:21 +00:00
}
std::size_t len = p.size();
2000-09-26 11:48:28 +00:00
if(len < buf_size)
{
2015-04-04 19:10:37 +01:00
BOOST_REGEX_DETAIL_NS::copy(p.c_str(), p.c_str() + p.size() + 1, buf);
2000-09-26 11:48:28 +00:00
}
return len + 1;
}
if(buf_size)
*buf = 0;
return 0;
}
2002-03-19 11:31:52 +00:00
BOOST_REGEX_DECL int BOOST_REGEX_CCALL regexecW(const regex_tW* expression, const wchar_t* buf, regsize_t n, regmatch_t* array, int eflags)
2000-09-26 11:48:28 +00:00
{
2005-01-13 17:06:21 +00:00
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4267)
#endif
2000-09-26 11:48:28 +00:00
bool result = false;
2003-05-17 11:45:48 +00:00
match_flag_type flags = match_default | expression->eflags;
2000-09-26 11:48:28 +00:00
const wchar_t* end;
const wchar_t* start;
wcmatch m;
if(eflags & REG_NOTBOL)
flags |= match_not_bol;
if(eflags & REG_NOTEOL)
flags |= match_not_eol;
if(eflags & REG_STARTEND)
{
start = buf + array[0].rm_so;
end = buf + array[0].rm_eo;
}
else
{
start = buf;
end = buf + std::wcslen(buf);
}
#ifndef BOOST_NO_EXCEPTIONS
2000-09-26 11:48:28 +00:00
try{
#endif
2000-09-26 11:48:28 +00:00
if(expression->re_magic == wmagic_value)
{
result = regex_search(start, end, m, *static_cast<wc_regex_type*>(expression->guts), flags);
2000-09-26 11:48:28 +00:00
}
else
return result;
#ifndef BOOST_NO_EXCEPTIONS
2000-09-26 11:48:28 +00:00
} catch(...)
{
return REG_E_UNKNOWN;
}
#endif
2000-09-26 11:48:28 +00:00
if(result)
{
// extract what matched:
2005-01-13 17:06:21 +00:00
std::size_t i;
2000-09-26 11:48:28 +00:00
for(i = 0; (i < n) && (i < expression->re_nsub + 1); ++i)
{
array[i].rm_so = (m[i].matched == false) ? -1 : (m[i].first - buf);
array[i].rm_eo = (m[i].matched == false) ? -1 : (m[i].second - buf);
}
// and set anything else to -1:
for(i = expression->re_nsub + 1; i < n; ++i)
{
array[i].rm_so = -1;
array[i].rm_eo = -1;
}
return 0;
}
return REG_NOMATCH;
2005-01-13 17:06:21 +00:00
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
2000-09-26 11:48:28 +00:00
}
BOOST_REGEX_DECL void BOOST_REGEX_CCALL regfreeW(regex_tW* expression)
2000-09-26 11:48:28 +00:00
{
if(expression->re_magic == wmagic_value)
{
delete static_cast<wc_regex_type*>(expression->guts);
2000-09-26 11:48:28 +00:00
}
expression->re_magic = 0;
}
} // namespace boost;
#endif
2003-09-30 13:02:51 +00:00