Re: How does rpm command compare 2 rpm files' version?



On Sat, 31 Dec 2005 03:01:37 +0100, Klein <hubo.obuh@xxxxxxxxx> wrote:

Here is my understanding. Is it correct?

As we know, RPM version is like this format:
   a.rpm <Epoch1> <{Segment1.1}.{Segment1.2}.{Segment1.3}.{Segment1.4}....> <Release1>
   b.rpm <Epoch2> <{Segment2.1}.{Segment2.2}.{Segment2.3}.{Segment2.4}....> <Release2>

The segments do not need to be separated by non-alphanumerics. E.g., "34.6pre.a" has the segments "34", "6", "pre", and "a".

It should also be noted that multiple separators are equivalent to a single
one, e.g., "1.2" is the same as "1..2".

1. Epoch is an int32, so it is easy to decide which one is newer

I haven't checked if the epoch is compared as an unsigned integer :)

2. If epoch is the same, RPM uses the following rules to make decision:
        A) All the non-digit and non-alphabet characters are the basic
separator of comparation phase. In each phase, rpm compares the digit
part and alphabet part one by one. If any part can make the decision,
the comparation finished.

It compares the first segments, then the second segments, etc. If at some point one segment is alpha and the other is numeric, the numeric one is "larger", i.e., "newer". If one string runs out of segments before the other, the string with more segments is "newer".

        B) During each part comparation
            a) From left to right, if a.rpm has a part of digits, but
b.rpm doesn't this part, a.rpm is newer

Yes. A segment of digits compares "newer" than a segment of alphabetics.

b) Digit part compares as integer

Yes. Note: as unbounded size integers. Leading zeroes are skipped, then the length of the remaining strings are compared, longer strings are larger/newer. Equal-length strings are compared "alphabetically", so 9 is larger than 1. The result should be equivalent to a numeric compare of infinite size numbers.

c) Alphabet part compares as string

Yes, as a string of bytes. The function strcmp() is used. I have not checked the function used to determine if a char is alphabetic, I just assume that only Ascii A-Z, a-z are alphabetic. Then 8-byte letters will not happen. You will have uppercase 'Z' is smaller/older than lowercase 'a'.

            d) In current comparation phase if the a.rpm last part is
alphabet, but b.rpm doesn't have this part, the first part of next
phase of b.rpm will compare vs. the a.rpm current part. (So "1.0a.1"
"1.0.a.1" are the same version!!)

Yes or no.... if I understand your language.

  "the a.rpm last part is alphabet, but b.rpm doesn't have this part"

is not very clear.  I presume that "part" is the same thing as
what we have called "segment" above, and "last part" is rather current
segment, i.e., after segments a.x and b.x have been found equal for
x=1,...,n-1, then "a.rpm last part" is segment a.n.  "Does not have
this part" could mean that b has just n-1 segments or that b.n is not
aphabetic.

  "First part of next phase"

is a tad confusing. My normal mode of reading is to look for an
interpretation that seems to make sense, but carring that mode too far,
I end up saying "yes" to almost everything.

If, after comparing segments 1..n-1, which have all been found equal,
segment a.n is alphabetic, and b.n exists and is numeric, then b is
larger/newer. If b.n does not exist, a is larger/newer.

There is a comment in the code that seems to be a leftover from
an earlier state of the code, where there was a final strcmp of the
string, to catch differences in separators. (No, I have not seen
such an earlier state, it's just my hypothesis about the comment.)
The code at that point just returns zero ("equal") if there are no
more segments in any of the strings.

However, note that "1.0a.1." is larger/newer than "1.0.a.1" because there are
characters left in "1.0a.1." after the end of "1.0.a.1" has been reached.
This is equivalent to saying that "1.0a.1." has a fifth segment, a zero-length
alpha segment at the end, while "1.0.a.1" has just four segments.  Notice that
zero-length segments are not posible except at the end.

3. Release compares like the version part.

Yes.

Disclaimer: I have not tested the above inequalities. I base my statements on
reading the code. I'm no computer, I do make incorrect inferences from time
to time.

-Enrique
.