summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-12-31 13:12:45 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-12-31 13:12:45 -0800
commit398b5e506ae146d3bc63882343b40a46185fdade (patch)
tree57f0be24c9c7ad3e114bd59bb3df188c45a4abdd
parentd62c9544d7aa667939c853ac668116270bc7a2a7 (diff)
downloadtxr-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.c11
1 files changed, 9 insertions, 2 deletions
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);