1.1 --- a/razor.c Wed Sep 19 17:23:53 2007 -0400
1.2 +++ b/razor.c Wed Sep 19 23:02:31 2007 -0400
1.3 @@ -10,6 +10,7 @@
1.4 #include <unistd.h>
1.5 #include <fcntl.h>
1.6 #include <errno.h>
1.7 +#include <ctype.h>
1.8
1.9 #include "razor.h"
1.10
1.11 @@ -555,6 +556,44 @@
1.12 }
1.13
1.14 static int
1.15 +versioncmp(const char *s1, const char *s2)
1.16 +{
1.17 + const char *p1, *p2;
1.18 + long n1, n2;
1.19 + int res;
1.20 +
1.21 + n1 = strtol(s1, (char **) &p1, 0);
1.22 + n2 = strtol(s2, (char **) &p2, 0);
1.23 +
1.24 + /* Epoch; if one but not the other has an epoch set, default
1.25 + * the epoch-less version to 0. */
1.26 + res = (*p1 == ':') - (*p2 == ':');
1.27 + if (res < 0) {
1.28 + n1 = 0;
1.29 + p1 = s1;
1.30 + p2++;
1.31 + } else if (res > 0) {
1.32 + p1++;
1.33 + n2 = 0;
1.34 + p2 = s2;
1.35 + }
1.36 +
1.37 + if (n1 != n2)
1.38 + return n1 - n2;
1.39 + while (*p1 && *p2) {
1.40 + if (*p1 != *p2)
1.41 + return *p1 - *p2;
1.42 + p1++;
1.43 + p2++;
1.44 + if (isdigit(*p1) && isdigit(*p2))
1.45 + return versioncmp(p1, p2);
1.46 + }
1.47 +
1.48 + return *p1 - *p2;
1.49 +}
1.50 +
1.51 +
1.52 +static int
1.53 compare_packages(const void *p1, const void *p2, void *data)
1.54 {
1.55 const struct razor_package *pkg1 = p1, *pkg2 = p2;
1.56 @@ -562,7 +601,7 @@
1.57 char *pool = set->string_pool.data;
1.58
1.59 if (pkg1->name == pkg2->name)
1.60 - return strcmp(&pool[pkg1->version], &pool[pkg2->version]);
1.61 + return versioncmp(&pool[pkg1->version], &pool[pkg2->version]);
1.62 else
1.63 return strcmp(&pool[pkg1->name], &pool[pkg2->name]);
1.64 }
1.65 @@ -575,7 +614,7 @@
1.66 char *pool = set->string_pool.data;
1.67
1.68 if (prop1->name == prop2->name)
1.69 - return strcmp(&pool[prop1->version], &pool[prop2->version]);
1.70 + return versioncmp(&pool[prop1->version], &pool[prop2->version]);
1.71 else
1.72 return strcmp(&pool[prop1->name], &pool[prop2->name]);
1.73 }
1.74 @@ -846,7 +885,7 @@
1.75 pool = set->string_pool.data;
1.76 end = properties->data + properties->size;
1.77 while (property < end && strcmp(name, &pool[property->name]) == 0) {
1.78 - if (version && strcmp(version, &pool[property->version]) != 0)
1.79 + if (version && versioncmp(version, &pool[property->version]) != 0)
1.80 goto next;
1.81 r = (unsigned long *)
1.82 set->property_pool.data + property->packages;
1.83 @@ -867,20 +906,26 @@
1.84 unsigned long *u;
1.85 char *pool;
1.86
1.87 - r = set->requires.data;
1.88 p = set->provides.data;
1.89 rend = set->requires.data + set->requires.size;
1.90 pend = set->provides.data + set->provides.size;
1.91 pool = set->string_pool.data;
1.92
1.93 - while (r < rend) {
1.94 + for (r = set->requires.data; r < rend; r++) {
1.95 while (p < pend && strcmp(&pool[r->name], &pool[p->name]) > 0)
1.96 p++;
1.97 - if (p == pend || strcmp(&pool[r->name], &pool[p->name]) != 0) {
1.98 + /* If there is more than one version of a provides,
1.99 + * seek to the end for the highest version. */
1.100 + while (p + 1 < pend && p->name == (p + 1)->name)
1.101 + p++;
1.102 + if (p == pend || strcmp(&pool[r->name], &pool[p->name]) != 0 ||
1.103 + versioncmp(&pool[r->version], &pool[p->version]) > 0) {
1.104 + /* FIXME: We ignore file requires for now. */
1.105 + if (pool[r->name] == '/')
1.106 + continue;
1.107 u = array_add(unsatisfied, sizeof *u);
1.108 *u = r - (struct razor_property *) set->requires.data;
1.109 }
1.110 - r++;
1.111 }
1.112 }
1.113