diff --git a/cmd-set-option.c b/cmd-set-option.c index d1b7f331..ab15eb70 100644 --- a/cmd-set-option.c +++ b/cmd-set-option.c @@ -292,10 +292,8 @@ cmd_set_option_user(struct cmd *self, struct cmdq_item *item, cmdq_error(item, "empty value"); return (CMD_RETURN_ERROR); } - if (o != NULL && args_has(args, 'a')) - options_set_string(oo, optstr, "%s%s", o->str, valstr); - else - options_set_string(oo, optstr, "%s", valstr); + options_set_string(oo, optstr, args_has(args, 'a'), "%s", + valstr); } return (CMD_RETURN_NORMAL); } @@ -316,10 +314,11 @@ cmd_set_option_unset(struct cmd *self, struct cmdq_item *item, if (args_has(args, 'g') || oo == global_options) { switch (oe->type) { case OPTIONS_TABLE_STRING: - options_set_string(oo, oe->name, "%s", oe->default_str); + options_set_string(oo, oe->name, 0, "%s", + oe->default_str); break; case OPTIONS_TABLE_STYLE: - options_set_style(oo, oe->name, oe->default_str, 0); + options_set_style(oo, oe->name, 0, oe->default_str); break; default: options_set_number(oo, oe->name, oe->default_num); @@ -391,20 +390,10 @@ cmd_set_option_string(struct cmd *self, __unused struct cmdq_item *item, const struct options_table_entry *oe, struct options *oo, const char *value) { - struct args *args = self->args; - struct options_entry *o; - char *oldval, *newval; + struct args *args = self->args; + int append = args_has(args, 'a'); - if (args_has(args, 'a')) { - oldval = options_get_string(oo, oe->name); - xasprintf(&newval, "%s%s", oldval, value); - } else - newval = xstrdup(value); - - o = options_set_string(oo, oe->name, "%s", newval); - - free(newval); - return (o); + return (options_set_string(oo, oe->name, append, "%s", value)); } /* Set a number option. */ @@ -544,11 +533,10 @@ cmd_set_option_style(struct cmd *self, struct cmdq_item *item, const char *value) { struct args *args = self->args; + int append = args_has(args, 'a'); struct options_entry *o; - int append; - append = args_has(args, 'a'); - if ((o = options_set_style(oo, oe->name, value, append)) == NULL) { + if ((o = options_set_style(oo, oe->name, append, value)) == NULL) { cmdq_error(item, "bad style: %s", value); return (NULL); } diff --git a/options-table.c b/options-table.c index a6bdda6f..92441ebe 100644 --- a/options-table.c +++ b/options-table.c @@ -915,10 +915,11 @@ options_table_populate_tree(enum options_table_scope scope, struct options *oo) continue; switch (oe->type) { case OPTIONS_TABLE_STRING: - options_set_string(oo, oe->name, "%s", oe->default_str); + options_set_string(oo, oe->name, 0, "%s", + oe->default_str); break; case OPTIONS_TABLE_STYLE: - options_set_style(oo, oe->name, oe->default_str, 0); + options_set_style(oo, oe->name, 0, oe->default_str); break; default: options_set_number(oo, oe->name, oe->default_num); diff --git a/options.c b/options.c index cb7f3d87..09e8669a 100644 --- a/options.c +++ b/options.c @@ -65,24 +65,17 @@ options_free1(struct options *oo, struct options_entry *o) } static struct options_entry * -options_new(struct options *oo, const char *name, char **s) +options_new(struct options *oo, const char *name) { struct options_entry *o; - if (s != NULL) - *s = NULL; - if ((o = options_find1(oo, name)) == NULL) { o = xmalloc(sizeof *o); o->name = xstrdup(name); RB_INSERT(options_tree, &oo->tree, o); memcpy(&o->style, &grid_default_cell, sizeof o->style); - } else if (o->type == OPTIONS_STRING) { - if (s != NULL) - *s = o->str; - else - free(o->str); - } + } else if (o->type == OPTIONS_STRING) + free(o->str); return (o); } @@ -143,20 +136,29 @@ options_remove(struct options *oo, const char *name) } struct options_entry * -options_set_string(struct options *oo, const char *name, const char *fmt, ...) +options_set_string(struct options *oo, const char *name, int append, + const char *fmt, ...) { struct options_entry *o; va_list ap; - char *s; + char *s, *value; va_start(ap, fmt); - - o = options_new(oo, name, &s); - o->type = OPTIONS_STRING; - xvasprintf(&o->str, fmt, ap); - free(s); - + xvasprintf(&s, fmt, ap); va_end(ap); + + o = options_find1(oo, name); + if (o == NULL || !append) + value = s; + else { + xasprintf(&value, "%s%s", s, o->str); + free(s); + } + + o = options_new(oo, name); + o->type = OPTIONS_STRING; + o->str = value; + return (o); } @@ -177,7 +179,7 @@ options_set_number(struct options *oo, const char *name, long long value) { struct options_entry *o; - o = options_new(oo, name, NULL); + o = options_new(oo, name); o->type = OPTIONS_NUMBER; o->num = value; @@ -197,8 +199,8 @@ options_get_number(struct options *oo, const char *name) } struct options_entry * -options_set_style(struct options *oo, const char *name, const char *value, - int append) +options_set_style(struct options *oo, const char *name, int append, + const char *value) { struct options_entry *o; struct grid_cell tmpgc; @@ -212,7 +214,7 @@ options_set_style(struct options *oo, const char *name, const char *value, if (style_parse(&grid_default_cell, &tmpgc, value) == -1) return (NULL); - o = options_new(oo, name, NULL); + o = options_new(oo, name); o->type = OPTIONS_STYLE; memcpy(&o->style, &tmpgc, sizeof o->style); diff --git a/style.c b/style.c index 8af739e5..f4a8f05f 100644 --- a/style.c +++ b/style.c @@ -143,7 +143,7 @@ style_update_new(struct options *oo, const char *name, const char *newname) o = options_find1(oo, newname); if (o == NULL) - o = options_set_style(oo, newname, "default", 0); + o = options_set_style(oo, newname, 0, "default"); gc = &o->style; o = options_find1(oo, name); diff --git a/tmux.c b/tmux.c index 194a16e5..664ff0c5 100644 --- a/tmux.c +++ b/tmux.c @@ -295,7 +295,8 @@ main(int argc, char **argv) global_s_options = options_create(NULL); options_table_populate_tree(OPTIONS_TABLE_SESSION, global_s_options); - options_set_string(global_s_options, "default-shell", "%s", getshell()); + options_set_string(global_s_options, "default-shell", 0, "%s", + getshell()); global_w_options = options_create(NULL); options_table_populate_tree(OPTIONS_TABLE_WINDOW, global_w_options); diff --git a/tmux.h b/tmux.h index 24c8dd11..fa157a1c 100644 --- a/tmux.h +++ b/tmux.h @@ -1627,14 +1627,14 @@ struct options_entry *options_next(struct options_entry *); struct options_entry *options_find1(struct options *, const char *); struct options_entry *options_find(struct options *, const char *); void options_remove(struct options *, const char *); -struct options_entry *printflike(3, 4) options_set_string(struct options *, - const char *, const char *, ...); +struct options_entry * printflike(4, 5) options_set_string(struct options *, + const char *, int, const char *, ...); char *options_get_string(struct options *, const char *); struct options_entry *options_set_number(struct options *, const char *, long long); long long options_get_number(struct options *, const char *); -struct options_entry *options_set_style(struct options *, const char *, - const char *, int); +struct options_entry *options_set_style(struct options *, const char *, int, + const char *); struct grid_cell *options_get_style(struct options *, const char *); /* options-table.c */