diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-12-31 13:12:45 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-12-31 13:12:45 -0800 |
commit | 398b5e506ae146d3bc63882343b40a46185fdade (patch) | |
tree | 57f0be24c9c7ad3e114bd59bb3df188c45a4abdd | |
parent | d62c9544d7aa667939c853ac668116270bc7a2a7 (diff) | |
download | txr-398b5e506ae146d3bc63882343b40a46185fdade.tar.gz txr-398b5e506ae146d3bc63882343b40a46185fdade.tar.bz2 txr-398b5e506ae146d3bc63882343b40a46185fdade.zip |
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.
-rw-r--r-- | lib.c | 11 |
1 files changed, 9 insertions, 2 deletions
@@ -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); |