aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar David Leverton <levertond@googlemail.com> 2009-05-16 22:13:15 +0100
committerAvatar David Leverton <levertond@googlemail.com> 2009-05-16 22:52:24 +0100
commitfb4784f9503227fc6ba6a61b588248afa56c5acb (patch)
tree879f2956eb1a09d4b9456fb20045adb47abd653c
parent2a9170ca94302a6a8fbb6b15c5fb92e151522e72 (diff)
downloadpaludis-fb4784f9503227fc6ba6a61b588248afa56c5acb.tar.gz
paludis-fb4784f9503227fc6ba6a61b588248afa56c5acb.tar.xz
Change the way we handle float-like version comparison
-rw-r--r--paludis/version_spec.cc87
-rw-r--r--paludis/version_spec.se1
2 files changed, 40 insertions, 48 deletions
diff --git a/paludis/version_spec.cc b/paludis/version_spec.cc
index 66185e7..c9e1d5c 100644
--- a/paludis/version_spec.cc
+++ b/paludis/version_spec.cc
@@ -123,11 +123,18 @@ VersionSpec::VersionSpec(const std::string & text, const VersionSpecOptions & op
if (! parser.consume(+simple_parser::any_of("0123456789") >> number_part))
throw BadVersionSpecError(text, "Expected number part not found at offset " + stringify(parser.offset()));
- _imp->parts.push_back(make_named_values<VersionSpecComponent>(
- value_for<n::number_value>(number_part),
- value_for<n::text>(first_number ? number_part : "." + number_part),
- value_for<n::type>(vsct_number)
- ));
+ if (first_number || '0' != number_part[0])
+ _imp->parts.push_back(make_named_values<VersionSpecComponent>(
+ value_for<n::number_value>(strip_leading(number_part, "0")),
+ value_for<n::text>(first_number ? number_part : "." + number_part),
+ value_for<n::type>(vsct_number)
+ ));
+ else
+ _imp->parts.push_back(make_named_values<VersionSpecComponent>(
+ value_for<n::number_value>(number_part),
+ value_for<n::text>("." + number_part),
+ value_for<n::type>(vsct_floatlike)
+ ));
if (! parser.consume(simple_parser::exact(".")))
break;
@@ -320,7 +327,6 @@ namespace
value_for<n::text>(""),
value_for<n::type>(vsct_empty)
));
- bool first(true);
while (true)
{
const VersionSpecComponent * const p1(v1 == v1_end ? &end_part : &*v1);
@@ -350,51 +356,25 @@ namespace
else
{
- std::string p1s, p2s;
- bool length_cmp(true);
-
- /* number parts */
- if ((*p1).type() == vsct_number)
- {
- if (first)
- {
- /* first component - always as integer (leading zeroes removed) */
- first = false;
- p1s = strip_leading((*p1).number_value(), "0");
- p2s = strip_leading((*p2).number_value(), "0");
- }
- else if ((! (*p1).number_value().empty() && (*p1).number_value().at(0) == '0') ||
- (! (*p2).number_value().empty() && (*p2).number_value().at(0) == '0'))
- {
- /* leading zeroes - stringwise compare with trailing zeroes removed */
- length_cmp = false;
- p1s = strip_trailing((*p1).number_value(), "0");
- p2s = strip_trailing((*p2).number_value(), "0");
- }
- else
- {
- p1s = (*p1).number_value();
- p2s = (*p2).number_value();
- }
- }
- /* anything else than number parts */
- else
+ std::string p1s((*p1).number_value()), p2s((*p2).number_value());
+ if ((*p1).type() == vsct_floatlike)
{
- p1s = (*p1).number_value();
- p2s = (*p2).number_value();
-
- /* _suffix-scm? */
- if (p1s == "MAX" && p2s == "MAX")
- compared = 0;
- else if (p1s == "MAX")
- compared = 1;
- else if (p2s == "MAX")
- compared = -1;
+ p1s = strip_trailing(p1s, "0");
+ p2s = strip_trailing(p2s, "0");
}
+
+ /* _suffix-scm? */
+ if (p1s == "MAX" && p2s == "MAX")
+ compared = 0;
+ else if (p1s == "MAX")
+ compared = 1;
+ else if (p2s == "MAX")
+ compared = -1;
+
if (compared == -2)
{
/* common part */
- if (length_cmp)
+ if ((*p1).type() != vsct_floatlike)
{
/* length compare (integers) */
int c = p1s.size() - p2s.size();
@@ -404,6 +384,7 @@ namespace
compared = 1;
}
}
+
if (compared == -2)
{
/* stringwise compare (also for integers with the same size) */
@@ -509,7 +490,7 @@ VersionSpec::hash() const
result ^= (hh >> h_shift);
std::string r_v;
- if (! (*r).number_value().empty() && (*r).number_value().at(0) == '0')
+ if ((*r).type() == vsct_floatlike)
r_v = strip_trailing((*r).number_value(), "0");
else
r_v = (*r).number_value();
@@ -547,6 +528,16 @@ namespace
return p.type() == p_;
}
};
+
+ template <VersionSpecComponentType p_, VersionSpecComponentType q_>
+ struct IsEitherVersionSpecComponentType :
+ std::unary_function<VersionSpecComponent, bool>
+ {
+ bool operator() (const VersionSpecComponent & p) const
+ {
+ return p.type() == p_ || p.type() == q_;
+ }
+ };
}
VersionSpec
@@ -676,7 +667,7 @@ VersionSpec::bump() const
{
std::vector<VersionSpecComponent> number_parts;
std::copy(_imp->parts.begin(),
- std::find_if(_imp->parts.begin(), _imp->parts.end(), std::not1(IsVersionSpecComponentType<vsct_number>())),
+ std::find_if(_imp->parts.begin(), _imp->parts.end(), std::not1(IsEitherVersionSpecComponentType<vsct_number, vsct_floatlike>())),
std::back_inserter(number_parts));
if (number_parts.empty())
diff --git a/paludis/version_spec.se b/paludis/version_spec.se
index aca4991..89adbc4 100644
--- a/paludis/version_spec.se
+++ b/paludis/version_spec.se
@@ -14,6 +14,7 @@ make_enum_VersionSpecComponentType()
key vsct_patch "A patch part"
key vsct_trypart "A try part"
key vsct_letter "A letter (e.g. x in 1.2x)"
+ key vsct_floatlike "A number to be compared using float-like rules"
key vsct_number "A number (e.g. 1 or 2 in 1.2_pre3)"
key vsct_scm "An scm part"