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:
parent
c89032e4e0
commit
419b02e9f7
41
degesch.c
41
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user