The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
table.h
Go to the documentation of this file.
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 /**
19  * $Id: 1ccb12f6bd550c64587949f517ae5e396663ac34 $
20  *
21  * @file lib/util/table.h
22  * @brief Lookup table functions
23  *
24  * @copyright 2019 The FreeRADIUS server project
25  * @copyright 2019 Arran Cudbard-Bell (a.cudbardb@freeradius.org)
26  */
27 RCSIDH(table_h, "$Id: 1ccb12f6bd550c64587949f517ae5e396663ac34 $")
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 #include <stddef.h>
34 #include <stdint.h>
35 #include <sys/types.h>
36 
37 typedef struct {
38  char const *str; //!< Literal string.
39  size_t len; //!< Literal string length.
41 
42 /** An element in a lexicographically sorted array of name to num mappings
43  *
44  */
45 typedef struct {
47  int value;
49 
50 /** An element in an arbitrarily ordered array of name to num mappings
51  *
52  */
53 typedef struct {
55  int value;
57 
58 /** An element in a lexicographically sorted array of name to ptr mappings
59  *
60  */
61 typedef struct {
63  void const *value;
65 
66 /** An element in an arbitrarily ordered array of name to ptr mappings
67  *
68  */
69 typedef struct {
71  void const *value;
73 
74 /** An element in a table indexed by bit position
75  *
76  * i.e. if only the first bit is set in a bitfield, the entry at index 0
77  * will be returned.
78  */
79 typedef struct {
81  uint64_t value;
83 
84 /** An element in a table indexed by numeric value
85  *
86  * i.e. if the value is 0, we return the string mapped to the first element of the table.
87  */
88 typedef struct {
90  unsigned int value;
92 
93 /** Macro to use as dflt
94  *
95  */
96 #define NAME_NUMBER_NOT_FOUND INT32_MIN
97 
98 char const *_fr_table_ptr_by_str_value(fr_table_ptr_sorted_t const *table, size_t table_len, char const *str_val, char const *def);
99 
100 /** Brute force search a sorted or ordered ptr table, assuming the pointers are strings
101  *
102  * @param[in] _table to search in.
103  * @param[in] _str_value to compare against the ptr field.
104  * @param[in] _def default value.
105  */
106 #define fr_table_str_by_str_value(_table, _str_value, _def) \
107 _Generic((_table), \
108  fr_table_ptr_sorted_t const * : _fr_table_ptr_by_str_value((fr_table_ptr_sorted_t const *)_table, _table ## _len, _str_value, _def), \
109  fr_table_ptr_ordered_t const * : _fr_table_ptr_by_str_value((fr_table_ptr_sorted_t const *)_table, _table ## _len, _str_value, _def), \
110  fr_table_ptr_sorted_t * : _fr_table_ptr_by_str_value((fr_table_ptr_sorted_t const *)_table, _table ## _len, _str_value, _def), \
111  fr_table_ptr_ordered_t * : _fr_table_ptr_by_str_value((fr_table_ptr_sorted_t const *)_table, _table ## _len, _str_value, _def))
112 
113 int fr_table_sorted_num_by_str(fr_table_num_sorted_t const *table, size_t table_len,
114  char const *name, int def);
115 
116 int fr_table_ordered_num_by_str(fr_table_num_ordered_t const *table, size_t table_len,
117  char const *name, int def);
118 
119 void *fr_table_sorted_ptr_by_str(fr_table_ptr_sorted_t const *table, size_t table_len,
120  char const *name, void const *def);
121 
122 void *fr_table_ordered_ptr_by_str(fr_table_ptr_ordered_t const *table, size_t table_len,
123  char const *name, void const *def);
124 
125 /** Convert a string to a value using a sorted or ordered table
126  *
127  * @param[in] _table to search in.
128  * @param[in] _name to resolve to a number.
129  * @param[in] _def Default value if no entry matched.
130  * @return
131  * - _def if name matched no entries in the table.
132  * - the numeric value of the matching entry.
133  */
134 #define fr_table_value_by_str(_table, _name, _def) \
135 _Generic((_table), \
136  fr_table_num_sorted_t const * : fr_table_sorted_num_by_str, \
137  fr_table_num_ordered_t const * : fr_table_ordered_num_by_str, \
138  fr_table_num_sorted_t * : fr_table_sorted_num_by_str, \
139  fr_table_num_ordered_t * : fr_table_ordered_num_by_str, \
140  fr_table_ptr_sorted_t const * : fr_table_sorted_ptr_by_str, \
141  fr_table_ptr_ordered_t const * : fr_table_ordered_ptr_by_str, \
142  fr_table_ptr_sorted_t * : fr_table_sorted_ptr_by_str, \
143  fr_table_ptr_ordered_t * : fr_table_ordered_ptr_by_str, \
144  fr_table_num_indexed_bit_pos_t * : fr_table_ordered_num_by_str, \
145  fr_table_num_indexed_bit_pos_t const * : fr_table_ordered_num_by_str, \
146  fr_table_num_indexed_t * : fr_table_ordered_num_by_str, \
147  fr_table_num_indexed_t const * : fr_table_ordered_num_by_str \
148 )(_table, _table ## _len, _name, _def)
149 
150 int fr_table_sorted_num_by_substr(fr_table_num_sorted_t const *table, size_t table_len,
151  char const *name, ssize_t name_len, int def);
152 
153 int fr_table_ordered_num_by_substr(fr_table_num_ordered_t const *table, size_t table_len,
154  char const *name, ssize_t name_len, int def);
155 
156 void *fr_table_sorted_ptr_by_substr(fr_table_ptr_sorted_t const *table, size_t table_len,
157  char const *name, ssize_t name_len, void const *def);
158 
159 void *fr_table_ordered_ptr_by_substr(fr_table_ptr_ordered_t const *table, size_t table_len,
160  char const *name, ssize_t name_len, void const *def);
161 
162 /** Convert a partial string to a value using an ordered or sorted table
163  *
164  * @param[in] _table to search in.
165  * @param[in] _name to resolve to a number.
166  * @param[in] _name_len The amount of name to match.
167  * If < 0, the length of the name in the table element
168  * will be used as the maximum match length.
169  * @param[in] _def Default value if no entry matched.
170  * @return
171  * - _def if name matched no entries in the table.
172  * - the numeric value of the matching entry.
173  */
174 #define fr_table_value_by_substr(_table, _name, _name_len, _def) \
175 _Generic((_table), \
176  fr_table_num_sorted_t const * : fr_table_sorted_num_by_substr, \
177  fr_table_num_ordered_t const * : fr_table_ordered_num_by_substr, \
178  fr_table_num_sorted_t * : fr_table_sorted_num_by_substr, \
179  fr_table_num_ordered_t * : fr_table_ordered_num_by_substr, \
180  fr_table_ptr_sorted_t const * : fr_table_sorted_ptr_by_substr, \
181  fr_table_ptr_ordered_t const * : fr_table_ordered_ptr_by_substr, \
182  fr_table_ptr_sorted_t * : fr_table_sorted_ptr_by_substr, \
183  fr_table_ptr_ordered_t * : fr_table_ordered_ptr_by_substr, \
184  fr_table_num_indexed_bit_pos_t * : fr_table_ordered_num_by_substr, \
185  fr_table_num_indexed_bit_pos_t const * : fr_table_ordered_num_by_substr, \
186  fr_table_num_indexed_t * : fr_table_ordered_num_by_substr, \
187  fr_table_num_indexed_t const * : fr_table_ordered_num_by_substr \
188 )(_table, _table ## _len, _name, _name_len, _def)
189 
190 int fr_table_sorted_num_by_longest_prefix(size_t *match_len, fr_table_num_sorted_t const *table, size_t table_len,
191  char const *name, ssize_t name_len, int def);
192 
193 int fr_table_ordered_num_by_longest_prefix(size_t *match_len, fr_table_num_ordered_t const *table, size_t table_len,
194  char const *name, ssize_t name_len, int def);
195 
196 void *fr_table_sorted_ptr_by_longest_prefix(size_t *match_len, fr_table_ptr_sorted_t const *table, size_t table_len,
197  char const *name, ssize_t name_len, void const *def);
198 
199 void *fr_table_ordered_ptr_by_longest_prefix(size_t *match_len, fr_table_ptr_ordered_t const *table, size_t table_len,
200  char const *name, ssize_t name_len, void const *def);
201 
202 /** Find the longest string match using a sorted or ordered table
203  *
204  * @param[out] _match_len How much of the input string matched.
205  * @param[in] _table to search in.
206  * @param[in] _name to resolve to a number.
207  * @param[in] _name_len The amount of name to match.
208  * @param[in] _def Default value if no entry matched.
209  * @return
210  * - _def if name matched no entries in the table.
211  * - the value of the matching entry.
212  */
213 #define fr_table_value_by_longest_prefix(_match_len, _table, _name, _name_len, _def) \
214 _Generic((_table), \
215  fr_table_num_sorted_t const * : fr_table_sorted_num_by_longest_prefix, \
216  fr_table_num_ordered_t const * : fr_table_ordered_num_by_longest_prefix, \
217  fr_table_num_sorted_t * : fr_table_sorted_num_by_longest_prefix, \
218  fr_table_num_ordered_t * : fr_table_ordered_num_by_longest_prefix, \
219  fr_table_ptr_sorted_t const * : fr_table_sorted_ptr_by_longest_prefix, \
220  fr_table_ptr_ordered_t const * : fr_table_ordered_ptr_by_longest_prefix, \
221  fr_table_ptr_sorted_t * : fr_table_sorted_ptr_by_longest_prefix, \
222  fr_table_ptr_ordered_t * : fr_table_ordered_ptr_by_longest_prefix, \
223  fr_table_num_indexed_bit_pos_t * : fr_table_ordered_num_by_longest_prefix, \
224  fr_table_num_indexed_bit_pos_t const * : fr_table_ordered_num_by_longest_prefix, \
225  fr_table_num_indexed_t * : fr_table_ordered_num_by_longest_prefix, \
226  fr_table_num_indexed_t const * : fr_table_ordered_num_by_longest_prefix \
227 )(_match_len, _table, _table ## _len, _name, _name_len, _def)
228 
229 char const *fr_table_ordered_str_by_num(fr_table_num_ordered_t const *table, size_t table_len,
230  int number, char const *def);
231 char const *fr_table_sorted_str_by_num(fr_table_num_sorted_t const *table, size_t table_len,
232  int number, char const *def);
233 char const *fr_table_ordered_str_by_ptr(fr_table_ptr_ordered_t const *table, size_t table_len,
234  void const *ptr, char const *def);
235 char const *fr_table_sorted_str_by_ptr(fr_table_ptr_sorted_t const *table, size_t table_len,
236  void const *ptr, char const *def);
237 
238 char const *fr_table_indexed_str_by_bit_field(fr_table_num_indexed_bit_pos_t const *table, size_t table_len,
239  uint64_t number, char const *def);
240 
241 char const *fr_table_indexed_str_by_num(fr_table_num_indexed_t const *table, size_t table_len,
242  unsigned int number, char const *def);
243 
244 /** Convert an integer to a string
245  *
246  * @param[in] _table to search in.
247  * @param[in] _number to resolve to a string.
248  * @param[in] _def Default string to return if there's no match.
249  * @return
250  * - _def if _number name matched no entries in the table.
251  * - the string value of the matching entry.
252  */
253 #define fr_table_str_by_value(_table, _number, _def) \
254 _Generic((_table), \
255  fr_table_num_sorted_t const * : fr_table_sorted_str_by_num, \
256  fr_table_num_ordered_t const * : fr_table_ordered_str_by_num, \
257  fr_table_num_sorted_t * : fr_table_sorted_str_by_num, \
258  fr_table_num_ordered_t * : fr_table_ordered_str_by_num, \
259  fr_table_ptr_sorted_t const * : fr_table_sorted_str_by_ptr, \
260  fr_table_ptr_ordered_t const * : fr_table_ordered_str_by_ptr, \
261  fr_table_ptr_sorted_t * : fr_table_sorted_str_by_ptr, \
262  fr_table_ptr_ordered_t * : fr_table_ordered_str_by_ptr, \
263  fr_table_num_indexed_bit_pos_t * : fr_table_indexed_str_by_bit_field, \
264  fr_table_num_indexed_bit_pos_t const * : fr_table_indexed_str_by_bit_field, \
265  fr_table_num_indexed_t * : fr_table_indexed_str_by_num, \
266  fr_table_num_indexed_t const * : fr_table_indexed_str_by_num \
267 )(_table, _table ## _len, _number, _def)
268 
269 #define TABLE_TYPE_NEEDLE_LEN_FUNC(_our_table_type, _our_name) \
270 static inline size_t _our_name(_our_table_type table, size_t table_len) \
271 { \
272  size_t i, max = 0; \
273  for (i = 0; i < table_len; i++) if (table->name.len > max) max = table->name.len; \
274  return max; \
275 }
276 
277 TABLE_TYPE_NEEDLE_LEN_FUNC(fr_table_num_sorted_t const *, fr_table_num_sorted_max_needle_len)
278 TABLE_TYPE_NEEDLE_LEN_FUNC(fr_table_num_ordered_t const *, fr_table_num_ordered_max_needle_len)
279 TABLE_TYPE_NEEDLE_LEN_FUNC(fr_table_ptr_sorted_t const *, fr_table_ptr_sorted_max_needle_len)
280 TABLE_TYPE_NEEDLE_LEN_FUNC(fr_table_ptr_ordered_t const *, fr_table_ptr_ordered_max_needle_len)
281 TABLE_TYPE_NEEDLE_LEN_FUNC(fr_table_num_indexed_bit_pos_t const *, fr_table_num_indexed_bit_pos_max_needle_len)
282 TABLE_TYPE_NEEDLE_LEN_FUNC(fr_table_num_indexed_t const *, fr_table_num_indexed_max_needle_len)
283 
284 #define fr_table_max_needle_len(_table) \
285 _Generic((_table), \
286  fr_table_num_sorted_t const * : fr_table_num_sorted_max_needle_len, \
287  fr_table_num_ordered_t const * : fr_table_num_ordered_max_needle_len, \
288  fr_table_num_sorted_t * : fr_table_num_sorted_max_needle_len, \
289  fr_table_num_ordered_t * : fr_table_num_ordered_max_needle_len, \
290  fr_table_ptr_sorted_t const * : fr_table_ptr_sorted_max_needle_len, \
291  fr_table_ptr_ordered_t const * : fr_table_ptr_ordered_max_needle_len, \
292  fr_table_ptr_sorted_t * : fr_table_ptr_sorted_max_needle_len, \
293  fr_table_ptr_ordered_t * : fr_table_ptr_ordered_max_needle_len, \
294  fr_table_num_indexed_bit_pos_t * : fr_table_num_indexed_bit_pos_max_needle_len, \
295  fr_table_num_indexed_bit_pos_t const * : fr_table_num_indexed_bit_pos_max_needle_len, \
296  fr_table_num_indexed_t * : fr_table_num_indexed_max_needle_len, \
297  fr_table_num_indexed_t const * : fr_table_num_indexed_max_needle_len \
298 )(_table, _table ## _len)
299 
300 #ifdef __cplusplus
301 }
302 #endif
#define RCSIDH(h, id)
Definition: build.h:445
long int ssize_t
Definition: merged_model.c:24
static char const * name
fr_table_elem_t name
Definition: table.h:80
int fr_table_ordered_num_by_substr(fr_table_num_ordered_t const *table, size_t table_len, char const *name, ssize_t name_len, int def)
fr_table_elem_t name
Definition: table.h:54
unsigned int value
Definition: table.h:90
char const * fr_table_sorted_str_by_ptr(fr_table_ptr_sorted_t const *table, size_t table_len, void const *ptr, char const *def)
int fr_table_ordered_num_by_longest_prefix(size_t *match_len, fr_table_num_ordered_t const *table, size_t table_len, char const *name, ssize_t name_len, int def)
void * fr_table_ordered_ptr_by_str(fr_table_ptr_ordered_t const *table, size_t table_len, char const *name, void const *def)
void * fr_table_ordered_ptr_by_longest_prefix(size_t *match_len, fr_table_ptr_ordered_t const *table, size_t table_len, char const *name, ssize_t name_len, void const *def)
fr_table_elem_t name
Definition: table.h:70
fr_table_elem_t name
Definition: table.h:46
#define TABLE_TYPE_NEEDLE_LEN_FUNC(_our_table_type, _our_name)
Definition: table.h:269
char const * str
Literal string.
Definition: table.h:38
size_t len
Literal string length.
Definition: table.h:39
fr_table_elem_t name
Definition: table.h:89
int fr_table_sorted_num_by_substr(fr_table_num_sorted_t const *table, size_t table_len, char const *name, ssize_t name_len, int def)
char const * fr_table_ordered_str_by_num(fr_table_num_ordered_t const *table, size_t table_len, int number, char const *def)
fr_table_elem_t name
Definition: table.h:62
void * fr_table_sorted_ptr_by_str(fr_table_ptr_sorted_t const *table, size_t table_len, char const *name, void const *def)
char const * fr_table_ordered_str_by_ptr(fr_table_ptr_ordered_t const *table, size_t table_len, void const *ptr, char const *def)
void const * value
Definition: table.h:71
void const * value
Definition: table.h:63
void * fr_table_sorted_ptr_by_substr(fr_table_ptr_sorted_t const *table, size_t table_len, char const *name, ssize_t name_len, void const *def)
char const * fr_table_sorted_str_by_num(fr_table_num_sorted_t const *table, size_t table_len, int number, char const *def)
int fr_table_sorted_num_by_str(fr_table_num_sorted_t const *table, size_t table_len, char const *name, int def)
char const * fr_table_indexed_str_by_num(fr_table_num_indexed_t const *table, size_t table_len, unsigned int number, char const *def)
void * fr_table_ordered_ptr_by_substr(fr_table_ptr_ordered_t const *table, size_t table_len, char const *name, ssize_t name_len, void const *def)
int fr_table_ordered_num_by_str(fr_table_num_ordered_t const *table, size_t table_len, char const *name, int def)
char const * _fr_table_ptr_by_str_value(fr_table_ptr_sorted_t const *table, size_t table_len, char const *str_val, char const *def)
Brute force search a sorted or ordered ptr table, assuming the pointers are strings.
Definition: table.c:42
void * fr_table_sorted_ptr_by_longest_prefix(size_t *match_len, fr_table_ptr_sorted_t const *table, size_t table_len, char const *name, ssize_t name_len, void const *def)
char const * fr_table_indexed_str_by_bit_field(fr_table_num_indexed_bit_pos_t const *table, size_t table_len, uint64_t number, char const *def)
int fr_table_sorted_num_by_longest_prefix(size_t *match_len, fr_table_num_sorted_t const *table, size_t table_len, char const *name, ssize_t name_len, int def)
An element in a table indexed by bit position.
Definition: table.h:79
An element in a table indexed by numeric value.
Definition: table.h:88
An element in an arbitrarily ordered array of name to num mappings.
Definition: table.h:53
An element in a lexicographically sorted array of name to num mappings.
Definition: table.h:45
An element in an arbitrarily ordered array of name to ptr mappings.
Definition: table.h:69
An element in a lexicographically sorted array of name to ptr mappings.
Definition: table.h:61