libropkg: implement package version API
This commit is contained in:
57
libropkg/include/ropkg/version.h
Normal file
57
libropkg/include/ropkg/version.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef ROPKG_VERSION_H_
|
||||||
|
#define ROPKG_VERSION_H_
|
||||||
|
|
||||||
|
#include <blue/core/error.h>
|
||||||
|
#include <ropkg/misc.h>
|
||||||
|
#include <ropkg/status.h>
|
||||||
|
|
||||||
|
#define ROPKG_VERSION_UPSTREAM_DIGIT_MAX 5
|
||||||
|
|
||||||
|
struct ropkg_version;
|
||||||
|
|
||||||
|
enum ropkg_comparison_op {
|
||||||
|
ROPKG_OP_EQUAL = 0,
|
||||||
|
ROPKG_OP_NOT_EQUAL = -1,
|
||||||
|
ROPKG_OP_LESS_THAN = -2,
|
||||||
|
ROPKG_OP_LESS_EQUAL = -3,
|
||||||
|
ROPKG_OP_GREATER_THAN = 1,
|
||||||
|
ROPKG_OP_GREATER_EQUAL = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ropkg_version_release_phase {
|
||||||
|
ROPKG_VERSION_RELEASE_PHASE_ALPHA = 0,
|
||||||
|
ROPKG_VERSION_RELEASE_PHASE_BETA,
|
||||||
|
ROPKG_VERSION_RELEASE_PHASE_RC,
|
||||||
|
ROPKG_VERSION_RELEASE_PHASE_RELEASE,
|
||||||
|
};
|
||||||
|
|
||||||
|
ROPKG_API enum ropkg_status ropkg_version_create(struct ropkg_version **out);
|
||||||
|
ROPKG_API void ropkg_version_destroy(struct ropkg_version *version);
|
||||||
|
|
||||||
|
ROPKG_API void ropkg_version_set_release_phase(
|
||||||
|
struct ropkg_version *version,
|
||||||
|
enum ropkg_version_release_phase phase);
|
||||||
|
ROPKG_API void ropkg_version_set_upstream_version(
|
||||||
|
struct ropkg_version *version,
|
||||||
|
const unsigned int upstream_version[ROPKG_VERSION_UPSTREAM_DIGIT_MAX]);
|
||||||
|
ROPKG_API void ropkg_version_set_version_release_phase(
|
||||||
|
struct ropkg_version *version,
|
||||||
|
enum ropkg_version_release_phase phase,
|
||||||
|
unsigned int revision);
|
||||||
|
ROPKG_API void ropkg_version_set_package_revision(
|
||||||
|
struct ropkg_version *version,
|
||||||
|
unsigned int revision);
|
||||||
|
|
||||||
|
ROPKG_API b_result
|
||||||
|
ropkg_version_parse(struct ropkg_version *version, const char *s);
|
||||||
|
ROPKG_API size_t ropkg_version_to_string(
|
||||||
|
const struct ropkg_version *version,
|
||||||
|
char *out,
|
||||||
|
size_t max);
|
||||||
|
|
||||||
|
ROPKG_API bool ropkg_version_compare(
|
||||||
|
const struct ropkg_version *left,
|
||||||
|
const struct ropkg_version *right,
|
||||||
|
enum ropkg_comparison_op op);
|
||||||
|
|
||||||
|
#endif
|
||||||
483
libropkg/version.c
Normal file
483
libropkg/version.c
Normal file
@@ -0,0 +1,483 @@
|
|||||||
|
#include "version.h"
|
||||||
|
|
||||||
|
#include <blue/core/stringstream.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
enum ropkg_status ropkg_version_create(struct ropkg_version **out)
|
||||||
|
{
|
||||||
|
struct ropkg_version *version = malloc(sizeof *version);
|
||||||
|
if (!version) {
|
||||||
|
return ROPKG_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(version, 0x0, sizeof *version);
|
||||||
|
|
||||||
|
version->v_release_phase = ROPKG_VERSION_RELEASE_PHASE_RELEASE;
|
||||||
|
version->v_upstream_version[0] = 1;
|
||||||
|
version->v_version_release_phase = ROPKG_VERSION_RELEASE_PHASE_RELEASE;
|
||||||
|
version->v_version_release_phase_revision = 1;
|
||||||
|
version->v_package_revision = 1;
|
||||||
|
|
||||||
|
*out = version;
|
||||||
|
return ROPKG_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ropkg_version_destroy(struct ropkg_version *version)
|
||||||
|
{
|
||||||
|
free(version);
|
||||||
|
}
|
||||||
|
|
||||||
|
static b_result parse_release_phase(
|
||||||
|
const char *s,
|
||||||
|
enum ropkg_version_release_phase *out)
|
||||||
|
{
|
||||||
|
if (s[0] == 0) {
|
||||||
|
*out = ROPKG_VERSION_RELEASE_PHASE_RELEASE;
|
||||||
|
} else if (!strcmp(s, "alpha")) {
|
||||||
|
*out = ROPKG_VERSION_RELEASE_PHASE_ALPHA;
|
||||||
|
} else if (!strcmp(s, "beta")) {
|
||||||
|
*out = ROPKG_VERSION_RELEASE_PHASE_BETA;
|
||||||
|
} else {
|
||||||
|
b_result result = b_error_with_msg_template(
|
||||||
|
ROPKG_ERROR_VENDOR,
|
||||||
|
ROPKG_ERR_INVALID_VERSION_FORMAT,
|
||||||
|
ROPKG_EMSG_INVALID_RELEASE_PHASE,
|
||||||
|
B_ERROR_PARAM("phase", s));
|
||||||
|
b_error_add_submsg(
|
||||||
|
result,
|
||||||
|
B_ERROR_SUBMSG_INFO,
|
||||||
|
ROPKG_EMSG_AVAILABLE_RELEASE_PHASES);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static b_result parse_version_release_phase(
|
||||||
|
const char *s,
|
||||||
|
enum ropkg_version_release_phase *out_phase,
|
||||||
|
unsigned int *out_revision,
|
||||||
|
size_t *nr_read)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
if (*s == '\0') {
|
||||||
|
*out_phase = ROPKG_VERSION_RELEASE_PHASE_RELEASE;
|
||||||
|
*out_revision = 1;
|
||||||
|
*nr_read = i;
|
||||||
|
return B_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*s == '~') {
|
||||||
|
i++;
|
||||||
|
s++;
|
||||||
|
} else {
|
||||||
|
return b_error_with_msg(
|
||||||
|
ROPKG_ERROR_VENDOR,
|
||||||
|
ROPKG_ERR_INVALID_VERSION_FORMAT,
|
||||||
|
ROPKG_EMSG_INVALID_VERSION_RELEASE_PHASE_UNKNOWN_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
char temp[64];
|
||||||
|
size_t z = 0;
|
||||||
|
|
||||||
|
while (*s && isalpha(*s) && z < sizeof temp - 1) {
|
||||||
|
temp[z++] = tolower(*s);
|
||||||
|
temp[z] = 0;
|
||||||
|
i++;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strcmp(temp, "alpha")) {
|
||||||
|
*out_phase = ROPKG_VERSION_RELEASE_PHASE_ALPHA;
|
||||||
|
} else if (!strcmp(temp, "beta")) {
|
||||||
|
*out_phase = ROPKG_VERSION_RELEASE_PHASE_BETA;
|
||||||
|
} else if (!strcmp(temp, "rc")) {
|
||||||
|
*out_phase = ROPKG_VERSION_RELEASE_PHASE_RC;
|
||||||
|
} else {
|
||||||
|
b_result result = b_error_with_msg_template(
|
||||||
|
ROPKG_ERROR_VENDOR,
|
||||||
|
ROPKG_ERR_INVALID_VERSION_FORMAT,
|
||||||
|
ROPKG_EMSG_INVALID_VERSION_RELEASE_PHASE,
|
||||||
|
B_ERROR_PARAM("phase", temp));
|
||||||
|
b_error_add_submsg(
|
||||||
|
result,
|
||||||
|
B_ERROR_SUBMSG_INFO,
|
||||||
|
ROPKG_EMSG_AVAILABLE_VERSION_RELEASE_PHASES);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
z = 0;
|
||||||
|
while (*s && isdigit(*s)) {
|
||||||
|
temp[z++] = *s;
|
||||||
|
temp[z] = 0;
|
||||||
|
i++;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (z > 0) {
|
||||||
|
char *ep;
|
||||||
|
*out_revision = strtoul(temp, &ep, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
*nr_read = i;
|
||||||
|
return B_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static b_result parse_package_revision(
|
||||||
|
const char *s,
|
||||||
|
unsigned int *out_revision,
|
||||||
|
size_t *nr_read)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
if (*s == '\0') {
|
||||||
|
*out_revision = 1;
|
||||||
|
*nr_read = i;
|
||||||
|
return B_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*s == '-') {
|
||||||
|
i++;
|
||||||
|
s++;
|
||||||
|
} else {
|
||||||
|
return b_error_with_msg(
|
||||||
|
ROPKG_ERROR_VENDOR,
|
||||||
|
ROPKG_ERR_INVALID_VERSION_FORMAT,
|
||||||
|
ROPKG_EMSG_INVALID_PACKAGE_REVISION_UNKNOWN_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
char temp[64];
|
||||||
|
size_t z = 0;
|
||||||
|
|
||||||
|
while (*s && isdigit(*s) && z < sizeof temp - 1) {
|
||||||
|
temp[z++] = *s;
|
||||||
|
temp[z] = 0;
|
||||||
|
i++;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *ep;
|
||||||
|
*out_revision = strtoul(temp, &ep, 10);
|
||||||
|
|
||||||
|
*nr_read = i;
|
||||||
|
return B_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static b_result parse_upstream_version(
|
||||||
|
const char *s,
|
||||||
|
unsigned int out[ROPKG_VERSION_UPSTREAM_DIGIT_MAX],
|
||||||
|
size_t *nr_read)
|
||||||
|
{
|
||||||
|
if (!isdigit(*s)) {
|
||||||
|
return b_error_with_msg(
|
||||||
|
ROPKG_ERROR_VENDOR,
|
||||||
|
ROPKG_ERR_INVALID_VERSION_FORMAT,
|
||||||
|
ROPKG_EMSG_INVALID_UPSTREAM_VERSION_UNKNOWN_START);
|
||||||
|
}
|
||||||
|
|
||||||
|
char temp[64];
|
||||||
|
size_t i = 0;
|
||||||
|
unsigned int nr_temp = 0;
|
||||||
|
unsigned int nr_digits = 0;
|
||||||
|
char last = 0;
|
||||||
|
char *ep;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
last = s[i];
|
||||||
|
|
||||||
|
if (isdigit(s[i])) {
|
||||||
|
temp[nr_temp++] = s[i];
|
||||||
|
temp[nr_temp] = 0;
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s[i] == '.') {
|
||||||
|
if (nr_temp == 0) {
|
||||||
|
return b_error_with_msg(
|
||||||
|
ROPKG_ERROR_VENDOR,
|
||||||
|
ROPKG_ERR_INVALID_VERSION_FORMAT,
|
||||||
|
ROPKG_EMSG_INVALID_UPSTREAM_VERSION_TWO_DOTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nr_digits >= ROPKG_VERSION_UPSTREAM_DIGIT_MAX - 1) {
|
||||||
|
return b_error_with_msg(
|
||||||
|
ROPKG_ERROR_VENDOR,
|
||||||
|
ROPKG_ERR_INVALID_VERSION_FORMAT,
|
||||||
|
ROPKG_EMSG_INVALID_UPSTREAM_VERSION_TOO_MANY_NUMBERS);
|
||||||
|
}
|
||||||
|
|
||||||
|
out[nr_digits] = strtoul(temp, &ep, 10);
|
||||||
|
nr_digits++;
|
||||||
|
nr_temp = 0;
|
||||||
|
i++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nr_temp == 0) {
|
||||||
|
return b_error_with_msg(
|
||||||
|
ROPKG_ERROR_VENDOR,
|
||||||
|
ROPKG_ERR_INVALID_VERSION_FORMAT,
|
||||||
|
ROPKG_EMSG_INVALID_UPSTREAM_VERSION_END_DOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
out[nr_digits] = strtoul(temp, &ep, 10);
|
||||||
|
nr_digits++;
|
||||||
|
nr_temp = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*nr_read = i;
|
||||||
|
return B_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
b_result ropkg_version_parse(struct ropkg_version *version, const char *s)
|
||||||
|
{
|
||||||
|
enum ropkg_version_release_phase release_phase
|
||||||
|
= ROPKG_VERSION_RELEASE_PHASE_RELEASE;
|
||||||
|
unsigned int upstream_version[ROPKG_VERSION_UPSTREAM_DIGIT_MAX]
|
||||||
|
= {0, 0, 0, 0, 0};
|
||||||
|
enum ropkg_version_release_phase version_release_phase
|
||||||
|
= ROPKG_VERSION_RELEASE_PHASE_RELEASE;
|
||||||
|
unsigned int version_release_phase_revision = 1;
|
||||||
|
unsigned int package_revision = 1;
|
||||||
|
|
||||||
|
b_result result = B_RESULT_SUCCESS;
|
||||||
|
|
||||||
|
char temp[64] = {0};
|
||||||
|
size_t z = 0;
|
||||||
|
|
||||||
|
while (*s && !isdigit(*s) && z < sizeof temp - 1) {
|
||||||
|
temp[z] = tolower(*s);
|
||||||
|
z++;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = parse_release_phase(temp, &release_phase);
|
||||||
|
if (b_result_is_error(result)) {
|
||||||
|
return b_result_propagate(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t nr_read = 0;
|
||||||
|
result = parse_upstream_version(s, upstream_version, &nr_read);
|
||||||
|
if (b_result_is_error(result)) {
|
||||||
|
return b_result_propagate(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
s += nr_read;
|
||||||
|
if (*s == '~' || *s == 0) {
|
||||||
|
result = parse_version_release_phase(
|
||||||
|
s,
|
||||||
|
&version_release_phase,
|
||||||
|
&version_release_phase_revision,
|
||||||
|
&nr_read);
|
||||||
|
|
||||||
|
s += nr_read;
|
||||||
|
if (b_result_is_error(result)) {
|
||||||
|
return b_result_propagate(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*s == '-' || *s == 0) {
|
||||||
|
result = parse_package_revision(s, &package_revision, &nr_read);
|
||||||
|
|
||||||
|
s += nr_read;
|
||||||
|
if (b_result_is_error(result)) {
|
||||||
|
return b_result_propagate(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*s != 0) {
|
||||||
|
return b_error_with_msg(
|
||||||
|
ROPKG_ERROR_VENDOR,
|
||||||
|
ROPKG_ERR_INVALID_VERSION_FORMAT,
|
||||||
|
ROPKG_EMSG_INVALID_VERSION_UNKNOWN_END);
|
||||||
|
}
|
||||||
|
|
||||||
|
version->v_release_phase = release_phase;
|
||||||
|
memcpy(version->v_upstream_version,
|
||||||
|
upstream_version,
|
||||||
|
sizeof upstream_version);
|
||||||
|
version->v_version_release_phase = version_release_phase;
|
||||||
|
version->v_version_release_phase_revision
|
||||||
|
= version_release_phase_revision;
|
||||||
|
version->v_package_revision = package_revision;
|
||||||
|
|
||||||
|
return B_RESULT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ropkg_version_set_release_phase(
|
||||||
|
struct ropkg_version *version,
|
||||||
|
enum ropkg_version_release_phase phase)
|
||||||
|
{
|
||||||
|
if (phase == ROPKG_VERSION_RELEASE_PHASE_RC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
version->v_release_phase = phase;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ropkg_version_set_upstream_version(
|
||||||
|
struct ropkg_version *version,
|
||||||
|
const unsigned int upstream_version[ROPKG_VERSION_UPSTREAM_DIGIT_MAX])
|
||||||
|
{
|
||||||
|
memcpy(version->v_upstream_version,
|
||||||
|
upstream_version,
|
||||||
|
sizeof version->v_upstream_version);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ropkg_version_set_version_release_phase(
|
||||||
|
struct ropkg_version *version,
|
||||||
|
enum ropkg_version_release_phase phase,
|
||||||
|
unsigned int revision)
|
||||||
|
{
|
||||||
|
version->v_version_release_phase = phase;
|
||||||
|
|
||||||
|
if (phase == ROPKG_VERSION_RELEASE_PHASE_RELEASE) {
|
||||||
|
version->v_version_release_phase_revision = 1;
|
||||||
|
} else {
|
||||||
|
version->v_version_release_phase_revision = revision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ropkg_version_set_package_revision(
|
||||||
|
struct ropkg_version *version,
|
||||||
|
unsigned int revision)
|
||||||
|
{
|
||||||
|
version->v_package_revision = revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *release_phase_to_string(
|
||||||
|
enum ropkg_version_release_phase phase)
|
||||||
|
{
|
||||||
|
switch (phase) {
|
||||||
|
case ROPKG_VERSION_RELEASE_PHASE_ALPHA:
|
||||||
|
return "alpha";
|
||||||
|
case ROPKG_VERSION_RELEASE_PHASE_BETA:
|
||||||
|
return "beta";
|
||||||
|
case ROPKG_VERSION_RELEASE_PHASE_RC:
|
||||||
|
return "rc";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned int upstream_version_length(
|
||||||
|
const unsigned int version[ROPKG_VERSION_UPSTREAM_DIGIT_MAX])
|
||||||
|
{
|
||||||
|
unsigned int length = 0;
|
||||||
|
for (unsigned int i = 0; i < ROPKG_VERSION_UPSTREAM_DIGIT_MAX; i++) {
|
||||||
|
if (version[i] != 0) {
|
||||||
|
length = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (length < 2) {
|
||||||
|
length = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ropkg_version_to_string(
|
||||||
|
const struct ropkg_version *version,
|
||||||
|
char *out,
|
||||||
|
size_t max)
|
||||||
|
{
|
||||||
|
b_stringstream str;
|
||||||
|
b_stringstream_begin(&str, out, max);
|
||||||
|
|
||||||
|
b_stringstream_add(
|
||||||
|
&str,
|
||||||
|
release_phase_to_string(version->v_release_phase));
|
||||||
|
|
||||||
|
unsigned int version_length
|
||||||
|
= upstream_version_length(version->v_upstream_version);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < version_length; i++) {
|
||||||
|
if (i > 0) {
|
||||||
|
b_stringstream_add(&str, ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
b_stringstream_addf(&str, "%u", version->v_upstream_version[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version->v_version_release_phase
|
||||||
|
!= ROPKG_VERSION_RELEASE_PHASE_RELEASE) {
|
||||||
|
b_stringstream_addf(
|
||||||
|
&str,
|
||||||
|
"~%s",
|
||||||
|
release_phase_to_string(
|
||||||
|
version->v_version_release_phase));
|
||||||
|
|
||||||
|
if (version->v_version_release_phase_revision > 1
|
||||||
|
|| version->v_version_release_phase
|
||||||
|
== ROPKG_VERSION_RELEASE_PHASE_RC) {
|
||||||
|
b_stringstream_addf(
|
||||||
|
&str,
|
||||||
|
"%u",
|
||||||
|
version->v_version_release_phase_revision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version->v_package_revision > 1) {
|
||||||
|
b_stringstream_addf(&str, "-%u", version->v_package_revision);
|
||||||
|
}
|
||||||
|
|
||||||
|
b_stringstream_end(&str);
|
||||||
|
return b_stringstream_get_length(&str);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int version_compare(
|
||||||
|
const struct ropkg_version *left,
|
||||||
|
const struct ropkg_version *right)
|
||||||
|
{
|
||||||
|
#define COMPARE(left, right, item) \
|
||||||
|
do { \
|
||||||
|
if ((left)->item < (right)->item) \
|
||||||
|
return -1; \
|
||||||
|
else if ((left)->item > (right)->item) \
|
||||||
|
return 1; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
COMPARE(left, right, v_release_phase);
|
||||||
|
|
||||||
|
for (int i = 0; i < ROPKG_VERSION_UPSTREAM_DIGIT_MAX; i++) {
|
||||||
|
COMPARE(left, right, v_upstream_version[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
COMPARE(left, right, v_version_release_phase);
|
||||||
|
COMPARE(left, right, v_version_release_phase_revision);
|
||||||
|
COMPARE(left, right, v_package_revision);
|
||||||
|
|
||||||
|
#undef COMPARE
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ropkg_version_compare(
|
||||||
|
const struct ropkg_version *left,
|
||||||
|
const struct ropkg_version *right,
|
||||||
|
enum ropkg_comparison_op op)
|
||||||
|
{
|
||||||
|
int result = version_compare(left, right);
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case ROPKG_OP_EQUAL:
|
||||||
|
return result == 0;
|
||||||
|
case ROPKG_OP_NOT_EQUAL:
|
||||||
|
return result != 0;
|
||||||
|
case ROPKG_OP_LESS_THAN:
|
||||||
|
return result < 0;
|
||||||
|
case ROPKG_OP_LESS_EQUAL:
|
||||||
|
return result <= 0;
|
||||||
|
case ROPKG_OP_GREATER_THAN:
|
||||||
|
return result > 0;
|
||||||
|
case ROPKG_OP_GREATER_EQUAL:
|
||||||
|
return result >= 0;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
libropkg/version.h
Normal file
17
libropkg/version.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef _VERSION_H_
|
||||||
|
#define _VERSION_H_
|
||||||
|
|
||||||
|
#include <ropkg/version.h>
|
||||||
|
|
||||||
|
struct ropkg_version {
|
||||||
|
enum ropkg_version_release_phase v_release_phase;
|
||||||
|
|
||||||
|
unsigned int v_upstream_version[ROPKG_VERSION_UPSTREAM_DIGIT_MAX];
|
||||||
|
|
||||||
|
enum ropkg_version_release_phase v_version_release_phase;
|
||||||
|
unsigned int v_version_release_phase_revision;
|
||||||
|
|
||||||
|
unsigned int v_package_revision;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user