Alien-TinyCCx
view release on metacpan or search on metacpan
src/tests/exsymtab/32-two-contexts-struct-self-reference.c view on Meta::CPAN
#define INCLUDE_MALLOC
#include "test_setup.h"
char first_code[] =
"void * malloc(int);\n"
"void free(void *);\n"
"#define STRUCT_SV sv\n"
"typedef struct STRUCT_SV SV;\n"
"struct STRUCT_SV { /* struct sv { */\n"
" int x;\n"
" int yval;\n"
" union {\n"
" int next_offset;\n"
" SV * next_pt;\n"
" } sv_u;\n"
"};\n"
"void * new_point(int x, int newy) {\n"
" SV * pt = malloc(sizeof(SV));\n"
" pt->x = x;\n"
" pt->yval = newy;\n"
" pt->sv_u.next_offset = 0;\n"
" return pt;\n"
"}\n"
;
char second_code[] =
"int sq_distance_to_pt(SV * pt) {\n"
" return (pt->x) * (pt->x) + (pt->yval) * (pt->yval);\n"
"}\n"
;
int main(int argc, char **argv)
{
/* ---- Compile the first code string and setup the callback data ---- */
TCCState *s1 = tcc_new();
extended_symtab_p my_symtab;
setup_and_compile_s1(my_symtab, first_code);
SETUP_SECOND_CALLBACK_DATA();
/* ---- Allocate a point and manually unpack it ---- */
void* (*allocate_ptr)(int, int) = tcc_get_symbol(s1, "new_point");
if (allocate_ptr == NULL) return 1;
void * point_p = allocate_ptr(6, 9);
if (point_p == NULL) {
fail("Unable to allocate point");
return 1;
}
else
pass("Allocated point");
int * manual_unpack = point_p;
is_i(manual_unpack[0], 6, "manually unpacked x-value");
is_i(manual_unpack[1], 9, "manually unpacked y-value");
/* ---- Compile the second compiler context ---- */
TCCState * s_second = tcc_new();
setup_and_relocate_second_state(s_second, second_code);
int (*sq_dist_ptr)(void*) = tcc_get_symbol(s_second, "sq_distance_to_pt");
if (sq_dist_ptr == NULL) return 1;
is_i(sq_dist_ptr(point_p), 9*9+6*6, "Second context able to unpack struct");
/* ---- clean up the memory ---- */
tcc_delete_extended_symbol_table(my_symtab);
tcc_delete(s1);
tcc_delete(s_second);
free(point_p);
pass("cleanup");
return done_testing();
}
( run in 0.760 second using v1.01-cache-2.11-cpan-5511b514fd6 )