Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for more arg types #23

Merged
merged 4 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion examples/c_print_args_alt/main.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

#include "print_args.h"
#include "metac/backend/va_list_ex.h"

#include <stdlib.h> /*free*/

Expand Down Expand Up @@ -36,6 +37,11 @@ int my_printf(const char * format, ...) {
}
METAC_GSYM_LINK(my_printf);

int my_vprintf(const char * format, va_list l) {
return vprintf(format, l);
}
METAC_GSYM_LINK(my_vprintf);

enum x {
xOne = 1,
xTwo = 2,
Expand All @@ -46,6 +52,11 @@ int test_function4_with_enum_args(enum x arg0, enum x arg1, enum x arg2) {
}
METAC_GSYM_LINK(test_function4_with_enum_args);

int test_function4_with_struct_args(list_t x) {
return 0;
}
METAC_GSYM_LINK(test_function4_with_struct_args);

metac_tag_map_t * p_tagmap = NULL;
METAC_TAG_MAP_NEW(va_args_tag_map, NULL, {.mask =
METAC_TAG_MAP_ENTRY_CATEGORY_MASK(METAC_TEC_variable) |
Expand All @@ -63,13 +74,22 @@ METAC_TAG_MAP_NEW(va_args_tag_map, NULL, {.mask =
)
METAC_TAG_MAP_ENTRY_END

METAC_TAG_MAP_ENTRY(METAC_GSYM_LINK_ENTRY(my_vprintf))
METAC_TAG_MAP_SET_TAG(0, METAC_TEO_entry, 0, METAC_TAG_MAP_ENTRY_PARAMETER({.n = "format"}),
METAC_ZERO_ENDED_STRING()
)
METAC_TAG_MAP_SET_TAG(0, METAC_TEO_entry, 0, METAC_TAG_MAP_ENTRY_PARAMETER({.n = "l"}),
METAC_FORMAT_BASED_VA_ARG()
)
METAC_TAG_MAP_ENTRY_END

METAC_TAG_MAP_END
//

int main() {
p_tagmap = va_args_tag_map();

printf("fn returned: %i\n", METAC_WRAP_FN_RES(NULL, test_function1_with_args,10, 22));
printf("fn returned: %i\n", METAC_WRAP_FN_RES(NULL, test_function1_with_args, 10, 22));

list_t * p_list = (list_t[]){{.x = 42.42, .p_next = (list_t[]){{ .x = 45.4, .p_next = NULL}}}};
printf("fn returned: %f\n", METAC_WRAP_FN_RES(NULL, test_function3_with_args, p_list));
Expand All @@ -79,6 +99,16 @@ int main() {
printf("fn returned: %i\n", METAC_WRAP_FN_RES(p_tagmap, test_function4_with_enum_args, xOne, xTwo, xMinusOne));
printf("fn returned: %i\n", METAC_WRAP_FN_RES(p_tagmap, test_function4_with_enum_args, 1, 2, -1));

printf("fn returned: %i\n", METAC_WRAP_FN_RES(p_tagmap, test_function4_with_struct_args, *p_list));

#if __linux__
#else
WITH_VA_LIST_CONTAINER(c,
VA_LIST_CONTAINER(c, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
printf("fn returned: %i\n", METAC_WRAP_FN_RES(p_tagmap, my_vprintf, "%d %d %d %d %d %d %d %d %d %d\n", c.parameters));
);
#endif

metac_tag_map_delete(p_tagmap);
return 0;
}
72 changes: 58 additions & 14 deletions examples/c_print_args_alt/print_args.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,18 @@
#include "metac/backend/value.h"
#include "mr.h"

static int _process_unspecified_params(
static int _process_unspecified_params_cntr(
//context
metac_parameter_storage_t * p_param_storage,
metac_value_t * p_val,
metac_entry_t *p_param_entry,
metac_tag_map_t * p_tag_map,
metac_num_t param_id,
// and all params
int n, ...) {
int n,
struct va_list_container * p_cntr) {

metac_recursive_iterator_t * p_iter = metac_new_recursive_iterator(p_val);

struct va_list_container cntr = {};
va_start(cntr.parameters, p_tag_map);

metac_value_t * p = (metac_value_t *)metac_recursive_iterator_next(p_iter); /* value itself */
metac_entry_tag_t * p_tag = metac_tag_map_tag(p_tag_map, p_param_entry);
Expand All @@ -28,7 +26,7 @@ static int _process_unspecified_params(
.type = METAC_RQVST_va_list,
.va_list_param_id = param_id,
.p_return_value = metac_parameter_storage_new_param_value(p_param_storage, param_id),
.p_va_list_container = &cntr,
.p_va_list_container = p_cntr,
};
if (ev.p_return_value == NULL) {
metac_recursive_iterator_fail(p_iter);
Expand All @@ -42,14 +40,40 @@ static int _process_unspecified_params(
metac_recursive_iterator_fail(p_iter);
}

va_end(cntr.parameters);

int failed = 0;
metac_recursive_iterator_get_out(p_iter, NULL, &failed);
metac_recursive_iterator_free(p_iter);
return failed;
}

static int _process_unspecified_params(
//context
metac_parameter_storage_t * p_param_storage,
metac_value_t * p_val,
metac_entry_t *p_param_entry,
metac_tag_map_t * p_tag_map,
metac_num_t param_id,
// and all params
int n, ...) {
struct va_list_container cntr = {};
va_start(cntr.parameters, p_tag_map);

int failed = _process_unspecified_params_cntr(
p_param_storage,
p_val,
p_param_entry,
p_tag_map,
param_id,
n, &cntr);

va_end(cntr.parameters);
return failed;
}

static void _va_list_cp_to_container(struct va_list_container * dst, va_list src) {
va_copy(dst->parameters, src);
}

#define _process_bt_(arg, _type_, _pseudoname_, _short_type_name_) \
if (strcmp(param_base_type_name, #_pseudoname_) == 0 && param_entry_byte_size == sizeof(_type_)) { \
metac_value_set_##_short_type_name_(p_param_value, *((_type_*)arg)); \
Expand All @@ -66,7 +90,16 @@ static int _process_unspecified_params(
#define _QSTRING_ARG(_args) \
_QSTRING(_args)

// #if __linux__
// #define _init_x_val(arg) \
// typeof(arg) _x_val = _Generic(arg, va_list: dummy, default: arg);
// #else
#define _init_x_val(arg) \
typeof(arg) _x_val = arg;
//#endif

#define _APPEND_PARAM(_NEXT_, _N_, args...) if (failure == 0) { \
va_list dummy; \
metac_entry_t *p_param_entry = metac_entry_by_paremeter_id(p_val_entry, param_id); \
if (metac_entry_is_unspecified_parameter(p_param_entry) == 0 && metac_entry_is_va_list_parameter(p_param_entry) == 0) { \
/* normal argument */ \
Expand All @@ -82,7 +115,8 @@ static int _process_unspecified_params(
failure = 2; \
break; \
} \
typeof(MR_FIRST(args)) _x_val = MR_FIRST(args); \
/*typeof(MR_FIRST(args)) _x_val = _Generic(MR_FIRST(args), char*:MR_FIRST(args), default: MR_FIRST(args)); */ \
_init_x_val(MR_FIRST(args)) \
if (metac_parameter_storage_append_by_buffer(p_param_storage, p_param_entry, param_entry_byte_size) == 0) { \
metac_value_t * p_param_value = metac_parameter_storage_new_param_value(p_param_storage, param_id); \
\
Expand Down Expand Up @@ -115,12 +149,14 @@ static int _process_unspecified_params(
/* ensure arg isn't string constant */ \
char _s_arg[] = _QSTRING_ARG(MR_FIRST(args)); \
if (_s_arg[0] == '\"') { \
/* TODO: can't handle structs, va_list as arguments because of this line */ \
char * s = ((char*)MR_FIRST(args)); \
/* can't handle structs, va_list as arguments because of this line */ \
char * s = ((char*)_Generic(MR_FIRST(args), char*: MR_FIRST(args), default: NULL)); \
memcpy(metac_value_addr(p_param_value), &s, param_entry_byte_size); \
} else { \
memcpy(metac_value_addr(p_param_value), &_x_val, param_entry_byte_size); \
} \
} else if (metac_entry_has_members(p_param_type_entry) != 0) { \
memcpy(metac_value_addr(p_param_value), &_x_val, param_entry_byte_size); \
} else { \
/* not supported */ \
failure = 3; \
Expand All @@ -131,9 +167,17 @@ static int _process_unspecified_params(
metac_value_delete(p_param_value); \
} \
} else if (metac_entry_is_va_list_parameter(p_param_entry) != 0) { \
/* not supported */ \
failure = 4; \
break; \
struct va_list_container cntr = {}; \
_va_list_cp_to_container(&cntr, _Generic(MR_FIRST(args), va_list: MR_FIRST(args), default: dummy)); \
if (metac_parameter_storage_append_by_parameter_storage(p_param_storage, p_param_entry) != 0) { \
failure = 5; \
break; \
} \
if (_process_unspecified_params_cntr(p_param_storage, p_val, p_param_entry, p_tag_map, param_id, _N_ , &cntr) != 0) { \
failure = 6; \
break; \
} \
va_end(cntr.parameters); \
} else if (metac_entry_is_unspecified_parameter(p_param_entry) != 0) { \
if (metac_parameter_storage_append_by_parameter_storage(p_param_storage, p_param_entry) != 0) { \
failure = 5; \
Expand Down
Loading