From b6996d29aece61c411a5b2eb269201698d982b63 Mon Sep 17 00:00:00 2001 From: Sam Schweigel Date: Fri, 23 May 2025 12:26:44 -0700 Subject: [PATCH 01/10] Make more types jl_static_show readably --- src/rtutils.c | 106 +++++++++++++++++++++++++++++++++++++++++--------- test/show.jl | 37 +++++++++++++++++- 2 files changed, 123 insertions(+), 20 deletions(-) diff --git a/src/rtutils.c b/src/rtutils.c index 4baf0ee5e6e9c..469dd4651685d 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -5,6 +5,8 @@ */ #include "platform.h" +#include +#include #include #include #include @@ -691,12 +693,12 @@ static int is_globfunction(jl_value_t *v, jl_datatype_t *dv, jl_sym_t **globname return 0; } -static size_t jl_static_show_string(JL_STREAM *out, const char *str, size_t len, int wrap) JL_NOTSAFEPOINT +static size_t jl_static_show_string(JL_STREAM *out, const char *str, size_t len, int wrap, int raw) JL_NOTSAFEPOINT { size_t n = 0; if (wrap) n += jl_printf(out, "\""); - if (!u8_isvalid(str, len)) { + if (!raw && !u8_isvalid(str, len)) { // alternate print algorithm that preserves data if it's not UTF-8 static const char hexdig[] = "0123456789abcdef"; for (size_t i = 0; i < len; i++) { @@ -713,7 +715,11 @@ static size_t jl_static_show_string(JL_STREAM *out, const char *str, size_t len, int special = 0; for (size_t i = 0; i < len; i++) { uint8_t c = str[i]; - if (c < 32 || c == 0x7f || c == '\\' || c == '"' || c == '$') { + if (raw && ((c == '\\' && i == len-1) || c == '"')) { + special = 1; + break; + } + else if (!raw && (c < 32 || c == 0x7f || c == '\\' || c == '"' || c == '$')) { special = 1; break; } @@ -722,6 +728,17 @@ static size_t jl_static_show_string(JL_STREAM *out, const char *str, size_t len, jl_uv_puts(out, str, len); n += len; } + else if (raw) { + for (size_t i = 0; i < len; i++) { + uint8_t c = str[i]; + if (c == '"') + jl_uv_puts(out, "\\\"", 2); + else if (c == '\\' && i == len - 1) + jl_uv_puts(out, "\\\\", 2); + else + jl_uv_puts(out, str + i, 1); + } + } else { char buf[512]; size_t i = 0; @@ -737,18 +754,28 @@ static size_t jl_static_show_string(JL_STREAM *out, const char *str, size_t len, return n; } +static int jl_is_quoted_sym(const char *sn) +{ + static const char *const quoted_syms[] = {":", "::", ":=", "=", "==", "===", "=>", "`"}; + for (int i = 0; i < sizeof quoted_syms / sizeof *quoted_syms; i++) + if (!strcmp(sn, quoted_syms[i])) + return 1; + return 0; +} + +// TODO: in theory, we need a separate function for showing symbols in an +// expression context (where `Symbol("foo\x01bar")` is ok) and a syntactic +// context (where var"" must be used). static size_t jl_static_show_symbol(JL_STREAM *out, jl_sym_t *name) JL_NOTSAFEPOINT { size_t n = 0; const char *sn = jl_symbol_name(name); - int quoted = !jl_is_identifier(sn) && !jl_is_operator(sn); - if (quoted) { - n += jl_printf(out, "var"); - // TODO: this is not quite right, since repr uses String escaping rules, and Symbol uses raw string rules - n += jl_static_show_string(out, sn, strlen(sn), 1); + if (jl_is_identifier(sn) || (jl_is_operator(sn) && !jl_is_quoted_sym(sn))) { + n += jl_printf(out, "%s", sn); } else { - n += jl_printf(out, "%s", sn); + n += jl_printf(out, "var"); + n += jl_static_show_string(out, sn, strlen(sn), 1, 1); } return n; } @@ -777,6 +804,42 @@ static int jl_static_is_function_(jl_datatype_t *vt) JL_NOTSAFEPOINT { return 0; } +static size_t jl_static_show_float(JL_STREAM *out, double v, + jl_datatype_t *vt) JL_NOTSAFEPOINT +{ + size_t n = 0; + // TODO: non-canonical NaNs do not round-trip + // TOOD: BFloat16 + const char *size_suffix = vt == jl_float16_type ? "16" : + vt == jl_float32_type ? "32" : + ""; + // Digits required to print p significand bits: ceil(p * log(10, 2)) + // Float16 4 + // Float32 8 + // Float64 17 + if (isnan(v)) { + n += jl_printf(out, "NaN%s", size_suffix); + } + else if (isinf(v)) { + n += jl_printf(out, "%sInf%s", v < 0 ? "-" : "", size_suffix); + } + else if (vt == jl_float64_type) { + // If no decimal point or exponent will be printed, we must add ".0" + double ipart, fpart; + fpart = modf(v, &ipart); + int dotzero = v == 0 || (fpart == 0.0 && ipart < 1e17); + n += jl_printf(out, "%.17g%s", v, dotzero ? ".0" : ""); + } + else if (vt == jl_float32_type) { + n += jl_printf(out, "Float32(%.8g)", v); + } + else { + assert(vt == jl_float16_type); + n += jl_printf(out, "Float16(%.4g)", v); + } + return n; +} + // `v` might be pointing to a field inlined in a structure therefore // `jl_typeof(v)` may not be the same with `vt` and only `vt` should be // used to determine the type of the value. @@ -954,17 +1017,21 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt int f = *(uint32_t*)jl_data_ptr(v); n += jl_printf(out, "#", f, jl_intrinsic_name(f)); } + else if (vt == jl_long_type) { + // Avoid unecessary Int64(x)/Int32(x) + n += jl_printf(out, "%" PRIdPTR, *(intptr_t*)v); + } else if (vt == jl_int64_type) { - n += jl_printf(out, "%" PRId64, *(int64_t*)v); + n += jl_printf(out, "Int64(%" PRId64 ")", *(int64_t*)v); } else if (vt == jl_int32_type) { - n += jl_printf(out, "%" PRId32, *(int32_t*)v); + n += jl_printf(out, "Int32(%" PRId32 ")", *(int32_t*)v); } else if (vt == jl_int16_type) { - n += jl_printf(out, "%" PRId16, *(int16_t*)v); + n += jl_printf(out, "Int16(%" PRId16 ")", *(int16_t*)v); } else if (vt == jl_int8_type) { - n += jl_printf(out, "%" PRId8, *(int8_t*)v); + n += jl_printf(out, "Int8(%" PRId8 ")", *(int8_t*)v); } else if (vt == jl_uint64_type) { n += jl_printf(out, "0x%016" PRIx64, *(uint64_t*)v); @@ -985,11 +1052,14 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt n += jl_printf(out, "0x%08" PRIx32, *(uint32_t*)v); #endif } + else if (vt == jl_float16_type) { + n += jl_static_show_float(out, julia_half_to_float(*(uint16_t *)v), vt); + } else if (vt == jl_float32_type) { - n += jl_printf(out, "%gf", *(float*)v); + n += jl_static_show_float(out, *(float *)v, vt); } else if (vt == jl_float64_type) { - n += jl_printf(out, "%g", *(double*)v); + n += jl_static_show_float(out, *(double *)v, vt); } else if (vt == jl_bool_type) { n += jl_printf(out, "%s", *(uint8_t*)v ? "true" : "false"); @@ -998,7 +1068,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt n += jl_printf(out, "nothing"); } else if (vt == jl_string_type) { - n += jl_static_show_string(out, jl_string_data(v), jl_string_len(v), 1); + n += jl_static_show_string(out, jl_string_data(v), jl_string_len(v), 1, 0); } else if (v == jl_bottom_type) { n += jl_printf(out, "Union{}"); @@ -1528,10 +1598,10 @@ void jl_log(int level, jl_value_t *module, jl_value_t *group, jl_value_t *id, } jl_printf(str, "\n@ "); if (jl_is_string(file)) { - jl_static_show_string(str, jl_string_data(file), jl_string_len(file), 0); + jl_static_show_string(str, jl_string_data(file), jl_string_len(file), 0, 0); } else if (jl_is_symbol(file)) { - jl_static_show_string(str, jl_symbol_name((jl_sym_t*)file), strlen(jl_symbol_name((jl_sym_t*)file)), 0); + jl_static_show_string(str, jl_symbol_name((jl_sym_t*)file), strlen(jl_symbol_name((jl_sym_t*)file)), 0, 0); } jl_printf(str, ":"); jl_static_show(str, line); diff --git a/test/show.jl b/test/show.jl index fa5989d6cd91d..3fb00e98d9f31 100644 --- a/test/show.jl +++ b/test/show.jl @@ -703,7 +703,7 @@ let oldout = stdout, olderr = stderr redirect_stderr(olderr) close(wrout) close(wrerr) - @test fetch(out) == "primitive type Int64 <: Signed\nTESTA\nTESTB\nΑ1Β2\"A\"\nA\n123\"C\"\n" + @test fetch(out) == "primitive type Int64 <: Signed\nTESTA\nTESTB\nΑ1Β2\"A\"\nA\n123.0\"C\"\n" @test fetch(err) == "TESTA\nTESTB\nΑ1Β2\"A\"\n" finally redirect_stdout(oldout) @@ -1570,8 +1570,41 @@ struct var"%X%" end # Invalid name without '#' typeof(+), var"#f#", typeof(var"#f#"), + + # Integers should round-trip (#52677) + 1, UInt(1), + Int8(1), Int16(1), Int32(1), Int64(1), + UInt8(1), UInt16(1), UInt32(1), UInt64(1), + + # Float round-trip + Float16(1), Float32(1), Float64(1), + Float16(1.5), Float32(1.5), Float64(1.5), + Float16(0.4893243538921085), Float32(0.4893243538921085), Float64(0.4893243538921085), + floatmax(Float16), floatmax(Float32), floatmax(Float64), + floatmin(Float16), floatmin(Float32), floatmin(Float64), + typemax(Float16), typemax(Float32), typemax(Float64), + typemin(Float16), typemin(Float32), typemin(Float64), + nextfloat(Float16(0)), nextfloat(Float32(0)), nextfloat(Float64(0)), + NaN16, NaN32, NaN, + + # :var"" escaping rules differ from strings (#58484) + :foo, + :var"bar baz", + :var"a $b", # No escaping for $ in raw string + :var"a\b", # No escaping for backslashes in middle + :var"a\\", # Backslashes must be escaped at the end + :var"\"", + :+, :var"+-", + :(=), :(:), :(::), # Requires quoting + Symbol("a\nb"), + + # BROKEN + # Symbol("a\xffb"), + # User-defined primtive types + # Non-canonical NaNs + # BFloat16 ) - @test v == eval(Meta.parse(static_shown(v))) + @test v === eval(Meta.parse(static_shown(v))) end end From e73b687f32518fc10764f9cfd42a5a0ddf7fedbe Mon Sep 17 00:00:00 2001 From: Sam Schweigel Date: Fri, 23 May 2025 12:40:51 -0700 Subject: [PATCH 02/10] Typo fix --- src/rtutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rtutils.c b/src/rtutils.c index 469dd4651685d..3fee246ab0744 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -1018,7 +1018,7 @@ static size_t jl_static_show_x_(JL_STREAM *out, jl_value_t *v, jl_datatype_t *vt n += jl_printf(out, "#", f, jl_intrinsic_name(f)); } else if (vt == jl_long_type) { - // Avoid unecessary Int64(x)/Int32(x) + // Avoid unnecessary Int64(x)/Int32(x) n += jl_printf(out, "%" PRIdPTR, *(intptr_t*)v); } else if (vt == jl_int64_type) { From 02f54e404e5cc4a3281788a8c0cfbcb6ee44a728 Mon Sep 17 00:00:00 2001 From: Sam Schweigel Date: Fri, 23 May 2025 12:41:15 -0700 Subject: [PATCH 03/10] Typo fix --- test/show.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/show.jl b/test/show.jl index 3fb00e98d9f31..644dc3d424b45 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1600,7 +1600,7 @@ struct var"%X%" end # Invalid name without '#' # BROKEN # Symbol("a\xffb"), - # User-defined primtive types + # User-defined primitive types # Non-canonical NaNs # BFloat16 ) From 8a9e42586e7a0051671c85bd2c8c0fd56ea876b2 Mon Sep 17 00:00:00 2001 From: Sam Schweigel Date: Fri, 23 May 2025 14:05:56 -0700 Subject: [PATCH 04/10] Fix jl_static_show for negative floats with no fractional part --- src/rtutils.c | 2 +- test/show.jl | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/rtutils.c b/src/rtutils.c index 3fee246ab0744..b2b599dc6ed21 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -827,7 +827,7 @@ static size_t jl_static_show_float(JL_STREAM *out, double v, // If no decimal point or exponent will be printed, we must add ".0" double ipart, fpart; fpart = modf(v, &ipart); - int dotzero = v == 0 || (fpart == 0.0 && ipart < 1e17); + int dotzero = v == 0 || (fpart == 0.0 && fabs(ipart) < 1e17); n += jl_printf(out, "%.17g%s", v, dotzero ? ".0" : ""); } else if (vt == jl_float32_type) { diff --git a/test/show.jl b/test/show.jl index 644dc3d424b45..8f62cdf2d0e87 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1582,10 +1582,14 @@ struct var"%X%" end # Invalid name without '#' Float16(0.4893243538921085), Float32(0.4893243538921085), Float64(0.4893243538921085), floatmax(Float16), floatmax(Float32), floatmax(Float64), floatmin(Float16), floatmin(Float32), floatmin(Float64), - typemax(Float16), typemax(Float32), typemax(Float64), - typemin(Float16), typemin(Float32), typemin(Float64), + Inf16, Inf32, Inf, + -Inf16, -Inf32, -Inf, nextfloat(Float16(0)), nextfloat(Float32(0)), nextfloat(Float64(0)), NaN16, NaN32, NaN, + Float16(1e3), 1f7, 1e16, + Float16(-1e3), -1f7, -1e16, + Float16(1e4), 1f8, 1e17, + Float16(-1e4), -1f8, -1e17, # :var"" escaping rules differ from strings (#58484) :foo, @@ -1598,6 +1602,12 @@ struct var"%X%" end # Invalid name without '#' :(=), :(:), :(::), # Requires quoting Symbol("a\nb"), + Val(Float16(1.0)), Val(1f0), Val(1.0), + Val(:abc), Val(:(=)), Val(:var"a\b"), + + Val(1), Val(Int8(1)), Val(Int16(1)), Val(Int32(1)), Val(Int64(1)), Val(Int128(1)), + Val(UInt(1)), Val(UInt8(1)), Val(UInt16(1)), Val(UInt32(1)), Val(UInt64(1)), Val(UInt128(1)), + # BROKEN # Symbol("a\xffb"), # User-defined primitive types From c4d21176e3f8a3e91f1c709a2b847f9d77bcb4c5 Mon Sep 17 00:00:00 2001 From: Sam Schweigel Date: Tue, 27 May 2025 12:36:41 -0700 Subject: [PATCH 05/10] Correct jl_static_show_string raw escaping n backslashes followed by " => 2n+1 backslashes and " n backslahes at the end => 2n backslashes --- src/rtutils.c | 20 ++++++++++++++------ test/show.jl | 5 ++++- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/rtutils.c b/src/rtutils.c index b2b599dc6ed21..8b2bc081a89d0 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -729,15 +729,23 @@ static size_t jl_static_show_string(JL_STREAM *out, const char *str, size_t len, n += len; } else if (raw) { + // REF: Base.escape_raw_string + int escapes = 0; for (size_t i = 0; i < len; i++) { uint8_t c = str[i]; - if (c == '"') - jl_uv_puts(out, "\\\"", 2); - else if (c == '\\' && i == len - 1) - jl_uv_puts(out, "\\\\", 2); - else - jl_uv_puts(out, str + i, 1); + if (c == '\\') { + escapes++; + } + else { + if (c == '"') + for (escapes++; escapes > 0; escapes--) + jl_uv_puts(out, "\\", 1); + escapes = 0; + } + jl_uv_puts(out, str + i, 1); } + for (; escapes > 0; escapes--) + jl_uv_puts(out, "\\", 1); } else { char buf[512]; diff --git a/test/show.jl b/test/show.jl index 8f62cdf2d0e87..c98f68a41b65e 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1597,7 +1597,10 @@ struct var"%X%" end # Invalid name without '#' :var"a $b", # No escaping for $ in raw string :var"a\b", # No escaping for backslashes in middle :var"a\\", # Backslashes must be escaped at the end - :var"\"", + :var"a\\\\", + :var"a\"b", + :var"a\"", + :var"\\\"", :+, :var"+-", :(=), :(:), :(::), # Requires quoting Symbol("a\nb"), From 208a56c43f31068d4d740f2477288bcc826da89c Mon Sep 17 00:00:00 2001 From: Sam Schweigel Date: Wed, 28 May 2025 10:55:38 -0700 Subject: [PATCH 06/10] Print floats with the correct precision, don't rely on fabs/modf --- src/rtutils.c | 33 +++++++++++++++++++++++---------- test/show.jl | 2 ++ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/rtutils.c b/src/rtutils.c index 8b2bc081a89d0..9098e6e570f3d 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -821,10 +821,14 @@ static size_t jl_static_show_float(JL_STREAM *out, double v, const char *size_suffix = vt == jl_float16_type ? "16" : vt == jl_float32_type ? "32" : ""; - // Digits required to print p significand bits: ceil(p * log(10, 2)) - // Float16 4 - // Float32 8 + // Requires minimum 1 (sign) + 17 (sig) + 1 (dot) + 5 ("e-123") + 1 (null) + char buf[32]; + // Base B significand digits required to print n base-b significand bits + // (including leading 1): N = 2 + floor(n/log(b, B)) + // Float16 5 + // Float32 9 // Float64 17 + // REF: https://dl.acm.org/doi/pdf/10.1145/93542.93559 if (isnan(v)) { n += jl_printf(out, "NaN%s", size_suffix); } @@ -832,18 +836,27 @@ static size_t jl_static_show_float(JL_STREAM *out, double v, n += jl_printf(out, "%sInf%s", v < 0 ? "-" : "", size_suffix); } else if (vt == jl_float64_type) { - // If no decimal point or exponent will be printed, we must add ".0" - double ipart, fpart; - fpart = modf(v, &ipart); - int dotzero = v == 0 || (fpart == 0.0 && fabs(ipart) < 1e17); - n += jl_printf(out, "%.17g%s", v, dotzero ? ".0" : ""); + size_t m = snprintf(buf, sizeof buf, "%.17g", v); + jl_uv_puts(out, buf, m); + n += m; + // If there is no decimal point or exponent, disambiguate + if (!strpbrk(buf, ".e")) + jl_printf(out, ".0"); } else if (vt == jl_float32_type) { - n += jl_printf(out, "Float32(%.8g)", v); + size_t m = snprintf(buf, sizeof buf, "%.9g", v); + // If the exponent was printed, replace it with 'f' + char *p = memchr(buf, 'e', m); + if (p) + *p = 'f'; + jl_uv_puts(out, buf, m); + // If no exponent was printed, we must add one + if (!p) + jl_printf(out, "f0"); } else { assert(vt == jl_float16_type); - n += jl_printf(out, "Float16(%.4g)", v); + n += jl_printf(out, "Float16(%.5g)", v); } return n; } diff --git a/test/show.jl b/test/show.jl index c98f68a41b65e..6b97b914b21cc 100644 --- a/test/show.jl +++ b/test/show.jl @@ -1580,6 +1580,8 @@ struct var"%X%" end # Invalid name without '#' Float16(1), Float32(1), Float64(1), Float16(1.5), Float32(1.5), Float64(1.5), Float16(0.4893243538921085), Float32(0.4893243538921085), Float64(0.4893243538921085), + # Examples that require the full 5, 9, and 17 digits of precision + Float16(0.00010014), Float32(1.00000075f-36), Float64(-1.561051336605761e-182), floatmax(Float16), floatmax(Float32), floatmax(Float64), floatmin(Float16), floatmin(Float32), floatmin(Float64), Inf16, Inf32, Inf, From 054ce44688eb807e5b0d87e1efc7b404352e0185 Mon Sep 17 00:00:00 2001 From: Sam Schweigel <33556084+xal-0@users.noreply.github.com> Date: Wed, 28 May 2025 11:09:29 -0700 Subject: [PATCH 07/10] Update src/rtutils.c Co-authored-by: Jameson Nash --- src/rtutils.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rtutils.c b/src/rtutils.c index 9098e6e570f3d..24cec501810b1 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -739,13 +739,13 @@ static size_t jl_static_show_string(JL_STREAM *out, const char *str, size_t len, else { if (c == '"') for (escapes++; escapes > 0; escapes--) - jl_uv_puts(out, "\\", 1); + n += jl_uv_puts(out, "\\", 1); escapes = 0; } - jl_uv_puts(out, str + i, 1); + n += jl_uv_puts(out, str + i, 1); } for (; escapes > 0; escapes--) - jl_uv_puts(out, "\\", 1); + n += jl_uv_puts(out, "\\", 1); } else { char buf[512]; From 77c913fc1598ea9edc5e598aa754f0754e2d9e26 Mon Sep 17 00:00:00 2001 From: Sam Schweigel <33556084+xal-0@users.noreply.github.com> Date: Wed, 28 May 2025 11:12:27 -0700 Subject: [PATCH 08/10] Update src/rtutils.c Co-authored-by: Jameson Nash --- src/rtutils.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/rtutils.c b/src/rtutils.c index 24cec501810b1..6a7b1d13ed651 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -836,12 +836,7 @@ static size_t jl_static_show_float(JL_STREAM *out, double v, n += jl_printf(out, "%sInf%s", v < 0 ? "-" : "", size_suffix); } else if (vt == jl_float64_type) { - size_t m = snprintf(buf, sizeof buf, "%.17g", v); - jl_uv_puts(out, buf, m); - n += m; - // If there is no decimal point or exponent, disambiguate - if (!strpbrk(buf, ".e")) - jl_printf(out, ".0"); + n += jl_printf(buf, sizeof buf, "%#.17g", v); } else if (vt == jl_float32_type) { size_t m = snprintf(buf, sizeof buf, "%.9g", v); From 77fcca37504667f98428fd8d451058017f11a3ab Mon Sep 17 00:00:00 2001 From: Sam Schweigel Date: Wed, 28 May 2025 11:17:14 -0700 Subject: [PATCH 09/10] Fixes, additional tests, use trailing zeros for floats --- src/rtutils.c | 13 +++++++------ test/show.jl | 4 +++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/rtutils.c b/src/rtutils.c index 6a7b1d13ed651..bb8e089e096b6 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -739,13 +739,13 @@ static size_t jl_static_show_string(JL_STREAM *out, const char *str, size_t len, else { if (c == '"') for (escapes++; escapes > 0; escapes--) - n += jl_uv_puts(out, "\\", 1); + n += jl_printf(out, "\\"); escapes = 0; } - n += jl_uv_puts(out, str + i, 1); + n += jl_printf(out, "%c", str[i]); } for (; escapes > 0; escapes--) - n += jl_uv_puts(out, "\\", 1); + n += jl_printf(out, "\\"); } else { char buf[512]; @@ -836,7 +836,7 @@ static size_t jl_static_show_float(JL_STREAM *out, double v, n += jl_printf(out, "%sInf%s", v < 0 ? "-" : "", size_suffix); } else if (vt == jl_float64_type) { - n += jl_printf(buf, sizeof buf, "%#.17g", v); + n += jl_printf(out, "%#.17g", v); } else if (vt == jl_float32_type) { size_t m = snprintf(buf, sizeof buf, "%.9g", v); @@ -845,13 +845,14 @@ static size_t jl_static_show_float(JL_STREAM *out, double v, if (p) *p = 'f'; jl_uv_puts(out, buf, m); + n += m; // If no exponent was printed, we must add one if (!p) - jl_printf(out, "f0"); + n += jl_printf(out, "f0"); } else { assert(vt == jl_float16_type); - n += jl_printf(out, "Float16(%.5g)", v); + n += jl_printf(out, "Float16(%#.5g)", v); } return n; } diff --git a/test/show.jl b/test/show.jl index 6b97b914b21cc..941f04c364d09 100644 --- a/test/show.jl +++ b/test/show.jl @@ -703,7 +703,7 @@ let oldout = stdout, olderr = stderr redirect_stderr(olderr) close(wrout) close(wrerr) - @test fetch(out) == "primitive type Int64 <: Signed\nTESTA\nTESTB\nΑ1Β2\"A\"\nA\n123.0\"C\"\n" + @test fetch(out) == "primitive type Int64 <: Signed\nTESTA\nTESTB\nΑ1Β2\"A\"\nA\n123.0000000000000000\"C\"\n" @test fetch(err) == "TESTA\nTESTB\nΑ1Β2\"A\"\n" finally redirect_stdout(oldout) @@ -1584,6 +1584,8 @@ struct var"%X%" end # Invalid name without '#' Float16(0.00010014), Float32(1.00000075f-36), Float64(-1.561051336605761e-182), floatmax(Float16), floatmax(Float32), floatmax(Float64), floatmin(Float16), floatmin(Float32), floatmin(Float64), + Float16(0.0), 0.0f0, 0.0, + Float16(-0.0), -0.0f0, -0.0, Inf16, Inf32, Inf, -Inf16, -Inf32, -Inf, nextfloat(Float16(0)), nextfloat(Float32(0)), nextfloat(Float64(0)), From 0d2a8330fc3caa33f0402373f7c924ded9d46163 Mon Sep 17 00:00:00 2001 From: Sam Schweigel Date: Wed, 28 May 2025 15:11:40 -0700 Subject: [PATCH 10/10] Fix -Werror=c++-compat --- src/rtutils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rtutils.c b/src/rtutils.c index bb8e089e096b6..44c133ce6faf2 100644 --- a/src/rtutils.c +++ b/src/rtutils.c @@ -841,7 +841,7 @@ static size_t jl_static_show_float(JL_STREAM *out, double v, else if (vt == jl_float32_type) { size_t m = snprintf(buf, sizeof buf, "%.9g", v); // If the exponent was printed, replace it with 'f' - char *p = memchr(buf, 'e', m); + char *p = (char *)memchr(buf, 'e', m); if (p) *p = 'f'; jl_uv_puts(out, buf, m);