infix
A JIT-Powered FFI Library for C
Loading...
Searching...
No Matches
004_signatures.c File Reference

Unit test for the signature string parser. More...

#include "common/compat_c23.h"
#include "common/double_tap.h"
#include <ctype.h>
#include <infix/infix.h>
#include <string.h>
Include dependency graph for 004_signatures.c:

Macros

#define DBLTAP_IMPLEMENTATION
 
#define CHECK_MANGLING(signature, dialect, expected_output)
 
#define CHECK_FUNC_MANGLING(sig, name, dialect, expected)
 

Functions

static void test_type_ok (const char *signature, infix_type_category expected_cat, const char *name)
 
static void test_type_fail (const char *signature, const char *name)
 
void dummy_handler ()
 
static void normalize_string (char *s)
 
static void test_print_roundtrip (const char *signature, const char *expected_output)
 
 subtest ("Valid Single Types")
 
 subtest ("Valid Edge Cases (Whitespace, Nesting, Empty)")
 
 subtest ("Valid Full Function Signatures")
 
 subtest ("Invalid Syntax and Logic")
 
 subtest ("Registry Type Introspection")
 
 subtest ("Round trip")
 
 subtest ("Round trip with named fields")
 
 subtest ("Mangling")
 

Variables

 TEST
 

Detailed Description

Unit test for the signature string parser.

This is one of the most important test files, as it exhaustively validates the correctness and robustness of the infix signature parser. It is divided into several subtests:

  • Valid Single Types: Checks that a wide variety of correct, individual type signatures (primitives, pointers, arrays, aggregates) parse successfully and result in the expected infix_type_category.
  • Valid Edge Cases: Tests the parser's handling of non-standard but valid syntax, such as extra whitespace, comments, empty aggregates ({}), and deeply nested pointer/function types.
  • Valid Full Function Signatures: Uses infix_signature_parse to test the parsing of complete function signatures, including variadic functions (with ;) and named arguments.
  • Invalid Syntax and Logic: A large set of negative test cases that feed the parser deliberately malformed or logically invalid signatures (e.g., [10:void]). It verifies that the parser correctly fails for each case.
  • Round Trip: A critical test that parses a signature, then uses infix_type_print to serialize the resulting type object back into a string. It then verifies that the output string matches the canonical representation of the input, ensuring that parsing and printing are inverse operations.
  • Mangling: This test verifies that infix can correctly generate C++ mangled names for both Itanium (GCC/Clang) and MSVC ABIs. It covers:
    • Primitive types (int, float, void, etc.)
    • Pointers
    • Named types (Structs)
    • Function signatures

Macro Definition Documentation

◆ CHECK_FUNC_MANGLING

#define CHECK_FUNC_MANGLING (   sig,
  name,
  dialect,
  expected 
)
Value:
do { \
infix_arena_t * arena = NULL; \
infix_type * ret_type = NULL; \
size_t n_args, n_fixed; \
if (infix_signature_parse(sig, &arena, &ret_type, &args, &n_args, &n_fixed, registry) == INFIX_SUCCESS) { \
char buffer[256]; \
if (infix_function_print(buffer, sizeof(buffer), name, ret_type, args, n_args, n_fixed, dialect) == \
ok(strcmp(buffer, expected) == 0, "Func Mangling '%s' -> '%s'", name, buffer); \
} \
else { \
fail("Func print failed"); \
} \
} \
else { \
fail("Func parse failed"); \
} \
infix_arena_destroy(arena); \
} while (0)
infix_arena_t * arena
Definition 005_layouts.c:62
infix_registry_t * registry
Definition 008_registry_introspection.c:33
void * args[]
Definition 202_in_structs.c:59
infix_type * ret_type
Definition 901_call_overhead.c:61
INFIX_API INFIX_NODISCARD infix_status infix_signature_parse(const char *, infix_arena_t **, infix_type **, infix_function_argument **, size_t *, size_t *, infix_registry_t *)
Parses a full function signature string into its constituent parts.
Definition signature.c:1087
@ INFIX_SUCCESS
Definition infix.h:434
INFIX_API INFIX_NODISCARD infix_status infix_function_print(char *, size_t, const char *, const infix_type *, const infix_function_argument *, size_t, size_t, infix_print_dialect_t)
Serializes a function signature's components into a string.
Definition signature.c:1892
Internal definition of a memory arena.
Definition infix_internals.h:138
Describes a single argument to a C function.
Definition infix.h:345
A semi-opaque structure that describes a C type.
Definition infix.h:273

◆ CHECK_MANGLING

#define CHECK_MANGLING (   signature,
  dialect,
  expected_output 
)
Value:
do { \
infix_type * type = NULL; \
infix_arena_t * arena = NULL; \
if (infix_type_from_signature(&type, &arena, signature, registry) == INFIX_SUCCESS) { \
char buffer[256]; \
if (infix_type_print(buffer, sizeof(buffer), type, dialect) == INFIX_SUCCESS) { \
ok(strcmp(buffer, expected_output) == 0, \
"Mangling '%s' -> '%s' (Expected: '%s')", \
signature, \
buffer, \
expected_output); \
} \
else { \
fail("Print failed for '%s'", signature); \
} \
} \
else { \
fail("Parse failed for '%s'", signature); \
} \
infix_arena_destroy(arena); \
} while (0)
INFIX_API INFIX_NODISCARD infix_status infix_type_from_signature(infix_type **, infix_arena_t **, const char *, infix_registry_t *)
Parses a signature string representing a single data type.
Definition signature.c:1028
INFIX_API INFIX_NODISCARD infix_status infix_type_print(char *, size_t, const infix_type *, infix_print_dialect_t)
Serializes an infix_type object graph back into a signature string.
Definition signature.c:1845

◆ DBLTAP_IMPLEMENTATION

#define DBLTAP_IMPLEMENTATION

Function Documentation

◆ dummy_handler()

void dummy_handler ( )

◆ normalize_string()

static void normalize_string ( char *  s)
static

◆ subtest() [1/8]

subtest ( "Invalid Syntax and Logic"  )

◆ subtest() [2/8]

subtest ( "Mangling"  )

◆ subtest() [3/8]

subtest ( "Registry Type Introspection"  )

◆ subtest() [4/8]

subtest ( "Round trip with named fields"  )

◆ subtest() [5/8]

subtest ( "Round trip"  )

◆ subtest() [6/8]

subtest ( "Valid Edge Cases (Whitespace, Nesting, Empty)"  )

◆ subtest() [7/8]

subtest ( "Valid Full Function Signatures"  )

◆ subtest() [8/8]

subtest ( "Valid Single Types"  )

◆ test_print_roundtrip()

static void test_print_roundtrip ( const char *  signature,
const char *  expected_output 
)
static

◆ test_type_fail()

static void test_type_fail ( const char *  signature,
const char *  name 
)
static

◆ test_type_ok()

static void test_type_ok ( const char *  signature,
infix_type_category  expected_cat,
const char *  name 
)
static

Variable Documentation

◆ TEST

TEST
Initial value:
{
plan(8)
#define plan(count)
Definition double_tap.h:192