Added explicitly case sensitive/insensitive filter operators.
The default case sensitivity is hard coded for each command. These operators allow to override the this default case sensitivity.
This commit is contained in:
parent
381215fd73
commit
c39d8e5813
|
@ -243,6 +243,43 @@ applies `Unicode normalization <https://unicode.org/reports/tr15/>`__
|
||||||
and converts all punctuation to ASCII equivalents
|
and converts all punctuation to ASCII equivalents
|
||||||
if MPD was compiled with `ICU <https://icu.unicode.org/>`__ support.
|
if MPD was compiled with `ICU <https://icu.unicode.org/>`__ support.
|
||||||
|
|
||||||
|
Explicit case-sensitivity [#since_0_24]_
|
||||||
|
----------------------------------------
|
||||||
|
|
||||||
|
.. note:: The following variants of filter operators override the default case sensitivity
|
||||||
|
that is command dependant with explicit case sensitivity.
|
||||||
|
|
||||||
|
.. list-table:: Explicitly case-sensitive operators
|
||||||
|
:widths: 33 33 33
|
||||||
|
|
||||||
|
* - Explicitly case-sensitive
|
||||||
|
- Explicitly case-insensitive
|
||||||
|
- Equivalent command dependant
|
||||||
|
|
||||||
|
* - ``eq_cs``
|
||||||
|
- ``eq_ci``
|
||||||
|
- ``==``
|
||||||
|
|
||||||
|
* - ``!eq_cs``
|
||||||
|
- ``!eq_ci``
|
||||||
|
- ``!=``
|
||||||
|
|
||||||
|
* - ``contains_cs``
|
||||||
|
- ``contains_ci``
|
||||||
|
- ``contains``
|
||||||
|
|
||||||
|
* - ``!contains_cs``
|
||||||
|
- ``!contains_ci``
|
||||||
|
- ``!contains``
|
||||||
|
|
||||||
|
* - ``starts_with_cs``
|
||||||
|
- ``starts_with_ci``
|
||||||
|
- ``starts_with``
|
||||||
|
|
||||||
|
* - ``!starts_with_cs``
|
||||||
|
- ``!starts_with_ci``
|
||||||
|
- ``!starts_with``
|
||||||
|
|
||||||
Prior to MPD 0.21, the syntax looked like this::
|
Prior to MPD 0.21, the syntax looked like this::
|
||||||
|
|
||||||
find TYPE VALUE
|
find TYPE VALUE
|
||||||
|
|
|
@ -190,6 +190,39 @@ ExpectQuoted(const char *&s)
|
||||||
return {buffer, length};
|
return {buffer, length};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Operator definition used to parse the operator
|
||||||
|
* from the command and create the StringFilter
|
||||||
|
* if it matched the operator prefix.
|
||||||
|
*/
|
||||||
|
struct OperatorDef {
|
||||||
|
const char *prefix;
|
||||||
|
bool fold_case;
|
||||||
|
bool negated;
|
||||||
|
StringFilter::Position position;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pre-defined operators with explicit case-sensitivity.
|
||||||
|
*/
|
||||||
|
static constexpr std::array<OperatorDef, 12> operators = {
|
||||||
|
// operator prefix fold case negated position
|
||||||
|
OperatorDef { "contains_cs ", false, false, StringFilter::Position::ANYWHERE },
|
||||||
|
OperatorDef { "!contains_cs ", false, true, StringFilter::Position::ANYWHERE },
|
||||||
|
OperatorDef { "contains_ci ", true, false, StringFilter::Position::ANYWHERE },
|
||||||
|
OperatorDef { "!contains_ci ", true, true, StringFilter::Position::ANYWHERE },
|
||||||
|
|
||||||
|
OperatorDef { "starts_with_cs ", false, false, StringFilter::Position::PREFIX },
|
||||||
|
OperatorDef { "!starts_with_cs ", false, true, StringFilter::Position::PREFIX },
|
||||||
|
OperatorDef { "starts_with_ci ", true, false, StringFilter::Position::PREFIX },
|
||||||
|
OperatorDef { "!starts_with_ci ", true, true, StringFilter::Position::PREFIX },
|
||||||
|
|
||||||
|
OperatorDef { "eq_cs ", false, false, StringFilter::Position::FULL },
|
||||||
|
OperatorDef { "!eq_cs ", false, true, StringFilter::Position::FULL },
|
||||||
|
OperatorDef { "eq_ci ", true, false, StringFilter::Position::FULL },
|
||||||
|
OperatorDef { "!eq_ci ", true, true, StringFilter::Position::FULL },
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a string operator and its second operand and convert it to a
|
* Parse a string operator and its second operand and convert it to a
|
||||||
* #StringFilter.
|
* #StringFilter.
|
||||||
|
@ -199,6 +232,17 @@ ExpectQuoted(const char *&s)
|
||||||
static StringFilter
|
static StringFilter
|
||||||
ParseStringFilter(const char *&s, bool fold_case)
|
ParseStringFilter(const char *&s, bool fold_case)
|
||||||
{
|
{
|
||||||
|
for (auto& op: operators) {
|
||||||
|
if (auto after_prefix = StringAfterPrefixIgnoreCase(s, op.prefix)) {
|
||||||
|
s = StripLeft(after_prefix);
|
||||||
|
return StringFilter(
|
||||||
|
ExpectQuoted(s),
|
||||||
|
op.fold_case,
|
||||||
|
op.position,
|
||||||
|
op.negated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (auto after_contains = StringAfterPrefixIgnoreCase(s, "contains ")) {
|
if (auto after_contains = StringAfterPrefixIgnoreCase(s, "contains ")) {
|
||||||
s = StripLeft(after_contains);
|
s = StripLeft(after_contains);
|
||||||
auto value = ExpectQuoted(s);
|
auto value = ExpectQuoted(s);
|
||||||
|
|
Loading…
Reference in New Issue