RE: problem comparing capability version strings

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Ok, thanks for the info!  I recently discovered that I can use rpmdsSingle()
to manufacture an rpmds object, and then compare rpmds objects using
rpmdsCompare().  My code looks roughly like this (with some error checking
omitted to keep it short):
 
struct DepInfo
 { rpmTag tag;
   const char* n;  // name
   const char* evr;  // epoch version release
   int_32 flags;
 };
 
int compare(struct DepInfo* d1, struct DepInfo* d2)
 { rpmds ds1, ds2;
   int result;
 
   ds1 = rpmdsSingle(d1->tag, d1->n, d1->evr, d1->flags);
   ds2 = rpmdsSingle(d2->tag, d2->n, d2->evr, d2->flags);
   ds1 = rpmdsInit(ds1); rpmdsNext(ds1);
   ds2 = rpmdsInit(ds2); rpmdsNext(ds2);
   result = rpmdsCompare(ds1, ds2);
   rpmdsFree(ds1); rpmdsFree(ds2);
   return result;
 }
 
This type of approach seems to work for me.  I guess rpmdsCompare()
is probably calling rpmvercmp() internally to compare pieces of the
capability version strings.
 
Dave
 
> The problem is likely conceptual.
>
> rpmvercmp compares strings according to rpm's comparison rules.
>
> However rpm uses the triple {Epoch,Version,Release} to determine newer.
>
> That means that rpmvercmp is called multiple times (Epoch is always a digit string,
> strcmp on zero-padded strings is used for infinite precision, but the comparison
> rules for digit-only strings do not need to use rpmvercmp). rpmvervmp is definitely
> called for each of Version and Release.
>
> Your example is comparing a Version "2.14.0" with a Version-Release "2.14.0-9.el5".
>
> That needs to be done by splitting on the '-' in "2.14.0-9.el5" and calling rpmvercmp
> twice.
>
> You are still likely to be surprised by the results.
> 
> rpmvercmp basically tries to compare alphas with alphas, and digits with digits,
> because originally (before YYYYMMDDhhmmss digit strings were noticed to
> exceed 32 bits) compared by converting to ints.
>
> That's the sensible part.
>
> The scwewy part(s) of rpmvercmp include the following:
>    1) leading 0's are ignored. e.g. 5.000000000003 is greater than 5.2 because 3 > 2
>    2) all punctuation is ignored and treated as equivalent. so 5.2 and 5_2 are equal.
> and (finally, this is the one that you will be surprised at)
>   3) mixed mode (as in digit string compared to something other than digit string) is reversed
>   from the comparison order one would expect. But its very hard to expect a result from
>    a comparison between something and nothing, consider what happens to strcmp
>    if fed NULL or "", two forms of expressing nothing.
>
> All well known flaws, been there forever, nothing can be done without coordinating the
> change, which is bloody unlikely to happen.
>
> hth
>
> 73 de Jeff
_______________________________________________
Rpm-list mailing list
Rpm-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/rpm-list

[Index of Archives]     [RPM Ecosystem]     [Linux Kernel]     [Red Hat Install]     [PAM]     [Red Hat Watch]     [Red Hat Development]     [Red Hat]     [Gimp]     [Yosemite News]     [IETF Discussion]

  Powered by Linux