forked from ariadne/pkgconf
pkg: add pkg_compare_version()
parent
e8a944f41d
commit
7e26842094
109
pkg.c
109
pkg.c
|
@ -33,6 +33,115 @@ pkg_find(const char *name)
|
|||
return parse_file(locbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
* pkg_compare_version(a, b)
|
||||
*
|
||||
* compare versions using RPM version comparison rules as described in the LSB.
|
||||
*/
|
||||
int
|
||||
pkg_compare_version(const char *a, const char *b)
|
||||
{
|
||||
char oldch1, oldch2;
|
||||
char *str1, *str2;
|
||||
char *one, *two;
|
||||
int ret;
|
||||
bool isnum;
|
||||
|
||||
/* optimization: if version matches then it's the same version. */
|
||||
if (!strcasecmp(a, b))
|
||||
return 0;
|
||||
|
||||
str1 = LOCAL_COPY(a);
|
||||
str2 = LOCAL_COPY(b);
|
||||
|
||||
one = str1;
|
||||
two = str2;
|
||||
|
||||
while (*one && *two)
|
||||
{
|
||||
while (*one && !isalnum(*one))
|
||||
one++;
|
||||
while (*two && !isalnum(*two))
|
||||
one++;
|
||||
|
||||
if (!(*one && *two))
|
||||
break;
|
||||
|
||||
str1 = one;
|
||||
str2 = two;
|
||||
|
||||
if (isdigit(*str1))
|
||||
{
|
||||
while (*str1 && isdigit(*str1))
|
||||
str1++;
|
||||
|
||||
while (*str2 && isdigit(*str2))
|
||||
str2++;
|
||||
|
||||
isnum = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*str1 && isalpha(*str1))
|
||||
str1++;
|
||||
|
||||
while (*str2 && isalpha(*str2))
|
||||
str2++;
|
||||
|
||||
isnum = false;
|
||||
}
|
||||
|
||||
oldch1 = *str1;
|
||||
oldch2 = *str2;
|
||||
|
||||
*str1 = '\0';
|
||||
*str2 = '\0';
|
||||
|
||||
if (one == str1)
|
||||
return -1;
|
||||
|
||||
if (two == str2)
|
||||
return (isnum ? 1 : -1);
|
||||
|
||||
if (isnum)
|
||||
{
|
||||
int onelen, twolen;
|
||||
|
||||
while (*one == '0')
|
||||
one++;
|
||||
|
||||
while (*two == '0')
|
||||
two++;
|
||||
|
||||
onelen = strlen(one);
|
||||
twolen = strlen(two);
|
||||
|
||||
if (one > two)
|
||||
return 1;
|
||||
else if (two > one)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = strcmp(one, two);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*str1 = oldch1;
|
||||
*str2 = oldch2;
|
||||
|
||||
one = str1;
|
||||
two = str2;
|
||||
}
|
||||
|
||||
if ((!*one) && (!*two))
|
||||
return 0;
|
||||
|
||||
if (!*one)
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* pkg_verify_graph(root, depth)
|
||||
*
|
||||
|
|
4
pkg.h
4
pkg.h
|
@ -54,6 +54,9 @@ typedef struct tuple_ pkg_tuple_t;
|
|||
#define foreach_list_entry(head, value) \
|
||||
for ((value) = (head); (value) != NULL; (value) = (value)->next)
|
||||
|
||||
#define LOCAL_COPY(a) \
|
||||
strcpy(alloca(strlen(a) + 1), a)
|
||||
|
||||
struct dependency_ {
|
||||
struct dependency_ *prev, *next;
|
||||
|
||||
|
@ -88,6 +91,7 @@ struct pkg_ {
|
|||
pkg_t *pkg_find(const char *name);
|
||||
void pkg_traverse(pkg_t *root, void (*pkg_traverse_func)(pkg_t *package, void *data), void *data, int maxdepth);
|
||||
void pkg_verify_graph(pkg_t *root, int depth);
|
||||
int pkg_compare_version(const char *a, const char *b);
|
||||
|
||||
/* parse.c */
|
||||
pkg_t *parse_file(const char *path);
|
||||
|
|
Loading…
Reference in New Issue