degesch: further unfucking

This commit is contained in:
Přemysl Eric Janouch 2015-04-29 21:25:57 +02:00
parent 101ab90100
commit b95b916c37
1 changed files with 50 additions and 49 deletions

View File

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