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.
This commit is contained in:
Přemysl Eric Janouch 2020-10-19 05:19:28 +02:00
parent c89032e4e0
commit 419b02e9f7
Signed by: p
GPG Key ID: A0420B94F92B9493

View File

@ -3413,8 +3413,8 @@ formatter_add (struct formatter *self, const char *format, ...)
struct line_char_attrs struct line_char_attrs
{ {
int named; ///< Named attribute or -1 short named; ///< Named attribute or -1
int text; ///< Text attributes short text; ///< Text attributes
int fg; ///< Foreground colour (-1 for default) int fg; ///< Foreground colour (-1 for default)
int bg; ///< Background colour (-1 for default) int bg; ///< Background colour (-1 for default)
}; };
@ -3423,18 +3423,15 @@ struct line_char
{ {
LIST_HEADER (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 wchar_t wide; ///< The character as a wchar_t
int width; ///< Width of the character in cells int width; ///< Width of the character in cells
struct line_char_attrs attrs; ///< Attributes struct line_char_attrs attrs; ///< Attributes
}; };
static struct line_char * 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); 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)); self->width = wcwidth ((self->wide = wc));
// Typically various control characters // Typically various control characters
@ -3476,7 +3473,7 @@ struct line_wrap_state
static void static void
line_wrap_flush_split (struct line_wrap_state *s, struct line_wrap_mark *before) 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); LIST_INSERT_WITH_TAIL (s->result, s->result_tail, nl, before->start);
s->line_used = before->used; s->line_used = before->used;
} }
@ -3512,7 +3509,7 @@ static void
line_wrap_nl (struct line_wrap_state *s) line_wrap_nl (struct line_wrap_state *s)
{ {
line_wrap_flush (s, true); 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); LIST_APPEND_WITH_TAIL (s->result, s->result_tail, nl);
s->line_used = 0; 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; s->line_used += tab_width;
while (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; space->attrs = c->attrs;
LIST_APPEND_WITH_TAIL (s->result, s->result_tail, space); 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); hard_assert (len != (size_t) -2 && len != (size_t) -1);
processed += len; 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; c->attrs = self->attrs;
LIST_APPEND_WITH_TAIL (self->result, self->result_tail, c); LIST_APPEND_WITH_TAIL (self->result, self->result_tail, c);
} }
@ -3698,6 +3695,18 @@ enum
FLUSH_OPT_NOWRAP = (1 << 1) ///< Do not wrap 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 static void
formatter_flush (struct formatter *self, FILE *stream, int flush_opts) 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)) if (!is_tty && !(flush_opts & FLUSH_OPT_RAW))
{ {
LIST_FOR_EACH (struct line_char, c, line) LIST_FOR_EACH (struct line_char, c, line)
{ formatter_putc (c, stream);
fwrite (c->bytes, c->len, 1, stream); formatter_putc (NULL, stream);
free (c);
}
return; return;
} }
@ -3726,6 +3733,8 @@ formatter_flush (struct formatter *self, FILE *stream, int flush_opts)
|| attrs.named != c->attrs.named || attrs.named != c->attrs.named
|| attrs.text != c->attrs.text) || attrs.text != c->attrs.text)
{ {
formatter_putc (NULL, stream);
attrs = c->attrs; attrs = c->attrs;
if (attrs.named != -1) if (attrs.named != -1)
attr_printer_apply_named (&state, attrs.named); 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); attr_printer_apply (&state, attrs.text, attrs.fg, attrs.bg);
} }
fwrite (c->bytes, c->len, 1, stream); formatter_putc (c, stream);
free (c);
} }
formatter_putc (NULL, stream);
attr_printer_reset (&state); attr_printer_reset (&state);
} }