Merge pull request #9789 from filbranden/cmp1

Add new CMP(a, b) macro
This commit is contained in:
Lennart Poettering 2018-08-07 09:39:26 +02:00 committed by GitHub
commit 2ed7449fcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 170 additions and 166 deletions

View File

@ -71,7 +71,7 @@ void trivial_hash_func(const void *p, struct siphash *state) {
}
int trivial_compare_func(const void *a, const void *b) {
return a < b ? -1 : (a > b ? 1 : 0);
return CMP(a, b);
}
const struct hash_ops trivial_hash_ops = {
@ -87,7 +87,7 @@ int uint64_compare_func(const void *_a, const void *_b) {
uint64_t a, b;
a = *(const uint64_t*) _a;
b = *(const uint64_t*) _b;
return a < b ? -1 : (a > b ? 1 : 0);
return CMP(a, b);
}
const struct hash_ops uint64_hash_ops = {
@ -104,7 +104,7 @@ int devt_compare_func(const void *_a, const void *_b) {
dev_t a, b;
a = *(const dev_t*) _a;
b = *(const dev_t*) _b;
return a < b ? -1 : (a > b ? 1 : 0);
return CMP(a, b);
}
const struct hash_ops devt_hash_ops = {

View File

@ -581,9 +581,11 @@ void in_addr_data_hash_func(const void *p, struct siphash *state) {
int in_addr_data_compare_func(const void *a, const void *b) {
const struct in_addr_data *x = a, *y = b;
int r;
if (x->family != y->family)
return x->family - y->family;
r = CMP(x->family, y->family);
if (r != 0)
return r;
return memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
}

View File

@ -7,7 +7,7 @@
#include <sys/sysmacros.h>
#include <sys/types.h>
#define _printf_(a,b) __attribute__ ((format (printf, a, b)))
#define _printf_(a, b) __attribute__ ((format (printf, a, b)))
#ifdef __clang__
# define _alloc_(...)
#else
@ -22,8 +22,8 @@
#define _packed_ __attribute__ ((packed))
#define _malloc_ __attribute__ ((malloc))
#define _weak_ __attribute__ ((weak))
#define _likely_(x) (__builtin_expect(!!(x),1))
#define _unlikely_(x) (__builtin_expect(!!(x),0))
#define _likely_(x) (__builtin_expect(!!(x), 1))
#define _unlikely_(x) (__builtin_expect(!!(x), 0))
#define _public_ __attribute__ ((visibility("default")))
#define _hidden_ __attribute__ ((visibility("hidden")))
#define _weakref_(x) __attribute__((weakref(#x)))
@ -146,10 +146,10 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
# define VOID_0 ((void*)0)
#endif
#define ELEMENTSOF(x) \
__extension__ (__builtin_choose_expr( \
#define ELEMENTSOF(x) \
(__builtin_choose_expr( \
!__builtin_types_compatible_p(typeof(x), typeof(&*(x))), \
sizeof(x)/sizeof((x)[0]), \
sizeof(x)/sizeof((x)[0]), \
VOID_0))
/*
@ -167,23 +167,23 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
*/
#define container_of(ptr, type, member) __container_of(UNIQ, (ptr), type, member)
#define __container_of(uniq, ptr, type, member) \
__extension__ ({ \
({ \
const typeof( ((type*)0)->member ) *UNIQ_T(A, uniq) = (ptr); \
(type*)( (char *)UNIQ_T(A, uniq) - offsetof(type,member) ); \
(type*)( (char *)UNIQ_T(A, uniq) - offsetof(type, member) ); \
})
#undef MAX
#define MAX(a, b) __MAX(UNIQ, (a), UNIQ, (b))
#define __MAX(aq, a, bq, b) \
__extension__ ({ \
({ \
const typeof(a) UNIQ_T(A, aq) = (a); \
const typeof(b) UNIQ_T(B, bq) = (b); \
UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \
UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \
})
/* evaluates to (void) if _A or _B are not constant or of different types */
#define CONST_MAX(_A, _B) \
__extension__ (__builtin_choose_expr( \
(__builtin_choose_expr( \
__builtin_constant_p(_A) && \
__builtin_constant_p(_B) && \
__builtin_types_compatible_p(typeof(_A), typeof(_B)), \
@ -193,47 +193,56 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
/* takes two types and returns the size of the larger one */
#define MAXSIZE(A, B) (sizeof(union _packed_ { typeof(A) a; typeof(B) b; }))
#define MAX3(x,y,z) \
__extension__ ({ \
const typeof(x) _c = MAX(x,y); \
MAX(_c, z); \
})
#define MAX3(x, y, z) \
({ \
const typeof(x) _c = MAX(x, y); \
MAX(_c, z); \
})
#undef MIN
#define MIN(a, b) __MIN(UNIQ, (a), UNIQ, (b))
#define __MIN(aq, a, bq, b) \
__extension__ ({ \
({ \
const typeof(a) UNIQ_T(A, aq) = (a); \
const typeof(b) UNIQ_T(B, bq) = (b); \
UNIQ_T(A,aq) < UNIQ_T(B,bq) ? UNIQ_T(A,aq) : UNIQ_T(B,bq); \
UNIQ_T(A, aq) < UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \
})
#define MIN3(x,y,z) \
__extension__ ({ \
const typeof(x) _c = MIN(x,y); \
MIN(_c, z); \
})
#define MIN3(x, y, z) \
({ \
const typeof(x) _c = MIN(x, y); \
MIN(_c, z); \
})
#define LESS_BY(a, b) __LESS_BY(UNIQ, (a), UNIQ, (b))
#define __LESS_BY(aq, a, bq, b) \
__extension__ ({ \
({ \
const typeof(a) UNIQ_T(A, aq) = (a); \
const typeof(b) UNIQ_T(B, bq) = (b); \
UNIQ_T(A,aq) > UNIQ_T(B,bq) ? UNIQ_T(A,aq) - UNIQ_T(B,bq) : 0; \
UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) - UNIQ_T(B, bq) : 0; \
})
#define CMP(a, b) __CMP(UNIQ, (a), UNIQ, (b))
#define __CMP(aq, a, bq, b) \
({ \
const typeof(a) UNIQ_T(A, aq) = (a); \
const typeof(b) UNIQ_T(B, bq) = (b); \
UNIQ_T(A, aq) < UNIQ_T(B, bq) ? -1 : \
UNIQ_T(A, aq) > UNIQ_T(B, bq) ? 1 : 0; \
})
#undef CLAMP
#define CLAMP(x, low, high) __CLAMP(UNIQ, (x), UNIQ, (low), UNIQ, (high))
#define __CLAMP(xq, x, lowq, low, highq, high) \
__extension__ ({ \
const typeof(x) UNIQ_T(X,xq) = (x); \
const typeof(low) UNIQ_T(LOW,lowq) = (low); \
const typeof(high) UNIQ_T(HIGH,highq) = (high); \
UNIQ_T(X,xq) > UNIQ_T(HIGH,highq) ? \
UNIQ_T(HIGH,highq) : \
UNIQ_T(X,xq) < UNIQ_T(LOW,lowq) ? \
UNIQ_T(LOW,lowq) : \
UNIQ_T(X,xq); \
({ \
const typeof(x) UNIQ_T(X, xq) = (x); \
const typeof(low) UNIQ_T(LOW, lowq) = (low); \
const typeof(high) UNIQ_T(HIGH, highq) = (high); \
UNIQ_T(X, xq) > UNIQ_T(HIGH, highq) ? \
UNIQ_T(HIGH, highq) : \
UNIQ_T(X, xq) < UNIQ_T(LOW, lowq) ? \
UNIQ_T(LOW, lowq) : \
UNIQ_T(X, xq); \
})
/* [(x + y - 1) / y] suffers from an integer overflow, even though the
@ -241,7 +250,7 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) {
* [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the
* quotient and the remainder, so both should be equally fast. */
#define DIV_ROUND_UP(_x, _y) \
__extension__ ({ \
({ \
const typeof(_x) __x = (_x); \
const typeof(_y) __y = (_y); \
(__x / __y + !!(__x % __y)); \

View File

@ -1108,12 +1108,7 @@ int pid_compare_func(const void *a, const void *b) {
const pid_t *p = a, *q = b;
/* Suitable for usage in qsort() */
if (*p < *q)
return -1;
if (*p > *q)
return 1;
return 0;
return CMP(*p, *q);
}
int ioprio_parse_priority(const char *s, int *ret) {

View File

@ -484,11 +484,11 @@ static void peer_address_hash_func(const void *p, struct siphash *state) {
static int peer_address_compare_func(const void *a, const void *b) {
const SocketPeer *x = a, *y = b;
int r;
if (x->peer.sa.sa_family < y->peer.sa.sa_family)
return -1;
if (x->peer.sa.sa_family > y->peer.sa.sa_family)
return 1;
r = CMP(x->peer.sa.sa_family, y->peer.sa.sa_family);
if (r != 0)
return r;
switch(x->peer.sa.sa_family) {
case AF_INET:

View File

@ -59,12 +59,12 @@ static void catalog_hash_func(const void *p, struct siphash *state) {
static int catalog_compare_func(const void *a, const void *b) {
const CatalogItem *i = a, *j = b;
unsigned k;
int r;
for (k = 0; k < ELEMENTSOF(j->id.bytes); k++) {
if (i->id.bytes[k] < j->id.bytes[k])
return -1;
if (i->id.bytes[k] > j->id.bytes[k])
return 1;
r = CMP(i->id.bytes[k], j->id.bytes[k]);
if (r != 0)
return r;
}
return strcmp(i->language, j->language);

View File

@ -26,22 +26,15 @@ static int lldp_neighbor_id_compare_func(const void *a, const void *b) {
if (r != 0)
return r;
if (x->chassis_id_size < y->chassis_id_size)
return -1;
if (x->chassis_id_size > y->chassis_id_size)
return 1;
r = CMP(x->chassis_id_size, y->chassis_id_size);
if (r != 0)
return r;
r = memcmp(x->port_id, y->port_id, MIN(x->port_id_size, y->port_id_size));
if (r != 0)
return r;
if (x->port_id_size < y->port_id_size)
return -1;
if (x->port_id_size > y->port_id_size)
return 1;
return 0;
return CMP(x->port_id_size, y->port_id_size);
}
const struct hash_ops lldp_neighbor_id_hash_ops = {
@ -52,13 +45,7 @@ const struct hash_ops lldp_neighbor_id_hash_ops = {
int lldp_neighbor_prioq_compare_func(const void *a, const void *b) {
const sd_lldp_neighbor *x = a, *y = b;
if (x->until < y->until)
return -1;
if (x->until > y->until)
return 1;
return 0;
return CMP(x->until, y->until);
}
_public_ sd_lldp_neighbor *sd_lldp_neighbor_ref(sd_lldp_neighbor *n) {

View File

@ -125,6 +125,7 @@ void client_id_hash_func(const void *p, struct siphash *state) {
int client_id_compare_func(const void *_a, const void *_b) {
const DHCPClientId *a, *b;
int r;
a = _a;
b = _b;
@ -132,8 +133,9 @@ int client_id_compare_func(const void *_a, const void *_b) {
assert(!a->length || a->data);
assert(!b->length || b->data);
if (a->length != b->length)
return a->length < b->length ? -1 : 1;
r = CMP(a->length, b->length);
if (r != 0)
return r;
return memcmp(a->data, b->data, a->length);
}

View File

@ -144,19 +144,18 @@ static void address_hash_func(const void *b, struct siphash *state) {
static int address_compare_func(const void *c1, const void *c2) {
const Address *a1 = c1, *a2 = c2;
int r;
if (a1->family < a2->family)
return -1;
if (a1->family > a2->family)
return 1;
r = CMP(a1->family, a2->family);
if (r != 0)
return r;
switch (a1->family) {
/* use the same notion of equality as the kernel does */
case AF_INET:
if (a1->prefixlen < a2->prefixlen)
return -1;
if (a1->prefixlen > a2->prefixlen)
return 1;
r = CMP(a1->prefixlen, a2->prefixlen);
if (r != 0)
return r;
/* compare the peer prefixes */
if (a1->prefixlen != 0) {
@ -174,10 +173,9 @@ static int address_compare_func(const void *c1, const void *c2) {
else
b2 = be32toh(a2->in_addr.in.s_addr) >> (32 - a1->prefixlen);
if (b1 < b2)
return -1;
if (b1 > b2)
return 1;
r = CMP(b1, b2);
if (r != 0)
return r;
}
_fallthrough_;

View File

@ -36,12 +36,7 @@ static int network_config_compare_func(const void *a, const void *b) {
if (r != 0)
return r;
if (x->line < y->line)
return -1;
if (x->line > y->line)
return 1;
return 0;
return CMP(x->line, y->line);
}
const struct hash_ops network_config_hash_ops = {

View File

@ -164,34 +164,30 @@ static void route_hash_func(const void *b, struct siphash *state) {
static int route_compare_func(const void *_a, const void *_b) {
const Route *a = _a, *b = _b;
int r;
if (a->family < b->family)
return -1;
if (a->family > b->family)
return 1;
r = CMP(a->family, b->family);
if (r != 0)
return r;
switch (a->family) {
case AF_INET:
case AF_INET6:
if (a->dst_prefixlen < b->dst_prefixlen)
return -1;
if (a->dst_prefixlen > b->dst_prefixlen)
return 1;
r = CMP(a->dst_prefixlen, b->dst_prefixlen);
if (r != 0)
return r;
if (a->tos < b->tos)
return -1;
if (a->tos > b->tos)
return 1;
r = CMP(a->tos, b->tos);
if (r != 0)
return r;
if (a->priority < b->priority)
return -1;
if (a->priority > b->priority)
return 1;
r = CMP(a->priority, b->priority);
if (r != 0)
return r;
if (a->table < b->table)
return -1;
if (a->table > b->table)
return 1;
r = CMP(a->table, b->table);
if (r != 0)
return r;
return memcmp(&a->dst, &b->dst, FAMILY_ADDRESS_SIZE(a->family));
default:

View File

@ -92,38 +92,32 @@ static int routing_policy_rule_compare_func(const void *_a, const void *_b) {
const RoutingPolicyRule *a = _a, *b = _b;
int r;
if (a->family < b->family)
return -1;
if (a->family > b->family)
return 1;
r = CMP(a->family, b->family);
if (r != 0)
return r;
switch (a->family) {
case AF_INET:
case AF_INET6:
if (a->from_prefixlen < b->from_prefixlen)
return -1;
if (a->from_prefixlen > b->from_prefixlen)
return 1;
r = CMP(a->from_prefixlen, b->from_prefixlen);
if (r != 0)
return r;
if (a->to_prefixlen < b->to_prefixlen)
return -1;
if (a->to_prefixlen > b->to_prefixlen)
return 1;
r = CMP(a->to_prefixlen, b->to_prefixlen);
if (r != 0)
return r;
if (a->tos < b->tos)
return -1;
if (a->tos > b->tos)
return 1;
r = CMP(a->tos, b->tos);
if (r != 0)
return r;
if (a->fwmask < b->fwmark)
return -1;
if (a->fwmask > b->fwmark)
return 1;
r = CMP(a->fwmask, b->fwmask);
if (r != 0)
return r;
if (a->table < b->table)
return -1;
if (a->table > b->table)
return 1;
r = CMP(a->table, b->table);
if (r != 0)
return r;
r = strcmp_ptr(a->iif, b->iif);
if (!r)

View File

@ -228,11 +228,7 @@ void dns_cache_prune(DnsCache *c) {
static int dns_cache_item_prioq_compare_func(const void *a, const void *b) {
const DnsCacheItem *x = a, *y = b;
if (x->until < y->until)
return -1;
if (x->until > y->until)
return 1;
return 0;
return CMP(x->until, y->until);
}
static int dns_cache_init(DnsCache *c) {

View File

@ -2339,11 +2339,11 @@ static void dns_packet_hash_func(const void *p, struct siphash *state) {
static int dns_packet_compare_func(const void *a, const void *b) {
const DnsPacket *x = a, *y = b;
int r;
if (x->size < y->size)
return -1;
if (x->size > y->size)
return 1;
r = CMP(x->size, y->size);
if (r != 0)
return r;
return memcmp(DNS_PACKET_DATA((DnsPacket*) x), DNS_PACKET_DATA((DnsPacket*) y), x->size);
}

View File

@ -300,15 +300,13 @@ static int dns_resource_key_compare_func(const void *a, const void *b) {
if (ret != 0)
return ret;
if (x->type < y->type)
return -1;
if (x->type > y->type)
return 1;
ret = CMP(x->type, y->type);
if (ret != 0)
return ret;
if (x->class < y->class)
return -1;
if (x->class > y->class)
return 1;
ret = CMP(x->class, y->class);
if (ret != 0)
return ret;
return 0;
}
@ -1515,10 +1513,9 @@ static int dns_resource_record_compare_func(const void *a, const void *b) {
if (dns_resource_record_equal(x, y))
return 0;
/* This is a bit dirty, we don't implement proper ordering, but
* the hashtable doesn't need ordering anyway, hence we don't
* care. */
return x < y ? -1 : 1;
/* We still use CMP() here, even though don't implement proper
* ordering, since the hashtable doesn't need ordering anyway. */
return CMP(x, y);
}
const struct hash_ops dns_resource_record_hash_ops = {

View File

@ -624,19 +624,17 @@ static int dns_server_compare_func(const void *a, const void *b) {
const DnsServer *x = a, *y = b;
int r;
if (x->family < y->family)
return -1;
if (x->family > y->family)
return 1;
r = CMP(x->family, y->family);
if (r != 0)
return r;
r = memcmp(&x->address, &y->address, FAMILY_ADDRESS_SIZE(x->family));
if (r != 0)
return r;
if (x->ifindex < y->ifindex)
return -1;
if (x->ifindex > y->ifindex)
return 1;
r = CMP(x->ifindex, y->ifindex);
if (r != 0)
return r;
return 0;
}

View File

@ -503,7 +503,7 @@ int dns_name_compare_func(const void *a, const void *b) {
r = dns_label_unescape_suffix(a, &x, la, sizeof(la));
q = dns_label_unescape_suffix(b, &y, lb, sizeof(lb));
if (r < 0 || q < 0)
return r - q;
return CMP(r, q);
r = ascii_strcasecmp_nn(la, r, lb, q);
if (r != 0)

View File

@ -53,6 +53,12 @@ static void test_max(void) {
.a = CONST_MAX(10, 100),
};
int d = 0;
unsigned long x = 12345;
unsigned long y = 54321;
const char str[] = "a_string_constant";
const unsigned long long arr[] = {9999ULL, 10ULL, 0ULL, 3000ULL, 2000ULL, 1000ULL, 100ULL, 9999999ULL};
void *p = (void *)str;
void *q = (void *)&str[16];
assert_cc(sizeof(val1.b) == sizeof(int) * 100);
@ -80,6 +86,35 @@ static void test_max(void) {
assert_se(LESS_BY(4, 8) == 0);
assert_se(LESS_BY(16, LESS_BY(8, 4)) == 12);
assert_se(LESS_BY(4, LESS_BY(8, 4)) == 0);
assert_se(CMP(-5, 5) == -1);
assert_se(CMP(5, -5) == 1);
assert_se(CMP(5, 5) == 0);
assert_se(CMP(x, y) == -1);
assert_se(CMP(y, x) == 1);
assert_se(CMP(x, x) == 0);
assert_se(CMP(y, y) == 0);
assert_se(CMP(UINT64_MAX, 0L) == 1);
assert_se(CMP(0L, UINT64_MAX) == -1);
assert_se(CMP(UINT64_MAX, UINT64_MAX) == 0);
assert_se(CMP(INT64_MIN, INT64_MAX) == -1);
assert_se(CMP(INT64_MAX, INT64_MIN) == 1);
assert_se(CMP(INT64_MAX, INT64_MAX) == 0);
assert_se(CMP(INT64_MIN, INT64_MIN) == 0);
assert_se(CMP(INT64_MAX, 0L) == 1);
assert_se(CMP(0L, INT64_MIN) == 1);
assert_se(CMP(INT64_MIN, 0L) == -1);
assert_se(CMP(0L, INT64_MAX) == -1);
assert_se(CMP(&str[2], &str[7]) == -1);
assert_se(CMP(&str[2], &str[2]) == 0);
assert_se(CMP(&str[7], (const char *)str) == 1);
assert_se(CMP(str[2], str[7]) == 1);
assert_se(CMP(str[7], *str) == 1);
assert_se(CMP((const unsigned long long *)arr, &arr[3]) == -1);
assert_se(CMP(*arr, arr[3]) == 1);
assert_se(CMP(p, q) == -1);
assert_se(CMP(q, p) == 1);
assert_se(CMP(p, p) == 0);
assert_se(CMP(q, q) == 0);
assert_se(CLAMP(-5, 0, 1) == 0);
assert_se(CLAMP(5, 0, 1) == 1);
assert_se(CLAMP(5, -10, 1) == 1);