53#define INITIAL_REGISTRY_BUCKETS 61
83 hash = ((hash << 5) + hash) + c;
100 if (strcmp(current->name, name) == 0)
126 size_t name_len = strlen(name) + 1;
133 new_entry->
name = name_copy;
134 new_entry->
type =
nullptr;
272 if (node->src == type)
282 memo_node->
src = type;
283 memo_node->
next = *memo_head;
284 *memo_head = memo_node;
293 if (!entry || !entry->
type) {
297 *type_ptr = entry->
type;
395 while (isspace((
unsigned char)*state->
p))
397 if (*state->
p ==
'#')
398 while (*state->
p !=
'\n' && *state->
p !=
'\0')
415 const char * name_start = state->
p;
416 while (isalnum((
unsigned char)*state->
p) || *state->
p ==
'_' || *state->
p ==
':') {
417 if (*state->
p ==
':' && state->
p[1] !=
':')
419 if (*state->
p ==
':')
423 size_t len = state->
p - name_start;
424 if (len == 0 || len >= buf_size)
473 const char * def_body_start;
477 size_t defs_capacity = 64;
478 struct def_info * defs_found =
infix_malloc(
sizeof(
struct def_info) * defs_capacity);
483 size_t num_defs_found = 0;
487 while (*state.
p !=
'\0') {
489 if (*state.
p ==
'\0')
492 if (*state.
p !=
'@') {
499 char name_buffer[256];
508 if (*state.
p ==
'=') {
524 if (num_defs_found >= defs_capacity) {
525 size_t new_capacity = defs_capacity * 2;
526 struct def_info * new_defs =
infix_realloc(defs_found,
sizeof(
struct def_info) * new_capacity);
532 defs_found = new_defs;
533 defs_capacity = new_capacity;
537 defs_found[num_defs_found].entry = entry;
538 defs_found[num_defs_found].def_body_start = state.
p;
540 const char * body_end = state.
p;
541 while (*body_end !=
'\0' &&
542 !(*body_end ==
';' &&
544 if (*body_end ==
'-' && body_end[1] ==
'>') {
548 if (*body_end ==
'{' || *body_end ==
'<' || *body_end ==
'(' || *body_end ==
'[')
550 if (*body_end ==
'}' || *body_end ==
'>' || *body_end ==
')' || *body_end ==
']')
554 defs_found[num_defs_found].def_body_len = body_end - state.
p;
558 else if (*state.
p ==
';') {
582 for (
size_t i = 0; i < num_defs_found; ++i) {
585 char * body_copy =
infix_malloc(defs_found[i].def_body_len + 1);
591 infix_memcpy(body_copy, defs_found[i].def_body_start, defs_found[i].def_body_len);
592 body_copy[defs_found[i].def_body_len] =
'\0';
614 if (existing_entry && existing_entry->
type)
615 type_to_alias = existing_entry->
type;
619 (
size_t)(defs_found[i].def_body_start -
definitions));
636 *prim_copy = *type_to_alias;
639 entry->
type = prim_copy;
658 for (
size_t i = 0; i < num_defs_found; ++i) {
infix_arena_t * arena
Definition 005_layouts.c:68
const char * definitions
Definition 008_registry_introspection.c:39
infix_registry_t * registry
Definition 008_registry_introspection.c:35
infix_status status
Definition 103_unions.c:66
#define c23_nodiscard
A compatibility macro for the C23 [[nodiscard]] attribute.
Definition compat_c23.h:113
#define INFIX_TLS
Definition error.c:58
infix_error_details_t infix_get_last_error(void)
Retrieves detailed information about the last error that occurred on the current thread.
Definition error.c:270
@ INFIX_CODE_UNRESOLVED_NAMED_TYPE
Definition infix.h:1346
@ INFIX_CODE_UNEXPECTED_TOKEN
Definition infix.h:1335
@ INFIX_CODE_UNKNOWN
Definition infix.h:1327
@ INFIX_CODE_OUT_OF_MEMORY
Definition infix.h:1330
@ INFIX_CATEGORY_ALLOCATION
Definition infix.h:1316
@ INFIX_CATEGORY_GENERAL
Definition infix.h:1315
@ INFIX_CATEGORY_PARSER
Definition infix.h:1317
struct infix_type_t::@0::@1 pointer_info
Metadata for INFIX_TYPE_POINTER.
size_t position
Definition infix.h:1363
union infix_type_t::@0 meta
A union containing metadata specific to the type's category.
struct infix_type_t::@0::@7 vector_info
Metadata for INFIX_TYPE_VECTOR.
infix_error_category_t category
Definition infix.h:1361
infix_type * type
Definition infix.h:289
struct infix_type_t::@0::@4 func_ptr_info
Metadata for INFIX_TYPE_REVERSE_TRAMPOLINE.
infix_arena_t * arena
Definition infix.h:217
infix_struct_member * members
Definition infix.h:231
struct infix_type_t::@0::@6 complex_info
Metadata for INFIX_TYPE_COMPLEX.
const char * name
Definition infix.h:212
infix_function_argument * args
Definition infix.h:244
infix_status
Enumerates the possible status codes returned by infix API functions.
Definition infix.h:389
infix_type_category category
Definition infix.h:213
struct infix_type_t::@0::@2 aggregate_info
Metadata for INFIX_TYPE_STRUCT and INFIX_TYPE_UNION.
struct infix_type_t::@0::@3 array_info
Metadata for INFIX_TYPE_ARRAY.
struct infix_type_t * pointee_type
Definition infix.h:226
infix_type * type
Definition infix.h:279
struct infix_type_t * element_type
Definition infix.h:237
struct infix_type_t * return_type
Definition infix.h:243
struct infix_type_t::@0::@5 enum_info
Metadata for INFIX_TYPE_ENUM.
struct infix_type_t * base_type
Definition infix.h:256
infix_error_code_t code
Definition infix.h:1362
size_t num_members
Definition infix.h:232
struct infix_type_t * underlying_type
Definition infix.h:251
struct infix_type_t::@0::@8 named_reference
Metadata for INFIX_TYPE_NAMED_REFERENCE.
size_t num_args
Definition infix.h:245
bool is_arena_allocated
Definition infix.h:216
@ INFIX_ERROR_ALLOCATION_FAILED
Definition infix.h:391
@ INFIX_SUCCESS
Definition infix.h:390
@ INFIX_ERROR_INVALID_ARGUMENT
Definition infix.h:392
#define infix_free
A macro that can be defined to override the default free function.
Definition infix.h:330
void infix_arena_destroy(infix_arena_t *)
Destroys an arena and frees all memory allocated from it.
Definition arena.c:90
#define infix_memcpy
A macro that can be defined to override the default memcpy function.
Definition infix.h:335
c23_nodiscard void * infix_arena_calloc(infix_arena_t *, size_t, size_t, size_t)
Allocates and zero-initializes a block of memory from an arena.
Definition arena.c:198
#define infix_realloc
A macro that can be defined to override the default realloc function.
Definition infix.h:325
c23_nodiscard void * infix_arena_alloc(infix_arena_t *, size_t, size_t)
Allocates a block of memory from an arena.
Definition arena.c:126
#define infix_malloc
A macro that can be defined to override the default malloc function.
Definition infix.h:315
c23_nodiscard infix_arena_t * infix_arena_create(size_t)
Creates a new memory arena.
Definition arena.c:55
void infix_registry_destroy(infix_registry_t *registry)
Destroys a type registry and frees all associated memory.
Definition type_registry.c:230
c23_nodiscard infix_status infix_register_types(infix_registry_t *registry, const char *definitions)
Parses a string of type definitions and adds them to a registry.
Definition type_registry.c:460
c23_nodiscard infix_registry_t * infix_registry_create(void)
Creates a new, empty named type registry.
Definition type_registry.c:156
c23_nodiscard const infix_type * infix_registry_lookup_type(const infix_registry_t *registry, const char *name)
Retrieves the canonical infix_type object for a given name from the registry.
Definition type_registry.c:802
c23_nodiscard infix_registry_t * infix_registry_create_in_arena(infix_arena_t *arena)
Creates a new, empty named type registry that allocates from a user-provided arena.
Definition type_registry.c:196
c23_nodiscard const infix_type * infix_registry_iterator_get_type(const infix_registry_iterator_t *iter)
Gets the infix_type object of the type at the iterator's current position.
Definition type_registry.c:769
c23_nodiscard infix_registry_iterator_t infix_registry_iterator_begin(const infix_registry_t *registry)
Initializes an iterator for traversing the types in a registry.
Definition type_registry.c:695
c23_nodiscard bool infix_registry_iterator_next(infix_registry_iterator_t *iter)
Advances the iterator to the next defined type in the registry.
Definition type_registry.c:708
c23_nodiscard const char * infix_registry_iterator_get_name(const infix_registry_iterator_t *iter)
Gets the name of the type at the iterator's current position.
Definition type_registry.c:755
c23_nodiscard bool infix_registry_is_defined(const infix_registry_t *registry, const char *name)
Checks if a type with the given name is fully defined in the registry.
Definition type_registry.c:785
@ INFIX_TYPE_UNION
Definition infix.h:166
@ INFIX_TYPE_COMPLEX
Definition infix.h:170
@ INFIX_TYPE_ARRAY
Definition infix.h:167
@ INFIX_TYPE_VECTOR
Definition infix.h:171
@ INFIX_TYPE_POINTER
Definition infix.h:164
@ INFIX_TYPE_NAMED_REFERENCE
Definition infix.h:172
@ INFIX_TYPE_REVERSE_TRAMPOLINE
Definition infix.h:168
@ INFIX_TYPE_ENUM
Definition infix.h:169
@ INFIX_TYPE_STRUCT
Definition infix.h:165
Internal data structures, function prototypes, and constants.
void _infix_set_error(infix_error_category_t category, infix_error_code_t code, size_t position)
Sets the thread-local error state with detailed information.
Definition error.c:155
void _infix_type_recalculate_layout(infix_type *type)
Recalculates the layout of a fully resolved type graph.
Definition types.c:780
c23_nodiscard infix_status _infix_parse_type_internal(infix_type **, infix_arena_t **, const char *)
The internal core of the signature parser.
Definition signature.c:979
infix_type * _copy_type_graph_to_arena(infix_arena_t *, const infix_type *)
Performs a deep copy of a type graph into a destination arena.
Definition types.c:971
void _infix_clear_error(void)
Clears the thread-local error state.
Definition error.c:257
A single entry in the registry's hash table.
Definition infix_internals.h:161
bool is_forward_declaration
Definition infix_internals.h:164
const char * name
Definition infix_internals.h:162
infix_type * type
Definition infix_internals.h:163
struct _infix_registry_entry_t * next
Definition infix_internals.h:165
Definition type_registry.c:383
const char * start
Definition type_registry.c:385
const char * p
Definition type_registry.c:384
Internal definition of a memory arena.
Definition infix_internals.h:146
Provides detailed, thread-local information about the last error that occurred.
Definition infix.h:1360
Internal definition of a registry iterator.
Definition infix_internals.h:190
const _infix_registry_entry_t * current_entry
Definition infix_internals.h:193
const infix_registry_t * registry
Definition infix_internals.h:191
size_t current_bucket
Definition infix_internals.h:192
Internal definition of a named type registry.
Definition infix_internals.h:175
size_t num_items
Definition infix_internals.h:179
bool is_external_arena
Definition infix_internals.h:177
infix_arena_t * arena
Definition infix_internals.h:176
_infix_registry_entry_t ** buckets
Definition infix_internals.h:180
size_t num_buckets
Definition infix_internals.h:178
A semi-opaque structure that describes a C type.
Definition infix.h:211
Definition type_registry.c:65
struct resolve_memo_node_t * next
Definition type_registry.c:67
infix_type * src
Definition type_registry.c:66
static uint64_t _registry_hash_string(const char *str)
Definition type_registry.c:79
#define INITIAL_REGISTRY_BUCKETS
Definition type_registry.c:53
c23_nodiscard infix_status _infix_resolve_type_graph_inplace(infix_type **type_ptr, infix_registry_t *registry)
Resolves all named type references in a type graph in-place.
Definition type_registry.c:358
static _infix_registry_entry_t * _registry_lookup(infix_registry_t *registry, const char *name)
Definition type_registry.c:94
static _infix_registry_entry_t * _registry_insert(infix_registry_t *registry, const char *name)
Definition type_registry.c:118
static char * _registry_parser_parse_name(_registry_parser_state_t *state, char *buffer, size_t buf_size)
Definition type_registry.c:413
static void _registry_parser_skip_whitespace(_registry_parser_state_t *state)
Definition type_registry.c:393
static infix_status _resolve_type_graph_inplace_recursive(infix_arena_t *temp_arena, infix_type **type_ptr, infix_registry_t *registry, resolve_memo_node_t **memo_head)
Definition type_registry.c:260
INFIX_TLS const char * g_infix_last_signature_context
A thread-local pointer to the full signature string being parsed.
Definition error.c:89