238 lines
4.4 KiB
C
238 lines
4.4 KiB
C
#include "../commands.h"
|
|
#include "ropkg/version.h"
|
|
|
|
#include <blue/cmd.h>
|
|
#include <stdio.h>
|
|
|
|
enum {
|
|
OPT_VERBOSE,
|
|
ARG_VERSION_LEFT,
|
|
ARG_OPERATOR,
|
|
ARG_VERSION_RIGHT,
|
|
};
|
|
|
|
static enum ropkg_status comparison_op_from_string(
|
|
const char *s,
|
|
enum ropkg_comparison_op *out)
|
|
{
|
|
if (!strcmp(s, "==") || !strcmp(s, "eq")) {
|
|
*out = ROPKG_OP_EQUAL;
|
|
} else if (!strcmp(s, "<") || !strcmp(s, "lt")) {
|
|
*out = ROPKG_OP_LESS_THAN;
|
|
} else if (!strcmp(s, "<=") || !strcmp(s, "le")) {
|
|
*out = ROPKG_OP_LESS_EQUAL;
|
|
} else if (!strcmp(s, ">") || !strcmp(s, "gt")) {
|
|
*out = ROPKG_OP_GREATER_THAN;
|
|
} else if (!strcmp(s, ">=") || !strcmp(s, "ge")) {
|
|
*out = ROPKG_OP_GREATER_EQUAL;
|
|
} else if (!strcmp(s, "!=") || !strcmp(s, "ne")) {
|
|
*out = ROPKG_OP_NOT_EQUAL;
|
|
} else {
|
|
return ROPKG_ERR_INVALID_ARGUMENT;
|
|
}
|
|
|
|
return ROPKG_SUCCESS;
|
|
}
|
|
|
|
static int compare_version(
|
|
const b_command *self,
|
|
const b_arglist *opt,
|
|
const b_array *args)
|
|
{
|
|
int ret = -1;
|
|
bool verbose = false;
|
|
|
|
struct ropkg_version *left = NULL, *right = NULL;
|
|
enum ropkg_status status = ropkg_version_create(&left);
|
|
if (!B_OK(status)) {
|
|
goto end;
|
|
}
|
|
|
|
status = ropkg_version_create(&right);
|
|
if (!B_OK(status)) {
|
|
goto end;
|
|
}
|
|
|
|
const char *left_string = NULL, *right_string = NULL, *op_string = NULL;
|
|
b_arglist_get_string(
|
|
opt,
|
|
B_COMMAND_INVALID_ID,
|
|
ARG_VERSION_LEFT,
|
|
0,
|
|
&left_string);
|
|
b_arglist_get_string(
|
|
opt,
|
|
B_COMMAND_INVALID_ID,
|
|
ARG_VERSION_RIGHT,
|
|
0,
|
|
&right_string);
|
|
b_arglist_get_string(
|
|
opt,
|
|
B_COMMAND_INVALID_ID,
|
|
ARG_OPERATOR,
|
|
0,
|
|
&op_string);
|
|
verbose = b_arglist_get_count(opt, OPT_VERBOSE, B_COMMAND_INVALID_ID)
|
|
> 0;
|
|
|
|
if (!left_string) {
|
|
b_arglist_report_missing_args(
|
|
opt,
|
|
B_COMMAND_INVALID_ID,
|
|
ARG_VERSION_LEFT,
|
|
0);
|
|
goto end;
|
|
}
|
|
|
|
if (!right_string) {
|
|
b_arglist_report_missing_args(
|
|
opt,
|
|
B_COMMAND_INVALID_ID,
|
|
ARG_VERSION_RIGHT,
|
|
0);
|
|
goto end;
|
|
}
|
|
|
|
if (!op_string) {
|
|
b_arglist_report_missing_args(
|
|
opt,
|
|
B_COMMAND_INVALID_ID,
|
|
ARG_OPERATOR,
|
|
0);
|
|
goto end;
|
|
}
|
|
|
|
b_result result = ropkg_version_parse(left, left_string);
|
|
if (b_result_is_error(result)) {
|
|
b_throw(result);
|
|
goto end;
|
|
}
|
|
|
|
result = ropkg_version_parse(right, right_string);
|
|
if (b_result_is_error(result)) {
|
|
b_throw(result);
|
|
goto end;
|
|
}
|
|
|
|
enum ropkg_comparison_op op;
|
|
status = comparison_op_from_string(op_string, &op);
|
|
if (status != ROPKG_SUCCESS) {
|
|
b_arglist_report_invalid_arg_value(
|
|
opt,
|
|
B_COMMAND_INVALID_ID,
|
|
ARG_OPERATOR,
|
|
op_string);
|
|
goto end;
|
|
}
|
|
|
|
bool comparison_result = ropkg_version_compare(left, right, op);
|
|
ret = comparison_result ? 0 : 1;
|
|
|
|
if (verbose) {
|
|
char temp[128];
|
|
ropkg_version_to_string(left, temp, sizeof temp);
|
|
|
|
printf("%s ", temp);
|
|
|
|
switch (op) {
|
|
case ROPKG_OP_EQUAL:
|
|
printf("== ");
|
|
break;
|
|
case ROPKG_OP_NOT_EQUAL:
|
|
printf("!= ");
|
|
break;
|
|
case ROPKG_OP_LESS_THAN:
|
|
printf("< ");
|
|
break;
|
|
case ROPKG_OP_LESS_EQUAL:
|
|
printf("<= ");
|
|
break;
|
|
case ROPKG_OP_GREATER_THAN:
|
|
printf("> ");
|
|
break;
|
|
case ROPKG_OP_GREATER_EQUAL:
|
|
printf(">= ");
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
ropkg_version_to_string(right, temp, sizeof temp);
|
|
printf("%s -> %s\n",
|
|
temp,
|
|
comparison_result ? "true" : "false");
|
|
}
|
|
|
|
end:
|
|
if (left) {
|
|
ropkg_version_destroy(left);
|
|
}
|
|
|
|
if (right) {
|
|
ropkg_version_destroy(right);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
B_COMMAND(CMD_VERSION_COMPARE, CMD_VERSION)
|
|
{
|
|
B_COMMAND_NAME("compare");
|
|
B_COMMAND_SHORT_NAME('C');
|
|
B_COMMAND_DESC("compare two package version identifiers.");
|
|
B_COMMAND_FLAGS(B_COMMAND_SHOW_HELP_BY_DEFAULT);
|
|
B_COMMAND_FUNCTION(compare_version);
|
|
|
|
B_COMMAND_HELP_OPTION();
|
|
|
|
B_COMMAND_OPTION(OPT_VERBOSE)
|
|
{
|
|
B_OPTION_SHORT_NAME('v');
|
|
B_OPTION_LONG_NAME("verbose");
|
|
B_OPTION_DESC(
|
|
"print the result of the comparison to "
|
|
"standard out.");
|
|
}
|
|
|
|
B_COMMAND_ARG(ARG_VERSION_LEFT)
|
|
{
|
|
B_ARG_NAME("left-version");
|
|
B_ARG_DESC("the left-side of the comparison operation.");
|
|
B_ARG_NR_VALUES(1);
|
|
}
|
|
|
|
B_COMMAND_ARG(ARG_OPERATOR)
|
|
{
|
|
B_ARG_NAME("operator");
|
|
B_ARG_DESC("the comparison operator to use.");
|
|
B_ARG_ALLOWED_VALUES(
|
|
"==",
|
|
"!=",
|
|
"<",
|
|
"<=",
|
|
">",
|
|
">=",
|
|
"eq",
|
|
"ne",
|
|
"lt",
|
|
"le",
|
|
"gt",
|
|
"ge");
|
|
B_ARG_NR_VALUES(1);
|
|
}
|
|
|
|
B_COMMAND_ARG(ARG_VERSION_RIGHT)
|
|
{
|
|
B_ARG_NAME("right-version");
|
|
B_ARG_DESC("the right-side of the comparison operation.");
|
|
B_ARG_NR_VALUES(1);
|
|
}
|
|
|
|
B_COMMAND_USAGE()
|
|
{
|
|
B_COMMAND_USAGE_ARG(ARG_VERSION_LEFT);
|
|
B_COMMAND_USAGE_ARG(ARG_OPERATOR);
|
|
B_COMMAND_USAGE_ARG(ARG_VERSION_RIGHT);
|
|
}
|
|
}
|