From 43105107b9d1e985e9c182b904f2ac79b17fb460 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Fri, 29 Aug 2025 13:32:17 -0400 Subject: Improvements to text and inline C code formatting/parsing --- src/stdlib/text.c | 43 +++++++++++++++++++++++-------------------- src/stdlib/text.h | 1 + 2 files changed, 24 insertions(+), 20 deletions(-) (limited to 'src/stdlib') diff --git a/src/stdlib/text.c b/src/stdlib/text.c index ed4023a4..57465034 100644 --- a/src/stdlib/text.c +++ b/src/stdlib/text.c @@ -1390,17 +1390,8 @@ Text_t Text$title(Text_t text, Text_t language) { } public -Text_t Text$quoted(Text_t text, bool colorize, Text_t quotation_mark) { - if (quotation_mark.length != 1) fail("Invalid quote text: ", quotation_mark, " (must have length == 1)"); - +Text_t Text$escaped(Text_t text, bool colorize, Text_t extra_escapes) { Text_t ret = colorize ? Text("\x1b[35m") : EMPTY_TEXT; - if (!Text$equal_values(quotation_mark, Text("\"")) && !Text$equal_values(quotation_mark, Text("'")) - && !Text$equal_values(quotation_mark, Text("`"))) - ret = concat2_assuming_safe(ret, Text("$")); - - ret = concat2_assuming_safe(ret, quotation_mark); - int32_t quote_char = Text$get_grapheme(quotation_mark, 0); - #define flush_unquoted() \ ({ \ if (unquoted_span > 0) { \ @@ -1454,15 +1445,18 @@ Text_t Text$quoted(Text_t text, bool colorize, Text_t quotation_mark) { break; } default: { - if (g == quote_char) { - flush_unquoted(); - if (colorize) ret = concat2_assuming_safe(ret, Text("\x1b[34;1m")); - ret = concat2_assuming_safe(ret, Text("\\")); - ret = concat2_assuming_safe(ret, quotation_mark); - if (colorize) ret = concat2_assuming_safe(ret, Text("\x1b[0;35m")); - } else { - unquoted_span += 1; + TextIter_t esc_state = NEW_TEXT_ITER_STATE(extra_escapes); + for (int64_t j = 0; j < extra_escapes.length; j++) { + int32_t esc = Text$get_grapheme_fast(&esc_state, j); + if (g == esc) { + flush_unquoted(); + if (colorize) ret = concat2_assuming_safe(ret, Text("\x1b[34;1m")); + ret = concat2_assuming_safe(ret, Text("\\")); + if (colorize) ret = concat2_assuming_safe(ret, Text("\x1b[0;35m")); + break; + } } + unquoted_span += 1; break; } } @@ -1470,10 +1464,19 @@ Text_t Text$quoted(Text_t text, bool colorize, Text_t quotation_mark) { flush_unquoted(); #undef add_escaped #undef flush_unquoted - - ret = concat2_assuming_safe(ret, quotation_mark); if (colorize) ret = concat2_assuming_safe(ret, Text("\x1b[m")); + return ret; +} + +public +Text_t Text$quoted(Text_t text, bool colorize, Text_t quotation_mark) { + if (quotation_mark.length != 1) fail("Invalid quote text: ", quotation_mark, " (must have length == 1)"); + Text_t ret = Text$escaped(text, colorize, quotation_mark); + if (!(Text$equal_values(quotation_mark, Text("\"")) || Text$equal_values(quotation_mark, Text("'")) + || Text$equal_values(quotation_mark, Text("`")))) + ret = Texts("$", quotation_mark, ret, quotation_mark); + else ret = Texts(quotation_mark, ret, quotation_mark); return ret; } diff --git a/src/stdlib/text.h b/src/stdlib/text.h index 5fa95675..d118cffd 100644 --- a/src/stdlib/text.h +++ b/src/stdlib/text.h @@ -54,6 +54,7 @@ Text_t Text$upper(Text_t text, Text_t language); Text_t Text$lower(Text_t text, Text_t language); Text_t Text$title(Text_t text, Text_t language); Text_t Text$as_text(const void *text, bool colorize, const TypeInfo_t *info); +Text_t Text$escaped(Text_t text, bool colorize, Text_t extra_escapes); Text_t Text$quoted(Text_t str, bool colorize, Text_t quotation_mark); PUREFUNC bool Text$starts_with(Text_t text, Text_t prefix, Text_t *remainder); PUREFUNC bool Text$ends_with(Text_t text, Text_t suffix, Text_t *remainder); -- cgit v1.2.3 From c0c6fe863f8e074cbe8297b5da2a476f455b6518 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 13:08:11 -0400 Subject: Make Texts() macro a bit more flexible. --- src/stdlib/integers.c | 2 ++ src/stdlib/integers.h | 1 + src/stdlib/nums.c | 36 ++++++++++++++++++++++-------------- src/stdlib/nums.h | 10 ++++++---- src/stdlib/pointers.c | 2 +- src/stdlib/text.c | 7 +++---- src/stdlib/text.h | 14 +++++++++++++- 7 files changed, 48 insertions(+), 24 deletions(-) (limited to 'src/stdlib') diff --git a/src/stdlib/integers.c b/src/stdlib/integers.c index 7dda77bd..5dc9ac55 100644 --- a/src/stdlib/integers.c +++ b/src/stdlib/integers.c @@ -617,6 +617,8 @@ void Int32$deserialize(FILE *in, void *outval, List_t *pointers, const TypeInfo_ Text_t text = _int64_to_text((int64_t)(*(c_type *)i)); \ return colorize ? Texts(Text("\033[35m"), text, Text("\033[m")) : text; \ } \ + public \ + Text_t KindOfInt##$value_as_text(c_type i) { return _int64_to_text((int64_t)i); } \ public \ PUREFUNC int32_t KindOfInt##$compare(const void *x, const void *y, const TypeInfo_t *info) { \ (void)info; \ diff --git a/src/stdlib/integers.h b/src/stdlib/integers.h index 40c40754..34195d23 100644 --- a/src/stdlib/integers.h +++ b/src/stdlib/integers.h @@ -22,6 +22,7 @@ bool is_none : 1; \ } Optional##type_name##_t; \ Text_t type_name##$as_text(const void *i, bool colorize, const TypeInfo_t *type); \ + Text_t type_name##$value_as_text(c_type i); \ PUREFUNC int32_t type_name##$compare(const void *x, const void *y, const TypeInfo_t *type); \ PUREFUNC bool type_name##$equal(const void *x, const void *y, const TypeInfo_t *type); \ Text_t type_name##$hex(c_type i, Int_t digits, bool uppercase, bool prefix); \ diff --git a/src/stdlib/nums.c b/src/stdlib/nums.c index 55131cfd..4bbb1f6a 100644 --- a/src/stdlib/nums.c +++ b/src/stdlib/nums.c @@ -14,13 +14,18 @@ #include "types.h" public -PUREFUNC Text_t Num$as_text(const void *f, bool colorize, const TypeInfo_t *info) { - (void)info; - if (!f) return Text("Num"); +PUREFUNC Text_t Num$value_as_text(double x) { char *str = GC_MALLOC_ATOMIC(24); - int len = fpconv_dtoa(*(double *)f, str); + int len = fpconv_dtoa(x, str); + return Text$from_strn(str, (size_t)len); +} + +public +PUREFUNC Text_t Num$as_text(const void *x, bool colorize, const TypeInfo_t *info) { + (void)info; + if (!x) return Text("Num"); static const Text_t color_prefix = Text("\x1b[35m"), color_suffix = Text("\x1b[m"); - Text_t text = Text$from_strn(str, (size_t)len); + Text_t text = Num$value_as_text(*(double *)x); return colorize ? Texts(color_prefix, text, color_suffix) : text; } @@ -60,10 +65,10 @@ CONSTFUNC bool Num$near(double a, double b, double ratio, double absolute) { } public -Text_t Num$percent(double f, double precision) { - double d = 100. * f; +Text_t Num$percent(double x, double precision) { + double d = 100. * x; d = Num$with_precision(d, precision); - return Texts(Num$as_text(&d, false, &Num$info), Text("%")); + return Texts(Num$value_as_text(d), Text("%")); } public @@ -142,10 +147,13 @@ const TypeInfo_t Num$info = { }; public -PUREFUNC Text_t Num32$as_text(const void *f, bool colorize, const TypeInfo_t *info) { +PUREFUNC Text_t Num32$value_as_text(float x) { return Num$value_as_text((double)x); } + +public +PUREFUNC Text_t Num32$as_text(const void *x, bool colorize, const TypeInfo_t *info) { (void)info; - if (!f) return Text("Num32"); - double d = (double)(*(float *)f); + if (!x) return Text("Num32"); + double d = (double)(*(float *)x); return Num$as_text(&d, colorize, &Num$info); } @@ -178,10 +186,10 @@ CONSTFUNC bool Num32$near(float a, float b, float ratio, float absolute) { } public -Text_t Num32$percent(float f, float precision) { - double d = 100. * (double)f; +Text_t Num32$percent(float x, float precision) { + double d = 100. * (double)x; d = Num$with_precision(d, (double)precision); - return Texts(Num$as_text(&d, false, &Num$info), Text("%")); + return Texts(Num$value_as_text(d), Text("%")); } public diff --git a/src/stdlib/nums.h b/src/stdlib/nums.h index db051ed2..303aa362 100644 --- a/src/stdlib/nums.h +++ b/src/stdlib/nums.h @@ -15,11 +15,12 @@ #define N32(n) ((float)(n)) #define N64(n) ((double)(n)) -Text_t Num$as_text(const void *f, bool colorize, const TypeInfo_t *type); +Text_t Num$as_text(const void *x, bool colorize, const TypeInfo_t *type); +Text_t Num$value_as_text(double x); PUREFUNC int32_t Num$compare(const void *x, const void *y, const TypeInfo_t *type); PUREFUNC bool Num$equal(const void *x, const void *y, const TypeInfo_t *type); CONSTFUNC bool Num$near(double a, double b, double ratio, double absolute); -Text_t Num$percent(double f, double precision); +Text_t Num$percent(double x, double precision); double CONSTFUNC Num$with_precision(double num, double precision); double Num$mod(double num, double modulus); double Num$mod1(double num, double modulus); @@ -70,11 +71,12 @@ MACROLIKE CONSTFUNC double Num$from_byte(Byte_t i) { return (double)i; } extern const TypeInfo_t Num$info; -Text_t Num32$as_text(const void *f, bool colorize, const TypeInfo_t *type); +Text_t Num32$as_text(const void *x, bool colorize, const TypeInfo_t *type); +Text_t Num32$value_as_text(float x); PUREFUNC int32_t Num32$compare(const void *x, const void *y, const TypeInfo_t *type); PUREFUNC bool Num32$equal(const void *x, const void *y, const TypeInfo_t *type); CONSTFUNC bool Num32$near(float a, float b, float ratio, float absolute); -Text_t Num32$percent(float f, float precision); +Text_t Num32$percent(float x, float precision); float CONSTFUNC Num32$with_precision(float num, float precision); float Num32$mod(float num, float modulus); float Num32$mod1(float num, float modulus); diff --git a/src/stdlib/pointers.c b/src/stdlib/pointers.c index b5e6400f..0a1623a0 100644 --- a/src/stdlib/pointers.c +++ b/src/stdlib/pointers.c @@ -44,7 +44,7 @@ Text_t Pointer$as_text(const void *x, bool colorize, const TypeInfo_t *type) { TypeInfo_t rec_table = *Table$info(type, &Int64$info); int64_t *id = Table$get(pending, x, &rec_table); if (id) { - Text_t text = Texts(Text$from_str(ptr_info.sigil), Int64$as_text(id, false, &Int64$info)); + Text_t text = Texts(Text$from_str(ptr_info.sigil), Int64$value_as_text(*id)); return colorize ? Texts(Text("\x1b[34;1m"), text, Text("\x1b[m")) : text; } int64_t next_id = pending.entries.length + 2; diff --git a/src/stdlib/text.c b/src/stdlib/text.c index ed4023a4..3bff0356 100644 --- a/src/stdlib/text.c +++ b/src/stdlib/text.c @@ -1726,10 +1726,9 @@ Int_t Text$memory_size(Text_t text) { public Text_t Text$layout(Text_t text) { switch (text.tag) { - case TEXT_ASCII: return Texts(Text("ASCII("), Int64$as_text((int64_t[1]){text.length}, false, NULL), Text(")")); - case TEXT_GRAPHEMES: - return Texts(Text("Graphemes("), Int64$as_text((int64_t[1]){text.length}, false, NULL), Text(")")); - case TEXT_BLOB: return Texts(Text("Blob("), Int64$as_text((int64_t[1]){text.length}, false, NULL), Text(")")); + case TEXT_ASCII: return Texts(Text("ASCII("), Int64$value_as_text(text.length), Text(")")); + case TEXT_GRAPHEMES: return Texts(Text("Graphemes("), Int64$value_as_text(text.length), Text(")")); + case TEXT_BLOB: return Texts(Text("Blob("), Int64$value_as_text(text.length), Text(")")); case TEXT_CONCAT: return Texts(Text("Concat("), Text$layout(*text.left), Text(", "), Text$layout(*text.right), Text(")")); default: errx(1, "Invalid text tag: %d", text.tag); diff --git a/src/stdlib/text.h b/src/stdlib/text.h index 5fa95675..23ceefea 100644 --- a/src/stdlib/text.h +++ b/src/stdlib/text.h @@ -7,7 +7,9 @@ #include #include "datatypes.h" +#include "integers.h" // IWYU pragma: export #include "mapmacro.h" +#include "nums.h" // IWYU pragma: export #include "types.h" #include "util.h" @@ -31,7 +33,17 @@ static inline Text_t Text_from_str_literal(const char *str) { static inline Text_t Text_from_text(Text_t t) { return t; } -#define convert_to_text(x) _Generic(x, Text_t: Text_from_text, char *: Text$from_str, const char *: Text$from_str)(x) +#define convert_to_text(x) \ + _Generic(x, \ + Text_t: Text_from_text, \ + char *: Text$from_str, \ + const char *: Text$from_str, \ + int8_t: Int8$value_as_text, \ + int16_t: Int16$value_as_text, \ + int32_t: Int32$value_as_text, \ + int64_t: Int64$value_as_text, \ + double: Num$value_as_text, \ + float: Num32$value_as_text)(x) Text_t Text$_concat(int n, Text_t items[n]); #define Text$concat(...) Text$_concat(sizeof((Text_t[]){__VA_ARGS__}) / sizeof(Text_t), (Text_t[]){__VA_ARGS__}) -- cgit v1.2.3 From e01383da05d5cf03d080854ac048df37df4d1b9a Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 15:11:52 -0400 Subject: Change module install directory to PREFIX/lib/tomo_vX.Y/* --- src/stdlib/stacktrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/stdlib') diff --git a/src/stdlib/stacktrace.c b/src/stdlib/stacktrace.c index 266dc4ef..c7ec54d3 100644 --- a/src/stdlib/stacktrace.c +++ b/src/stdlib/stacktrace.c @@ -98,7 +98,7 @@ void print_stacktrace(FILE *out, int offset) { cwd[cwd_len++] = '/'; cwd[cwd_len] = '\0'; - const char *install_dir = TOMO_PREFIX "/share/tomo_" TOMO_VERSION "/installed/"; + const char *install_dir = TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/"; static void *stack[1024]; int64_t size = (int64_t)backtrace(stack, sizeof(stack) / sizeof(stack[0])); -- cgit v1.2.3 From 081a26de86eca95ba3ee0887992cdc3d96190cce Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 17:32:42 -0400 Subject: Fixes for local-tomo so that it *actually* uses local header files, which don't need to be installed anymore. --- src/stdlib/stacktrace.c | 2 +- src/stdlib/stdlib.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'src/stdlib') diff --git a/src/stdlib/stacktrace.c b/src/stdlib/stacktrace.c index c7ec54d3..0953e660 100644 --- a/src/stdlib/stacktrace.c +++ b/src/stdlib/stacktrace.c @@ -98,7 +98,7 @@ void print_stacktrace(FILE *out, int offset) { cwd[cwd_len++] = '/'; cwd[cwd_len] = '\0'; - const char *install_dir = TOMO_PREFIX "/lib/tomo_" TOMO_VERSION "/"; + const char *install_dir = String(TOMO_PATH, "/lib/tomo_" TOMO_VERSION "/"); static void *stack[1024]; int64_t size = (int64_t)backtrace(stack, sizeof(stack) / sizeof(stack[0])); diff --git a/src/stdlib/stdlib.c b/src/stdlib/stdlib.c index bf36ca0d..5ea8cb79 100644 --- a/src/stdlib/stdlib.c +++ b/src/stdlib/stdlib.c @@ -41,6 +41,9 @@ bool USE_COLOR; public Text_t TOMO_VERSION_TEXT = Text(TOMO_VERSION); +public +const char *TOMO_PATH = TOMO_INSTALL; + static _Noreturn void signal_handler(int sig, siginfo_t *info, void *userdata) { (void)info, (void)userdata; assert(sig == SIGILL); -- cgit v1.2.3 From 94ff047dd74cd3ad793f68503729a0fe004c10f4 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Mon, 1 Sep 2025 20:15:02 -0400 Subject: Bugfix for Int.parse() --- src/stdlib/integers.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/stdlib') diff --git a/src/stdlib/integers.c b/src/stdlib/integers.c index 5dc9ac55..863bb42d 100644 --- a/src/stdlib/integers.c +++ b/src/stdlib/integers.c @@ -430,7 +430,7 @@ OptionalInt_t Int$parse(Text_t text, Text_t *remainder) { else if (*end != '\0') return NONE_INT; result = mpz_init_set_str(i, str + 2, 2); } else { - const char *end = str + 2 + strspn(str + 2, "0123456789"); + const char *end = str + strspn(str, "0123456789"); if (remainder) *remainder = Text$from_str(end); else if (*end != '\0') return NONE_INT; result = mpz_init_set_str(i, str, 10); -- cgit v1.2.3