diff --git a/examples/c_ffi_call/value_ffi.c b/examples/c_ffi_call/value_ffi.c index ef5c880..dd7a933 100644 --- a/examples/c_ffi_call/value_ffi.c +++ b/examples/c_ffi_call/value_ffi.c @@ -100,6 +100,32 @@ static int _val_to_ffi_type(metac_entry_t * p_entry, metac_flag_t variadic, ffi_ _process_(long, ffi_type_slong); _process_(long long, ffi_type_slong); #undef _process_ + } else if ( + metac_entry_is_va_list_parameter(p_entry) != 0 ) { + ffi_type * p_ffi_type = calloc(1, sizeof(ffi_type)); + if (p_ffi_type == NULL) { + return -ENOMEM; + } +#if __linux__ + p_ffi_type->alignment = 0; + p_ffi_type->type = FFI_TYPE_STRUCT; + p_ffi_type->size = sizeof(va_list); + p_ffi_type->elements = calloc(sizeof(ffi_type)/sizeof(void*) + 1 /* for NULL */, sizeof(ffi_type *)); + if (p_ffi_type->elements == NULL) { + free(p_ffi_type); + return -(ENOMEM); + } + for (int i = 0; i < sizeof(ffi_type)/sizeof(void*); ++i) { + p_ffi_type->elements[i] = calloc(1, sizeof(ffi_type)); + if (p_ffi_type->elements[i] != NULL) { + memcpy(p_ffi_type->elements[i], &ffi_type_pointer, sizeof(ffi_type)); + } + } +#else + memcpy(p_ffi_type, &ffi_type_pointer, sizeof(ffi_type)); +#endif + *pp_rtype = p_ffi_type; + return 0; } else if ( metac_entry_is_pointer(p_entry) != 0) { ffi_type * p_ffi_type = calloc(1, sizeof(ffi_type)); @@ -110,11 +136,9 @@ static int _val_to_ffi_type(metac_entry_t * p_entry, metac_flag_t variadic, ffi_ *pp_rtype = p_ffi_type; return 0; } else if ( - metac_entry_is_va_list_parameter(p_entry) != 0 || // TODO: to check - ( variadic != 0 && ( metac_entry_has_members(p_entry) != 0 || - metac_entry_has_elements(p_entry) != 0))) { + metac_entry_has_elements(p_entry) != 0)) { ffi_type * p_ffi_type = calloc(1, sizeof(ffi_type)); if (p_ffi_type == NULL) { return -ENOMEM; @@ -223,7 +247,7 @@ static int _val_to_ffi_type(metac_entry_t * p_entry, metac_flag_t variadic, ffi_ bitfield_state = 0; if (_val_to_ffi_type(p_memb_entry, variadic, &p_tmp->elements[memb_id]) != 0) { - free(p_tmp->elements); + free(p_tmp->elements); // TODO: cleanup _tmp->elements prior to free(p_tmp); return -(EFAULT); } @@ -437,7 +461,12 @@ int _call(metac_value_t * p_param_storage_val, void (*fn)(void), metac_value_t * } else { assert(va_list_number_cur < va_list_number); assert(p_val_list_entries[va_list_number_cur].id == i); - values[i] = &p_val_list_entries[va_list_number_cur].va_list_c; +#if __linux__ + values[i] = &p_val_list_entries[va_list_number_cur].va_list_c.parameters; +#else + va_list * x = &p_val_list_entries[va_list_number_cur].va_list_c; + values[i] = x; +#endif ++va_list_number_cur; // // simple approach (without recursion) // assert(metac_value_has_parameter_load(p_param_val)); diff --git a/examples/c_ffi_call/value_ffi_test.c b/examples/c_ffi_call/value_ffi_test.c index 69b74e9..352fc39 100644 --- a/examples/c_ffi_call/value_ffi_test.c +++ b/examples/c_ffi_call/value_ffi_test.c @@ -623,14 +623,20 @@ METAC_START_TEST(test_function_with_extra) { // variadic param tests int test_function_with_va_list(const char * format, va_list vl) { + // va_list l; + // va_copy(l, vl); + // int i = va_arg(l, int); + // va_end(l); + return vsnprintf(called, sizeof(called), format, vl); +// return 0; } METAC_GSYM_LINK(test_function_with_va_list); int test_function_with_va_args(const char * format, ...) { va_list l; va_start(l, format); - int res = test_function_with_va_list(format, l); + int res = vsnprintf(called, sizeof(called), format, l); va_end(l); return res; } @@ -786,14 +792,16 @@ METAC_START_TEST(test_variadic_list) { { called[0] = 0; metac_entry_t * p_entry = METAC_GSYM_LINK_ENTRY(test_function_with_va_list); - metac_value_t * p_params_val = METAC_NEW_VALUE_WITH_CALL_PARAMS_AND_WRAP(p_tagmap, p_entry, test_function_with_va_list, "test_function_with_va_list %d", VA_LIST(777)); + metac_value_t * p_params_val = METAC_NEW_VALUE_WITH_CALL_PARAMS_AND_WRAP(p_tagmap, p_entry, + test_function_with_va_list, "test_function_with_va_list %x %x %x %x %x %x", VA_LIST(1,2,3,4,5,6)); metac_value_t *p_res_val = metac_new_value_with_call_result(p_entry); int res = metac_value_call(p_params_val, (void (*)(void)) test_function_with_va_list, p_res_val); - expected = "test_function_with_va_list(\"test_function_with_va_list %d\", VA_LIST((int)777))"; + expected = "test_function_with_va_list(\"test_function_with_va_list %x %x %x %x %x %x\", " + "VA_LIST((unsigned int)1, (unsigned int)2, (unsigned int)3, (unsigned int)4, (unsigned int)5, (unsigned int)6))"; s = metac_value_string_ex(p_params_val, METAC_WMODE_deep, p_tagmap); fail_unless(s != NULL); - //fail_unless(strcmp(s, expected) == 0, "got %s, expected %s", s, expected); + fail_unless(strcmp(s, expected) == 0, "got %s, expected %s", s, expected); free(s); fail_unless(res == 0, "Call wasn't successful, expected successful");