Make options_tostring allocate its result instead of using a stack

buffer (needed for something in the future).
pull/1702/head
nicm 2019-04-25 18:18:55 +00:00
parent 1677bb0dea
commit 32a81e197b
4 changed files with 32 additions and 41 deletions

View File

@ -162,8 +162,8 @@ cmd_show_options_print(struct cmd *self, struct cmdq_item *item,
struct options_entry *o, int idx) struct options_entry *o, int idx)
{ {
struct options_array_item *a; struct options_array_item *a;
const char *name, *value; const char *name;
char *tmp, *escaped; char *value, *tmp, *escaped;
if (idx != -1) { if (idx != -1) {
xasprintf(&tmp, "%s[%d]", options_name(o), idx); xasprintf(&tmp, "%s[%d]", options_name(o), idx);
@ -191,6 +191,7 @@ cmd_show_options_print(struct cmd *self, struct cmdq_item *item,
free(escaped); free(escaped);
} else } else
cmdq_print(item, "%s %s", name, value); cmdq_print(item, "%s %s", name, value);
free(value);
free(tmp); free(tmp);
} }

View File

@ -904,9 +904,8 @@ format_find(struct format_tree *ft, const char *key, int modifiers)
struct environ_entry *envent; struct environ_entry *envent;
static char s[64]; static char s[64];
struct options_entry *o; struct options_entry *o;
const char *found;
int idx; int idx;
char *copy, *saved; char *found, *saved;
if (~modifiers & FORMAT_TIMESTRING) { if (~modifiers & FORMAT_TIMESTRING) {
o = options_parse_get(global_options, key, &idx, 0); o = options_parse_get(global_options, key, &idx, 0);
@ -933,12 +932,11 @@ format_find(struct format_tree *ft, const char *key, int modifiers)
return (NULL); return (NULL);
ctime_r(&fe->t, s); ctime_r(&fe->t, s);
s[strcspn(s, "\n")] = '\0'; s[strcspn(s, "\n")] = '\0';
found = s; found = xstrdup(s);
goto found; goto found;
} }
if (fe->t != 0) { if (fe->t != 0) {
xsnprintf(s, sizeof s, "%lld", (long long)fe->t); xasprintf(&found, "%lld", (long long)fe->t);
found = s;
goto found; goto found;
} }
if (fe->value == NULL && fe->cb != NULL) { if (fe->value == NULL && fe->cb != NULL) {
@ -946,7 +944,7 @@ format_find(struct format_tree *ft, const char *key, int modifiers)
if (fe->value == NULL) if (fe->value == NULL)
fe->value = xstrdup(""); fe->value = xstrdup("");
} }
found = fe->value; found = xstrdup(fe->value);
goto found; goto found;
} }
@ -957,7 +955,7 @@ format_find(struct format_tree *ft, const char *key, int modifiers)
if (envent == NULL) if (envent == NULL)
envent = environ_find(global_environ, key); envent = environ_find(global_environ, key);
if (envent != NULL) { if (envent != NULL) {
found = envent->value; found = xstrdup(envent->value);
goto found; goto found;
} }
} }
@ -967,23 +965,22 @@ format_find(struct format_tree *ft, const char *key, int modifiers)
found: found:
if (found == NULL) if (found == NULL)
return (NULL); return (NULL);
copy = xstrdup(found);
if (modifiers & FORMAT_BASENAME) { if (modifiers & FORMAT_BASENAME) {
saved = copy; saved = found;
copy = xstrdup(basename(saved)); found = xstrdup(basename(saved));
free(saved); free(saved);
} }
if (modifiers & FORMAT_DIRNAME) { if (modifiers & FORMAT_DIRNAME) {
saved = copy; saved = found;
copy = xstrdup(dirname(saved)); found = xstrdup(dirname(saved));
free(saved); free(saved);
} }
if (modifiers & FORMAT_QUOTE) { if (modifiers & FORMAT_QUOTE) {
saved = copy; saved = found;
copy = xstrdup(format_quote(saved)); found = xstrdup(format_quote(saved));
free(saved); free(saved);
} }
return (copy); return (found);
} }
/* Skip until end. */ /* Skip until end. */

View File

