mirror of
https://github.com/matrix-construct/construct
synced 2024-11-16 15:00:51 +01:00
ircd: Add stringops suite for globular expression matching.
This commit is contained in:
parent
680734c47b
commit
8aa67ccb48
2 changed files with 117 additions and 0 deletions
|
@ -21,6 +21,10 @@ namespace ircd
|
||||||
struct igreater;
|
struct igreater;
|
||||||
struct iequals;
|
struct iequals;
|
||||||
|
|
||||||
|
// Globular ('*' and '?') expression utils.
|
||||||
|
struct gmatch;
|
||||||
|
struct gequals;
|
||||||
|
|
||||||
// Vintage
|
// Vintage
|
||||||
struct strlcpy;
|
struct strlcpy;
|
||||||
struct strlcat;
|
struct strlcat;
|
||||||
|
@ -296,6 +300,60 @@ const
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Globular equals. This allows either side of the comparison to include '*'
|
||||||
|
/// and '?' characters and equality of the string expressions will be
|
||||||
|
/// determined.
|
||||||
|
struct ircd::gequals
|
||||||
|
{
|
||||||
|
using is_transparent = std::true_type;
|
||||||
|
|
||||||
|
bool s;
|
||||||
|
|
||||||
|
operator const bool &() const
|
||||||
|
{
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const string_view &a, const string_view &b) const;
|
||||||
|
|
||||||
|
template<class A,
|
||||||
|
class B>
|
||||||
|
gequals(A&& a, B&& b)
|
||||||
|
:s{operator()(std::forward<A>(a), std::forward<B>(b))}
|
||||||
|
{}
|
||||||
|
|
||||||
|
gequals() = default;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Globular match. Similar to gequals but only one side of the comparison is
|
||||||
|
/// considered to be the expression with '*' and '?' characters. The expression
|
||||||
|
/// string is passed at construction. The comparison inputs are treated as
|
||||||
|
/// non-expression strings. This allows for greater optimization than gequals.
|
||||||
|
struct ircd::gmatch
|
||||||
|
{
|
||||||
|
string_view expr;
|
||||||
|
bool s;
|
||||||
|
|
||||||
|
operator const bool &() const
|
||||||
|
{
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator()(const string_view &a) const;
|
||||||
|
|
||||||
|
gmatch(const string_view &expr)
|
||||||
|
:expr{expr}
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<class A>
|
||||||
|
gmatch(const string_view &expr, A&& a)
|
||||||
|
:expr{expr}
|
||||||
|
,s{operator()(std::forward<A>(a))}
|
||||||
|
{}
|
||||||
|
|
||||||
|
gmatch() = default;
|
||||||
|
};
|
||||||
|
|
||||||
inline ircd::string_view
|
inline ircd::string_view
|
||||||
ircd::trunc(const string_view &s,
|
ircd::trunc(const string_view &s,
|
||||||
const size_t &max)
|
const size_t &max)
|
||||||
|
|
|
@ -452,3 +452,62 @@ ircd::replace(const string_view &s,
|
||||||
return std::distance(begin(buf), p);
|
return std::distance(begin(buf), p);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// gequals
|
||||||
|
//
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::gequals::operator()(const string_view &a, const string_view &b)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
size_t ap(0), bp(0);
|
||||||
|
while(ap < a.size() && bp < b.size())
|
||||||
|
{
|
||||||
|
const auto ca(tolower(a.at(ap))), cb(tolower(b.at(bp)));
|
||||||
|
const auto globa(ca == '*'), globb(cb == '*');
|
||||||
|
const auto wilda(ca == '?'), wildb(cb == '?');
|
||||||
|
|
||||||
|
if(!globa && !globb && !wilda && !wildb && ca != cb)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if((globa && ap + 1 >= a.size()) || (globb && bp + 1 >= b.size()))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(globa && cb == tolower(a.at(ap + 1)))
|
||||||
|
ap += 2;
|
||||||
|
|
||||||
|
if(globb && ca == tolower(b.at(bp + 1)))
|
||||||
|
bp += 2;
|
||||||
|
|
||||||
|
if(globa && globb)
|
||||||
|
++ap, ++bp;
|
||||||
|
|
||||||
|
if(!globa)
|
||||||
|
++ap;
|
||||||
|
|
||||||
|
if(!globb)
|
||||||
|
++bp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ap < a.size() && !b.empty() && b.back() == '*')
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if(bp < b.size() && !a.empty() && a.back() == '*')
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return std::equal(a.begin() + ap, a.end(), b.begin() + bp, b.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// gmatch
|
||||||
|
//
|
||||||
|
|
||||||
|
bool
|
||||||
|
ircd::gmatch::operator()(const string_view &a)
|
||||||
|
const
|
||||||
|
{
|
||||||
|
//TODO: optimize.
|
||||||
|
const gequals gequals(expr, a);
|
||||||
|
return bool(gequals);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue