From 398b5e506ae146d3bc63882343b40a46185fdade Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 31 Dec 2016 13:12:45 -0800 Subject: Bugfix: quasilit var read-print consistency. The problem is that objects like `@{foo:bar} @{*xyz*}` are printing as `@foo:bar @*xyz*` without the required braces. This changes the meaning, as in @foo:bar which is @foo followed by the text :bar, or creates a syntax error, as in @*xyz*. * lib.c (out_quasi_str): When printing a var, first convert it to a string form by printing to a string stream. Then if the string form consists of anything other than letters, digits and underscores, mark it as needing braces, in addition to the existing conditions. --- lib.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'lib.c') diff --git a/lib.c b/lib.c index 574055b6..b0559b0a 100644 --- a/lib.c +++ b/lib.c @@ -9606,15 +9606,22 @@ static void out_quasi_str(val args, val out, struct strm_ctx *ctx) val mods = third(elem); val next_elem_char = and3(next_elem && !mods, stringp(next_elem), chr_str(next_elem, zero)); + val osstrm = make_string_output_stream(); + val namestr = (obj_print_impl(name, osstrm, nil, ctx), + get_string_from_stream(osstrm)); int need_brace = mods || (next_elem_char && (chr_isalpha(next_elem_char) || chr_isdigit(next_elem_char) || - next_elem_char == chr('_'))); + next_elem_char == chr('_'))) || + (span_str(namestr, lit("0123456789_" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz")) + != length(namestr)); put_char(chr('@'), out); if (need_brace) put_char(chr('{'), out); - obj_print_impl(name, out, nil, ctx); + obj_print_impl(namestr, out, t, ctx); while (mods) { put_char(chr(' '), out); obj_print_impl(car(mods), out, nil, ctx); -- cgit v1.2.3