Coverage Report

Created: 2026-08-08 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/freeradius-devel/util/lst.h
Line
Count
Source
1
#pragma once
2
/*
3
 *  This program is free software; you can redistribute it and/or modify
4
 *  it under the terms of the GNU General Public License as published by
5
 *  the Free Software Foundation; either version 2 of the License, or
6
 *  (at your option) any later version.
7
 *
8
 *  This program is distributed in the hope that it will be useful,
9
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 *  GNU General Public License for more details.
12
 *
13
 *  You should have received a copy of the GNU General Public License
14
 *  along with this program; if not, write to the Free Software
15
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16
 */
17
18
/** Structures and prototypes for leftmost skeleton trees (LSTs)
19
 *
20
 * @file src/lib/util/lst.h
21
 *
22
 * @copyright 2021  Network RADIUS SAS (legal@networkradius.com)
23
 */
24
RCSIDH(lst_h, "$Id: 820bdb0f6c461937d236d6fa304d698e7f37eb5b $")
25
26
#ifdef __cplusplus
27
extern "C" {
28
#endif
29
30
#include <freeradius-devel/build.h>
31
#include <freeradius-devel/util/misc.h>
32
#include <freeradius-devel/util/talloc.h>
33
34
#include <stdint.h>
35
36
typedef struct fr_lst_s fr_lst_t;
37
38
/*
39
 * The type of LST indexes.
40
 * The type passed to fr_lst_alloc() and fr_lst_talloc_alloc() in _type must be the
41
 * type of a structure with a member of type fr_lst_index_t. That member's name must be
42
 * passed as the _field argument.
43
 */
44
typedef unsigned int fr_lst_index_t;
45
46
typedef fr_lst_index_t  fr_lst_iter_t;
47
48
/** Creates an LST that can be used with non-talloced elements
49
 *
50
 * @param[in] _ctx    Talloc ctx to allocate LST in.
51
 * @param[in] _cmp    Comparator used to compare elements.
52
 * @param[in] _type   Of elements.
53
 * @param[in] _field    to store LST indexes in.
54
 * @param[in] _init   initial capacity (0 for default initial size);
55
 *        the capacity will be rounded up to a power of two.
56
 * @return
57
 *  - A pointer to the new LST.
58
 *  - NULL on error
59
 */
60
#define fr_lst_alloc(_ctx, _cmp, _type, _field, _init) \
61
  _fr_lst_alloc(_ctx, _cmp, NULL, (size_t)offsetof(_type, _field), _init)
62
63
/** Creates an LST that verifies elements are of a specific talloc type
64
 *
65
 * @param[in] _ctx    Talloc ctx to allocate LST in.
66
 * @param[in] _cmp    Comparator used to compare elements.
67
 * @param[in] _talloc_type  of elements.
68
 * @param[in] _field    to store heap indexes in.
69
 * @param[in] _init   initial capacity (0 for default initial size);
70
 *        the capacity will be rounded up to a power of two.
71
 * @return
72
 *  - A pointer to the new LST.
73
 *  - NULL on error.
74
 */
75
#define fr_lst_talloc_alloc(_ctx, _cmp, _talloc_type, _field, _init) \
76
0
  _fr_lst_alloc(_ctx, _cmp, #_talloc_type, (size_t)offsetof(_talloc_type, _field), _init)
77
78
fr_lst_t *_fr_lst_alloc(TALLOC_CTX *ctx, fr_cmp_t cmp, char const *type, size_t offset, fr_lst_index_t init) CC_HINT(nonnull(2));
79
80
/** Check if an entry is inserted into an LST.
81
 *
82
 * @param[in] lst_id    An fr_lst_index_t value *as stored in an item*
83
 *
84
 * Thus one should only pass this function an index as retrieved directly from
85
 * the item, *not* the value returned by item_index() (q.v.).
86
 *
87
 * This checks a necessary condition for a fr_lst_index_t value to be
88
 * that of an inserted entry. A more complete check would need the entry
89
 * itself and a pointer to the fr_lst_t it may be inserted in.
90
 * Provided here to let heap users move to LSTs.
91
 */
92
static inline bool fr_lst_entry_inserted(fr_lst_index_t lst_id)
93
0
{
94
0
  return (lst_id > 0);
95
0
}
Unexecuted instantiation: timer.c:fr_lst_entry_inserted
Unexecuted instantiation: lst.c:fr_lst_entry_inserted
96
97
void  *fr_lst_peek(fr_lst_t *lst) CC_HINT(nonnull);
98
99
void  *fr_lst_pop(fr_lst_t *lst) CC_HINT(nonnull);
100
101
int   fr_lst_insert(fr_lst_t *lst, void *data) CC_HINT(nonnull);
102
103
int fr_lst_extract(fr_lst_t *lst, void *data) CC_HINT(nonnull);
104
105
unsigned int  fr_lst_num_elements(fr_lst_t *lst) CC_HINT(nonnull);
106
107
108
void    *fr_lst_iter_init(fr_lst_t *lst, fr_lst_iter_t *iter) CC_HINT(nonnull);
109
110
void    *fr_lst_iter_next(fr_lst_t *lst, fr_lst_iter_t *iter) CC_HINT(nonnull);
111
112
#ifndef TALLOC_GET_TYPE_ABORT_NOOP
113
void fr_lst_verify(char const *file, int line, fr_lst_t const *lst);
114
#define FR_LST_VERIFY(_lst) fr_lst_verify(__FILE__, __LINE__, _lst)
115
#elif !defined(NDEBUG)
116
#define FR_LST_VERIFY(_lst) fr_assert(_lst)
117
#else
118
#define FR_LST_VERIFY(_lst)
119
#endif
120
121
/** Iterate over the contents of an LST
122
 *
123
 * @note The initializer section of a for loop can't declare variables with distinct
124
 *   base types, so we require a containing block, and can't follow the standard
125
 *   do {...} while(0) dodge. The code to be run for each item in the LST should
126
 *   thus start with one open brace and end with two close braces, and shouldn't
127
 *   be followed with a semicolon.
128
 *   This may fake out code formatting programs and code-aware editors.
129
 *
130
 * @param[in] _lst    to iterate over.
131
 * @param[in] _type   of item the heap contains.
132
 * @param[in] _data   Name of variable holding a pointer to the LST element.
133
 *        Will be declared in the scope of the loop.
134
 */
135
#define fr_lst_foreach(_lst, _type, _data) \
136
{ \
137
  fr_lst_iter_t _iter; \
138
  for (_type *_data = fr_lst_iter_init(_lst, &_iter); _data; _data = fr_lst_iter_next(_lst, &_iter))
139
140
#ifdef __cplusplus
141
}
142
#endif