@ -110,47 +110,43 @@ options_value_free(struct options_entry *o, union options_value *ov)
free(ov->string); free(ov->string);
} }
static const char * static char *
options_value_tostring(struct options_entry *o, union options_value *ov, options_value_tostring(struct options_entry *o, union options_value *ov,
int numeric) int numeric)
{ {
static char s[1024]; char *s;
const char *tmp;
if (OPTIONS_IS_STYLE(o)) if (OPTIONS_IS_STYLE(o))
return (style_tostring(&ov->style)); return (xstrdup(style_tostring(&ov->style)));
if (OPTIONS_IS_NUMBER(o)) { if (OPTIONS_IS_NUMBER(o)) {
tmp = NULL;
switch (o->tableentry->type) { switch (o->tableentry->type) {
case OPTIONS_TABLE_NUMBER: case OPTIONS_TABLE_NUMBER:
xsnprintf(s, sizeof s, "%lld", ov->number); xasprintf(&s, "%lld", ov->number);
break; break;
case OPTIONS_TABLE_KEY: case OPTIONS_TABLE_KEY:
tmp = key_string_lookup_key(ov->number); s = xstrdup(key_string_lookup_key(ov->number));
break; break;
case OPTIONS_TABLE_COLOUR: case OPTIONS_TABLE_COLOUR:
tmp = colour_tostring(ov->number); s = xstrdup(colour_tostring(ov->number));
break; break;
case OPTIONS_TABLE_FLAG: case OPTIONS_TABLE_FLAG:
if (numeric) if (numeric)
xsnprintf(s, sizeof s, "%lld", ov->number); xasprintf(&s, "%lld", ov->number);
else else
tmp = (ov->number ? "on" : "off"); s = xstrdup(ov->number ? "on" : "off");
break; break;
case OPTIONS_TABLE_CHOICE: case OPTIONS_TABLE_CHOICE:
tmp = o->tableentry->choices[ov->number]; s = xstrdup(o->tableentry->choices[ov->number]);
break; break;
case OPTIONS_TABLE_STRING: case OPTIONS_TABLE_STRING:
case OPTIONS_TABLE_STYLE: case OPTIONS_TABLE_STYLE:
break; fatalx("not a number option type");
} }
if (tmp != NULL)
xsnprintf(s, sizeof s, "%s", tmp);
return (s); return (s);
} }
if (OPTIONS_IS_STRING(o)) if (OPTIONS_IS_STRING(o))
return (ov->string); return (xstrdup(ov->string));
return (""); return (xstrdup(""));
} }
struct options * struct options *
@ -218,11 +214,8 @@ options_empty(struct options *oo, const struct options_table_entry *oe)
o = options_add(oo, oe->name); o = options_add(oo, oe->name);
o->tableentry = oe; o->tableentry = oe;
if (oe->flags & OPTIONS_TABLE_IS_ARRAY) { if (oe->flags & OPTIONS_TABLE_IS_ARRAY)
if (oe->type != OPTIONS_TABLE_STRING)
fatalx("arrays can only be strings");
RB_INIT(&o->value.array); RB_INIT(&o->value.array);
}
return (o); return (o);
} }
@ -443,17 +436,17 @@ options_isstring(struct options_entry *o)
return (OPTIONS_IS_STRING(o)); return (OPTIONS_IS_STRING(o));
} }
const char * char *
options_tostring(struct options_entry *o, int idx, int numeric) options_tostring(struct options_entry *o, int idx, int numeric)
{ {
struct options_array_item *a; struct options_array_item *a;
if (OPTIONS_IS_ARRAY(o)) { if (OPTIONS_IS_ARRAY(o)) {
if (idx == -1) if (idx == -1)
return (NULL); return (xstrdup(""));
a = options_array_item(o, idx); a = options_array_item(o, idx);
if (a == NULL) if (a == NULL)
return (""); return (xstrdup(""));
return (options_value_tostring(o, &a->value, numeric)); return (options_value_tostring(o, &a->value, numeric));
} }
return (options_value_tostring(o, &o->value, numeric)); return (options_value_tostring(o, &o->value, numeric));

2
tmux.h
View File

@ -1742,7 +1742,7 @@ u_int options_array_item_index(struct options_array_item *);
union options_value *options_array_item_value(struct options_array_item *); union options_value *options_array_item_value(struct options_array_item *);
int options_isarray(struct options_entry *); int options_isarray(struct options_entry *);
int options_isstring(struct options_entry *); int options_isstring(struct options_entry *);
const char *options_tostring(struct options_entry *, int, int); char *options_tostring(struct options_entry *, int, int);
char *options_parse(const char *, int *); char *options_parse(const char *, int *);
struct options_entry *options_parse_get(struct options *, const char *, int *, struct options_entry *options_parse_get(struct options *, const char *, int *,
int); int);