49#define INITIAL_REGISTRY_BUCKETS 61
76 hash = ((hash << 5) + hash) + c;
92 if (strcmp(current->name, name) == 0)
117 size_t name_len = strlen(name) + 1;
124 new_entry->
name = name_copy;
125 new_entry->
type =
nullptr;
254 if (node->src == type)
263 memo_node->
src = type;
264 memo_node->
next = *memo_head;
265 *memo_head = memo_node;
273 if (!entry || !entry->
type) {
277 *type_ptr = entry->
type;
367 while (isspace((
unsigned char)*state->
p))
369 if (*state->
p ==
'#')
370 while (*state->
p !=
'\n' && *state->
p !=
'\0')
386 const char * name_start = state->
p;
387 while (isalnum((
unsigned char)*state->
p) || *state->
p ==
'_' || *state->
p ==
':') {
388 if (*state->
p ==
':' && state->
p[1] !=
':')
390 if (*state->
p ==
':')
394 size_t len = state->
p - name_start;
395 if (len == 0 || len >= buf_size)
441 const char * def_body_start;
444 size_t defs_capacity = 64;
445 struct def_info * defs_found =
infix_malloc(
sizeof(
struct def_info) * defs_capacity);
450 size_t num_defs_found = 0;
453 while (*state.
p !=
'\0') {
455 if (*state.
p ==
'\0')
457 if (*state.
p !=
'@') {
463 char name_buffer[256];
471 if (*state.
p ==
'=') {
487 if (num_defs_found >= defs_capacity) {
488 size_t new_capacity = defs_capacity * 2;
489 struct def_info * new_defs =
infix_realloc(defs_found,
sizeof(
struct def_info) * new_capacity);
495 defs_found = new_defs;
496 defs_capacity = new_capacity;
499 defs_found[num_defs_found].entry = entry;
500 defs_found[num_defs_found].def_body_start = state.
p;
502 const char * body_end = state.
p;
503 while (*body_end !=
'\0' &&
504 !(*body_end ==
';' &&
506 if (*body_end ==
'-' && body_end[1] ==
'>') {
510 if (*body_end ==
'{' || *body_end ==
'<' || *body_end ==
'(' || *body_end ==
'[')
512 if (*body_end ==
'}' || *body_end ==
'>' || *body_end ==
')' || *body_end ==
']')
516 defs_found[num_defs_found].def_body_len = body_end - state.
p;
520 else if (*state.
p ==
';') {
542 for (
size_t i = 0; i < num_defs_found; ++i) {
545 char * body_copy =
infix_malloc(defs_found[i].def_body_len + 1);
551 infix_memcpy(body_copy, defs_found[i].def_body_start, defs_found[i].def_body_len);
552 body_copy[defs_found[i].def_body_len] =
'\0';
571 if (existing_entry && existing_entry->
type)
572 type_to_alias = existing_entry->
type;
576 (
size_t)(defs_found[i].def_body_start -
definitions));
592 *prim_copy = *type_to_alias;
595 entry->
type = prim_copy;
610 for (
size_t i = 0; i < num_defs_found; ++i) {
infix_arena_t * arena
Definition 005_layouts.c:60
const char * definitions
Definition 008_registry_introspection.c:35
infix_registry_t * registry
Definition 008_registry_introspection.c:32
infix_status status
Definition 103_unions.c:59
#define c23_nodiscard
A compatibility macro for the C23 [[nodiscard]] attribute.
Definition compat_c23.h:106
#define INFIX_TLS
Definition error.c:68
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:271
@ INFIX_CODE_UNRESOLVED_NAMED_TYPE
Definition infix.h:1242
@ INFIX_CODE_UNEXPECTED_TOKEN
Definition infix.h:1232
@ INFIX_CODE_UNKNOWN
Definition infix.h:1226
@ INFIX_CODE_OUT_OF_MEMORY
Definition infix.h:1228
@ INFIX_CATEGORY_ALLOCATION
Definition infix.h:1216
@ INFIX_CATEGORY_GENERAL
Definition infix.h:1215
@ INFIX_CATEGORY_PARSER
Definition infix.h:1217
struct infix_type_t::@0::@1 pointer_info
Metadata for INFIX_TYPE_POINTER.
size_t position
Definition infix.h:1257
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:1255
infix_type * type
Definition infix.h:266
struct infix_type_t::@0::@4 func_ptr_info
Metadata for INFIX_TYPE_REVERSE_TRAMPOLINE.
infix_arena_t * arena
Definition infix.h:200
infix_struct_member * members
Definition infix.h:211
struct infix_type_t::@0::@6 complex_info
Metadata for INFIX_TYPE_COMPLEX.
const char * name
Definition infix.h:195
infix_function_argument * args
Definition infix.h:224
infix_status
Enumerates the possible status codes returned by infix API functions.
Definition infix.h:352
infix_type_category category
Definition infix.h:196
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:207
infix_type * type
Definition infix.h:254
struct infix_type_t * element_type
Definition infix.h:217
struct infix_type_t * return_type
Definition infix.h:223
struct infix_type_t::@0::@5 enum_info
Metadata for INFIX_TYPE_ENUM.
struct infix_type_t * base_type
Definition infix.h:234
infix_error_code_t code
Definition infix.h:1256
size_t num_members
Definition infix.h:212
struct infix_type_t * underlying_type
Definition infix.h:230
struct infix_type_t::@0::@8 named_reference
Metadata for INFIX_TYPE_NAMED_REFERENCE.
size_t num_args
Definition infix.h:225
bool is_arena_allocated
Definition infix.h:199
@ INFIX_ERROR_ALLOCATION_FAILED
Definition infix.h:354
@ INFIX_SUCCESS
Definition infix.h:353
@ INFIX_ERROR_INVALID_ARGUMENT
Definition infix.h:355
#define infix_free
A macro that can be defined to override the default free function.
Definition infix.h:301
void infix_arena_destroy(infix_arena_t *)
Destroys an arena and frees all memory allocated from it.
Definition arena.c:83
#define infix_memcpy
A macro that can be defined to override the default memcpy function.
Definition infix.h:305
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:179
#define infix_realloc
A macro that can be defined to override the default realloc function.
Definition infix.h:297
c23_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_malloc
A macro that can be defined to override the default malloc function.
Definition infix.h:289
c23_nodiscard infix_arena_t * infix_arena_create(size_t)
Creates a new memory arena.
Definition arena.c:52
void infix_registry_destroy(infix_registry_t *registry)
Destroys a type registry and frees all associated memory.
Definition type_registry.c:216
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:430
c23_nodiscard infix_registry_t * infix_registry_create(void)
Creates a new, empty named type registry.
Definition type_registry.c:145
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:740
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:183
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:709
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:645
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:657
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:696
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:724
@ INFIX_TYPE_UNION
Definition infix.h:152
@ INFIX_TYPE_COMPLEX
Definition infix.h:156
@ INFIX_TYPE_ARRAY
Definition infix.h:153
@ INFIX_TYPE_VECTOR
Definition infix.h:157
@ INFIX_TYPE_POINTER
Definition infix.h:150
@ INFIX_TYPE_NAMED_REFERENCE
Definition infix.h:158
@ INFIX_TYPE_REVERSE_TRAMPOLINE
Definition infix.h:154
@ INFIX_TYPE_ENUM
Definition infix.h:155
@ INFIX_TYPE_STRUCT
Definition infix.h:151
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:165
void _infix_type_recalculate_layout(infix_type *type)
Recalculates the layout of a fully resolved type graph.
Definition types.c:938
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:963
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:1125
void _infix_clear_error(void)
Clears the thread-local error state.
Definition error.c:258
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:356
const char * start
Definition type_registry.c:358
const char * p
Definition type_registry.c:357
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:1254
Internal definition of a registry iterator.
Definition infix_internals.h:179
const _infix_registry_entry_t * current_entry
Definition infix_internals.h:182
const infix_registry_t * registry
Definition infix_internals.h:180
size_t current_bucket
Definition infix_internals.h:181
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:194
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:335
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:109
static char * _registry_parser_parse_name(_registry_parser_state_t *state, char *buffer, size_t buf_size)
Definition type_registry.c:384
static void _registry_parser_skip_whitespace(_registry_parser_state_t *state)
Definition type_registry.c:365
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:244
INFIX_TLS const char * g_infix_last_signature_context
A thread-local pointer to the full signature string being parsed.
Definition error.c:99