From 419b02e9f720cc198012c67dfed71394997d81d7 Mon Sep 17 00:00:00 2001 From: Přemysl Eric Janouch
Date: Mon, 19 Oct 2020 05:19:28 +0200 Subject: degesch: slightly cut down memory usage The worst offenders are actually OpenSSL and Lua, this is mostly about a preventable surprise. This is more correct because we mix escape sequences for attributes with text, however in practice no one will use shit-jizz with degesch. It is also a clean-up: "struct line_char" has been almost halved in size. We used to use it as a cache and now we recompute the multibyte sequence. Of course, it'd be best to get rid of the linked list but it would take a very long time to rewrite the algorithm. Plus, it's not certain that it could be improved by much. The change in "struct line_char_attrs" is merely cosmetical. --- degesch.c | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/degesch.c b/degesch.c index 4e58684..7063343 100644 --- a/degesch.c +++ b/degesch.c @@ -3413,8 +3413,8 @@ formatter_add (struct formatter *self, const char *format, ...) struct line_char_attrs { - int named; ///< Named attribute or -1 - int text; ///< Text attributes + short named; ///< Named attribute or -1 + short text; ///< Text attributes int fg; ///< Foreground colour (-1 for default) int bg; ///< Background colour (-1 for default) }; @@ -3423,18 +3423,15 @@ struct line_char { LIST_HEADER (struct line_char) - char bytes[MB_LEN_MAX]; ///< The character - size_t len; ///< Length of the character in bytes wchar_t wide; ///< The character as a wchar_t int width; ///< Width of the character in cells struct line_char_attrs attrs; ///< Attributes }; static struct line_char * -line_char_new (const char *mb, size_t mb_len, wchar_t wc) +line_char_new (wchar_t wc) { struct line_char *self = xcalloc (1, sizeof *self); - memcpy (self->bytes, mb, (self->len = MIN (mb_len, sizeof self->bytes))); self->width = wcwidth ((self->wide = wc)); // Typically various control characters @@ -3476,7 +3473,7 @@ struct line_wrap_state static void line_wrap_flush_split (struct line_wrap_state *s, struct line_wrap_mark *before) { - struct line_char *nl = line_char_new ("\n", 1, L'\n'); + struct line_char *nl = line_char_new (L'\n'); LIST_INSERT_WITH_TAIL (s->result, s->result_tail, nl, before->start); s->line_used = before->used; } @@ -3512,7 +3509,7 @@ static void line_wrap_nl (struct line_wrap_state *s) { line_wrap_flush (s, true); - struct line_char *nl = line_char_new ("\n", 1, L'\n'); + struct line_char *nl = line_char_new (L'\n'); LIST_APPEND_WITH_TAIL (s->result, s->result_tail, nl); s->line_used = 0; } @@ -3533,7 +3530,7 @@ line_wrap_tab (struct line_wrap_state *s, struct line_char *c) s->line_used += tab_width; while (tab_width--) { - struct line_char *space = line_char_new (" ", 1, L' '); + struct line_char *space = line_char_new (L' '); space->attrs = c->attrs; LIST_APPEND_WITH_TAIL (s->result, s->result_tail, space); } @@ -3664,7 +3661,7 @@ explode_text (struct exploder *self, const char *text) hard_assert (len != (size_t) -2 && len != (size_t) -1); processed += len; - struct line_char *c = line_char_new (term + processed - len, len, wch); + struct line_char *c = line_char_new (wch); c->attrs = self->attrs; LIST_APPEND_WITH_TAIL (self->result, self->result_tail, c); } @@ -3698,6 +3695,18 @@ enum FLUSH_OPT_NOWRAP = (1 << 1) ///< Do not wrap }; +/// The input is a bunch of wide characters--respect shift state encodings +static void +formatter_putc (struct line_char *c, FILE *stream) +{ + static mbstate_t mb; + char buf[MB_LEN_MAX] = {}; + size_t len = wcrtomb (buf, c ? c->wide : L'\0', &mb); + if (len != (size_t) -1 && len) + fwrite (buf, len - !c, 1, stream); + free (c); +} + static void formatter_flush (struct formatter *self, FILE *stream, int flush_opts) { @@ -3707,10 +3716,8 @@ formatter_flush (struct formatter *self, FILE *stream, int flush_opts) if (!is_tty && !(flush_opts & FLUSH_OPT_RAW)) { LIST_FOR_EACH (struct line_char, c, line) - { - fwrite (c->bytes, c->len, 1, stream); - free (c); - } + formatter_putc (c, stream); + formatter_putc (NULL, stream); return; } @@ -3726,6 +3733,8 @@ formatter_flush (struct formatter *self, FILE *stream, int flush_opts) || attrs.named != c->attrs.named || attrs.text != c->attrs.text) { + formatter_putc (NULL, stream); + attrs = c->attrs; if (attrs.named != -1) attr_printer_apply_named (&state, attrs.named); @@ -3733,9 +3742,9 @@ formatter_flush (struct formatter *self, FILE *stream, int flush_opts) attr_printer_apply (&state, attrs.text, attrs.fg, attrs.bg); } - fwrite (c->bytes, c->len, 1, stream); - free (c); + formatter_putc (c, stream); } + formatter_putc (NULL, stream); attr_printer_reset (&state); } -- cgit v1.2.3-70-g09d2