+/**
+ * Launch nagbar to indicate errors in the configuration file.
+ */
+void start_config_error_nagbar(const char *configpath, bool has_errors) {
+ char *editaction, *pageraction;
+ sasprintf(&editaction, "i3-sensible-editor \"%s\" && i3-msg reload\n", configpath);
+ sasprintf(&pageraction, "i3-sensible-pager \"%s\"\n", errorfilename);
+ char *argv[] = {
+ NULL, /* will be replaced by the executable path */
+ "-f",
+ (config.font.pattern ? config.font.pattern : "fixed"),
+ "-t",
+ (has_errors ? "error" : "warning"),
+ "-m",
+ (has_errors ? "You have an error in your i3 config file!" : "Your config is outdated. Please fix the warnings to make sure everything works."),
+ "-b",
+ "edit config",
+ editaction,
+ (errorfilename ? "-b" : NULL),
+ (has_errors ? "show errors" : "show warnings"),
+ pageraction,
+ NULL};
+
+ start_nagbar(&config_error_nagbar_pid, argv);
+ free(editaction);
+ free(pageraction);
+}
+
+/*
+ * Inserts or updates a variable assignment depending on whether it already exists.
+ *
+ */
+static void upsert_variable(struct variables_head *variables, char *key, char *value) {
+ struct Variable *current;
+ SLIST_FOREACH(current, variables, variables) {
+ if (strcmp(current->key, key) != 0) {
+ continue;
+ }
+
+ DLOG("Updated variable: %s = %s -> %s\n", key, current->value, value);
+ FREE(current->value);
+ current->value = sstrdup(value);
+ return;
+ }
+
+ DLOG("Defined new variable: %s = %s\n", key, value);
+ struct Variable *new = scalloc(1, sizeof(struct Variable));
+ struct Variable *test = NULL, *loc = NULL;
+ new->key = sstrdup(key);
+ new->value = sstrdup(value);
+ /* ensure that the correct variable is matched in case of one being
+ * the prefix of another */
+ SLIST_FOREACH(test, variables, variables) {
+ if (strlen(new->key) >= strlen(test->key))
+ break;
+ loc = test;
+ }
+
+ if (loc == NULL) {
+ SLIST_INSERT_HEAD(variables, new, variables);
+ } else {
+ SLIST_INSERT_AFTER(loc, new, variables);
+ }
+}
+
+static char *get_resource(char *name) {
+ if (conn == NULL) {
+ return NULL;
+ }
+
+ /* Load the resource database lazily. */
+ if (database == NULL) {
+ database = xcb_xrm_database_from_default(conn);
+
+ if (database == NULL) {
+ ELOG("Failed to open the resource database.\n");
+
+ /* Load an empty database so we don't keep trying to load the
+ * default database over and over again. */
+ database = xcb_xrm_database_from_string("");
+
+ return NULL;
+ }
+ }
+
+ char *resource;
+ xcb_xrm_resource_get_string(database, name, NULL, &resource);
+ return resource;
+}
+