degesch: further unfucking
This commit is contained in:
parent
101ab90100
commit
b95b916c37
99
degesch.c
99
degesch.c
@ -21,6 +21,7 @@
|
|||||||
/// Some arbitrary limit for the history file
|
/// Some arbitrary limit for the history file
|
||||||
#define HISTORY_LIMIT 10000
|
#define HISTORY_LIMIT 10000
|
||||||
|
|
||||||
|
// A table of all attributes we use for output
|
||||||
#define ATTR_TABLE(XX) \
|
#define ATTR_TABLE(XX) \
|
||||||
XX( PROMPT, "prompt", "Terminal attributes for the prompt" ) \
|
XX( PROMPT, "prompt", "Terminal attributes for the prompt" ) \
|
||||||
XX( RESET, "reset", "String to reset terminal attributes" ) \
|
XX( RESET, "reset", "String to reset terminal attributes" ) \
|
||||||
@ -41,13 +42,6 @@ enum
|
|||||||
ATTR_COUNT
|
ATTR_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *g_attr_table[ATTR_COUNT] =
|
|
||||||
{
|
|
||||||
#define XX(x, y, z) [ATTR_ ## x] = "attr_" y,
|
|
||||||
ATTR_TABLE (XX)
|
|
||||||
#undef XX
|
|
||||||
};
|
|
||||||
|
|
||||||
// User data for logger functions to enable formatted logging
|
// User data for logger functions to enable formatted logging
|
||||||
#define print_fatal_data ((void *) ATTR_ERROR)
|
#define print_fatal_data ((void *) ATTR_ERROR)
|
||||||
#define print_error_data ((void *) ATTR_ERROR)
|
#define print_error_data ((void *) ATTR_ERROR)
|
||||||
@ -430,6 +424,7 @@ struct app_context
|
|||||||
// Configuration:
|
// Configuration:
|
||||||
|
|
||||||
struct str_map config; ///< User configuration
|
struct str_map config; ///< User configuration
|
||||||
|
char *attrs[ATTR_COUNT]; ///< Terminal attributes
|
||||||
bool no_colors; ///< Colour output mode
|
bool no_colors; ///< Colour output mode
|
||||||
bool reconnect; ///< Whether to reconnect on conn. fail.
|
bool reconnect; ///< Whether to reconnect on conn. fail.
|
||||||
unsigned long reconnect_delay; ///< Reconnect delay in seconds
|
unsigned long reconnect_delay; ///< Reconnect delay in seconds
|
||||||
@ -562,6 +557,8 @@ static void
|
|||||||
app_context_free (struct app_context *self)
|
app_context_free (struct app_context *self)
|
||||||
{
|
{
|
||||||
str_map_free (&self->config);
|
str_map_free (&self->config);
|
||||||
|
for (size_t i = 0; i < ATTR_COUNT; i++)
|
||||||
|
free (self->attrs[i]);
|
||||||
str_free (&self->read_buffer);
|
str_free (&self->read_buffer);
|
||||||
|
|
||||||
if (self->irc_fd != -1)
|
if (self->irc_fd != -1)
|
||||||
@ -730,20 +727,12 @@ vprint_attributed (struct app_context *ctx,
|
|||||||
printer = NULL;
|
printer = NULL;
|
||||||
|
|
||||||
if (printer)
|
if (printer)
|
||||||
{
|
tputs (ctx->attrs[attribute], 1, printer);
|
||||||
const char *value = str_map_find
|
|
||||||
(&ctx->config, g_attr_table[attribute]);
|
|
||||||
tputs (value, 1, printer);
|
|
||||||
}
|
|
||||||
|
|
||||||
vfprintf (stream, fmt, ap);
|
vfprintf (stream, fmt, ap);
|
||||||
|
|
||||||
if (printer)
|
if (printer)
|
||||||
{
|
tputs (ctx->attrs[ATTR_RESET], 1, printer);
|
||||||
const char *value = str_map_find
|
|
||||||
(&ctx->config, g_attr_table[ATTR_RESET]);
|
|
||||||
tputs (value, 1, printer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -774,31 +763,47 @@ log_message_attributed (void *user_data, const char *quote, const char *fmt,
|
|||||||
app_readline_restore (&state, g_ctx->readline_prompt);
|
app_readline_restore (&state, g_ctx->readline_prompt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_attribute (struct app_context *ctx, int id, const char *default_)
|
||||||
|
{
|
||||||
|
static const char *table[ATTR_COUNT] =
|
||||||
|
{
|
||||||
|
#define XX(x, y, z) [ATTR_ ## x] = "attr_" y,
|
||||||
|
ATTR_TABLE (XX)
|
||||||
|
#undef XX
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *user = str_map_find (&ctx->config, table[id]);
|
||||||
|
if (user)
|
||||||
|
ctx->attrs[id] = xstrdup (user);
|
||||||
|
else
|
||||||
|
ctx->attrs[id] = xstrdup (default_);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_colors (struct app_context *ctx)
|
init_colors (struct app_context *ctx)
|
||||||
{
|
{
|
||||||
bool have_ti = init_terminal ();
|
bool have_ti = init_terminal ();
|
||||||
|
|
||||||
// Use escape sequences from terminfo if possible, and SGR as a fallback
|
// Use escape sequences from terminfo if possible, and SGR as a fallback
|
||||||
#define INIT_ATTR(id, ti) \
|
#define INIT_ATTR(id, ti) init_attribute (ctx, ATTR_ ## id, have_ti ? (ti) : "")
|
||||||
str_map_set (&ctx->config, g_attr_table[id], xstrdup (have_ti ? (ti) : ""))
|
|
||||||
|
|
||||||
INIT_ATTR (ATTR_PROMPT, enter_bold_mode);
|
INIT_ATTR (PROMPT, enter_bold_mode);
|
||||||
INIT_ATTR (ATTR_RESET, exit_attribute_mode);
|
INIT_ATTR (RESET, exit_attribute_mode);
|
||||||
INIT_ATTR (ATTR_WARNING, g_terminal.color_set_fg[3]);
|
INIT_ATTR (WARNING, g_terminal.color_set_fg[3]);
|
||||||
INIT_ATTR (ATTR_ERROR, g_terminal.color_set_fg[1]);
|
INIT_ATTR (ERROR, g_terminal.color_set_fg[1]);
|
||||||
|
|
||||||
INIT_ATTR (ATTR_EXTERNAL, g_terminal.color_set_fg[7]);
|
INIT_ATTR (EXTERNAL, g_terminal.color_set_fg[7]);
|
||||||
INIT_ATTR (ATTR_TIMESTAMP, g_terminal.color_set_fg[7]);
|
INIT_ATTR (TIMESTAMP, g_terminal.color_set_fg[7]);
|
||||||
INIT_ATTR (ATTR_ACTION, g_terminal.color_set_fg[1]);
|
INIT_ATTR (ACTION, g_terminal.color_set_fg[1]);
|
||||||
INIT_ATTR (ATTR_JOIN, g_terminal.color_set_fg[2]);
|
INIT_ATTR (JOIN, g_terminal.color_set_fg[2]);
|
||||||
INIT_ATTR (ATTR_PART, g_terminal.color_set_fg[1]);
|
INIT_ATTR (PART, g_terminal.color_set_fg[1]);
|
||||||
|
|
||||||
char *highlight = xstrdup_printf ("%s%s%s",
|
char *highlight = xstrdup_printf ("%s%s%s",
|
||||||
g_terminal.color_set_fg[3],
|
g_terminal.color_set_fg[3],
|
||||||
g_terminal.color_set_bg[5],
|
g_terminal.color_set_bg[5],
|
||||||
enter_bold_mode);
|
enter_bold_mode);
|
||||||
INIT_ATTR (ATTR_HIGHLIGHT, highlight);
|
INIT_ATTR (HIGHLIGHT, highlight);
|
||||||
free (highlight);
|
free (highlight);
|
||||||
|
|
||||||
#undef INIT_ATTR
|
#undef INIT_ATTR
|
||||||
@ -896,7 +901,7 @@ setup_signal_handlers (void)
|
|||||||
enum formatter_item_type
|
enum formatter_item_type
|
||||||
{
|
{
|
||||||
FORMATTER_ITEM_TEXT, ///< Text
|
FORMATTER_ITEM_TEXT, ///< Text
|
||||||
FORMATTER_ITEM_ATTR, ///< Named formatting attributes
|
FORMATTER_ITEM_ATTR, ///< Formatting attributes
|
||||||
FORMATTER_ITEM_FG_COLOR, ///< Foreground color
|
FORMATTER_ITEM_FG_COLOR, ///< Foreground color
|
||||||
FORMATTER_ITEM_BG_COLOR ///< Background color
|
FORMATTER_ITEM_BG_COLOR ///< Background color
|
||||||
};
|
};
|
||||||
@ -907,7 +912,8 @@ struct formatter_item
|
|||||||
|
|
||||||
enum formatter_item_type type; ///< Type of this item
|
enum formatter_item_type type; ///< Type of this item
|
||||||
int color; ///< Color
|
int color; ///< Color
|
||||||
char *data; ///< Either text or an attribute string
|
int attribute; ///< Attribute ID
|
||||||
|
char *text; ///< Either text or an attribute string
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct formatter_item *
|
static struct formatter_item *
|
||||||
@ -920,7 +926,7 @@ formatter_item_new (void)
|
|||||||
static void
|
static void
|
||||||
formatter_item_destroy (struct formatter_item *self)
|
formatter_item_destroy (struct formatter_item *self)
|
||||||
{
|
{
|
||||||
free (self->data);
|
free (self->text);
|
||||||
free (self);
|
free (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -962,7 +968,7 @@ formatter_add_text (struct formatter *self, const char *text)
|
|||||||
{
|
{
|
||||||
struct formatter_item *item = formatter_add_blank (self);
|
struct formatter_item *item = formatter_add_blank (self);
|
||||||
item->type = FORMATTER_ITEM_TEXT;
|
item->type = FORMATTER_ITEM_TEXT;
|
||||||
item->data = xstrdup (text);
|
item->text = xstrdup (text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -973,7 +979,7 @@ formatter_add_reset (struct formatter *self)
|
|||||||
|
|
||||||
struct formatter_item *item = formatter_add_blank (self);
|
struct formatter_item *item = formatter_add_blank (self);
|
||||||
item->type = FORMATTER_ITEM_ATTR;
|
item->type = FORMATTER_ITEM_ATTR;
|
||||||
item->data = NULL;
|
item->attribute = ATTR_RESET;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -984,8 +990,7 @@ formatter_add_attr (struct formatter *self, int attr_id)
|
|||||||
|
|
||||||
struct formatter_item *item = formatter_add_blank (self);
|
struct formatter_item *item = formatter_add_blank (self);
|
||||||
item->type = FORMATTER_ITEM_ATTR;
|
item->type = FORMATTER_ITEM_ATTR;
|
||||||
item->data = xstrdup (str_map_find
|
item->attribute = attr_id;
|
||||||
(&self->ctx->config, g_attr_table[attr_id]));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -1106,12 +1111,11 @@ formatter_flush (struct formatter *self, FILE *stream)
|
|||||||
{
|
{
|
||||||
LIST_FOR_EACH (struct formatter_item, iter, self->items)
|
LIST_FOR_EACH (struct formatter_item, iter, self->items)
|
||||||
if (iter->type == FORMATTER_ITEM_TEXT)
|
if (iter->type == FORMATTER_ITEM_TEXT)
|
||||||
fputs (iter->data, stream);
|
fputs (iter->text, stream);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *attr_reset = str_map_find
|
const char *attr_reset = self->ctx->attrs[ATTR_RESET];
|
||||||
(&self->ctx->config, g_attr_table[ATTR_RESET]);
|
|
||||||
tputs (attr_reset, 1, printer);
|
tputs (attr_reset, 1, printer);
|
||||||
|
|
||||||
bool is_attributed = false;
|
bool is_attributed = false;
|
||||||
@ -1122,7 +1126,7 @@ formatter_flush (struct formatter *self, FILE *stream)
|
|||||||
char *term;
|
char *term;
|
||||||
case FORMATTER_ITEM_TEXT:
|
case FORMATTER_ITEM_TEXT:
|
||||||
term = iconv_xstrdup
|
term = iconv_xstrdup
|
||||||
(self->ctx->term_from_utf8, iter->data, -1, NULL);
|
(self->ctx->term_from_utf8, iter->text, -1, NULL);
|
||||||
fputs (term, stream);
|
fputs (term, stream);
|
||||||
free (term);
|
free (term);
|
||||||
break;
|
break;
|
||||||
@ -1132,9 +1136,9 @@ formatter_flush (struct formatter *self, FILE *stream)
|
|||||||
tputs (attr_reset, 1, printer);
|
tputs (attr_reset, 1, printer);
|
||||||
is_attributed = false;
|
is_attributed = false;
|
||||||
}
|
}
|
||||||
if (iter->data)
|
if (iter->attribute != ATTR_RESET)
|
||||||
{
|
{
|
||||||
tputs (iter->data, 1, printer);
|
tputs (self->ctx->attrs[iter->attribute], 1, printer);
|
||||||
is_attributed = true;
|
is_attributed = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2142,14 +2146,12 @@ refresh_prompt (struct app_context *ctx)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// XXX: to be completely correct, we should use tputs, but we cannot
|
// XXX: to be completely correct, we should use tputs, but we cannot
|
||||||
const char *prompt_attrs = str_map_find
|
|
||||||
(&ctx->config, g_attr_table[ATTR_PROMPT]);
|
|
||||||
const char *reset_attrs = str_map_find
|
|
||||||
(&ctx->config, g_attr_table[ATTR_RESET]);
|
|
||||||
ctx->readline_prompt = xstrdup_printf ("%c%s%c%s%c%s%c",
|
ctx->readline_prompt = xstrdup_printf ("%c%s%c%s%c%s%c",
|
||||||
RL_PROMPT_START_IGNORE, prompt_attrs, RL_PROMPT_END_IGNORE,
|
RL_PROMPT_START_IGNORE, ctx->attrs[ATTR_PROMPT],
|
||||||
|
RL_PROMPT_END_IGNORE,
|
||||||
prompt.str,
|
prompt.str,
|
||||||
RL_PROMPT_START_IGNORE, reset_attrs, RL_PROMPT_END_IGNORE);
|
RL_PROMPT_START_IGNORE, ctx->attrs[ATTR_RESET],
|
||||||
|
RL_PROMPT_END_IGNORE);
|
||||||
}
|
}
|
||||||
str_free (&prompt);
|
str_free (&prompt);
|
||||||
|
|
||||||
@ -4549,7 +4551,6 @@ main (int argc, char *argv[])
|
|||||||
exit (EXIT_FAILURE);
|
exit (EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: this overwrites all custom attribute settings
|
|
||||||
init_colors (&ctx);
|
init_colors (&ctx);
|
||||||
init_poller_events (&ctx);
|
init_poller_events (&ctx);
|
||||||
init_buffers (&ctx);
|
init_buffers (&ctx);
|
||||||
|
Loading…
Reference in New Issue
Block a user