1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
|
// SPDX-FileCopyrightText: 2023-2024, Alejandro Colomar <alx@kernel.org>
// SPDX-License-Identifier: BSD-3-Clause
#ifndef SHADOW_INCLUDE_LIB_ADDS_H_
#define SHADOW_INCLUDE_LIB_ADDS_H_
#include <config.h>
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include "search/sort/qsort.h"
#include "sizeof.h"
#define addsl(a, b, ...) \
({ \
long addend_[] = {a, b, __VA_ARGS__}; \
\
addslN(NITEMS(addend_), addend_); \
})
inline long addsl2(long a, long b);
inline long addslN(size_t n, long addend[n]);
inline long
addsl2(long a, long b)
{
if (a > 0 && b > LONG_MAX - a) {
errno = EOVERFLOW;
return LONG_MAX;
}
if (a < 0 && b < LONG_MIN - a) {
errno = EOVERFLOW;
return LONG_MIN;
}
return a + b;
}
inline long
addslN(size_t n, long addend[n])
{
int e;
if (n == 0) {
errno = EDOM;
return 0;
}
e = errno;
while (n > 1) {
QSORT(addend, n);
errno = 0;
addend[0] = addsl2(addend[0], addend[--n]);
if (errno == EOVERFLOW)
return addend[0];
}
errno = e;
return addend[0];
}
#endif // include guard
|