/src/systemd/src/fundamental/cleanup-fundamental.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | #pragma once |
3 | | |
4 | | #include "assert-fundamental.h" |
5 | | |
6 | | /* A wrapper for 'func' to return void. |
7 | | * Only useful when a void-returning function is required by some API. */ |
8 | | #define DEFINE_TRIVIAL_DESTRUCTOR(name, type, func) \ |
9 | | static inline void name(type *p) { \ |
10 | | func(p); \ |
11 | | } |
12 | | |
13 | | /* When func() returns the void value (NULL, -1, …) of the appropriate type */ |
14 | | #define DEFINE_TRIVIAL_CLEANUP_FUNC(type, func) \ |
15 | | static inline void func##p(type *p) { \ |
16 | | if (*p) \ |
17 | | *p = func(*p); \ |
18 | | } |
19 | | |
20 | | /* When func() doesn't return the appropriate type, set variable to empty afterwards. |
21 | | * The func() may be provided by a dynamically loaded shared library, hence add an assertion. */ |
22 | | #define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(type, func, empty) \ |
23 | | static inline void func##p(type *p) { \ |
24 | | if (*p != (empty)) { \ |
25 | | DISABLE_WARNING_ADDRESS; \ |
26 | | assert(func); \ |
27 | | REENABLE_WARNING; \ |
28 | | func(*p); \ |
29 | | *p = (empty); \ |
30 | | } \ |
31 | | } |
32 | | |
33 | | /* When func() doesn't return the appropriate type, and is also a macro, set variable to empty afterwards. */ |
34 | | #define DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_MACRO(type, func, empty) \ |
35 | | static inline void func##p(type *p) { \ |
36 | | if (*p != (empty)) { \ |
37 | | func(*p); \ |
38 | | *p = (empty); \ |
39 | | } \ |
40 | | } |
41 | | |
42 | | typedef void (*free_array_func_t)(void *p, size_t n); |
43 | | |
44 | | /* An automatic _cleanup_-like logic for destroy arrays (i.e. pointers + size) when leaving scope */ |
45 | | typedef struct ArrayCleanup { |
46 | | void **parray; |
47 | | size_t *pn; |
48 | | free_array_func_t pfunc; |
49 | | } ArrayCleanup; |
50 | | |
51 | 0 | static inline void array_cleanup(const ArrayCleanup *c) { |
52 | 0 | assert(c); |
53 | 0 | assert(!c->parray == !c->pn); |
54 | 0 |
|
55 | 0 | if (!c->parray) |
56 | 0 | return; |
57 | 0 |
|
58 | 0 | if (*c->parray) { |
59 | 0 | assert(c->pfunc); |
60 | 0 | c->pfunc(*c->parray, *c->pn); |
61 | 0 | *c->parray = NULL; |
62 | 0 | } |
63 | 0 |
|
64 | 0 | *c->pn = 0; |
65 | 0 | } Unexecuted instantiation: fuzz-bcd.c:array_cleanup Unexecuted instantiation: bcd.c:array_cleanup Unexecuted instantiation: efi-string.c:array_cleanup |
66 | | |
67 | | #define CLEANUP_ARRAY(array, n, func) \ |
68 | | _cleanup_(array_cleanup) _unused_ const ArrayCleanup CONCATENATE(_cleanup_array_, UNIQ) = { \ |
69 | | .parray = (void**) &(array), \ |
70 | | .pn = &(n), \ |
71 | | .pfunc = (free_array_func_t) ({ \ |
72 | | void (*_f)(typeof(array[0]) *a, size_t b) = func; \ |
73 | | _f; \ |
74 | | }), \ |
75 | | } |