mirror of
https://github.com/boostorg/regex.git
synced 2025-07-17 06:12:10 +02:00
Added support for perl style \u \U \l \L etc in formatting.
[SVN r22486]
This commit is contained in:
@ -57,7 +57,7 @@ template class BOOST_REGEX_DECL reg_expression< BOOST_REGEX_CHAR_T >;
|
|||||||
# include BOOST_ABI_SUFFIX
|
# include BOOST_ABI_SUFFIX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#elif defined(BOOST_MSVC) || defined(__GNUC__)
|
#elif (defined(BOOST_MSVC) && defined(_MSC_EXTENSIONS)) || defined(__GNUC__)
|
||||||
|
|
||||||
# ifndef BOOST_REGEX_INSTANTIATE
|
# ifndef BOOST_REGEX_INSTANTIATE
|
||||||
# define template extern template
|
# define template extern template
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
* Copyright (c) 1998-2002
|
* Copyright (c) 1998-2002
|
||||||
* Dr John Maddock
|
* Dr John Maddock
|
||||||
*
|
*
|
||||||
* Use, modification and distribution are subject to the
|
* Use, modification and distribution are subject to the
|
||||||
* Boost Software License, Version 1.0. (See accompanying file
|
* Boost Software License, Version 1.0. (See accompanying file
|
||||||
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
* LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@ -36,18 +36,111 @@ class match_results;
|
|||||||
|
|
||||||
namespace re_detail{
|
namespace re_detail{
|
||||||
|
|
||||||
template <class O, class I>
|
// make_upper and make_lower should ideally be implemented in regex_traits
|
||||||
O BOOST_REGEX_CALL re_copy_out(O out, I first, I last)
|
#if defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
|
||||||
|
|
||||||
|
//
|
||||||
|
// VC6 needs to link to user32.lib, as do all compilers that
|
||||||
|
// claim to be VC6/7 compatible:
|
||||||
|
//
|
||||||
|
#if defined(_MSC_VER) && !defined(__BORLANDC__)
|
||||||
|
#pragma comment(lib, "user32.lib")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline wchar_t make_upper(wchar_t c)
|
||||||
|
{
|
||||||
|
return LOWORD(::CharUpperW(reinterpret_cast<wchar_t*>(static_cast<unsigned short>(c))));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline char make_upper(char c)
|
||||||
|
{
|
||||||
|
return static_cast<char>(LOWORD(::CharUpperA(reinterpret_cast<char*>(static_cast<unsigned short>(c)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline wchar_t make_lower(wchar_t c)
|
||||||
|
{
|
||||||
|
return LOWORD(::CharLowerW(reinterpret_cast<wchar_t*>(static_cast<unsigned short>(c))));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline char make_lower(char c)
|
||||||
|
{
|
||||||
|
return static_cast<char>(LOWORD(::CharLowerA(reinterpret_cast<char*>(static_cast<unsigned short>(c)))));
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// TODO: make this traits class sensitive:
|
||||||
|
#ifndef BOOST_NO_WREGEX
|
||||||
|
inline wchar_t make_upper(wchar_t c)
|
||||||
|
{
|
||||||
|
return (std::towupper)(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline wchar_t make_lower(wchar_t c)
|
||||||
|
{
|
||||||
|
return (std::towlower)(c);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
inline char make_upper(char c)
|
||||||
|
{
|
||||||
|
return static_cast<char>((std::toupper)(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline char make_lower(char c)
|
||||||
|
{
|
||||||
|
return static_cast<char>((std::tolower)(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //defined(_WIN32) && !defined(BOOST_REGEX_NO_W32)
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
case_nochange,
|
||||||
|
case_oneupper,
|
||||||
|
case_onelower,
|
||||||
|
case_allupper,
|
||||||
|
case_alllower
|
||||||
|
} case_flags_type;
|
||||||
|
|
||||||
|
// traits_type is unused, but provided to make it possible to use it for case conversion
|
||||||
|
template <class O, class charT, class traits_type>
|
||||||
|
void BOOST_REGEX_CALL output_char(O& out, charT c, traits_type& /*t*/, case_flags_type& f)
|
||||||
|
{
|
||||||
|
switch (f) {
|
||||||
|
case case_oneupper:
|
||||||
|
f = case_nochange;
|
||||||
|
// drop through
|
||||||
|
case case_allupper:
|
||||||
|
*out = make_upper(c);
|
||||||
|
break;
|
||||||
|
case case_onelower:
|
||||||
|
f = case_nochange;
|
||||||
|
// drop through
|
||||||
|
case case_alllower:
|
||||||
|
*out = make_lower(c);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*out = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class O, class I, class traits_type>
|
||||||
|
O BOOST_REGEX_CALL re_copy_out(O out, I first, I last, traits_type& t, case_flags_type& f)
|
||||||
{
|
{
|
||||||
while(first != last)
|
while(first != last)
|
||||||
{
|
{
|
||||||
*out = *first;
|
if (f != case_nochange)
|
||||||
|
output_char(out, *first, t, f);
|
||||||
|
else
|
||||||
|
*out = *first;
|
||||||
|
|
||||||
++out;
|
++out;
|
||||||
++first;
|
++first;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class charT, class traits_type>
|
template <class charT, class traits_type>
|
||||||
void BOOST_REGEX_CALL re_skip_format(const charT*& fmt, const traits_type& traits_inst)
|
void BOOST_REGEX_CALL re_skip_format(const charT*& fmt, const traits_type& traits_inst)
|
||||||
{
|
{
|
||||||
@ -134,10 +227,11 @@ namespace{
|
|||||||
// _reg_format_aux does the actual work:
|
// _reg_format_aux does the actual work:
|
||||||
//
|
//
|
||||||
template <class OutputIterator, class Iterator, class Allocator, class charT, class traits_type>
|
template <class OutputIterator, class Iterator, class Allocator, class charT, class traits_type>
|
||||||
OutputIterator BOOST_REGEX_CALL _reg_format_aux(OutputIterator out,
|
OutputIterator BOOST_REGEX_CALL _reg_format_aux(OutputIterator out,
|
||||||
const match_results<Iterator, Allocator>& m,
|
const match_results<Iterator, Allocator>& m,
|
||||||
const charT*& fmt,
|
const charT*& fmt,
|
||||||
match_flag_type flags, const traits_type& traits_inst)
|
match_flag_type flags, const traits_type& traits_inst,
|
||||||
|
case_flags_type& case_flags)
|
||||||
{
|
{
|
||||||
#ifdef __BORLANDC__
|
#ifdef __BORLANDC__
|
||||||
#pragma option push -w-8037
|
#pragma option push -w-8037
|
||||||
@ -171,11 +265,13 @@ OutputIterator BOOST_REGEX_CALL _reg_format_aux(OutputIterator out,
|
|||||||
switch(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*fmt)))
|
switch(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*fmt)))
|
||||||
{
|
{
|
||||||
case traits_type::syntax_start_buffer:
|
case traits_type::syntax_start_buffer:
|
||||||
oi_assign(&out, re_copy_out(out, Iterator(m[-1].first), Iterator(m[-1].second)));
|
oi_assign(&out, re_copy_out(out, Iterator(m[-1].first), Iterator(m[-1].second),
|
||||||
|
traits_inst, case_flags));
|
||||||
++fmt;
|
++fmt;
|
||||||
continue;
|
continue;
|
||||||
case traits_type::syntax_end_buffer:
|
case traits_type::syntax_end_buffer:
|
||||||
oi_assign(&out, re_copy_out(out, Iterator(m[-2].first), Iterator(m[-2].second)));
|
oi_assign(&out, re_copy_out(out, Iterator(m[-2].first), Iterator(m[-2].second),
|
||||||
|
traits_inst, case_flags));
|
||||||
++fmt;
|
++fmt;
|
||||||
continue;
|
continue;
|
||||||
case traits_type::syntax_digit:
|
case traits_type::syntax_digit:
|
||||||
@ -183,14 +279,16 @@ OutputIterator BOOST_REGEX_CALL _reg_format_aux(OutputIterator out,
|
|||||||
expand_sub:
|
expand_sub:
|
||||||
unsigned int index = traits_inst.toi(fmt, fmt_end, 10);
|
unsigned int index = traits_inst.toi(fmt, fmt_end, 10);
|
||||||
if(index < m.size())
|
if(index < m.size())
|
||||||
oi_assign(&out, re_copy_out(out, Iterator(m[index].first), Iterator(m[index].second)));
|
oi_assign(&out, re_copy_out(out, Iterator(m[index].first), Iterator(m[index].second),
|
||||||
|
traits_inst, case_flags));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// anything else:
|
// anything else:
|
||||||
if(*fmt == '&')
|
if(*fmt == '&')
|
||||||
{
|
{
|
||||||
oi_assign(&out, re_copy_out(out, Iterator(m[0].first), Iterator(m[0].second)));
|
oi_assign(&out, re_copy_out(out, Iterator(m[0].first), Iterator(m[0].second),
|
||||||
|
traits_inst, case_flags));
|
||||||
++fmt;
|
++fmt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -327,6 +425,32 @@ expand_sub:
|
|||||||
else
|
else
|
||||||
c = (charT)traits_inst.toi(fmt, fmt_end, -8);
|
c = (charT)traits_inst.toi(fmt, fmt_end, -8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case traits_type::syntax_u:
|
||||||
|
++fmt;
|
||||||
|
if(flags & format_sed) break;
|
||||||
|
case_flags = case_oneupper;
|
||||||
|
continue;
|
||||||
|
case traits_type::syntax_l:
|
||||||
|
++fmt;
|
||||||
|
if(flags & format_sed) break;
|
||||||
|
case_flags = case_onelower;
|
||||||
|
continue;
|
||||||
|
case traits_type::syntax_U:
|
||||||
|
++fmt;
|
||||||
|
if(flags & format_sed) break;
|
||||||
|
case_flags = case_allupper;
|
||||||
|
continue;
|
||||||
|
case traits_type::syntax_L:
|
||||||
|
++fmt;
|
||||||
|
if(flags & format_sed) break;
|
||||||
|
case_flags = case_alllower;
|
||||||
|
continue;
|
||||||
|
case traits_type::syntax_E:
|
||||||
|
++fmt;
|
||||||
|
if(flags & format_sed) break;
|
||||||
|
case_flags = case_nochange;
|
||||||
|
continue;
|
||||||
default:
|
default:
|
||||||
//c = *fmt;
|
//c = *fmt;
|
||||||
++fmt;
|
++fmt;
|
||||||
@ -346,7 +470,7 @@ expand_sub:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
++fmt; // recurse
|
++fmt; // recurse
|
||||||
oi_assign(&out, _reg_format_aux(out, m, fmt, flags, traits_inst));
|
oi_assign(&out, _reg_format_aux(out, m, fmt, flags, traits_inst, case_flags));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
case traits_type::syntax_close_bracket:
|
case traits_type::syntax_close_bracket:
|
||||||
@ -395,7 +519,7 @@ expand_sub:
|
|||||||
unsigned int id = traits_inst.toi(fmt, fmt_end, 10);
|
unsigned int id = traits_inst.toi(fmt, fmt_end, 10);
|
||||||
if(m[id].matched)
|
if(m[id].matched)
|
||||||
{
|
{
|
||||||
oi_assign(&out, _reg_format_aux(out, m, fmt, flags | regex_constants::format_is_if, traits_inst));
|
oi_assign(&out, _reg_format_aux(out, m, fmt, flags | regex_constants::format_is_if, traits_inst, case_flags));
|
||||||
if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*(fmt-1))) == traits_type::syntax_colon)
|
if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*(fmt-1))) == traits_type::syntax_colon)
|
||||||
re_skip_format(fmt, traits_inst);
|
re_skip_format(fmt, traits_inst);
|
||||||
}
|
}
|
||||||
@ -403,7 +527,7 @@ expand_sub:
|
|||||||
{
|
{
|
||||||
re_skip_format(fmt, traits_inst);
|
re_skip_format(fmt, traits_inst);
|
||||||
if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*(fmt-1))) == traits_type::syntax_colon)
|
if(traits_inst.syntax_type((traits_size_type)(traits_uchar_type)(*(fmt-1))) == traits_type::syntax_colon)
|
||||||
oi_assign(&out, _reg_format_aux(out, m, fmt, flags | regex_constants::format_is_if, traits_inst));
|
oi_assign(&out, _reg_format_aux(out, m, fmt, flags | regex_constants::format_is_if, traits_inst, case_flags));
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@ -412,11 +536,13 @@ expand_sub:
|
|||||||
default_opt:
|
default_opt:
|
||||||
if((flags & format_sed) && (*fmt == '&'))
|
if((flags & format_sed) && (*fmt == '&'))
|
||||||
{
|
{
|
||||||
oi_assign(&out, re_copy_out(out, Iterator(m[0].first), Iterator(m[0].second)));
|
oi_assign(&out, re_copy_out(out, Iterator(m[0].first), Iterator(m[0].second),
|
||||||
|
traits_inst, case_flags));
|
||||||
++fmt;
|
++fmt;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*out = *fmt;
|
|
||||||
|
output_char(out, *fmt, traits_inst, case_flags);
|
||||||
++out;
|
++out;
|
||||||
++fmt;
|
++fmt;
|
||||||
}
|
}
|
||||||
@ -441,10 +567,10 @@ public:
|
|||||||
string_out_iterator& operator++() { return *this; }
|
string_out_iterator& operator++() { return *this; }
|
||||||
string_out_iterator& operator++(int) { return *this; }
|
string_out_iterator& operator++(int) { return *this; }
|
||||||
string_out_iterator& operator*() { return *this; }
|
string_out_iterator& operator*() { return *this; }
|
||||||
string_out_iterator& operator=(typename S::value_type v)
|
string_out_iterator& operator=(typename S::value_type v)
|
||||||
{
|
{
|
||||||
out->append(1, v);
|
out->append(1, v);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -467,9 +593,17 @@ public:
|
|||||||
bool BOOST_REGEX_CALL operator()(const boost::match_results<Iterator, alloc_type>& m)
|
bool BOOST_REGEX_CALL operator()(const boost::match_results<Iterator, alloc_type>& m)
|
||||||
{
|
{
|
||||||
const charT* f = fmt;
|
const charT* f = fmt;
|
||||||
|
case_flags_type cf = case_nochange;
|
||||||
if(0 == (flags & format_no_copy))
|
if(0 == (flags & format_no_copy))
|
||||||
oi_assign(out, re_copy_out(*out, Iterator(m[-1].first), Iterator(m[-1].second)));
|
{
|
||||||
oi_assign(out, _reg_format_aux(*out, m, f, flags, *pt));
|
oi_assign(out, re_copy_out(
|
||||||
|
*out,
|
||||||
|
Iterator(m[-1].first),
|
||||||
|
Iterator(m[-1].second),
|
||||||
|
*pt,
|
||||||
|
cf));
|
||||||
|
}
|
||||||
|
oi_assign(out, _reg_format_aux(*out, m, f, flags, *pt, cf));
|
||||||
*last = m[-2].first;
|
*last = m[-2].first;
|
||||||
return flags & format_first_only ? false : true;
|
return flags & format_first_only ? false : true;
|
||||||
}
|
}
|
||||||
@ -485,7 +619,9 @@ OutputIterator regex_format(OutputIterator out,
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
regex_traits<charT> t;
|
regex_traits<charT> t;
|
||||||
return re_detail::_reg_format_aux(out, m, fmt, flags, t);
|
|
||||||
|
re_detail::case_flags_type cf = re_detail::case_nochange;
|
||||||
|
return re_detail::_reg_format_aux(out, m, fmt, flags, t, cf);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class OutputIterator, class Iterator, class Allocator, class charT>
|
template <class OutputIterator, class Iterator, class Allocator, class charT>
|
||||||
@ -497,12 +633,14 @@ OutputIterator regex_format(OutputIterator out,
|
|||||||
{
|
{
|
||||||
regex_traits<charT> t;
|
regex_traits<charT> t;
|
||||||
const charT* start = fmt.c_str();
|
const charT* start = fmt.c_str();
|
||||||
return re_detail::_reg_format_aux(out, m, start, flags, t);
|
|
||||||
}
|
re_detail::case_flags_type cf = re_detail::case_nochange;
|
||||||
|
return re_detail::_reg_format_aux(out, m, start, flags, t, cf);
|
||||||
|
}
|
||||||
|
|
||||||
template <class Iterator, class Allocator, class charT>
|
template <class Iterator, class Allocator, class charT>
|
||||||
std::basic_string<charT> regex_format(const match_results<Iterator, Allocator>& m,
|
std::basic_string<charT> regex_format(const match_results<Iterator, Allocator>& m,
|
||||||
const charT* fmt,
|
const charT* fmt,
|
||||||
match_flag_type flags = format_all)
|
match_flag_type flags = format_all)
|
||||||
{
|
{
|
||||||
std::basic_string<charT> result;
|
std::basic_string<charT> result;
|
||||||
@ -512,8 +650,8 @@ std::basic_string<charT> regex_format(const match_results<Iterator, Allocator>&
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class Iterator, class Allocator, class charT>
|
template <class Iterator, class Allocator, class charT>
|
||||||
std::basic_string<charT> regex_format(const match_results<Iterator, Allocator>& m,
|
std::basic_string<charT> regex_format(const match_results<Iterator, Allocator>& m,
|
||||||
const std::basic_string<charT>& fmt,
|
const std::basic_string<charT>& fmt,
|
||||||
match_flag_type flags = format_all)
|
match_flag_type flags = format_all)
|
||||||
{
|
{
|
||||||
std::basic_string<charT> result;
|
std::basic_string<charT> result;
|
||||||
|
@ -39,7 +39,7 @@ OutputIterator regex_replace(OutputIterator out,
|
|||||||
Iterator l = first;
|
Iterator l = first;
|
||||||
re_detail::merge_out_predicate<OutputIterator, Iterator, charT, Allocator, traits> oi(out, l, fmt, flags, e.get_traits());
|
re_detail::merge_out_predicate<OutputIterator, Iterator, charT, Allocator, traits> oi(out, l, fmt, flags, e.get_traits());
|
||||||
regex_grep(oi, first, last, e, flags);
|
regex_grep(oi, first, last, e, flags);
|
||||||
return (flags & format_no_copy) ? out : re_detail::re_copy_out(out, l, last);
|
return (flags & format_no_copy) ? out : std::copy(l, last, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class OutputIterator, class Iterator, class traits, class Allocator, class charT>
|
template <class OutputIterator, class Iterator, class traits, class Allocator, class charT>
|
||||||
|
Reference in New Issue
Block a user