diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2019-04-16 18:36:56 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2019-04-16 18:36:56 -0700 |
commit | 566de7d4516c8c0d161a95dafcbb530601306538 (patch) | |
tree | c293e50d359d19444b22b56f80abf52cef269a76 | |
parent | 59c4fe61bdbe56eb215e29535e89ad72c3a2ee4b (diff) | |
download | txr-566de7d4516c8c0d161a95dafcbb530601306538.tar.gz txr-566de7d4516c8c0d161a95dafcbb530601306538.tar.bz2 txr-566de7d4516c8c0d161a95dafcbb530601306538.zip |
streams: force-off indent mode.
The fourth indent mode indent-foff (force off) is introduced.
* buf.c (buf_print): Turn on data mode indentation if
the current mode is not indent-foff, rather than when it
is indent-off.
* lib.c (obj_print_impl): The unconditional set_indent_mode
calls are replaced with test_neq_set_indent_mode so we only
set the mode if it is not forced off.
* stream.c (formatv): For the ! directive, turn on data
mode identation is not indent-foff, rather than when it is
indent-off.
(put_string, put_char, width_check): Recognize ident-foff as
indentation off.
(test_neq_set_indent_mode): New function.
(stream_init): Register test-neq-set-indent-mode function
and indent-foff variable.
* stream.h (indent_mode): New enum constant, indent_foff.
(test_neq_set_indent_mode): Declared.
* struct.c (struct_inst_print): Turn on data mode indentation
if the current mode is not indent-foff, rather than when it is
indent-off.
* txr.1: Documented.
-rw-r--r-- | buf.c | 4 | ||||
-rw-r--r-- | lib.c | 6 | ||||
-rw-r--r-- | stream.c | 30 | ||||
-rw-r--r-- | stream.h | 4 | ||||
-rw-r--r-- | struct.c | 4 | ||||
-rw-r--r-- | txr.1 | 77 |
6 files changed, 93 insertions, 32 deletions
@@ -634,8 +634,8 @@ val buf_print(val buf, val stream_in) struct buf *b = buf_handle(buf, lit("buf-print")); cnum len = c_num(b->len), count = 0; mem_t *data = b->data; - val save_mode = test_set_indent_mode(stream, num_fast(indent_off), - num_fast(indent_data)); + val save_mode = test_neq_set_indent_mode(stream, num_fast(indent_foff), + num_fast(indent_data)); val save_indent; int fb = 0; @@ -11124,7 +11124,7 @@ val obj_print_impl(val obj, val out, val pretty, struct strm_ctx *ctx) if (sym == lambda_s && consp(cdr(obj)) && symbolp(second(obj))) { indent = one; save_indent = inc_indent(out, indent); - set_indent_mode(out, num_fast(indent_code)); + test_neq_set_indent_mode(out, num_fast(indent_foff), num_fast(indent_code)); obj_print_impl(sym, out, pretty, ctx); if (second(obj)) { put_string(lit(" (. "), out); @@ -11137,12 +11137,12 @@ val obj_print_impl(val obj, val out, val pretty, struct strm_ctx *ctx) goto finish; } else if (special_operator_p(sym) || macro_form_p(obj, nil)) { indent = one; - set_indent_mode(out, num_fast(indent_code)); + test_neq_set_indent_mode(out, num_fast(indent_foff), num_fast(indent_code)); } else if (fboundp(sym)) { obj_print_impl(sym, out, pretty, ctx); indent = one; save_indent = inc_indent(out, indent); - set_indent_mode(out, num_fast(indent_code)); + test_neq_set_indent_mode(out, num_fast(indent_foff), num_fast(indent_code)); iter = obj; goto finish; } @@ -3449,8 +3449,8 @@ val formatv(val stream_in, val fmtstr, struct args *al) } goto output_num; case '!': - save_mode = test_set_indent_mode(stream, num_fast(indent_off), - num_fast(indent_data)); + save_mode = test_neq_set_indent_mode(stream, num_fast(indent_foff), + num_fast(indent_data)); if (lt) set_indent(stream, plus(save_indent, num(width))); else @@ -3558,7 +3558,7 @@ val put_string(val string, val stream_in) const wchar_t *str = c_str(string), *p = str; - if (s->indent_mode != indent_off) { + if (s->indent_mode != indent_off && s->indent_mode != indent_foff) { while (*str) put_char(chr(*str++), stream); return t; @@ -3602,7 +3602,9 @@ val put_char(val ch, val stream_in) s->force_break = 0; break; case L'\t': - if (s->column == 0 && s->indent_mode != indent_off) { + if (s->column == 0 && s->indent_mode != indent_off && + s->indent_mode != indent_foff) + { put_indent(stream, ops, s->indent_chars); s->column = s->indent_chars; } @@ -3610,7 +3612,9 @@ val put_char(val ch, val stream_in) s->column = (s->column + 1) | 7; break; default: - if (s->column == 0 && s->indent_mode != indent_off) { + if (s->column == 0 && s->indent_mode != indent_off && + s->indent_mode != indent_foff) + { put_indent(stream, ops, s->indent_chars); s->column = s->indent_chars; } @@ -3720,6 +3724,17 @@ val test_set_indent_mode(val stream, val compare, val mode) return oldval; } +val test_neq_set_indent_mode(val stream, val compare, val mode) +{ + val self = lit("test-neq-set-indent-mode"); + struct strm_base *s = coerce(struct strm_base *, + cobj_handle(self, stream, stream_s)); + val oldval = num_fast(s->indent_mode); + if (oldval != compare) + s->indent_mode = convert(enum indent_mode, c_num(mode)); + return oldval; +} + val set_indent_mode(val stream, val mode) { val self = lit("set-indent-mode"); @@ -3773,7 +3788,8 @@ val width_check(val stream, val alt) s->column >= s->indent_chars + s->code_width) || (s->indent_mode == indent_data && s->column >= s->indent_chars + s->data_width) || - (s->indent_mode != indent_off && s->force_break)) + (s->indent_mode != indent_off && + s->indent_mode != indent_foff && s->force_break)) { put_char(chr('\n'), stream); s->force_break = 0; @@ -4679,6 +4695,7 @@ void stream_init(void) reg_varl(intern(lit("path-sep-chars"), user_package), static_str(path_sep_chars)); reg_fun(intern(lit("get-indent-mode"), user_package), func_n1(get_indent_mode)); reg_fun(intern(lit("test-set-indent-mode"), user_package), func_n3(test_set_indent_mode)); + reg_fun(intern(lit("test-neq-set-indent-mode"), user_package), func_n3(test_neq_set_indent_mode)); reg_fun(intern(lit("set-indent-mode"), user_package), func_n2(set_indent_mode)); reg_fun(intern(lit("get-indent"), user_package), func_n1(get_indent)); reg_fun(intern(lit("set-indent"), user_package), func_n2(set_indent)); @@ -4688,6 +4705,7 @@ void stream_init(void) 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)); + reg_varl(intern(lit("indent-foff"), user_package), num_fast(indent_foff)); #if HAVE_SOCKETS uw_register_subtype(socket_error_s, error_s); @@ -34,7 +34,8 @@ enum strm_whence { enum indent_mode { indent_off, indent_data, - indent_code + indent_code, + indent_foff }; struct strm_ctx { @@ -205,6 +206,7 @@ val seek_stream(val stream, val offset, val whence); val truncate_stream(val stream, val len); val get_indent_mode(val stream); val test_set_indent_mode(val stream, val compare, val mode); +val test_neq_set_indent_mode(val stream, val compare, val mode); val set_indent_mode(val stream, val mode); val get_indent(val stream); val set_indent(val stream, val indent); @@ -1445,8 +1445,8 @@ static void struct_inst_print(val obj, val out, val pretty, { struct struct_inst *si = coerce(struct struct_inst *, obj->co.handle); struct struct_type *st = si->type; - val save_mode = test_set_indent_mode(out, num_fast(indent_off), - num_fast(indent_data)); + val save_mode = test_neq_set_indent_mode(out, num_fast(indent_foff), + num_fast(indent_data)); val save_indent, iter, once; int force_br = 0; int compat = opt_compat && opt_compat <= 154; @@ -46953,31 +46953,55 @@ function does not interact with indentation. The column position tracking will be incorrect if byte and character output are mixed, affecting the placement of indentation. -Indentation mode takes on three numeric values, given by the three +Indentation mode takes on four numeric values, given by the four variables .codn indent-off , .codn indent-data , +.code indent-code and -.codn indent-code . -As far as stream output is concerned, the code and data modes behave +.codn indent-foff . +As far as stream output is concerned, the code and data modes +represented by +.code indent-code +and +.code indent-data +behave the same way: both represent the "indentation turned on" state. The difference between them influences the behavior of the .code width-check -function. This function isn't used by any stream output routines. -It is used by the object printing functions like +function. This function isn't used by any lower-level stream output +routines. It is used by the object printing functions like .code print and .code pprint to break up long lines. +The +.code indent-off +and +.code intent-foff +modes are also treated the same way by lower level stream output, +indicating "indentation turned off". The modes are distinguished +by +.code print +and +.code pprint +in the following way: +.code indent-off +is a "soft" disable which allows these object-printing routines +to temporarily turn on indentation while traversing aggregate objects. +Whereas the +.code indent-foff +("force off") value is a "hard" disable: the object-printing routines will not +enable indentation and will not break up long lines. -.coNP Variables @, indent-off @ indent-data and @ indent-code +.coNP Variables @, indent-off @, indent-data @ indent-code and @ indent-foff .desc These variables hold integer values representing output stream indentation modes. The value of .code indent-off is zero. -.coNP Functions @, get-indent-mode @ set-indent-mode and @ test-set-indent-mode +.coNP Functions @ get-indent-mode and @ set-indent-mode .synb .mets (get-indent-mode << stream ) .mets (set-indent-mode < stream << new-mode ) @@ -46989,7 +47013,6 @@ The .code get-indent-mode retrieves the current indent mode of .metn stream . - The .code set-indent-mode function sets the indent mode of @@ -46998,6 +47021,23 @@ to .meta new-mode and returns the previous mode. +Note: it is encouraged to save and restore the indentation mode, +and in a way that is exception safe. +If a block of code sets up indentation on a stream such as +.code *stdout* +and is terminated by an exception, the indentation will remain in +effect and affect subsequent output. The +.code with-resources +macro or +.code unwind-protect +operator may be used. + +.coNP Functions @ test-set-indent-mode and @ test-neq-set-indent-mode +.synb +.mets (test-set-indent-mode < stream < compare-mode << new-mode ) +.mets (test-neq-set-indent-mode < stream < compare-mode << new-mode ) +.syne +.desc The .code test-set-indent-mode function sets the indent mode of @@ -47009,16 +47049,17 @@ its current mode is equal to .metn compare-mode . Whether or not it changes the mode, it returns the previous mode. -Note: it is encouraged to save and restore the indentation mode, -and in a way that is exception safe. -If a block of code sets up indentation on a stream such as -.code *stdout* -and is terminated by an exception, the indentation will remain in -effect and affect subsequent output. The -.code with-resources -macro or -.code unwind-protect -operator may be used. +The +.code test-neq-set-indent-mode +only differs in that it sets +.meta stream +to +.meta new-mode +if, and only if, +the current mode is +.B not +equal to +.metn compare-mode . .coNP Functions @, get-indent @ set-indent and @ inc-indent .synb |