From 3c26f55d893b3b4dbabd59b97546254d28c552b5 Mon Sep 17 00:00:00 2001 From: iWas-Coder Date: Mon, 9 Dec 2024 00:57:46 +0100 Subject: [PATCH] Implemented custom print funcs with string interpolation Finally `"%$"` is implemented in C. --- carbon.h | 49 ++++++++++++++++++++++++++++++++++++++++++++--- src/carbon_log.c | 44 ++++++++++++++++++++++++++++++++++++++++++ src/carbon_math.c | 10 +++++----- 3 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 src/carbon_log.c diff --git a/carbon.h b/carbon.h index 96f361f..c58ea91 100644 --- a/carbon.h +++ b/carbon.h @@ -108,6 +108,14 @@ #define CARBON_EXPAND_AND_PASTE(x, y) CARBON_PASTE(x, y) #define CARBON_NOTUSED(x) (void)(x) #define CARBON_ARRAY_LEN(x) (sizeof((x)) / sizeof((x)[0])) +#define CARBON_TYPE_OF(x) __typeof__(x) + +#ifdef __cplusplus +#include +#define CARBON_TYPE_IS_SAME(T, U) std::is_same::value +#else +#define CARBON_TYPE_IS_SAME(T, U) __builtin_types_compatible_p(T, U) +#endif #ifdef __cplusplus #define CARBON_API extern "C" @@ -397,16 +405,50 @@ CARBON_API u32 carbon_crypto_crc32(const u8 *in, const usz in_size); #define CARBON_COLOR_YELLOW "\033[1;33m" #define CARBON_COLOR_MAGENTA "\033[1;35m" #define CARBON_COLOR_CYAN "\033[1;36m" -#define CARBON_INFO_RAW(msg, ...) printf(msg, ##__VA_ARGS__) -#define CARBON_INFO(msg, ...) CARBON_INFO_RAW(msg "\n", ##__VA_ARGS__) + +#define CARBON_INFO_RAW(msg, ...) carbon_print(msg, ##__VA_ARGS__) +#define CARBON_INFO(msg, ...) carbon_println(msg, ##__VA_ARGS__) #define CARBON_INFO_COLOR(color, msg, ...) CARBON_INFO(color msg CARBON_COLOR_RESET, ##__VA_ARGS__) #define CARBON_INFO_FQDN(msg, ...) CARBON_INFO_COLOR(CARBON_COLOR_YELLOW, "[*] " __FILE__ ":" CARBON_EXPAND_AND_QUOTE(__LINE__) " (%s) :: " msg, __func__, ##__VA_ARGS__) #define CARBON_WARNING(msg, ...) CARBON_INFO_COLOR(CARBON_COLOR_MAGENTA, "[?] " __FILE__ ":" CARBON_EXPAND_AND_QUOTE(__LINE__) " (%s) :: " msg, __func__, ##__VA_ARGS__) -#define CARBON_ERROR_RAW(msg, ...) fprintf(stderr, msg, ##__VA_ARGS__) + +#define CARBON_ERROR_RAW(msg, ...) carbon_eprint(msg, ##__VA_ARGS__) #define CARBON_ERROR_PREFIX(prefix, msg, ...) CARBON_ERROR_RAW(CARBON_COLOR_RED prefix "" msg CARBON_COLOR_RESET "\n", ##__VA_ARGS__) #define CARBON_ERROR_ASS(msg, ...) CARBON_ERROR_PREFIX("", msg, ##__VA_ARGS__) #define CARBON_ERROR(msg, ...) CARBON_ERROR_PREFIX("[!] " __FILE__ ":" CARBON_EXPAND_AND_QUOTE(__LINE__) " (%s) :: ", msg, __func__, ##__VA_ARGS__) +#define carbon_log__var_to_spec(x) \ + (CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), usz) ? "%zu" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), isz) ? "%zd" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), u8) ? "%hhu" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), i8) ? "%hhd" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), u16) ? "%hu" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), i16) ? "%hd" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), u32) ? "%u" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), i32) ? "%d" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), u64) ? "%llu" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), i64) ? "%lld" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), f32) ? "%f" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), f64) ? "%lf" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), char) ? "%c" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), char *) ? "%s" \ + : CARBON_TYPE_IS_SAME(CARBON_TYPE_OF(x), const char *) ? "%s" \ + : "<'Stuff' At %p>") + +#define $(x) (CBN_Log_BoxedVar){carbon_log__var_to_spec(x), &x} + +#define carbon_print(msg, ...) carbon_log_print(stdout, msg, ##__VA_ARGS__) +#define carbon_eprint(msg, ...) carbon_log_print(stderr, msg, ##__VA_ARGS__) +#define carbon_println(msg, ...) carbon_print(carbon_string_fmt("%s\n", msg), ##__VA_ARGS__) +#define carbon_eprintln(msg, ...) carbon_eprint(carbon_string_fmt("%s\n", msg), ##__VA_ARGS__) + +typedef struct { + const char *spec; + void *var; +} CBN_Log_BoxedVar; + +CARBON_API void carbon_log_print(FILE *stream, const char *fmt, ...); + /* ** $$====================$$ ** || Should || @@ -795,6 +837,7 @@ CARBON_API void carbon_junit_output(const CBN_List junit_tcs, const char *out_fi #include "src/carbon_math.c" #include "src/carbon_math_ops.cc" #include "src/carbon_crypto.c" +#include "src/carbon_log.c" #include "src/carbon_time.c" #include "src/carbon_clock.c" #include "src/carbon_list.c" diff --git a/src/carbon_log.c b/src/carbon_log.c new file mode 100644 index 0000000..be2bbf7 --- /dev/null +++ b/src/carbon_log.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: AGPL-3.0-only +// Copyright (C) Wasym A. Alonso. All Rights Reserved. + +#ifndef CARBON_IMPLEMENTATION +#include +#endif // CARBON_IMPLEMENTATION + +#define carbon_log__printv(stream, x) fprintf(stream, carbon_log__var_to_spec(x), (x)) + +CARBON_INLINE void carbon_log__print_boxed_var(FILE *stream, CBN_Log_BoxedVar x) { + if (!carbon_string_cmp(x.spec, "%zu")) carbon_log__printv(stream, *((usz *) x.var)); + else if (!carbon_string_cmp(x.spec, "%zd")) carbon_log__printv(stream, *((isz *) x.var)); + else if (!carbon_string_cmp(x.spec, "%hhu")) carbon_log__printv(stream, *((u8 *) x.var)); + else if (!carbon_string_cmp(x.spec, "%hhd")) carbon_log__printv(stream, *((i8 *) x.var)); + else if (!carbon_string_cmp(x.spec, "%hu")) carbon_log__printv(stream, *((u16 *) x.var)); + else if (!carbon_string_cmp(x.spec, "%hd")) carbon_log__printv(stream, *((i16 *) x.var)); + else if (!carbon_string_cmp(x.spec, "%u")) carbon_log__printv(stream, *((u32 *) x.var)); + else if (!carbon_string_cmp(x.spec, "%u")) carbon_log__printv(stream, *((u32 *) x.var)); + else if (!carbon_string_cmp(x.spec, "%d")) carbon_log__printv(stream, *((i32 *) x.var)); + else if (!carbon_string_cmp(x.spec, "%llu")) carbon_log__printv(stream, *((u64 *) x.var)); + else if (!carbon_string_cmp(x.spec, "%lld")) carbon_log__printv(stream, *((i64 *) x.var)); + else if (!carbon_string_cmp(x.spec, "%f")) carbon_log__printv(stream, *((f32 *) x.var)); + else if (!carbon_string_cmp(x.spec, "%lf")) carbon_log__printv(stream, *((f64 *) x.var)); + else if (!carbon_string_cmp(x.spec, "%c")) carbon_log__printv(stream, *((char *) x.var)); + else if (!carbon_string_cmp(x.spec, "%s")) carbon_log__printv(stream, *((char **) x.var)); + else carbon_log__printv(stream, x.var); +} + +void carbon_log_print(FILE *stream, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + CBN_StrList fmt_splitted = carbon_strlist_from_splitted_cstr(fmt, "%$"); + carbon_strlist_foreach(fmt_splitted) { + vfprintf(stream, carbon_strview_to_cstr(it.sv), args); + if ((it.i != fmt_splitted.size - 1) || (it.i == fmt_splitted.size - 1 && carbon_string_ends_with_substr(fmt, "%$"))) { + CBN_Log_BoxedVar arg = va_arg(args, CBN_Log_BoxedVar); + // TODO: check that arg is a valid `CBN_Log_BoxedVar` + carbon_log__print_boxed_var(stream, arg); + } + } + fflush(stream); + carbon_strlist_destroy(&fmt_splitted); + va_end(args); +} diff --git a/src/carbon_math.c b/src/carbon_math.c index ded73b6..45fa195 100644 --- a/src/carbon_math.c +++ b/src/carbon_math.c @@ -509,15 +509,15 @@ void carbon_math_mat_map(CBN_Matrix m, f32 (*f)(f32)) { } void carbon_math_mat_print(CBN_Matrix m, const char *name) { - CARBON_INFO("%s = [", name); + carbon_println("%s = [", name); for (usz i = 0; i < m.rows; ++i) { - CARBON_INFO_RAW(" "); + carbon_print(" "); for (usz j = 0; j < m.cols; ++j) { - CARBON_INFO_RAW("%f ", CARBON_MAT_AT(m, i, j)); + carbon_print("%f ", CARBON_MAT_AT(m, i, j)); } - CARBON_INFO(); + carbon_println(""); } - CARBON_INFO("];"); + carbon_println("];"); } CBN_Row carbon_math_row_create(usz cols) {