From dbcd967e12dda152a93925603824ae63dfebafc6 Mon Sep 17 00:00:00 2001 From: dzaima Date: Thu, 12 Jan 2023 17:13:42 +0200 Subject: [PATCH] attempt at replxx-based printf --- src/h.h | 6 ++++++ src/main.c | 45 +++++++++++++++++++++++++++------------------ src/utils/utf.c | 49 ++++++++++++++++++++----------------------------- 3 files changed, 53 insertions(+), 47 deletions(-) diff --git a/src/h.h b/src/h.h index 2ece6e3b..fc683112 100644 --- a/src/h.h +++ b/src/h.h @@ -161,6 +161,12 @@ typedef double f64; #define JOIN0(A,B) A##B #define JOIN(A,B) JOIN0(A,B) +#if USE_REPLXX_IO + #include + extern Replxx* global_replxx; + #define printf(...) replxx_print(global_replxx, __VA_ARGS__) + #define fprintf(f, ...) replxx_print(global_replxx, __VA_ARGS__) +#endif #if USZ_64 typedef u64 usz; #define USZ_MAX ((u64)(1ULL<<48)) diff --git a/src/main.c b/src/main.c index c53f1dfd..0f7f9d87 100644 --- a/src/main.c +++ b/src/main.c @@ -15,6 +15,9 @@ #if __GNUC__ && __i386__ && !__clang__ #warning "CBQN is known to miscompile on GCC for 32-bit x86 builds; using clang instead is suggested" #endif +#if USE_REPLXX_IO && !USE_REPLXX + #error "Cannot use USE_REPLXX_IO without USE_REPLXX" +#endif static B replPath; static Scope* gsc; @@ -52,7 +55,7 @@ static bool isCmd(char* s, char** e, const char* cmd) { #include #include "utils/calls.h" #include "utils/cstr.h" - static Replxx* global_replxx; + Replxx* global_replxx; static char* global_histfile; static i8 themes[3][12][3] = { @@ -453,6 +456,8 @@ static bool isCmd(char* s, char** e, const char* cmd) { gc_add(sysvalNames); gc_add(sysvalNamesNorm); gc_addFn(replxx_gcFn); + + global_replxx = replxx_init(); } #else void before_exit() { } @@ -747,6 +752,10 @@ int main() { #elif !CBQN_SHARED int main(int argc, char* argv[]) { repl_init(); + #if USE_REPLXX_IO + cbqn_init_replxx(); + #endif + bool startREPL = argc==1; bool silentREPL = false; bool execStdin = false; @@ -864,37 +873,37 @@ int main(int argc, char* argv[]) { repl_init(); #if USE_REPLXX if (!silentREPL) { - cbqn_init_replxx(); - Replxx* replxx = replxx_init(); + #if !USE_REPLXX_IO + cbqn_init_replxx(); + #endif B f = get_config_path(false, ".cbqn_repl_history"); char* histfile = toCStr(f); dec(f); gc_add(tag(TOBJ(histfile), OBJ_TAG)); - replxx_history_load(replxx, histfile); - global_replxx = replxx; + replxx_history_load(global_replxx, histfile); global_histfile = histfile; - replxx_set_ignore_case(replxx, true); - replxx_set_highlighter_callback(replxx, highlighter_replxx, NULL); - replxx_set_hint_callback(replxx, hint_replxx, NULL); - replxx_set_completion_callback(replxx, complete_replxx, NULL); - replxx_enable_bracketed_paste(replxx); - replxx_bind_key(replxx, '\\', backslash_replxx, NULL); - replxx_bind_key(replxx, REPLXX_KEY_ENTER, enter_replxx, NULL); - replxx_set_modify_callback(replxx, modified_replxx, NULL); - replxx_bind_key_internal(replxx, REPLXX_KEY_CONTROL('N'), "history_next"); - replxx_bind_key_internal(replxx, REPLXX_KEY_CONTROL('P'), "history_previous"); + replxx_set_ignore_case(global_replxx, true); + replxx_set_highlighter_callback(global_replxx, highlighter_replxx, NULL); + replxx_set_hint_callback(global_replxx, hint_replxx, NULL); + replxx_set_completion_callback(global_replxx, complete_replxx, NULL); + replxx_enable_bracketed_paste(global_replxx); + replxx_bind_key(global_replxx, '\\', backslash_replxx, NULL); + replxx_bind_key(global_replxx, REPLXX_KEY_ENTER, enter_replxx, NULL); + replxx_set_modify_callback(global_replxx, modified_replxx, NULL); + replxx_bind_key_internal(global_replxx, REPLXX_KEY_CONTROL('N'), "history_next"); + replxx_bind_key_internal(global_replxx, REPLXX_KEY_CONTROL('P'), "history_previous"); while(true) { - const char* ln = replxx_input(replxx, " "); + const char* ln = replxx_input(global_replxx, " "); if (ln==NULL) { if (errno==0) printf("\n"); break; } - replxx_history_add(replxx, ln); + replxx_history_add(global_replxx, ln); cbqn_runLine((char*)ln, strlen(ln)); - replxx_history_save(replxx, histfile); + replxx_history_save(global_replxx, histfile); } } else diff --git a/src/utils/utf.c b/src/utils/utf.c index 7832973e..7d3e612f 100644 --- a/src/utils/utf.c +++ b/src/utils/utf.c @@ -18,6 +18,14 @@ static u32 utf8_p(u8* p) { case 4: return (0b111u &*p)<<18 | (0b111111u&p[3]) | (0b111111u&p[2])<<6 | (0b111111u&p[1])<<12; } } +FORCE_INLINE void utf8_w(char** buf_i, u32 c) { + char* buf = *buf_i; + if (c<128) { *buf++ = c; } + else if (c<=0x07FF) { *buf++ = 0xC0| c>>6 ; *buf++ = 0x80|(c &0x3F); } + else if (c<=0xFFFF) { *buf++ = 0xE0| c>>12; *buf++ = 0x80|(c>>6 &0x3F); *buf++ = 0x80|(c &0x3F); } + else { *buf++ = 0xF0| c>>18; *buf++ = 0x80|(c>>12&0x3F); *buf++ = 0x80|(c>>6&0x3F); *buf++ = 0x80|(c&0x3F); } + *buf_i = buf; +} B utf8Decode(const char* s, i64 len) { u64 sz = 0; @@ -55,41 +63,30 @@ B utf8DecodeA(I8Arr* a) { // consumes a // printing functions should avoid allocations, as they'll be used to print.. the out-of-memory message -#if defined(_WIN32) || defined(_WIN64) - #include - #include +#if defined(USE_REPLXX_IO) void fprintsU32(FILE* f, u32* s, usz len) { - _setmode(_fileno(f), _O_U16TEXT); - #define BUF_SZ 1024 - wchar_t buf[BUF_SZ]; u32* s_e = s+len; + + #define BUF_SZ 1024 + char buf[BUF_SZ]; while (s> 10); - buf_c[1] = 0xDC00 + (c & ((1<<10)-1)); - buf_c+= 2; - } + if (c==0) break; // can't print null bytes into null-terminated buffer + utf8_w(&buf_c, c); s++; } buf_c[0] = 0; - fwprintf(f, L"%ls", buf); + fprintf(f, "%s", buf); - while (s>6 ; *p++ = 0x80|(c &0x3F); } - else if (c<=0xFFFF) { *p++ = 0xE0|c>>12; *p++ = 0x80|(c>>6 &0x3F);*p++ = 0x80|(c &0x3F); } - else { *p++ = 0xF0|c>>18; *p++ = 0x80|(c>>12&0x3F);*p++ = 0x80|(c>>6&0x3F); *p++ = 0x80|(c&0x3F); } - } + for (usz i = 0; i < ia; i++) utf8_w(&p, o2cG(GetU(x,i))); }