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
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user