summaryrefslogtreecommitdiffstats
path: root/src/mergesort.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mergesort.c')
-rw-r--r--src/mergesort.c43
1 files changed, 22 insertions, 21 deletions
diff --git a/src/mergesort.c b/src/mergesort.c
index 152b0556..5e676be1 100644
--- a/src/mergesort.c
+++ b/src/mergesort.c
@@ -2,17 +2,16 @@
* Copyright (c) 2017 Elise Lennion <elise.lennion@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
+ * it under the terms of the GNU General Public License version 2 (or any
+ * later) as published by the Free Software Foundation.
*/
-#include <stdint.h>
+#include <nft.h>
+
#include <expression.h>
#include <gmputil.h>
#include <list.h>
-static void expr_msort_value(const struct expr *expr, mpz_t value);
-
static void concat_expr_msort_value(const struct expr *expr, mpz_t value)
{
unsigned int len = 0, ilen;
@@ -28,19 +27,17 @@ static void concat_expr_msort_value(const struct expr *expr, mpz_t value)
mpz_import_data(value, data, BYTEORDER_HOST_ENDIAN, len);
}
-static void expr_msort_value(const struct expr *expr, mpz_t value)
+static mpz_srcptr expr_msort_value(const struct expr *expr, mpz_t value)
{
switch (expr->etype) {
case EXPR_SET_ELEM:
- expr_msort_value(expr->key, value);
- break;
+ return expr_msort_value(expr->key, value);
case EXPR_BINOP:
case EXPR_MAPPING:
- expr_msort_value(expr->left, value);
- break;
+ case EXPR_RANGE:
+ return expr_msort_value(expr->left, value);
case EXPR_VALUE:
- mpz_set(value, expr->value);
- break;
+ return expr->value;
case EXPR_CONCAT:
concat_expr_msort_value(expr, value);
break;
@@ -51,25 +48,29 @@ static void expr_msort_value(const struct expr *expr, mpz_t value)
default:
BUG("Unknown expression %s\n", expr_name(expr));
}
+ return value;
}
static int expr_msort_cmp(const struct expr *e1, const struct expr *e2)
{
- mpz_t value1, value2;
+ mpz_srcptr value1;
+ mpz_srcptr value2;
+ mpz_t value1_tmp;
+ mpz_t value2_tmp;
int ret;
- mpz_init(value1);
- mpz_init(value2);
- expr_msort_value(e1, value1);
- expr_msort_value(e2, value2);
+ mpz_init(value1_tmp);
+ mpz_init(value2_tmp);
+ value1 = expr_msort_value(e1, value1_tmp);
+ value2 = expr_msort_value(e2, value2_tmp);
ret = mpz_cmp(value1, value2);
- mpz_clear(value1);
- mpz_clear(value2);
+ mpz_clear(value1_tmp);
+ mpz_clear(value2_tmp);
return ret;
}
-static void list_splice_sorted(struct list_head *list, struct list_head *head)
+void list_splice_sorted(struct list_head *list, struct list_head *head)
{
struct list_head *h = head->next;
struct list_head *l = list->next;
@@ -77,7 +78,7 @@ static void list_splice_sorted(struct list_head *list, struct list_head *head)
while (l != list) {
if (h == head ||
expr_msort_cmp(list_entry(l, typeof(struct expr), list),
- list_entry(h, typeof(struct expr), list)) < 0) {
+ list_entry(h, typeof(struct expr), list)) <= 0) {
l = l->next;
list_add_tail(l->prev, h);
continue;