diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-04-05 06:53:24 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-04-05 06:53:24 -0700 |
commit | e69a99cc4c183a98dd380fdaf47a5a1dcb5d68a0 (patch) | |
tree | 8dceea3e5455d6c8e711cbdfc78525bc87257fc6 /stream.c | |
parent | 34efdb8b2e45eb6543a8fbaadf8867ee58870677 (diff) | |
download | txr-e69a99cc4c183a98dd380fdaf47a5a1dcb5d68a0.tar.gz txr-e69a99cc4c183a98dd380fdaf47a5a1dcb5d68a0.tar.bz2 txr-e69a99cc4c183a98dd380fdaf47a5a1dcb5d68a0.zip |
printer: improve object formatting.
There is an issue with the printer in that it produces
output whereby objects continue on the same line after
a multi-line object, e.g:
(foo (foobly bar
xyzzy quux) (oops same
line))
rather than:
(foo (foobly bar
xyzzy quux)
(oops same line))
There is a simple fix for this: set a flag to force
a line break on the next width-check operation whenever
an object has been broken into multiple lines.
width-check can return a Boolean indication whether
it generated a line break, and so aggregate object
printing routines can tell whether their object
has been broken into lines, and set the flag.
* stream.h (struct strm_base): New member, force_break.
(force_break): Declared.
* stream.c (strm_base_init): Extent initializer to cover
force_break flag.
(put_string, put_char): Clear the force_break flag whenever
we hit column zero.
(width_check): If indent mode is on, and force_break is
true, generate a break. Clear force_break.
(force_break): New function.
(stream_init): Register force-break intrinsic.
* buf.c (buf_print): Set the force break flag if the buffer
was broken into multiple lines.
* hash.c (hash_print_op): Set the force break flag if the
hash was broken into multiple lines.
* lib.c (obj_print_impl): Same logic for lists.
* struct.c (struct_inst_print): Same logic for structs.
* tests/009/json.expected, tests/011/macros-2.expected,
tests/012/struct.tl, tests/017/glob-zarray.expected:
Update expected textual output to reflect new formatting.
Diffstat (limited to 'stream.c')
-rw-r--r-- | stream.c | 20 |
1 files changed, 17 insertions, 3 deletions
@@ -103,7 +103,7 @@ val shell, shell_arg; void strm_base_init(struct strm_base *s) { - static struct strm_base init = { indent_off, 60, 10, 0, 0, 0 }; + static struct strm_base init = { indent_off, 60, 10, 0, 0, 0, 0 }; *s = init; } @@ -3512,6 +3512,7 @@ val put_string(val string, val stream_in) switch (*p) { case '\n': col = 0; + s->force_break = 0; break; case '\t': col = (col + 1) | 7; @@ -3540,6 +3541,7 @@ val put_char(val ch, val stream_in) case L'\n': ops->put_char(stream, ch); s->column = 0; + s->force_break = 0; break; case L'\t': if (s->column == 0 && s->indent_mode != indent_off) { @@ -3697,14 +3699,25 @@ val width_check(val stream, val alt) if ((s->indent_mode == indent_code && s->column >= s->indent_chars + s->code_width) || (s->indent_mode == indent_data && - s->column >= s->indent_chars + s->data_width)) + s->column >= s->indent_chars + s->data_width) || + (s->indent_mode != indent_off && s->force_break)) { put_char(chr('\n'), stream); + s->force_break = 0; + return t; } else if (alt) { put_char(alt, stream); } - return t; + return nil; +} + +val force_break(val stream) +{ + struct strm_base *s = coerce(struct strm_base *, + cobj_handle(stream, stream_s)); + s->force_break = 1; + return stream; } struct strm_ctx *get_set_ctx(val stream, struct strm_ctx *ctx) @@ -4596,6 +4609,7 @@ void stream_init(void) reg_fun(intern(lit("set-indent"), user_package), func_n2(set_indent)); reg_fun(intern(lit("inc-indent"), user_package), func_n2(inc_indent)); reg_fun(intern(lit("width-check"), user_package), func_n2(width_check)); + reg_fun(intern(lit("force-break"), user_package), func_n1(force_break)); reg_varl(intern(lit("indent-off"), user_package), num_fast(indent_off)); reg_varl(intern(lit("indent-data"), user_package), num_fast(indent_data)); reg_varl(intern(lit("indent-code"), user_package), num_fast(indent_code)); |