Implement comparison of version strings and use where appropriate.
authorKristian H?gsberg <krh@redhat.com>
Wed Sep 19 23:02:31 2007 -0400 (2007-09-19)
changeset 3542be648b39d8
parent 34 45caae67088b
child 36 266dba01582d
Implement comparison of version strings and use where appropriate.
razor.c
     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