macro: Introduce ABS() macro and use it in header files

abs() requires including the entirety of stdlib.h just for a single
trivial function. Let's introduce the ABS() macro and use it in header
files instead so we can get rid of stdlib.h transitive includes in header
files in a later commit.
This commit is contained in:
Daan De Meyer
2025-05-06 10:14:26 +02:00
parent c94f6ab1bf
commit 40a6cdc29e
9 changed files with 23 additions and 15 deletions
+3 -2
View File
@@ -2,9 +2,10 @@
#pragma once
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "macro.h"
/*
* MAX_ERRNO is defined as 4095 in linux/err.h
* We use the same value here.
@@ -16,7 +17,7 @@ static inline const char* errno_to_name(int id) {
if (id == 0) /* To stay in line with our own impl */
return NULL;
return strerrorname_np(abs(id));
return strerrorname_np(ABS(id));
}
#else
const char* errno_to_name(int id);
+4 -6
View File
@@ -2,7 +2,6 @@
#pragma once
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include "assert-util.h"
@@ -16,7 +15,7 @@
* https://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks
*
* Note that we use the GNU variant of strerror_r() here. */
#define STRERROR(errnum) strerror_r(abs(errnum), (char[ERRNO_BUF_LEN]){}, ERRNO_BUF_LEN)
#define STRERROR(errnum) strerror_r(ABS(errnum), (char[ERRNO_BUF_LEN]){}, ERRNO_BUF_LEN)
/* A helper to print an error message or message for functions that return 0 on EOF.
* Note that we can't use ({ … }) to define a temporary variable, so errnum is
@@ -41,7 +40,7 @@ static inline void _reset_errno_(int *saved_errno) {
#define LOCAL_ERRNO(value) \
PROTECT_ERRNO; \
errno = abs(value)
errno = ABS(value)
static inline int negative_errno(void) {
/* This helper should be used to shut up gcc if you know 'errno' is
@@ -93,15 +92,14 @@ static inline int errno_or_else(int fallback) {
if (errno > 0)
return -errno;
return -abs(fallback);
return -ABS(fallback);
}
/* abs(3) says: Trying to take the absolute value of the most negative integer is not defined. */
#define _DEFINE_ABS_WRAPPER(name) \
static inline bool ERRNO_IS_##name(intmax_t r) { \
if (r == INTMAX_MIN) \
return false; \
return ERRNO_IS_NEG_##name(-imaxabs(r)); \
return ERRNO_IS_NEG_##name(-ABS(r)); \
}
assert_cc(INT_MAX <= INTMAX_MAX);
+2 -2
View File
@@ -33,9 +33,9 @@ typedef enum LogTarget{
#define LOG_NULL (LOG_EMERG - 1)
assert_cc(LOG_NULL == -1);
#define SYNTHETIC_ERRNO(num) (abs(num) | (1 << 30))
#define SYNTHETIC_ERRNO(num) (ABS(num) | (1 << 30))
#define IS_SYNTHETIC_ERRNO(val) (((val) >> 30) == 1)
#define ERRNO_VALUE(val) (abs(val) & ~(1 << 30))
#define ERRNO_VALUE(val) (ABS(val) & ~(1 << 30))
/* The callback function to be invoked when syntax warnings are seen
* in the unit files. */
+1 -1
View File
@@ -105,7 +105,7 @@ static inline size_t GREEDY_ALLOC_ROUND_UP(size_t l) {
#define return_with_errno(r, err) \
do { \
errno = abs(err); \
errno = ABS(err); \
return r; \
} while (false)
@@ -6,6 +6,8 @@
#include <stdbool.h>
#include <stddef.h>
#include "macro.h"
/* crypt_dump() internal indentation magic */
#define CRYPT_DUMP_LINE_SEP "\n\t "
@@ -15,7 +17,7 @@
#define crypt_log(cd, ...) crypt_logf(cd, CRYPT_LOG_NORMAL, __VA_ARGS__)
#define crypt_log_full_errno(cd, e, lvl, ...) ({ \
int _e = abs(e), _s = errno; \
int _e = ABS(e), _s = errno; \
errno = _e; \
crypt_logf(cd, lvl, __VA_ARGS__); \
errno = _s; \
+7
View File
@@ -176,6 +176,13 @@
UNIQ_T(A, aq) > UNIQ_T(B, bq) ? UNIQ_T(A, aq) : UNIQ_T(B, bq); \
})
#define ABS(a) __ABS(UNIQ, (a))
#define __ABS(aq, a) \
({ \
const typeof(a) UNIQ_T(A, aq) = (a); \
UNIQ_T(A, aq) < 0 ? -UNIQ_T(A, aq) : UNIQ_T(A, aq); \
})
#define IS_UNSIGNED_INTEGER_TYPE(type) \
(__builtin_types_compatible_p(typeof(type), unsigned char) || \
__builtin_types_compatible_p(typeof(type), unsigned short) || \
+1 -1
View File
@@ -149,7 +149,7 @@ int journal_add_matchf(sd_journal *j, const char *format, ...) _printf_(2, 3);
/* All errors that we might encounter while extracting a field that are not real errors,
* but only mean that the field is too large or we don't support the compression. */
static inline bool JOURNAL_ERRNO_IS_UNAVAILABLE_FIELD(int r) {
return IN_SET(abs(r),
return IN_SET(ABS(r),
ENOBUFS, /* Field or decompressed field too large */
E2BIG, /* Field too large for pointer width */
EPROTONOSUPPORT); /* Unsupported compression */
+1 -1
View File
@@ -10,5 +10,5 @@ int plymouth_send_raw(const void *raw, size_t size, int flags);
int plymouth_send_msg(const char *text, bool pause_spinner);
static inline bool ERRNO_IS_NO_PLYMOUTH(int r) {
return IN_SET(abs(r), EAGAIN, ENOENT) || ERRNO_IS_DISCONNECT(r);
return IN_SET(ABS(r), EAGAIN, ENOENT) || ERRNO_IS_DISCONNECT(r);
}
+1 -1
View File
@@ -40,7 +40,7 @@ static inline void log_set_assert_return_is_criticalp(bool *p) {
#define ASSERT_RETURN_EXPECTED_SE(expr) ASSERT_RETURN_EXPECTED(assert_se(expr));
static inline bool manager_errno_skip_test(int r) {
return IN_SET(abs(r),
return IN_SET(ABS(r),
EPERM,
EACCES,
EADDRINUSE,