From 101ab90100aca7d68af4d2436f09cc3aabbd9e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Wed, 29 Apr 2015 20:56:26 +0200 Subject: [PATCH] degesch: unfuck terminal attribute handling --- degesch.c | 135 ++++++++++++++++++++++++++---------------------------- 1 file changed, 66 insertions(+), 69 deletions(-) diff --git a/degesch.c b/degesch.c index 849b7ce..cb9c741 100644 --- a/degesch.c +++ b/degesch.c @@ -21,23 +21,37 @@ /// Some arbitrary limit for the history file #define HISTORY_LIMIT 10000 -// String constants for all attributes we use for output -#define ATTR_PROMPT "attr_prompt" -#define ATTR_RESET "attr_reset" -#define ATTR_WARNING "attr_warning" -#define ATTR_ERROR "attr_error" +#define ATTR_TABLE(XX) \ + XX( PROMPT, "prompt", "Terminal attributes for the prompt" ) \ + XX( RESET, "reset", "String to reset terminal attributes" ) \ + XX( WARNING, "warning", "Terminal attributes for warnings" ) \ + XX( ERROR, "error", "Terminal attributes for errors" ) \ + XX( EXTERNAL, "external", "Terminal attributes for external lines" ) \ + XX( TIMESTAMP, "timestamp", "Terminal attributes for timestamps" ) \ + XX( HIGHLIGHT, "highlight", "Terminal attributes for highlights" ) \ + XX( ACTION, "action", "Terminal attributes for user actions" ) \ + XX( JOIN, "join", "Terminal attributes for joins" ) \ + XX( PART, "part", "Terminal attributes for parts" ) -#define ATTR_EXTERNAL "attr_external" -#define ATTR_TIMESTAMP "attr_timestamp" -#define ATTR_HIGHLIGHT "attr_highlight" -#define ATTR_ACTION "attr_action" -#define ATTR_JOIN "attr_join" -#define ATTR_PART "attr_part" +enum +{ +#define XX(x, y, z) ATTR_ ## x, + ATTR_TABLE (XX) +#undef XX + 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 ATTR_ERROR -#define print_error_data ATTR_ERROR -#define print_warning_data ATTR_WARNING +#define print_fatal_data ((void *) ATTR_ERROR) +#define print_error_data ((void *) ATTR_ERROR) +#define print_warning_data ((void *) ATTR_WARNING) #include "config.h" #undef PROGRAM_NAME @@ -89,17 +103,9 @@ static struct config_item g_config_table[] = { "isolate_buffers", "off", "Isolate global/server buffers" }, - { ATTR_PROMPT, NULL, "Terminal attributes for the prompt" }, - { ATTR_RESET, NULL, "String to reset terminal attributes" }, - { ATTR_WARNING, NULL, "Terminal attributes for warnings" }, - { ATTR_ERROR, NULL, "Terminal attributes for errors" }, - - { ATTR_EXTERNAL, NULL, "Terminal attributes for external lines" }, - { ATTR_TIMESTAMP, NULL, "Terminal attributes for timestamps" }, - { ATTR_HIGHLIGHT, NULL, "Terminal attributes for highlights" }, - { ATTR_ACTION, NULL, "Terminal attributes for user actions" }, - { ATTR_JOIN, NULL, "Terminal attributes for joins" }, - { ATTR_PART, NULL, "Terminal attributes for parts" }, +#define XX(x, y, z) { "attr_" y, NULL, z }, + ATTR_TABLE (XX) +#undef XX { NULL, NULL, NULL } }; @@ -419,19 +425,12 @@ buffer_destroy (struct buffer *self) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -enum color_mode -{ - COLOR_AUTO, ///< Autodetect if colours are available - COLOR_ALWAYS, ///< Always use coloured output - COLOR_NEVER ///< Never use coloured output -}; - struct app_context { // Configuration: struct str_map config; ///< User configuration - enum color_mode color_mode; ///< Colour output mode + bool no_colors; ///< Colour output mode bool reconnect; ///< Whether to reconnect on conn. fail. unsigned long reconnect_delay; ///< Reconnect delay in seconds bool isolate_buffers; ///< Isolate global/server buffers @@ -724,7 +723,7 @@ get_attribute_printer (FILE *stream) static void vprint_attributed (struct app_context *ctx, - FILE *stream, const char *attribute, const char *fmt, va_list ap) + FILE *stream, intptr_t attribute, const char *fmt, va_list ap) { terminal_printer_fn printer = get_attribute_printer (stream); if (!attribute) @@ -732,7 +731,8 @@ vprint_attributed (struct app_context *ctx, if (printer) { - const char *value = str_map_find (&ctx->config, attribute); + const char *value = str_map_find + (&ctx->config, g_attr_table[attribute]); tputs (value, 1, printer); } @@ -740,14 +740,15 @@ vprint_attributed (struct app_context *ctx, if (printer) { - const char *value = str_map_find (&ctx->config, ATTR_RESET); + const char *value = str_map_find + (&ctx->config, g_attr_table[ATTR_RESET]); tputs (value, 1, printer); } } static void print_attributed (struct app_context *ctx, - FILE *stream, const char *attribute, const char *fmt, ...) + FILE *stream, intptr_t attribute, const char *fmt, ...) { va_list ap; va_start (ap, fmt); @@ -765,8 +766,8 @@ log_message_attributed (void *user_data, const char *quote, const char *fmt, if (g_ctx->readline_prompt_shown) app_readline_hide (&state); - print_attributed (g_ctx, stream, user_data, "%s", quote); - vprint_attributed (g_ctx, stream, user_data, fmt, ap); + print_attributed (g_ctx, stream, (intptr_t) user_data, "%s", quote); + vprint_attributed (g_ctx, stream, (intptr_t) user_data, fmt, ap); fputs ("\n", stream); if (g_ctx->readline_prompt_shown) @@ -779,42 +780,33 @@ 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, vt100) \ - str_map_set (&ctx->config, (id), xstrdup (have_ti ? (ti) : (vt100))); +#define INIT_ATTR(id, ti) \ + str_map_set (&ctx->config, g_attr_table[id], xstrdup (have_ti ? (ti) : "")) - INIT_ATTR (ATTR_PROMPT, enter_bold_mode, "\x1b[1m"); - INIT_ATTR (ATTR_RESET, exit_attribute_mode, "\x1b[0m"); - INIT_ATTR (ATTR_WARNING, g_terminal.color_set_fg[3], "\x1b[33m"); - INIT_ATTR (ATTR_ERROR, g_terminal.color_set_fg[1], "\x1b[31m"); + 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 (ATTR_EXTERNAL, g_terminal.color_set_fg[7], "\x1b[37m"); - INIT_ATTR (ATTR_TIMESTAMP, g_terminal.color_set_fg[7], "\x1b[37m"); - INIT_ATTR (ATTR_ACTION, g_terminal.color_set_fg[1], "\x1b[31m"); - INIT_ATTR (ATTR_JOIN, g_terminal.color_set_fg[2], "\x1b[32m"); - INIT_ATTR (ATTR_PART, g_terminal.color_set_fg[1], "\x1b[31m"); + 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]); 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, "\x1b[33;47;1m"); + INIT_ATTR (ATTR_HIGHLIGHT, highlight); free (highlight); #undef INIT_ATTR - switch (ctx->color_mode) + if (ctx->no_colors) { - case COLOR_ALWAYS: - g_terminal.stdout_is_tty = true; - g_terminal.stderr_is_tty = true; - break; - case COLOR_AUTO: - if (!g_terminal.initialized) - { - case COLOR_NEVER: - g_terminal.stdout_is_tty = false; - g_terminal.stderr_is_tty = false; - } + g_terminal.stdout_is_tty = false; + g_terminal.stderr_is_tty = false; } g_log_message_real = log_message_attributed; @@ -985,14 +977,15 @@ formatter_add_reset (struct formatter *self) } static void -formatter_add_attr (struct formatter *self, const char *attr_name) +formatter_add_attr (struct formatter *self, int attr_id) { if (self->ignore_new_attributes) return; struct formatter_item *item = formatter_add_blank (self); item->type = FORMATTER_ITEM_ATTR; - item->data = xstrdup (str_map_find (&self->ctx->config, attr_name)); + item->data = xstrdup (str_map_find + (&self->ctx->config, g_attr_table[attr_id])); } static void @@ -1047,7 +1040,7 @@ restart: break; case 'a': - formatter_add_attr (self, va_arg (*ap, const char *)); + formatter_add_attr (self, va_arg (*ap, int)); break; case 'c': formatter_add_fg_color (self, va_arg (*ap, int)); @@ -1117,7 +1110,8 @@ formatter_flush (struct formatter *self, FILE *stream) return; } - const char *attr_reset = str_map_find (&self->ctx->config, ATTR_RESET); + const char *attr_reset = str_map_find + (&self->ctx->config, g_attr_table[ATTR_RESET]); tputs (attr_reset, 1, printer); bool is_attributed = false; @@ -2148,8 +2142,10 @@ 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, ATTR_PROMPT); - const char *reset_attrs = str_map_find (&ctx->config, ATTR_RESET); + 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, prompt.str, @@ -4553,6 +4549,7 @@ 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);