aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-02-22 18:45:58 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2006-02-22 18:45:58 +0000
commit8348f66dd71856d463f6cf1c760c1bb68897d428 (patch)
tree0927c692334bfb03b0957028f59d75ad8befd5c2
parent5612f7e103dfa9d174649cad59adc05f408bb660 (diff)
downloadpaludis-8348f66dd71856d463f6cf1c760c1bb68897d428.tar.gz
paludis-8348f66dd71856d463f6cf1c760c1bb68897d428.tar.xz
Make match sequence less pointless
-rw-r--r--paludis/match_sequence.cc44
-rw-r--r--paludis/match_sequence.hh3
-rw-r--r--paludis/match_sequence_TEST.cc13
3 files changed, 47 insertions, 13 deletions
diff --git a/paludis/match_sequence.cc b/paludis/match_sequence.cc
index 3197c7b..00e8c40 100644
--- a/paludis/match_sequence.cc
+++ b/paludis/match_sequence.cc
@@ -45,10 +45,7 @@ struct MatchRule::StringRule :
std::string::size_type
local_match(const std::string & t, std::string::size_type p) const
{
- if (p + s.length() <= t.length())
- return (0 == t.compare(p, s.length(), s)) ? s.length() : std::string::npos;
- else
- return std::string::npos;
+ return (0 == t.compare(p, s.length(), s)) ? s.length() : std::string::npos;
}
};
@@ -67,9 +64,32 @@ struct MatchRule::SequenceRule :
local_match(const std::string & t, std::string::size_type p) const
{
std::string::size_type l1(r1._rule->local_match(t, p)), l2(0);
+ if (std::string::npos == l1)
+ return l1;
+
+ l2 = r2._rule->local_match(t, p + l1);
+ return (std::string::npos == l2) ? l2 : l1 + l2;
+ }
+};
+
+struct MatchRule::EitherRule :
+ MatchRule::Rule
+{
+ const MatchRule r1, r2;
+
+ EitherRule(const MatchRule & rr1, const MatchRule & rr2) :
+ r1(rr1),
+ r2(rr2)
+ {
+ }
+
+ std::string::size_type
+ local_match(const std::string & t, std::string::size_type p) const
+ {
+ std::string::size_type l1(r1._rule->local_match(t, p));
if (std::string::npos != l1)
- l2 = r2._rule->local_match(t, p + l1);
- return (std::string::npos == l2) ? l2 : p + l1 + l2;
+ return l1;
+ return r2._rule->local_match(t, p);
}
};
@@ -88,13 +108,9 @@ struct MatchRule::ZeroOrMoreRule :
{
std::string::size_type result(p), q;
while (std::string::npos != ((q = r1._rule->local_match(t, result))))
- {
- if (0 == q)
- break;
result += q;
- }
- return result;
+ return result - p;
}
};
@@ -140,6 +156,12 @@ MatchRule::operator>> (const MatchRule & other) const
}
const MatchRule
+MatchRule::operator|| (const MatchRule & other) const
+{
+ return MatchRule(CountedPtr<Rule>(new EitherRule(*this, other)));
+}
+
+const MatchRule
MatchRule::operator* () const
{
return MatchRule(CountedPtr<Rule>(new ZeroOrMoreRule(*this)));
diff --git a/paludis/match_sequence.hh b/paludis/match_sequence.hh
index b679930..fa462d6 100644
--- a/paludis/match_sequence.hh
+++ b/paludis/match_sequence.hh
@@ -32,6 +32,7 @@ namespace paludis
struct StringRule;
struct SequenceRule;
struct ZeroOrMoreRule;
+ struct EitherRule;
struct EolRule;
CountedPtr<Rule> _rule;
@@ -51,6 +52,8 @@ namespace paludis
const MatchRule operator>> (const MatchRule &) const;
+ const MatchRule operator|| (const MatchRule &) const;
+
const MatchRule operator* () const;
bool match(const std::string &) const;
diff --git a/paludis/match_sequence_TEST.cc b/paludis/match_sequence_TEST.cc
index d0d8f7f..179fd29 100644
--- a/paludis/match_sequence_TEST.cc
+++ b/paludis/match_sequence_TEST.cc
@@ -34,17 +34,26 @@ namespace test_case
{
typedef MatchRule X;
- X r1(*X("\t") >> X("econf") >> X::eol());
+ TEST_CHECK(X::eol().match(""));
+ TEST_CHECK(! X::eol().match("a"));
+
+ X r1(*X("\t") >> X("econf") >> *X(" ") >> (X::eol() || (X("||") >> *X(" ") >> X("die"))));
TEST_CHECK(r1.match("econf"));
TEST_CHECK(r1.match("\teconf"));
TEST_CHECK(r1.match("\t\teconf"));
+ TEST_CHECK(r1.match("\t\teconf "));
TEST_CHECK(! r1.match(" econf"));
TEST_CHECK(! r1.match("\tecong"));
TEST_CHECK(! r1.match("\t"));
+ TEST_CHECK(! r1.match("econfmoo"));
TEST_CHECK(! r1.match("econf moo"));
- X r2(*X("\t") >> X("econf") >> *X(" ") >> X("||") >> *X(" ") >> X("die"));
+ TEST_CHECK(r1.match("\teconf || die"));
+ TEST_CHECK(r1.match("\teconf || die \"moo\""));
+ TEST_CHECK(! r1.match("\teconf ||"));
+ TEST_CHECK(r1.match("\teconf || die"));
+ TEST_CHECK(! r1.match("\texonf || die"));
}
} test_match_rule;
}