diff options
| -rw-r--r-- | common.c | 18 | ||||
| -rw-r--r-- | degesch.c | 75 | 
2 files changed, 67 insertions, 26 deletions
@@ -1911,8 +1911,6 @@ config_schema_initialize_item (struct config_schema *schema,  	item->schema = schema;  	item->user_data = user_data; -	if (schema->on_change) -		schema->on_change (item);  }  static void @@ -1924,6 +1922,22 @@ config_schema_apply_to_object (struct config_schema *schema_array,  		config_schema_initialize_item (schema_array++, object, user_data);  } +static void +config_schema_call_changed (struct config_item_ *item) +{ +	if (item->type == CONFIG_ITEM_OBJECT) +	{ +		struct str_map_iter iter; +		str_map_iter_init (&iter, &item->value.object); + +		struct config_item_ *child; +		while ((child = str_map_iter_next (&iter))) +			config_schema_call_changed (child); +	} +	else if (item->schema && item->schema->on_change) +		item->schema->on_change (item); +} +  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  // XXX: this doesn't necessarily have to be well designed at all @@ -1288,6 +1288,8 @@ server_destroy (void *self)  struct app_context  { +	char *attrs_defaults[ATTR_COUNT];   ///< Default terminal attributes +  	// Configuration:  	struct config config;               ///< Program configuration @@ -1380,7 +1382,10 @@ app_context_free (struct app_context *self)  {  	config_free (&self->config);  	for (size_t i = 0; i < ATTR_COUNT; i++) +	{ +		free (self->attrs_defaults[i]);  		free (self->attrs[i]); +	}  	LIST_FOR_EACH (struct buffer, iter, self->buffers)  	{ @@ -1411,7 +1416,8 @@ static bool irc_is_this_us (struct server *s, const char *prefix);  // --- Configuration ----------------------------------------------------------- -// TODO: eventually add "on_change" callbacks +// TODO: "on_change" callbacks for everything +static void on_config_attribute_change (struct config_item_ *item);  static bool  config_validate_nonjunk_string @@ -1565,7 +1571,8 @@ static struct config_schema g_config_behaviour[] =  static struct config_schema g_config_attributes[] =  { -#define XX(x, y, z) { .name = y, .comment = z, .type = CONFIG_ITEM_STRING }, +#define XX(x, y, z) { .name = y, .comment = z, .type = CONFIG_ITEM_STRING, \ +	.on_change = on_config_attribute_change },  	ATTR_TABLE (XX)  #undef XX  	{} @@ -1862,7 +1869,7 @@ log_message_attributed (void *user_data, const char *quote, const char *fmt,  }  static void -init_attribute (struct app_context *ctx, int id, const char *default_) +on_config_attribute_change (struct config_item_ *item)  {  	static const char *table[ATTR_COUNT] =  	{ @@ -1871,19 +1878,22 @@ init_attribute (struct app_context *ctx, int id, const char *default_)  #undef XX  	}; -	const char *user = get_config_string (ctx->config.root, table[id]); -	if (user) -		ctx->attrs[id] = xstrdup (user); -	else -		ctx->attrs[id] = xstrdup (default_); +	struct app_context *ctx = item->user_data; +	for (int id = 0; id < ATTR_COUNT; id++) +	{ +		const char *user = get_config_string (ctx->config.root, table[id]); +		free (ctx->attrs[id]); +		ctx->attrs[id] = xstrdup (user ? user : ctx->attrs_defaults[id]); +	}  }  static void  init_colors (struct app_context *ctx)  {  	bool have_ti = init_terminal (); +	char **defaults = ctx->attrs_defaults; -#define INIT_ATTR(id, ti) init_attribute (ctx, ATTR_ ## id, have_ti ? (ti) : "") +#define INIT_ATTR(id, ti) defaults[ATTR_ ## id] = xstrdup (have_ti ? (ti) : "")  	INIT_ATTR (PROMPT,    enter_bold_mode);  	INIT_ATTR (RESET,     exit_attribute_mode); @@ -1913,6 +1923,10 @@ init_colors (struct app_context *ctx)  	}  	g_log_message_real = log_message_attributed; + +	// Apply the default values so that we start with any formatting at all +	config_schema_call_changed +		(config_item_get (ctx->config.root, "attributes", NULL));  }  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -8343,7 +8357,7 @@ load_configuration_file (const char *filename, struct error **e)  	struct error *error = NULL;  	if (!(root = config_item_parse (data.str, data.len, false, &error)))  	{ -		error_set (e, "configuration parse error: %s", error->message); +		error_set (e, "Configuration parse error: %s", error->message);  		error_free (error);  	}  end: @@ -8361,20 +8375,21 @@ load_configuration (struct app_context *ctx)  	if (filename)  		root = load_configuration_file (filename, &e);  	else -		print_status ("configuration file not found"); +		log_global_error (ctx, "Configuration file not found");  	free (filename);  	if (e)  	{ -		print_error ("%s", e->message); +		log_global_error (ctx, "#s", e->message);  		error_free (e); -		e = NULL;  	} - -	config_load (&ctx->config, root ? root : config_item_object ()); - -	ctx->isolate_buffers = -		get_config_boolean (ctx->config.root, "behaviour.isolate_buffers"); +	if (root) +	{ +		config_item_destroy (ctx->config.root); +		ctx->config.root = NULL; +		config_load (&ctx->config, root); +		log_global_status (ctx, "Configuration loaded"); +	}  }  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -8408,8 +8423,8 @@ load_server_from_config (struct app_context *ctx,  	buffer_add (ctx, buffer);  	buffer_activate (ctx, buffer); -	// This fires any "on_change" callbacks  	config_schema_apply_to_object (g_config_server, subtree, s); +	config_schema_call_changed (subtree);  	// XXX: is this desirable in here?  I think we should do it only when  	//   actually creating a new server instead of every time we load them. @@ -8427,7 +8442,7 @@ load_server_from_config (struct app_context *ctx,  }  static void -init_servers (struct app_context *ctx) +load_servers (struct app_context *ctx)  {  	struct config_item_ *servers =  		config_item_get (ctx->config.root, "servers", NULL); @@ -8713,14 +8728,26 @@ main (int argc, char *argv[])  	SSL_load_error_strings ();  	atexit (ERR_free_strings); -	setup_signal_handlers (); +	// Bootstrap configuration, so that we can access schema items at all  	register_config_modules (&ctx); -	load_configuration (&ctx); +	config_load (&ctx.config, config_item_object ()); +	// The following part is a bit brittle because of interdependencies +	setup_signal_handlers ();  	init_colors (&ctx); -	init_poller_events (&ctx);  	init_global_buffer (&ctx); -	init_servers (&ctx); +	init_poller_events (&ctx); +	load_configuration (&ctx); + +	// TODO: this won't be needed after adding an "on_change" callback +	ctx.isolate_buffers = +		get_config_boolean (ctx.config.root, "behaviour.isolate_buffers"); + +	// At this moment we can safely call any "on_change" callbacks +	config_schema_call_changed (ctx.config.root); + +	// Finally, we juice the configuration for some servers to create +	load_servers (&ctx);  	refresh_prompt (&ctx);  	input_start (&ctx.input, argv[0]);  | 
