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);
|
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)
|
* 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) \
|
#define foreach_list_entry(head, value) \
|
||||||
for ((value) = (head); (value) != NULL; (value) = (value)->next)
|
for ((value) = (head); (value) != NULL; (value) = (value)->next)
|
||||||
|
|
||||||
|
#define LOCAL_COPY(a) \
|
||||||
|
strcpy(alloca(strlen(a) + 1), a)
|
||||||
|
|
||||||
struct dependency_ {
|
struct dependency_ {
|
||||||
struct dependency_ *prev, *next;
|
struct dependency_ *prev, *next;
|
||||||
|
|
||||||
|
@ -88,6 +91,7 @@ struct pkg_ {
|
||||||
pkg_t *pkg_find(const char *name);
|
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_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);
|
void pkg_verify_graph(pkg_t *root, int depth);
|
||||||
|
int pkg_compare_version(const char *a, const char *b);
|
||||||
|
|
||||||
/* parse.c */
|
/* parse.c */
|
||||||
pkg_t *parse_file(const char *path);
|
pkg_t *parse_file(const char *path);
|
||||||
|
|
Loading…
Reference in New Issue