49#define INITIAL_REGISTRY_BUCKETS 61
76 hash = ((hash << 5) + hash) + c;
92 if (strcmp(current->name, name) == 0)
128 size_t new_index = hash % new_num_buckets;
131 entry->
next = new_buckets[new_index];
132 new_buckets[new_index] = entry;
169 size_t name_len = strlen(name) + 1;
176 new_entry->
name = name_copy;
177 new_entry->
type =
nullptr;
273 for (
size_t i = 0; i <
src->num_buckets; ++i) {
290 if (!new_entry->
type) {
348 if (node->src == type)
357 memo_node->
src = type;
358 memo_node->
next = *memo_head;
359 *memo_head = memo_node;
367 if (!entry || !entry->
type) {
371 *type_ptr = entry->
type;
461 while (isspace((
unsigned char)*state->
p))
463 if (*state->
p ==
'#')
464 while (*state->
p !=
'\n' && *state->
p !=
'\0')
480 const char * name_start = state->
p;
481 while (isalnum((
unsigned char)*state->
p) || *state->
p ==
'_' || *state->
p ==
':') {
482 if (*state->
p ==
':' && state->
p[1] !=
':')
484 if (*state->
p ==
':')
488 size_t len = state->
p - name_start;
489 if (len == 0 || len >= buf_size)
533 const char * def_body_start;
536 size_t defs_capacity = 64;
537 struct def_info * defs_found =
infix_malloc(
sizeof(
struct def_info) * defs_capacity);
542 size_t num_defs_found = 0;
546 while (*state.
p !=
'\0') {
548 if (*state.
p ==
'\0')
550 if (*state.
p !=
'@') {
556 char name_buffer[256];
564 if (*state.
p ==
'=') {
580 if (num_defs_found >= defs_capacity) {
581 size_t new_capacity = defs_capacity * 2;
582 struct def_info * new_defs =
infix_realloc(defs_found,
sizeof(
struct def_info) * new_capacity);
588 defs_found = new_defs;
589 defs_capacity = new_capacity;
592 defs_found[num_defs_found].entry = entry;
593 defs_found[num_defs_found].def_body_start = state.
p;
595 const char * body_end = state.
p;
596 while (*body_end !=
'\0' &&
597 !(*body_end ==
';' &&
599 if (*body_end ==
'-' && body_end[1] ==
'>') {
603 if (*body_end ==
'{' || *body_end ==
'<' || *body_end ==
'(' || *body_end ==
'[')
605 if (*body_end ==
'}' || *body_end ==
'>' || *body_end ==
')' || *body_end ==
']')
609 defs_found[num_defs_found].def_body_len = body_end - state.
p;
613 else if (*state.
p ==
';') {
657 for (
size_t i = 0; i < num_defs_found; ++i) {
660 char * body_copy =
infix_malloc(defs_found[i].def_body_len + 1);
666 infix_memcpy(body_copy, defs_found[i].def_body_start, defs_found[i].def_body_len);
667 body_copy[defs_found[i].def_body_len] =
'\0';
686 if (existing_entry && existing_entry->
type)
687 type_to_alias = existing_entry->
type;
692 (
size_t)(defs_found[i].def_body_start -
definitions) + relative_pos);
706 *new_def = *type_to_alias;
726 *entry->
type = *new_def;
733 entry->
type = new_def;
742 for (
size_t i = 0; i < num_defs_found; ++i) {
750 size_t body_offset = defs_found[i].def_body_start -
definitions;
infix_arena_t * arena
Definition 005_layouts.c:62
const char * definitions
Definition 008_registry_introspection.c:36
infix_registry_t * registry
Definition 008_registry_introspection.c:33
infix_status status
Definition 103_unions.c:61
#define c23_nodiscard
Internal alias for the public INFIX_NODISCARD macro.
Definition compat_c23.h:91
#define INFIX_TLS
Definition error.c:68
INFIX_API 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:279
@ INFIX_CODE_UNRESOLVED_NAMED_TYPE
Definition infix.h:1368
@ INFIX_CODE_UNEXPECTED_TOKEN
Definition infix.h:1356
@ INFIX_CODE_NULL_POINTER
Definition infix.h:1346
@ INFIX_CODE_OUT_OF_MEMORY
Definition infix.h:1350
@ INFIX_CATEGORY_ALLOCATION
Definition infix.h:1335
@ INFIX_CATEGORY_GENERAL
Definition infix.h:1334
@ INFIX_CATEGORY_PARSER
Definition infix.h:1336
size_t source_offset
Definition infix.h:281
void * _current_entry
Definition infix.h:519
struct infix_type_t::@0::@1 pointer_info
Metadata for INFIX_TYPE_POINTER.
size_t position
Definition infix.h:1384
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:1382
const infix_registry_t * registry
Definition infix.h:517
bool is_incomplete
Definition infix.h:279
infix_type * type
Definition infix.h:347
struct infix_type_t::@0::@4 func_ptr_info
Metadata for INFIX_TYPE_REVERSE_TRAMPOLINE.
infix_arena_t * arena
Definition infix.h:280
size_t size
Definition infix.h:276
size_t alignment
Definition infix.h:277
infix_struct_member * members
Definition infix.h:292
struct infix_type_t::@0::@6 complex_info
Metadata for INFIX_TYPE_COMPLEX.
const char * name
Definition infix.h:274
infix_function_argument * args
Definition infix.h:305
infix_status
Enumerates the possible status codes returned by infix API functions.
Definition infix.h:433
infix_type_category category
Definition infix.h:275
size_t _bucket_index
Definition infix.h:518
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:288
infix_type * type
Definition infix.h:335
struct infix_type_t * element_type
Definition infix.h:298
struct infix_type_t * return_type
Definition infix.h:304
struct infix_type_t::@0::@5 enum_info
Metadata for INFIX_TYPE_ENUM.
struct infix_type_t * base_type
Definition infix.h:315
infix_error_code_t code
Definition infix.h:1383
size_t num_members
Definition infix.h:293
struct infix_type_t * underlying_type
Definition infix.h:311
struct infix_type_t::@0::@8 named_reference
Metadata for INFIX_TYPE_NAMED_REFERENCE.
size_t num_args
Definition infix.h:306
bool is_arena_allocated
Definition infix.h:278
@ INFIX_ERROR_ALLOCATION_FAILED
Definition infix.h:435
@ INFIX_SUCCESS
Definition infix.h:434
@ INFIX_ERROR_INVALID_ARGUMENT
Definition infix.h:436
#define infix_free
A macro that can be defined to override the default free function.
Definition infix.h:382
INFIX_API INFIX_NODISCARD void * infix_arena_alloc(infix_arena_t *, size_t, size_t)
Allocates a block of memory from an arena.
Definition arena.c:117
#define infix_memcpy
A macro that can be defined to override the default memcpy function.
Definition infix.h:386
#define infix_realloc
A macro that can be defined to override the default realloc function.
Definition infix.h:378
INFIX_API INFIX_NODISCARD infix_arena_t * infix_arena_create(size_t)
Creates a new memory arena.
Definition arena.c:52
INFIX_API INFIX_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:188
#define infix_malloc
A macro that can be defined to override the default malloc function.
Definition infix.h:370
INFIX_API void infix_arena_destroy(infix_arena_t *)
Destroys an arena and frees all memory allocated from it.
Definition arena.c:83
INFIX_API void infix_registry_destroy(infix_registry_t *registry)
Destroys a type registry and frees all associated memory.
Definition type_registry.c:310
INFIX_API 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:522
INFIX_API c23_nodiscard infix_registry_t * infix_registry_create(void)
Creates a new, empty named type registry.
Definition type_registry.c:197
INFIX_API c23_nodiscard infix_registry_t * infix_registry_clone(const infix_registry_t *src)
Creates a deep copy of an existing registry.
Definition type_registry.c:264
INFIX_API 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:888
INFIX_API 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:235
INFIX_API 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:799
INFIX_API 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:782
INFIX_API 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:856
INFIX_API 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:872
INFIX_API 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:842
@ INFIX_TYPE_UNION
Definition infix.h:231
@ INFIX_TYPE_COMPLEX
Definition infix.h:235
@ INFIX_TYPE_ARRAY
Definition infix.h:232
@ INFIX_TYPE_VECTOR
Definition infix.h:236
@ INFIX_TYPE_POINTER
Definition infix.h:229
@ INFIX_TYPE_NAMED_REFERENCE
Definition infix.h:237
@ INFIX_TYPE_REVERSE_TRAMPOLINE
Definition infix.h:233
@ INFIX_TYPE_ENUM
Definition infix.h:234
@ INFIX_TYPE_STRUCT
Definition infix.h:230
#define INFIX_API
Symbol visibility macro.
Definition infix.h:114
Internal data structures, function prototypes, and constants.
INFIX_INTERNAL 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:978
INFIX_INTERNAL 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:1141
INFIX_INTERNAL void _infix_type_recalculate_layout(infix_type *type)
Recalculates the layout of a fully resolved type graph.
Definition types.c:953
INFIX_INTERNAL void _infix_clear_error(void)
Clears the thread-local error state.
Definition error.c:266
INFIX_INTERNAL 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:173
A single entry in the registry's hash table.
Definition infix_internals.h:152
bool is_forward_declaration
Definition infix_internals.h:155
const char * name
Definition infix_internals.h:153
infix_type * type
Definition infix_internals.h:154
struct _infix_registry_entry_t * next
Definition infix_internals.h:156
Definition type_registry.c:450
const char * start
Definition type_registry.c:452
const char * p
Definition type_registry.c:451
Internal definition of a memory arena.
Definition infix_internals.h:138
Provides detailed, thread-local information about the last error that occurred.
Definition infix.h:1381
An iterator for traversing a type registry.
Definition infix.h:516
Internal definition of a named type registry.
Definition infix_internals.h:165
size_t num_items
Definition infix_internals.h:169
bool is_external_arena
Definition infix_internals.h:167
infix_arena_t * arena
Definition infix_internals.h:166
_infix_registry_entry_t ** buckets
Definition infix_internals.h:170
size_t num_buckets
Definition infix_internals.h:168
A semi-opaque structure that describes a C type.
Definition infix.h:273
Definition type_registry.c:60
struct resolve_memo_node_t * next
Definition type_registry.c:62
infix_type * src
Definition type_registry.c:61
static uint64_t _registry_hash_string(const char *str)
Definition type_registry.c:72
#define INITIAL_REGISTRY_BUCKETS
Definition type_registry.c:49
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:429
static void _registry_rehash(infix_registry_t *registry)
Definition type_registry.c:103
static _infix_registry_entry_t * _registry_lookup(infix_registry_t *registry, const char *name)
Definition type_registry.c:86
static _infix_registry_entry_t * _registry_insert(infix_registry_t *registry, const char *name)
Definition type_registry.c:156
static char * _registry_parser_parse_name(_registry_parser_state_t *state, char *buffer, size_t buf_size)
Definition type_registry.c:478
static void _registry_parser_skip_whitespace(_registry_parser_state_t *state)
Definition type_registry.c:459
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:338
INFIX_TLS const char * g_infix_last_signature_context
A thread-local pointer to the full signature string being parsed.
Definition error.c:99