From fb375c6ef4441ce3784129cd6a4d8e1afe2173fe Mon Sep 17 00:00:00 2001 From: Alexey Odinokov Date: Wed, 5 Jun 2024 01:09:04 -0500 Subject: [PATCH] made return print implementation --- examples/c_print_args/main.c | 78 +++++++++++++++++++++++++++++++---- include/metac/reflect/entry.h | 10 +++++ src/entry.c | 12 ++++++ 3 files changed, 92 insertions(+), 8 deletions(-) diff --git a/examples/c_print_args/main.c b/examples/c_print_args/main.c index d03e2b0..2dc53b1 100644 --- a/examples/c_print_args/main.c +++ b/examples/c_print_args/main.c @@ -5,13 +5,10 @@ #include "metac/reflect.h" -void print_args(metac_tag_map_t * p_tag_map, metac_entry_t *p_entry, ...) { +void vprint_args(metac_tag_map_t * p_tag_map, metac_entry_t *p_entry, va_list args) { if (p_entry == NULL || metac_entry_has_paremeter(p_entry) == 0) { return; } - - va_list args; - va_start(args, p_entry); printf("%s(", metac_entry_name(p_entry)); @@ -45,13 +42,11 @@ void print_args(metac_tag_map_t * p_tag_map, metac_entry_t *p_entry, ...) { } char buf[32]; - int handled = 0; #define _handle_sz_(_sz_) \ do { \ if (param_byte_sz == _sz_) { \ - char *x = &buf[0]; \ - x = va_arg(args, char[_sz_]); \ + char *x = va_arg(args, char[_sz_]); \ memcpy(buf, x, _sz_); \ handled = 1; \ } \ @@ -118,16 +113,73 @@ void print_args(metac_tag_map_t * p_tag_map, metac_entry_t *p_entry, ...) { metac_value_delete(p_val); } - printf(")\n"); + printf(")"); +} + +void print_args(metac_tag_map_t * p_tag_map, metac_entry_t *p_entry, ...) { + va_list args; + va_start(args, p_entry); + vprint_args(p_tag_map, p_entry, args); va_end(args); return; } +void print_res(metac_tag_map_t * p_tag_map, metac_entry_t * p_entry, metac_value_t * p_val) { + if (p_entry == NULL || metac_entry_has_result(p_entry) == 0 || p_val == NULL) { + return; + } + metac_entry_t * p_res_type = metac_entry_result_type(p_entry); + if (metac_entry_final_entry(p_res_type, NULL) != metac_entry_final_entry(metac_value_entry(p_val), NULL)) { + printf("provided type doesn't match with type info\n"); + return; + } + char * v = metac_value_string_ex(p_val, METAC_WMODE_deep, p_tag_map); + if (v == NULL) { + return; + } + + printf("%s() returned %s\n", metac_entry_name(p_entry), v); + free(v); +} + +void print_args_and_res(metac_tag_map_t * p_tag_map, metac_entry_t * p_entry, metac_value_t * p_val, ...) { + if (p_entry == NULL || metac_entry_has_result(p_entry) == 0 || p_val == NULL) { + return; + } + metac_entry_t * p_res_type = metac_entry_result_type(p_entry); + if (metac_entry_final_entry(p_res_type, NULL) != metac_entry_final_entry(metac_value_entry(p_val), NULL)) { + printf("provided type doesn't match with type info\n"); + return; + } + char * v = metac_value_string_ex(p_val, METAC_WMODE_deep, p_tag_map); + if (v == NULL) { + return; + } + + va_list args; + va_start(args, p_val); + vprint_args(p_tag_map, p_entry, args); + va_end(args); + printf(" returned %s\n", v); + free(v); +} + #define METAC_WRAP_FN(_fn_, _args_...) ({ \ + printf("calling "); \ print_args(NULL, METAC_GSYM_LINK_ENTRY(_fn_), _args_); \ + printf("\n"); \ _fn_(_args_); \ }) +#define METAC_WRAP_FN_RES(_type_, _fn_, _args_...) ({ \ + printf("calling "); \ + print_args(NULL, METAC_GSYM_LINK_ENTRY(_fn_), _args_); \ + printf("\n"); \ + WITH_METAC_DECLLOC(loc, _type_ res = _fn_(_args_)); \ + print_args_and_res(NULL, METAC_GSYM_LINK_ENTRY(_fn_), METAC_VALUE_FROM_DECLLOC(loc, res), _args_); \ + res; \ + }) + int test_function1_with_args(int a, short b){ @@ -155,6 +207,12 @@ double test_function3_with_args(list_t *p_list) { } METAC_GSYM_LINK(test_function3_with_args); +double test_function4_with_args(list_t *p_list) { + return METAC_WRAP_FN_RES(double, test_function3_with_args, p_list) - 1000; +} +METAC_GSYM_LINK(test_function4_with_args); + + int main() { printf("fn returned: %i\n", METAC_WRAP_FN(test_function1_with_args, 10, 22)); @@ -164,5 +222,9 @@ int main() { 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(test_function3_with_args, p_list)); + METAC_WRAP_FN_RES(int, test_function2_with_args, &x, 22); + + METAC_WRAP_FN_RES(double, test_function4_with_args, p_list); + return 0; } \ No newline at end of file diff --git a/include/metac/reflect/entry.h b/include/metac/reflect/entry.h index 4acce17..09a5123 100644 --- a/include/metac/reflect/entry.h +++ b/include/metac/reflect/entry.h @@ -262,4 +262,14 @@ metac_flag_t metac_entry_is_unspecified_parameter(metac_entry_t * p_entry); */ metac_entry_t * metac_entry_parameter_entry(metac_entry_t *p_entry); +/** + * @brief check if final entry is function (METAC_KND_subroutine) which isn't void +*/ +metac_flag_t metac_entry_has_result(metac_entry_t * p_entry); + +/** + * @brief returns type which the function returns +*/ +metac_entry_t * metac_entry_result_type(metac_entry_t * p_entry); + #endif \ No newline at end of file diff --git a/src/entry.c b/src/entry.c index 6a1dc99..f47b98b 100644 --- a/src/entry.c +++ b/src/entry.c @@ -529,6 +529,18 @@ metac_entry_t * metac_entry_by_parameter_ids(metac_entry_t * p_entry, metac_flag return metac_entry_final_entry(p_entry, NULL); } +metac_flag_t metac_entry_has_result(metac_entry_t * p_entry) { + metac_entry_t * p_final_entry = _entry_with_paremeter_info(p_entry); + _check_(p_final_entry == NULL, 0); + return p_final_entry->subprogram_info.type != NULL; +} + +metac_entry_t * metac_entry_result_type(metac_entry_t * p_entry) { + metac_entry_t * p_final_entry = _entry_with_paremeter_info(p_entry); + _check_(p_final_entry == NULL, NULL); + return p_final_entry->subprogram_info.type; +} + metac_flag_t metac_entry_is_parameter(metac_entry_t * p_entry) { _check_(p_entry == NULL, 0); return metac_entry_kind(p_entry) == METAC_KND_subprogram_parameter;