📄 regex_compile.hpp
字号:
else
traits_inst.transform(c1, ranges.peek());
ranges.pop();
if(flags() & regbase::nocollate)
c2 = ranges.peek();
else
traits_inst.transform(c2, ranges.peek());
ranges.pop();
if(c1 < c2)
{
// for some reason bc5 crashes when throwing exceptions
// from here - probably an EH-compiler bug, but hard to
// be sure...
// delay throw to later:
#ifdef __BORLANDC__
boost::uint_fast32_t f = _flags;
_flags &= ~regbase::use_except;
#endif
fail(REG_ERANGE);
#ifdef __BORLANDC__
_flags = f;
#endif
return 0;
}
for(unsigned int i = 0; i < 256; ++i)
{
c4 = (charT)i;
if(flags() & regbase::nocollate)
c3 = c4;
else
traits_inst.transform(c3, c4);
if((c3 <= c1) && (c3 >= c2))
dat->_map[i] = re_detail::mask_all;
}
}
while(equivalents.empty() == false)
{
traits_string_type c1, c2;
for(unsigned int i = 0; i < 256; ++i)
{
c2 = (charT)i;
traits_inst.transform_primary(c1, c2);
if(c1 == equivalents.peek())
dat->_map[i] = re_detail::mask_all;
}
equivalents.pop();
}
boost::uint_fast32_t flags = 0;
while(classes.empty() == false)
{
flags |= classes.peek();
classes.pop();
}
if(flags)
{
for(unsigned int i = 0; i < 256; ++i)
{
if(traits_inst.is_class(charT(i), flags))
dat->_map[(traits_uchar_type)traits_inst.translate((charT)i, (_flags & regbase::icase))] = re_detail::mask_all;
}
}
if(isnot)
{
for(unsigned int i = 0; i < 256; ++i)
{
dat->_map[i] = !dat->_map[i];
}
}
dat->type = re_detail::syntax_element_set;
dat->next.i = 0;
return dat;
}
#ifndef __CODEGUARD__
// this must not be inline when Borland's codeguard support is turned
// on, otherwise we _will_ get surious codeguard errors...
inline
#endif
re_detail::re_syntax_base* add_offset(void* base, std::ptrdiff_t off)
{
return reinterpret_cast<re_detail::re_syntax_base*>(reinterpret_cast<char*>(base) + off);
}
template <class charT, class traits, class Allocator>
void BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::fixup_apply(re_detail::re_syntax_base* b, unsigned cbraces)
{
typedef typename boost::detail::rebind_allocator<bool, Allocator>::type b_alloc;
register unsigned char* base = reinterpret_cast<unsigned char*>(b);
register re_detail::re_syntax_base* ptr = b;
bool* pb = 0;
b_alloc a(data.allocator());
#ifndef BOOST_NO_EXCEPTIONS
try
{
#endif
pb = a.allocate(cbraces);
BOOST_REGEX_NOEH_ASSERT(pb)
for(unsigned i = 0; i < cbraces; ++i)
pb[i] = false;
repeats = 0;
while(ptr->next.i)
{
switch(ptr->type)
{
case re_detail::syntax_element_rep:
jm_assert(data.size() > static_cast<re_detail::re_jump*>(ptr)->alt.i);
static_cast<re_detail::re_jump*>(ptr)->alt.p = add_offset(base, static_cast<re_detail::re_jump*>(ptr)->alt.i);
#ifdef BOOST_REGEX_DEBUG
if((re_detail::padding_mask & reinterpret_cast<int>(static_cast<re_detail::re_jump*>(ptr)->alt.p)) && (static_cast<re_detail::re_jump*>(ptr)->alt.p != b))
{
jm_trace("padding mis-aligment in repeat jump to object type: " << static_cast<re_detail::re_jump*>(ptr)->alt.p->type)
//jm_assert(0 == (padding_mask & (int)((re_detail::re_jump*)ptr)->alt.p));
}
#endif
static_cast<re_detail::re_repeat*>(ptr)->id = repeats;
++repeats;
goto rebase;
case re_detail::syntax_element_jump:
case re_detail::syntax_element_alt:
jm_assert(data.size() > static_cast<re_detail::re_jump*>(ptr)->alt.i);
static_cast<re_detail::re_jump*>(ptr)->alt.p = add_offset(base, static_cast<re_detail::re_jump*>(ptr)->alt.i);
#ifdef BOOST_REGEX_DEBUG
if((re_detail::padding_mask & reinterpret_cast<int>(static_cast<re_detail::re_jump*>(ptr)->alt.p) && (static_cast<re_detail::re_jump*>(ptr)->alt.p != b)))
{
jm_trace("padding mis-aligment in alternation jump to object type: " << static_cast<re_detail::re_jump*>(ptr)->alt.p->type)
//jm_assert(0 == (padding_mask & (int)((re_detail::re_jump*)ptr)->alt.p));
}
#endif
goto rebase;
case re_detail::syntax_element_backref:
if((static_cast<re_detail::re_brace*>(ptr)->index >= (int)cbraces) || (pb[static_cast<re_detail::re_brace*>(ptr)->index] == false) )
{
fail(REG_ESUBREG);
a.deallocate(pb, cbraces);
return;
}
goto rebase;
case re_detail::syntax_element_endmark:
if(static_cast<re_detail::re_brace*>(ptr)->index > 0)
pb[static_cast<re_detail::re_brace*>(ptr)->index] = true;
goto rebase;
default:
rebase:
jm_assert(data.size() > ptr->next.i);
ptr->next.p = add_offset(base, ptr->next.i);
#ifdef BOOST_REGEX_DEBUG
if((re_detail::padding_mask & (int)(ptr->next.p)) && (static_cast<re_detail::re_jump*>(ptr)->alt.p != b))
{
jm_trace("padding mis-alignment in next record of type " << ptr->next.p->type)
jm_assert(0 == (re_detail::padding_mask & (int)(ptr->next.p)));
}
#endif
ptr = ptr->next.p;
}
}
a.deallocate(pb, cbraces);
pb = 0;
#ifndef BOOST_NO_EXCEPTIONS
}
catch(...)
{
if(pb)
a.deallocate(pb, cbraces);
throw;
}
#endif
}
template <class charT, class traits, class Allocator>
unsigned int BOOST_REGEX_CALL reg_expression<charT, traits, Allocator>::set_expression(const charT* p, const charT* end, flag_type f)
{
# ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4127)
#endif
#ifdef __OpenBSD__
// strxfrm not working on OpenBSD??
f |= regbase::nocollate;
#endif
if(p == expression())
{
traits_string_type s(p, end);
return set_expression(s.c_str(), s.c_str() + s.size(), f);
}
typedef typename traits_type::sentry sentry_t;
sentry_t sent(traits_inst);
if(sent){
const charT* base = p;
data.clear();
_flags = f;
fail(REG_NOERROR); // clear any error
if(p >= end)
{
fail(REG_EMPTY);
return error_code();
}
const charT* ptr = p;
marks = 0;
re_detail::jstack<std::size_t, Allocator> mark(64, data.allocator());
re_detail::jstack<int, Allocator> markid(64, data.allocator());
std::size_t last_mark_popped = 0;
register traits_size_type c;
register re_detail::re_syntax_base* dat;
unsigned rep_min = 0;
unsigned rep_max = 0;
//
// set up header:
//
++marks;
dat = 0;
if(_flags & regbase::literal)
{
while(ptr != end)
{
dat = add_literal(dat, traits_inst.translate(*ptr, (_flags & regbase::icase)));
++ptr;
}
}
while (ptr < end)
{
c = (traits_size_type)(traits_uchar_type)*ptr;
// this is only used for the switch(), but cannot be folded in
// due to a bug in Comeau 4.2.44beta3
traits_size_type syntax = traits_inst.syntax_type(c);
switch(syntax)
{
case traits_type::syntax_open_bracket:
if(_flags & bk_parens)
{
dat = add_literal(dat, (charT)c);
++ptr;
continue;
}
open_bracked_jump:
// extend:
dat = add_simple(dat, re_detail::syntax_element_startmark, sizeof(re_detail::re_brace));
markid.push(marks);
static_cast<re_detail::re_brace*>(dat)->index = marks++;
mark.push(data.index(dat));
++ptr;
//
// check for perl like (?...) extention syntax
c = (traits_size_type)(traits_uchar_type)*ptr;
if(((_flags & bk_parens) == 0) && (traits_type::syntax_question == traits_inst.syntax_type(c)))
{
++ptr;
c = (traits_size_type)(traits_uchar_type)*ptr;
// this is only used for the switch(), but cannot be folded in
// due to a bug in Comeau 4.2.44beta3
traits_size_type syntax = traits_inst.syntax_type(c);
switch(syntax)
{
case traits_type::syntax_colon:
static_cast<re_detail::re_brace*>(dat)->index = 0;
--marks;
markid.pop();
markid.push(0);
++ptr;
continue;
case traits_type::syntax_equal:
static_cast<re_detail::re_brace*>(dat)->index = -1;
markid.pop();
markid.push(-1);
common_forward_assert:
--marks;
++ptr;
// extend:
dat = add_simple(dat, re_detail::syntax_element_jump, re_detail::re_jump_size);
data.align();
//
// we don't know what value to put here yet,
// use an arbitrarily large value for now
// and check it later:
static_cast<re_detail::re_jump*>(dat)->alt.i = INT_MAX/2;
mark.push(data.size() - re_detail::re_jump_size);
continue;
case traits_type::syntax_not:
static_cast<re_detail::re_brace*>(dat)->index = -2;
markid.pop();
markid.push(-2);
goto common_forward_assert;
case traits_type::syntax_hash:
// comment just skip it:
static_cast<re_detail::re_brace*>(dat)->index = 0;
--marks;
markid.pop();
mark.pop();
do{
++ptr;
c = (traits_size_type)(traits_uchar_type)*ptr;
}while(traits_type::syntax_close_bracket != traits_inst.syntax_type(c));
++ptr;
continue;
default:
//
// error, return to standard parsing and let that handle the error:
--ptr;
continue;
}
}
break;
case traits_type::syntax_close_bracket:
if(_flags & bk_parens)
{
dat = add_literal(dat, (charT)c);
++ptr;
continue;
}
close_bracked_jump:
if(dat)
{
data.align();
dat->next.i = data.size();
}
if(mark.empty())
{
fail(REG_EPAREN);
return error_code();
}
// see if we have an empty alternative:
if(mark.peek() == data.index(dat) )
{
re_detail::re_syntax_base* para = reinterpret_cast<re_detail::re_syntax_base*>(reinterpret_cast<char*>(data.data()) + mark.peek());
if(para->type == re_detail::syntax_element_jump)
{
fail(REG_EMPTY);
return error_code();
}
}
// pop any pushed alternatives and set the target end destination:
dat = reinterpret_cast<re_detail::re_syntax_base*>(reinterpret_cast<unsigned char*>(data.data()) + mark.peek());
while(dat->type == re_detail::syntax_element_jump)
{
static_cast<re_detail::re_jump*>(dat)->alt.i = data.size();
mark.pop();
if(mark.empty())
{
fail(REG_EPAREN);
return error_code();
}
dat = reinterpret_cast<re_detail::re_jump*>(reinterpret_cast<unsigned char*>(data.data()) + mark.peek());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -