The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
types.c
Go to the documentation of this file.
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/** Boxed value structures and functions to manipulate them
18 *
19 * @file src/lib/util/types.c
20 *
21 * @copyright 2021 The FreeRADIUS server project
22 */
23RCSID("$Id: a222b8ad36591ace470ee3b9f1fe2ae5e0c86132 $")
24
25#include <freeradius-devel/util/strerror.h>
26#include <freeradius-devel/util/types.h>
27#include <freeradius-devel/util/value.h>
28
29/** Map data types to names representing those types
30 */
32 { L("null"), FR_TYPE_NULL },
33 { L("string"), FR_TYPE_STRING },
34 { L("octets"), FR_TYPE_OCTETS },
35
36 { L("ipaddr"), FR_TYPE_IPV4_ADDR },
37 { L("ipv4addr"), FR_TYPE_IPV4_ADDR },
38 { L("ipv4prefix"), FR_TYPE_IPV4_PREFIX },
39 { L("ipv6addr"), FR_TYPE_IPV6_ADDR },
40 { L("ipv6prefix"), FR_TYPE_IPV6_PREFIX },
41 { L("ifid"), FR_TYPE_IFID },
42 { L("combo-ip"), FR_TYPE_COMBO_IP_ADDR },
43 { L("combo-prefix"), FR_TYPE_COMBO_IP_PREFIX },
44 { L("ether"), FR_TYPE_ETHERNET },
45
46 { L("bool"), FR_TYPE_BOOL },
47
48 { L("uint8"), FR_TYPE_UINT8 },
49 { L("uint16"), FR_TYPE_UINT16 },
50 { L("uint32"), FR_TYPE_UINT32 },
51 { L("uint64"), FR_TYPE_UINT64 },
52
53 { L("int8"), FR_TYPE_INT8 },
54 { L("int16"), FR_TYPE_INT16 },
55 { L("int32"), FR_TYPE_INT32 },
56 { L("int64"), FR_TYPE_INT64 },
57
58 { L("float32"), FR_TYPE_FLOAT32 },
59 { L("float64"), FR_TYPE_FLOAT64 },
60
61 { L("date"), FR_TYPE_DATE },
62 { L("time_delta"), FR_TYPE_TIME_DELTA },
63
64 { L("size"), FR_TYPE_SIZE },
65
66 { L("tlv"), FR_TYPE_TLV },
67 { L("struct"), FR_TYPE_STRUCT },
68
69 { L("vsa"), FR_TYPE_VSA },
70 { L("vendor"), FR_TYPE_VENDOR },
71 { L("group"), FR_TYPE_GROUP },
72 { L("union"), FR_TYPE_UNION },
73
74 { L("attribute"), FR_TYPE_ATTR },
75
76 /*
77 * Alternative names
78 */
79 { L("cidr"), FR_TYPE_IPV4_PREFIX },
80 { L("byte"), FR_TYPE_UINT8 },
81 { L("short"), FR_TYPE_UINT16 },
82 { L("integer"), FR_TYPE_UINT32 },
83 { L("integer64"), FR_TYPE_UINT64 },
84 { L("decimal"), FR_TYPE_FLOAT64 },
85 { L("signed"), FR_TYPE_INT32 }
86};
88
89/** Map each `fr_type_t` to the C identifier of its enum constant.
90 *
91 * The complement of fr_type_table - that one maps to the short
92 * "string", "ipv4addr", "uint32" names used in dictionaries and conf
93 * files; this maps to the source-identical FR_TYPE_STRING /
94 * FR_TYPE_IPV4_ADDR / FR_TYPE_UINT32 forms, for tooling that wants
95 * to grep the v4 source tree by enum name (radmod2json, etc.).
96 *
97 * Stored as `fr_table_num_indexed_t` so fr_table_str_by_value() can
98 * do the value->name look-up through v4's standard table machinery;
99 * the table is indexed directly by `fr_type_t` value (gaps return
100 * the default).
101 */
139};
141
143{
144 return fr_table_str_by_value(fr_type_to_enum_str_table, t, "FR_TYPE_NULL");
145}
146
147/** Table of all the direct mappings between types and C types
148 *
149 * Useful for setting talloc types correctly.
150 */
151static char const *fr_type_to_c_type[] = {
152 [FR_TYPE_STRING] = "char *",
153 [FR_TYPE_OCTETS] = "uint8_t *",
154
155 [FR_TYPE_IPV4_ADDR] = "fr_ipaddr_t",
156 [FR_TYPE_IPV4_PREFIX] = "fr_ipaddr_t",
157 [FR_TYPE_IPV6_ADDR] = "fr_ipaddr_t",
158 [FR_TYPE_IPV6_PREFIX] = "fr_ipaddr_t",
159 [FR_TYPE_COMBO_IP_ADDR] = "fr_ipaddr_t",
160 [FR_TYPE_COMBO_IP_PREFIX] = "fr_ipaddr_t",
161 [FR_TYPE_IFID] = "fr_ifid_t",
162 [FR_TYPE_ETHERNET] = "fr_ethernet_t",
163
164 [FR_TYPE_BOOL] = "bool",
165 [FR_TYPE_UINT8] = "uint8_t",
166 [FR_TYPE_UINT16] = "uint16_t",
167 [FR_TYPE_UINT32] = "uint32_t",
168 [FR_TYPE_UINT64] = "uint64_t",
169
170 [FR_TYPE_INT8] = "int8_t",
171 [FR_TYPE_INT16] = "int16_t",
172 [FR_TYPE_INT32] = "int32_t",
173 [FR_TYPE_INT64] = "int64_t",
174
175 [FR_TYPE_FLOAT32] = "float",
176 [FR_TYPE_FLOAT64] = "double",
177
178 [FR_TYPE_DATE] = "fr_unix_time_t",
179
180 [FR_TYPE_TIME_DELTA] = "fr_time_delta_t",
181 [FR_TYPE_SIZE] = "size_t",
182 [FR_TYPE_VALUE_BOX] = "fr_value_box_t",
183 [FR_TYPE_ATTR] = "fr_dict_attr_t *",
184 [FR_TYPE_VOID] = "void *",
185
186 [FR_TYPE_VALUE_BOX_CURSOR] = "fr_dcursor_t *",
187 [FR_TYPE_PAIR_CURSOR] = "fr_dcursor_t *",
188
189 [FR_TYPE_MAX] = 0 //!< Ensure array covers all types.
190};
191
192/** Table of all the direct mappings between types and C type sizes
193 *
194 */
195static size_t const fr_type_to_c_size[] = {
196 [FR_TYPE_STRING] = sizeof(char *),
197 [FR_TYPE_OCTETS] = sizeof(uint8_t *),
198
199 [FR_TYPE_IPV4_ADDR] = sizeof(fr_ipaddr_t),
201 [FR_TYPE_IPV6_ADDR] = sizeof(fr_ipaddr_t),
205 [FR_TYPE_IFID] = sizeof(fr_ifid_t),
207
208 [FR_TYPE_BOOL] = sizeof(bool),
209 [FR_TYPE_UINT8] = sizeof(uint8_t),
210 [FR_TYPE_UINT16] = sizeof(uint16_t),
211 [FR_TYPE_UINT32] = sizeof(uint32_t),
212 [FR_TYPE_UINT64] = sizeof(uint64_t),
213
214 [FR_TYPE_INT8] = sizeof(int8_t),
215 [FR_TYPE_INT16] = sizeof(int16_t),
216 [FR_TYPE_INT32] = sizeof(int32_t),
217 [FR_TYPE_INT64] = sizeof(int64_t),
218
219 [FR_TYPE_FLOAT32] = sizeof(float),
220 [FR_TYPE_FLOAT64] = sizeof(double),
221
222 [FR_TYPE_DATE] = sizeof(fr_unix_time_t),
223
225 [FR_TYPE_SIZE] = sizeof(size_t),
227 [FR_TYPE_ATTR] = sizeof(fr_dict_attr_t *),
228 [FR_TYPE_VOID] = sizeof(void *),
229
230 [FR_TYPE_VALUE_BOX_CURSOR] = sizeof(void *),
231 [FR_TYPE_PAIR_CURSOR] = sizeof(void *),
232
233 [FR_TYPE_MAX] = 0 //!< Ensure array covers all types.
234};
235
236#define ARRAY_BEG(_type) { [_type] = true,
237#define ARRAY_MID(_type) [_type] = true,
238#define ARRAY_END(_type) [_type] = true }
239
244
246
250
255
256#define O(_x) [FR_TYPE_ ## _x] = true
257
258/*
259 * Can we promote [src][dst] -> dst
260 * dst is not octets / string
261 * src and dst are both FR_TYPE_VALUE
262 */
265 O(IPV4_PREFIX),
266 O(IPV6_ADDR),
267 O(IPV6_PREFIX),
268 O(COMBO_IP_ADDR),
269 O(COMBO_IP_PREFIX),
270 O(UINT32), /* ipv4 addresses are uint32 */
271 },
273 O(IPV4_ADDR), /* if the prefix is /32 */
274 O(IPV6_ADDR),
275 O(IPV6_PREFIX),
276 O(COMBO_IP_ADDR),
277 O(COMBO_IP_PREFIX)
278 },
280 O(IPV6_PREFIX),
281 O(COMBO_IP_ADDR),
282 O(COMBO_IP_PREFIX)
283 },
285 O(IPV6_ADDR), /* if the prefix is /128 */
286 O(COMBO_IP_ADDR),
287 O(COMBO_IP_PREFIX)
288 },
290 O(IPV4_ADDR),
291 O(IPV4_PREFIX),
292 O(IPV6_ADDR),
293 O(IPV6_PREFIX),
294 O(COMBO_IP_PREFIX)
295 },
297 O(IPV4_ADDR),
298 O(IPV4_PREFIX),
299 O(IPV6_ADDR),
300 O(IPV6_PREFIX),
301 O(COMBO_IP_ADDR) /* if the prefix is /128 or /32 */
302 },
303
304 [FR_TYPE_ETHERNET] = {
305 O(UINT64),
306 },
307
308 [FR_TYPE_UINT64] = {
309 O(ETHERNET),
310 },
311
312 [FR_TYPE_DATE] = { /* in 2021, dates always have values 2^31 or more */
313 O(UINT32),
314 O(UINT64),
315 O(INT32),
316 O(INT64),
317 O(SIZE),
318 O(FLOAT32),
319 O(FLOAT64),
320 O(TIME_DELTA),
321 },
322
324 O(DATE),
325 },
326
327 [FR_TYPE_UINT32] = {
328 O(IPV4_ADDR),
329 },
330
331};
332
333/*
334 * This is different from FR_TYPE_NUMERIC, largely in that it
335 * doesn't include FR_TYPE_DATE. Because we know that dates
336 * always have values 2^31 or greater, so casts exclude some of
337 * the smaller integer types.
338 */
339static const bool type_is_number[FR_TYPE_MAX] = {
340 O(BOOL), O(SIZE), O(FLOAT32), O(FLOAT64),
341 O(UINT8), O(UINT16), O(UINT32), O(UINT64),
342 O(INT8), O(INT16), O(INT32), O(INT64),
343 O(TIME_DELTA),
344};
345
346/** Return if we're allowed to cast the types.
347 *
348 * @param dst the destination type we wish to cast to
349 * @param src the source type we wish to cast to
350 *
351 */
353{
354 /*
355 * Invalid casts.
356 */
357 switch (dst) {
358 case FR_TYPE_NON_LEAF:
359 return false;
360
361 default:
362 break;
363 }
364
365 switch (src) {
366 case FR_TYPE_NON_LEAF:
367 return false;
368
369 default:
370 break;
371 }
372
373 if (src == dst) return true;
374
375 /*
376 * Anything can be converted to octets or strings.
377 */
378 if (dst == FR_TYPE_OCTETS) return true;
379 if (dst == FR_TYPE_STRING) return true;
380
381 /*
382 * Strings and octets can be converted to anything. We
383 * do run-time checks on the values to see if they fit.
384 */
385 if (src == FR_TYPE_OCTETS) return true;
386 if (src == FR_TYPE_STRING) return true;
387
388 /*
389 * Any integer-style thing can be cast to any other
390 * integer-style thing. Mostly. We do run-time checks
391 * on values to see if they fit.
392 */
393 if (type_is_number[src] && type_is_number[dst]) {
394 return true;
395 }
396
397 /*
398 * That takes care of the simple cases. :( Now to the
399 * complex ones. Instead of masses of if / then / else,
400 * we just use a lookup table.
401 */
402 return type_cast_table[src][dst];
403}
404
405#undef O
406#define O(_x) [FR_TYPE_ ## _x] = FR_TYPE_ ## _x
407
408/** promote (a,b) -> a or b
409 * a/b are not octets / string
410 * a and b are both FR_TYPE_VALUE
411 *
412 * Note that this table can return a type which is _not_ a or b.
413 *
414 * Many lookups of table[a][b] will return b. Some will return a.
415 * Others will return a type which is compatible with both a and b.
416 */
419 O(IPV4_PREFIX),
420 O(IPV6_ADDR),
421 O(IPV6_PREFIX),
423 },
424
427 O(IPV4_PREFIX),
429 O(IPV6_PREFIX),
430 },
431
433 O(IPV6_PREFIX),
434 },
435
438 },
439
440 /* unsigned integers */
441
442 [FR_TYPE_BOOL] = {
443 O(UINT8),
444 O(UINT16),
445 O(UINT32),
446 O(UINT64),
447 O(INT8),
448 O(INT16),
449 O(INT32),
450 O(INT64),
451 O(SIZE),
452 O(FLOAT32),
453 O(FLOAT64),
454 O(TIME_DELTA),
455 },
456
457 [FR_TYPE_UINT8] = {
459 O(UINT16),
460 O(UINT32),
461 O(UINT64),
463 O(INT16),
464 O(INT32),
465 O(INT64),
466 O(SIZE),
467 O(FLOAT32),
468 O(FLOAT64),
469 O(TIME_DELTA),
470 },
471
472 [FR_TYPE_UINT16] = {
475 O(UINT32),
476 O(UINT64),
478 O(INT32),
479 O(INT64),
480 O(SIZE),
481 O(FLOAT32),
482 O(FLOAT64),
483 O(TIME_DELTA),
484 },
485
486 [FR_TYPE_UINT32] = {
488 O(IPV4_ADDR),
491 O(UINT64),
493 O(INT64),
494 O(SIZE),
495 O(FLOAT32),
496 O(FLOAT64),
497 O(TIME_DELTA),
498 O(DATE),
499 },
500
501 [FR_TYPE_UINT64] = {
506
511 O(SIZE),
513 O(FLOAT64),
514 O(TIME_DELTA),
515 O(DATE),
516 },
517
518 /* signed integers */
519 [FR_TYPE_INT8] = {
521 O(UINT8),
522 O(UINT16),
523 O(UINT32),
524 O(UINT64),
525 O(INT16),
526 O(INT32),
527 O(INT64),
528 O(SIZE),
529 O(FLOAT32),
530 O(FLOAT64),
531 O(TIME_DELTA),
532 },
533
534 [FR_TYPE_INT16] = {
537 O(UINT16),
538 O(UINT32),
539 O(UINT64),
541 O(INT32),
542 O(INT64),
543 O(SIZE),
544 O(FLOAT32),
545 O(FLOAT64),
546 O(TIME_DELTA),
547 },
548
549 [FR_TYPE_INT32] = {
553 O(UINT32),
554 O(UINT64),
557 O(INT64),
558 O(SIZE),
559 O(FLOAT32),
560 O(FLOAT64),
561 O(TIME_DELTA),
562 O(DATE),
563 },
564
565 [FR_TYPE_INT64] = {
569 O(UINT64),
570 O(SIZE),
575 O(FLOAT64),
576 O(TIME_DELTA),
577 O(DATE),
578 },
579
587
592
596 },
597
598 [FR_TYPE_DATE] = {
602
605
608 O(TIME_DELTA),
609 },
610
611 [FR_TYPE_SIZE] = {
622 O(FLOAT64),
624 O(DATE),
625 }
626};
627
628/** Return the promoted type
629 *
630 * We presume that the two types are compatible, as checked by
631 * calling fr_type_cast(). The main difference here is that the two
632 * types don't have any src / dst relationship. Instead, we just
633 * pick one which best suits any value-box comparisons
634 *
635 * Note that this function can return a type which is _not_ a or b.
636 *
637 * @param a type one
638 * @param b type two
639 * @return the promoted type
640 */
642{
643 if (!fr_type_is_leaf(a) || !fr_type_is_leaf(b)) return FR_TYPE_NULL;
644
645 if (a == b) return a;
646
647 /*
648 * string / octets and "type", the un-typed data gets cast to
649 * "type".
650 *
651 * We prefer to cast raw data to real types. We also
652 * prefer to _parse_ strings, and do the type checking on
653 * the real types. That way we have things like: "000" == 0
654 */
655 if (a == FR_TYPE_OCTETS) return b;
656 if (b == FR_TYPE_OCTETS) return a;
657
658 /*
659 * Check for string after octets, because we want to cast
660 * octets to string, and not vice versa.
661 */
662 if (a == FR_TYPE_STRING) return b;
663 if (b == FR_TYPE_STRING) return a;
664
665 /*
666 * Otherwise bad things happen. :(
667 */
668 if (unlikely(type_promote_table[a][b] != type_promote_table[b][a])) {
669 fr_strerror_printf("Inverse type mapping inconsistent for a = %s, b = %s",
671 fr_type_to_str(b));
672
673 return FR_TYPE_NULL;
674 }
675
677 fr_strerror_printf("No type promotions for a = %s, b = %s",
679 fr_type_to_str(b));
680 return FR_TYPE_NULL;
681 }
682
683 /*
684 * That takes care of the simple cases. :( Now to the
685 * complex ones. Instead of masses of if / then / else,
686 * we just use a lookup table.
687 */
688 return type_promote_table[a][b];
689}
690
691/** Allocate an array of a given type
692 *
693 * @param[in] ctx to allocate array in.
694 * @param[in] type array to allocate.
695 * @param[in] count The number of elements to allocate.
696 * @return
697 * - NULL on error.
698 * - A new talloc array.
699 */
700void **fr_type_array_alloc(TALLOC_CTX *ctx, fr_type_t type, size_t count)
701{
702 char const *c_type;
703
704 c_type = fr_type_to_c_type[type];
705 if (c_type == NULL) {
706 fr_strerror_printf("Type %s does not have a C type equivalent", fr_type_to_str(type));
707 return NULL;
708 }
709
710 return _talloc_zero_array(ctx, fr_type_to_c_size[type], count, c_type);
711 }
#define RCSID(id)
Definition build.h:512
#define L(_str)
Helper for initialising arrays of string literals.
Definition build.h:228
#define unlikely(_x)
Definition build.h:407
#define NUM_ELEMENTS(_t)
Definition build.h:358
Struct to represent an ethernet address.
Definition inet.h:44
Struct to represent an interface id.
Definition inet.h:53
IPv4/6 prefix.
unsigned short uint16_t
fr_type_t
@ FR_TYPE_TIME_DELTA
A period of time measured in nanoseconds.
@ FR_TYPE_FLOAT32
Single precision floating point.
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_INT8
8 Bit signed integer.
@ FR_TYPE_TLV
Contains nested attributes.
@ FR_TYPE_ETHERNET
48 Bit Mac-Address.
@ FR_TYPE_IPV6_PREFIX
IPv6 Prefix.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_MAX
Number of defined data types.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_INT64
64 Bit signed integer.
@ FR_TYPE_INT16
16 Bit signed integer.
@ FR_TYPE_DATE
Unix time stamp, always has value >2^31.
@ FR_TYPE_COMBO_IP_PREFIX
IPv4 or IPv6 address prefix depending on length.
@ FR_TYPE_VALUE_BOX
A boxed value.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
@ FR_TYPE_INT32
32 Bit signed integer.
@ FR_TYPE_VENDOR
Attribute that represents a vendor in the attribute tree.
@ FR_TYPE_UINT64
64 Bit unsigned integer.
@ FR_TYPE_IPV6_ADDR
128 Bit IPv6 Address.
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
@ FR_TYPE_VOID
User data.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_SIZE
Unsigned integer capable of representing any memory address on the local system.
@ FR_TYPE_VSA
Vendor-Specific, for RADIUS attribute 26.
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
@ FR_TYPE_IFID
Interface ID.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_GROUP
A grouping of other attributes.
@ FR_TYPE_FLOAT64
Double precision floating point.
unsigned int uint32_t
unsigned char bool
unsigned char uint8_t
return count
Definition module.c:155
fr_aka_sim_id_type_t type
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
Definition table.h:804
#define FR_TABLE_INDEXED_ENTRY(_v)
Build a single fr_table_num_indexed_t entry from an enum identifier.
Definition table.h:110
An element in a table indexed by numeric value.
Definition table.h:92
An element in an arbitrarily ordered array of name to num mappings.
Definition table.h:57
struct fr_time_delta_s fr_time_delta_t
A time delta, a difference in time measured in nanoseconds.
"Unix" time.
Definition time.h:95
#define fr_strerror_printf(_fmt,...)
Log to thread local error buffer.
Definition strerror.h:64
#define O(_x)
Definition types.c:256
fr_table_num_ordered_t const fr_type_table[]
Map data types to names representing those types.
Definition types.c:31
static char const * fr_type_to_c_type[]
Table of all the direct mappings between types and C types.
Definition types.c:151
bool const fr_type_structural_except_vsa[FR_TYPE_MAX+1]
Definition types.c:251
#define ARRAY_MID(_type)
Definition types.c:237
bool const fr_type_non_leaf[FR_TYPE_MAX+1]
Definition types.c:254
char const * fr_type_to_enum_str(fr_type_t t)
Return the source-identifier name for a type (e.g.
Definition types.c:142
bool fr_type_cast(fr_type_t dst, fr_type_t src)
Return if we're allowed to cast the types.
Definition types.c:352
bool const fr_type_signed[FR_TYPE_MAX+1]
Definition types.c:243
bool const fr_type_integer[FR_TYPE_MAX+1]
Definition types.c:241
static fr_table_num_indexed_t const fr_type_to_enum_str_table[]
Map each fr_type_t to the C identifier of its enum constant.
Definition types.c:102
bool const fr_type_variable_size[FR_TYPE_MAX+1]
Definition types.c:248
bool const fr_type_numeric[FR_TYPE_MAX+1]
Definition types.c:242
static fr_type_t type_promote_table[FR_TYPE_MAX][FR_TYPE_MAX]
promote (a,b) -> a or b a/b are not octets / string a and b are both FR_TYPE_VALUE
Definition types.c:417
bool const fr_type_ip[FR_TYPE_MAX+1]
Definition types.c:245
static const bool type_is_number[FR_TYPE_MAX]
Definition types.c:339
bool const fr_type_fixed_size[FR_TYPE_MAX+1]
Definition types.c:247
#define ARRAY_END(_type)
Definition types.c:238
bool const fr_type_integer_except_bool[FR_TYPE_MAX+1]
Definition types.c:240
bool const fr_type_quoted[FR_TYPE_MAX+1]
Definition types.c:249
void ** fr_type_array_alloc(TALLOC_CTX *ctx, fr_type_t type, size_t count)
Allocate an array of a given type.
Definition types.c:700
bool const fr_type_leaf[FR_TYPE_MAX+1]
Definition types.c:253
size_t fr_type_table_len
Definition types.c:87
static size_t const fr_type_to_c_size[]
Table of all the direct mappings between types and C type sizes.
Definition types.c:195
fr_type_t fr_type_promote(fr_type_t a, fr_type_t b)
Return the promoted type.
Definition types.c:641
static const bool type_cast_table[FR_TYPE_MAX][FR_TYPE_MAX]
Definition types.c:263
#define ARRAY_BEG(_type)
Definition types.c:236
static size_t fr_type_to_enum_str_table_len
Definition types.c:140
bool const fr_type_structural[FR_TYPE_MAX+1]
Definition types.c:252
#define FR_TYPE_NON_LEAF_DEF(_beg, _mid, _end)
Types which do not represent leaf values.
Definition types.h:288
#define FR_TYPE_IP_DEF(_beg, _mid, _end)
Types which can fit in an fr_ipaddr_t.
Definition types.h:167
#define FR_TYPE_FIXED_SIZE_DEF(_beg, _mid, _end)
Match all fixed length types.
Definition types.h:181
@ FR_TYPE_VALUE_BOX_CURSOR
cursor over a fr_value_box_t
Definition types.h:88
@ FR_TYPE_UNION
A union of limited children.
Definition types.h:81
@ FR_TYPE_ATTR
A contains an attribute reference.
Definition types.h:83
@ FR_TYPE_PAIR_CURSOR
cursor over a fr_pair_t
Definition types.h:90
#define FR_TYPE_STRUCTURAL_EXCEPT_VSA_DEF(_beg, _mid, _end)
Stupid hack for things which produce special error messages for VSAs.
Definition types.h:219
#define FR_TYPE_NON_LEAF
Definition types.h:318
#define FR_TYPE_SIGNED_DEF(_beg, _mid, _end)
Signed values.
Definition types.h:136
#define FR_TYPE_VARIABLE_SIZE_DEF(_beg, _mid, _end)
Match all variable length types.
Definition types.h:199
#define FR_TYPE_NUMERIC_DEF(_beg, _mid, _end)
Naturally numeric types.
Definition types.h:153
#define FR_TYPE_INTEGER_EXCEPT_BOOL_DEF(_beg, _mid, _end)
All integer types except bool.
Definition types.h:106
#define FR_TYPE_LEAF_DEF(_beg, _mid, _end)
Types which represent concrete values.
Definition types.h:259
#define fr_type_is_leaf(_x)
Definition types.h:393
#define FR_TYPE_STRUCTURAL_DEF(_beg, _mid, _end)
Match all non value types in case statements.
Definition types.h:248
static char const * fr_type_to_str(fr_type_t type)
Return a static string containing the type name.
Definition types.h:454
#define FR_TYPE_QUOTED_DEF(_beg, _mid, _end)
Types which should be wrapped in double quotes when printed.
Definition types.h:208
#define FR_TYPE_INTEGER_DEF(_beg, _mid, _end)
Signed or unsigned integers.
Definition types.h:126