Merge branch 'maint'

* maint: (35 commits)
  config.c: guard config parser from value=NULL
  builtin-log.c: guard config parser from value=NULL
  imap-send.c: guard config parser from value=NULL
  wt-status.c: guard config parser from value=NULL
  setup.c: guard config parser from value=NULL
  remote.c: guard config parser from value=NULL
  merge-recursive.c: guard config parser from value=NULL
  http.c: guard config parser from value=NULL
  help.c: guard config parser from value=NULL
  git.c: guard config parser from value=NULL
  diff.c: guard config parser from value=NULL
  convert.c: guard config parser from value=NULL
  connect.c: guard config parser from value=NULL
  builtin-tag.c: guard config parser from value=NULL
  builtin-show-branch.c: guard config parser from value=NULL
  builtin-reflog.c: guard config parser from value=NULL
  builtin-log.c: guard config parser from value=NULL
  builtin-config.c: guard config parser from value=NULL
  builtin-commit.c: guard config parser from value=NULL
  builtin-branch.c: guard config parser from value=NULL
  ...
This commit is contained in:
Junio C Hamano 2008-02-11 13:23:06 -08:00
commit 04f32cf1b3
34 changed files with 255 additions and 59 deletions

View File

@ -333,7 +333,7 @@ branch.autosetupmerge::
so that linkgit:git-pull[1] will appropriately merge from that
remote branch. Note that even if this option is not set,
this behavior can be chosen per-branch using the `--track`
and `--no-track` options. This option defaults to false.
and `--no-track` options. This option defaults to true.
branch.<name>.remote::
When in branch <name>, it tells `git fetch` which remote to fetch.

View File

@ -34,11 +34,11 @@ Note that this will create the new branch, but it will not switch the
working tree to it; use "git checkout <newbranch>" to switch to the
new branch.
When a local branch is started off a remote branch, git can setup the
When a local branch is started off a remote branch, git sets up the
branch so that linkgit:git-pull[1] will appropriately merge from that
remote branch. If this behavior is desired, it is possible to make it
the default using the global `branch.autosetupmerge` configuration
flag. Otherwise, it can be chosen per-branch using the `--track`
remote branch. If this behavior is not desired, it is possible to
disable it using the global `branch.autosetupmerge` configuration
flag. That setting can be overridden by using the `--track`
and `--no-track` options.
With a '-m' or '-M' option, <oldbranch> will be renamed to <newbranch>.
@ -108,10 +108,11 @@ OPTIONS
Set up configuration so that git-pull will automatically
retrieve data from the remote branch. Use this if you always
pull from the same remote branch into the new branch, or if you
don't want to use "git pull <repository> <refspec>" explicitly. Set the
branch.autosetupmerge configuration variable to true if you
don't want to use "git pull <repository> <refspec>" explicitly.
This behavior is the default. Set the
branch.autosetupmerge configuration variable to false if you
want git-checkout and git-branch to always behave as if
'--track' were given.
'--no-track' were given.
--no-track::
When a branch is created off a remote branch,

View File

@ -52,10 +52,11 @@ OPTIONS
set up configuration so that git-pull will automatically
retrieve data from the remote branch. Use this if you always
pull from the same remote branch into the new branch, or if you
don't want to use "git pull <repository> <refspec>" explicitly. Set the
branch.autosetupmerge configuration variable to true if you
don't want to use "git pull <repository> <refspec>" explicitly.
This behavior is the default. Set the
branch.autosetupmerge configuration variable to false if you
want git-checkout and git-branch to always behave as if
'--track' were given.
'--no-track' were given.
--no-track::
When -b is given and a branch is created off a remote branch,

View File

@ -39,11 +39,11 @@ include::merge-strategies.txt[]
there is a remote ref for the upstream branch, and this branch
was rebased since last fetched, the rebase uses that information
to avoid rebasing non-local changes.
*NOTE:* This is a potentially _dangerous_ mode of operation.
It rewrites history, which does not bode well when you
published that history already. Do *not* use this option
unless you have read linkgit:git-rebase[1] carefully.
+
*NOTE:* This is a potentially _dangerous_ mode of operation.
It rewrites history, which does not bode well when you
published that history already. Do *not* use this option
unless you have read linkgit:git-rebase[1] carefully.
\--no-rebase::
Override earlier \--rebase.

View File

@ -222,7 +222,7 @@ static void write_global_extended_header(const unsigned char *sha1)
static int git_tar_config(const char *var, const char *value)
{
if (!strcmp(var, "tar.umask")) {
if (!strcmp(value, "user")) {
if (value && !strcmp(value, "user")) {
tar_umask = umask(0);
umask(tar_umask);
} else {

View File

@ -2746,6 +2746,8 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
static int git_apply_config(const char *var, const char *value)
{
if (!strcmp(var, "apply.whitespace")) {
if (!value)
return config_error_nonbool(var);
apply_default_whitespace = xstrdup(value);
return 0;
}

View File

@ -70,12 +70,15 @@ static int git_branch_config(const char *var, const char *value)
}
if (!prefixcmp(var, "color.branch.")) {
int slot = parse_branch_color_slot(var, 13);
if (!value)
return config_error_nonbool(var);
color_parse(value, var, branch_colors[slot]);
return 0;
}
if (!strcmp(var, "branch.autosetupmerge"))
branch_track = git_config_bool(var, value);
if (!strcmp(var, "branch.autosetupmerge")) {
branch_track = git_config_bool(var, value);
return 0;
}
return git_default_config(var, value);
}

View File

@ -743,6 +743,8 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
int git_commit_config(const char *k, const char *v)
{
if (!strcmp(k, "commit.template")) {
if (!v)
return config_error_nonbool(v);
template_file = xstrdup(v);
return 0;
}
@ -929,6 +931,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
unlink(git_path("MERGE_HEAD"));
unlink(git_path("MERGE_MSG"));
unlink(git_path("SQUASH_MSG"));
if (commit_index_files())
die ("Repository has been updated, but unable to write\n"

View File

@ -168,6 +168,8 @@ static char parsed_color[COLOR_MAXLEN];
static int git_get_color_config(const char *var, const char *value)
{
if (!strcmp(var, get_color_slot)) {
if (!value)
config_error_nonbool(var);
color_parse(value, var, parsed_color);
get_color_found = 1;
}

View File

@ -37,7 +37,7 @@ static const char *argv_rerere[] = {"rerere", "gc", NULL};
static int gc_config(const char *var, const char *value)
{
if (!strcmp(var, "gc.packrefs")) {
if (!strcmp(value, "notbare"))
if (value && !strcmp(value, "notbare"))
pack_refs = -1;
else
pack_refs = git_config_bool(var, value);

View File

@ -219,7 +219,7 @@ static int git_log_config(const char *var, const char *value)
{
if (!strcmp(var, "format.subjectprefix")) {
if (!value)
die("format.subjectprefix without value");
config_error_nonbool(var);
fmt_patch_subject_prefix = xstrdup(value);
return 0;
}
@ -432,7 +432,7 @@ static int git_format_config(const char *var, const char *value)
}
if (!strcmp(var, "format.suffix")) {
if (!value)
die("format.suffix without value");
return config_error_nonbool(var);
fmt_patch_suffix = xstrdup(value);
return 0;
}
@ -440,11 +440,10 @@ static int git_format_config(const char *var, const char *value)
return 0;
}
if (!strcmp(var, "format.numbered")) {
if (!strcasecmp(value, "auto")) {
if (value && !strcasecmp(value, "auto")) {
auto_number = 1;
return 0;
}
numbered = git_config_bool(var, value);
return 0;
}

View File

@ -1464,7 +1464,7 @@ static unsigned int check_delta_limit(struct object_entry *me, unsigned int n)
return m;
}
static unsigned long free_unpacked(struct unpacked *n)
static unsigned long free_unpacked_data(struct unpacked *n)
{
unsigned long freed_mem = sizeof_delta_index(n->index);
free_delta_index(n->index);
@ -1474,6 +1474,12 @@ static unsigned long free_unpacked(struct unpacked *n)
free(n->data);
n->data = NULL;
}
return freed_mem;
}
static unsigned long free_unpacked(struct unpacked *n)
{
unsigned long freed_mem = free_unpacked_data(n);
n->entry = NULL;
n->depth = 0;
return freed_mem;
@ -1514,7 +1520,7 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
mem_usage > window_memory_limit &&
count > 1) {
uint32_t tail = (idx + window - count) % window;
mem_usage -= free_unpacked(array + tail);
mem_usage -= free_unpacked_data(array + tail);
count--;
}
@ -1547,6 +1553,9 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
if (!m->entry)
break;
ret = try_delta(n, m, max_depth, &mem_usage);
if (window_memory_limit &&
mem_usage > window_memory_limit)
mem_usage -= free_unpacked_data(m);
if (ret < 0)
break;
else if (ret > 0)

View File

@ -83,6 +83,44 @@ static void prune_object_dir(const char *path)
}
}
/*
* Write errors (particularly out of space) can result in
* failed temporary packs (and more rarely indexes and other
* files begining with "tmp_") accumulating in the
* object directory.
*/
static void remove_temporary_files(void)
{
DIR *dir;
struct dirent *de;
char* dirname=get_object_directory();
dir = opendir(dirname);
if (!dir) {
fprintf(stderr, "Unable to open object directory %s\n",
dirname);
return;
}
while ((de = readdir(dir)) != NULL) {
if (!prefixcmp(de->d_name, "tmp_")) {
char name[PATH_MAX];
int c = snprintf(name, PATH_MAX, "%s/%s",
dirname, de->d_name);
if (c < 0 || c >= PATH_MAX)
continue;
if (expire) {
struct stat st;
if (stat(name, &st) != 0 || st.st_mtime >= expire)
continue;
}
printf("Removing stale temporary file %s\n", name);
if (!show_only)
unlink(name);
}
}
closedir(dir);
}
int cmd_prune(int argc, const char **argv, const char *prefix)
{
int i;
@ -115,5 +153,6 @@ int cmd_prune(int argc, const char **argv, const char *prefix)
sync();
prune_packed_objects(show_only);
remove_temporary_files();
return 0;
}

View File

@ -307,13 +307,19 @@ static int collect_reflog(const char *ref, const unsigned char *sha1, int unused
static int reflog_expire_config(const char *var, const char *value)
{
if (!strcmp(var, "gc.reflogexpire"))
if (!strcmp(var, "gc.reflogexpire")) {
if (!value)
config_error_nonbool(var);
default_reflog_expire = approxidate(value);
else if (!strcmp(var, "gc.reflogexpireunreachable"))
return 0;
}
if (!strcmp(var, "gc.reflogexpireunreachable")) {
if (!value)
config_error_nonbool(var);
default_reflog_expire_unreachable = approxidate(value);
else
return git_default_config(var, value);
return 0;
return 0;
}
return git_default_config(var, value);
}
static int cmd_reflog_expire(int argc, const char **argv, const char *prefix)

View File

@ -536,6 +536,8 @@ static void append_one_rev(const char *av)
static int git_show_branch_config(const char *var, const char *value)
{
if (!strcmp(var, "showbranch.default")) {
if (!value)
return config_error_nonbool(var);
if (default_alloc <= default_num + 1) {
default_alloc = default_alloc * 3 / 2 + 20;
default_arg = xrealloc(default_arg, sizeof *default_arg * default_alloc);

View File

@ -258,7 +258,7 @@ static int git_tag_config(const char *var, const char *value)
{
if (!strcmp(var, "user.signingkey")) {
if (!value)
die("user.signingkey without value");
return config_error_nonbool(value);
set_signingkey(value);
return 0;
}

View File

@ -589,6 +589,7 @@ extern int git_config_set_multivar(const char *, const char *, const char *, int
extern int git_config_rename_section(const char *, const char *);
extern const char *git_etc_gitconfig(void);
extern int check_repository_format_version(const char *var, const char *value);
extern int config_error_nonbool(const char *);
#define MAX_GITNAME (1000)
extern char git_default_email[MAX_GITNAME];

View File

@ -408,21 +408,29 @@ int git_default_config(const char *var, const char *value)
}
if (!strcmp(var, "user.name")) {
if (!value)
return config_error_nonbool(var);
strlcpy(git_default_name, value, sizeof(git_default_name));
return 0;
}
if (!strcmp(var, "user.email")) {
if (!value)
return config_error_nonbool(var);
strlcpy(git_default_email, value, sizeof(git_default_email));
return 0;
}
if (!strcmp(var, "i18n.commitencoding")) {
if (!value)
return config_error_nonbool(var);
git_commit_encoding = xstrdup(value);
return 0;
}
if (!strcmp(var, "i18n.logoutputencoding")) {
if (!value)
return config_error_nonbool(var);
git_log_output_encoding = xstrdup(value);
return 0;
}
@ -434,23 +442,29 @@ int git_default_config(const char *var, const char *value)
}
if (!strcmp(var, "core.pager")) {
if (!value)
return config_error_nonbool(var);
pager_program = xstrdup(value);
return 0;
}
if (!strcmp(var, "core.editor")) {
if (!value)
return config_error_nonbool(var);
editor_program = xstrdup(value);
return 0;
}
if (!strcmp(var, "core.excludesfile")) {
if (!value)
die("core.excludesfile without value");
return config_error_nonbool(var);
excludes_file = xstrdup(value);
return 0;
}
if (!strcmp(var, "core.whitespace")) {
if (!value)
return config_error_nonbool(var);
whitespace_rule_cfg = parse_whitespace_rule(value);
return 0;
}
@ -701,12 +715,17 @@ static ssize_t find_beginning_of_line(const char* contents, size_t size,
size_t equal_offset = size, bracket_offset = size;
ssize_t offset;
contline:
for (offset = offset_-2; offset > 0
&& contents[offset] != '\n'; offset--)
switch (contents[offset]) {
case '=': equal_offset = offset; break;
case ']': bracket_offset = offset; break;
}
if (offset > 0 && contents[offset-1] == '\\') {
offset_ = offset;
goto contline;
}
if (bracket_offset < equal_offset) {
*found_bracket = 1;
offset = bracket_offset+1;
@ -1074,3 +1093,12 @@ int git_config_rename_section(const char *old_name, const char *new_name)
free(config_filename);
return ret;
}
/*
* Call this to report error for your variable that should not
* get a boolean value (i.e. "[my] var" means "true").
*/
int config_error_nonbool(const char *var)
{
return error("Missing value for '%s'", var);
}

View File

@ -370,6 +370,8 @@ static int git_proxy_command_options(const char *var, const char *value)
if (git_proxy_command)
return 0;
if (!value)
return config_error_nonbool(var);
/* [core]
* ;# matches www.kernel.org as well
* gitproxy = netcatter-1 for kernel.org

View File

@ -326,14 +326,14 @@ static int read_convert_config(const char *var, const char *value)
if (!strcmp("smudge", ep)) {
if (!value)
return error("%s: lacks value", var);
return config_error_nonbool(var);
drv->smudge = strdup(value);
return 0;
}
if (!strcmp("clean", ep)) {
if (!value)
return error("%s: lacks value", var);
return config_error_nonbool(var);
drv->clean = strdup(value);
return 0;
}

14
diff.c
View File

@ -158,6 +158,8 @@ int git_diff_ui_config(const char *var, const char *value)
return 0;
}
if (!strcmp(var, "diff.external")) {
if (!value)
return config_error_nonbool(var);
external_diff_cmd_cfg = xstrdup(value);
return 0;
}
@ -165,8 +167,11 @@ int git_diff_ui_config(const char *var, const char *value)
const char *ep = strrchr(var, '.');
if (ep != var + 4) {
if (!strcmp(ep, ".command"))
if (!strcmp(ep, ".command")) {
if (!value)
return config_error_nonbool(var);
return parse_lldiff_command(var, ep, value);
}
}
}
@ -177,6 +182,8 @@ int git_diff_basic_config(const char *var, const char *value)
{
if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) {
int slot = parse_diff_color_slot(var, 11);
if (!value)
return config_error_nonbool(var);
color_parse(value, var, diff_colors[slot]);
return 0;
}
@ -184,8 +191,11 @@ int git_diff_basic_config(const char *var, const char *value)
if (!prefixcmp(var, "diff.")) {
const char *ep = strrchr(var, '.');
if (ep != var + 4) {
if (!strcmp(ep, ".funcname"))
if (!strcmp(ep, ".funcname")) {
if (!value)
return config_error_nonbool(var);
return parse_funcname_pattern(var, ep, value);
}
}
}

View File

@ -26,6 +26,9 @@ OPTIONS_SPEC=
. git-sh-setup
require_work_tree
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
sq() {
@@PERL@@ -e '
for (@ARGV) {
@ -60,7 +63,8 @@ bisect_start() {
# top-of-line master first!
#
head=$(GIT_DIR="$GIT_DIR" git symbolic-ref HEAD) ||
die "Bad HEAD - I need a symbolic ref"
head=$(GIT_DIR="$GIT_DIR" git rev-parse --verify HEAD) ||
die "Bad HEAD - I need a HEAD"
case "$head" in
refs/heads/bisect)
if [ -s "$GIT_DIR/head-name" ]; then
@ -70,7 +74,7 @@ bisect_start() {
fi
git checkout $branch || exit
;;
refs/heads/*)
refs/heads/*|$_x40)
[ -s "$GIT_DIR/head-name" ] && die "won't bisect on seeked tree"
echo "${head#refs/heads/}" >"$GIT_DIR/head-name"
;;

View File

@ -432,7 +432,7 @@ do
shift ;;
esac
;;
--merge)
-m|--merge)
# we use merge anyway
;;
-C*)

2
git.c
View File

@ -93,6 +93,8 @@ static char *alias_string;
static int git_alias_config(const char *var, const char *value)
{
if (!prefixcmp(var, "alias.") && !strcmp(var + 6, alias_command)) {
if (!value)
return config_error_nonbool(var);
alias_string = xstrdup(value);
}
return 0;

2
help.c
View File

@ -40,6 +40,8 @@ static void parse_help_format(const char *format)
static int git_help_config(const char *var, const char *value)
{
if (!strcmp(var, "help.format")) {
if (!value)
return config_error_nonbool(var);
help_default_format = xstrdup(value);
return 0;
}

25
http.c
View File

@ -101,16 +101,18 @@ static int http_options(const char *var, const char *value)
if (!strcmp("http.sslcert", var)) {
if (ssl_cert == NULL) {
ssl_cert = xmalloc(strlen(value)+1);
strcpy(ssl_cert, value);
if (!value)
return config_error_nonbool(var);
ssl_cert = xstrdup(value);
}
return 0;
}
#if LIBCURL_VERSION_NUM >= 0x070902
if (!strcmp("http.sslkey", var)) {
if (ssl_key == NULL) {
ssl_key = xmalloc(strlen(value)+1);
strcpy(ssl_key, value);
if (!value)
return config_error_nonbool(var);
ssl_key = xstrdup(value);
}
return 0;
}
@ -118,16 +120,18 @@ static int http_options(const char *var, const char *value)
#if LIBCURL_VERSION_NUM >= 0x070908
if (!strcmp("http.sslcapath", var)) {
if (ssl_capath == NULL) {
ssl_capath = xmalloc(strlen(value)+1);
strcpy(ssl_capath, value);
if (!value)
return config_error_nonbool(var);
ssl_capath = xstrdup(value);
}
return 0;
}
#endif
if (!strcmp("http.sslcainfo", var)) {
if (ssl_cainfo == NULL) {
ssl_cainfo = xmalloc(strlen(value)+1);
strcpy(ssl_cainfo, value);
if (!value)
return config_error_nonbool(var);
ssl_cainfo = xstrdup(value);
}
return 0;
}
@ -157,8 +161,9 @@ static int http_options(const char *var, const char *value)
}
if (!strcmp("http.proxy", var)) {
if (curl_http_proxy == NULL) {
curl_http_proxy = xmalloc(strlen(value)+1);
strcpy(curl_http_proxy, value);
if (!value)
return config_error_nonbool(var);
curl_http_proxy = xstrdup(value);
}
return 0;
}

View File

@ -1254,6 +1254,10 @@ git_imap_config(const char *key, const char *val)
if (strncmp( key, imap_key, sizeof imap_key - 1 ))
return 0;
if (!val)
return config_error_nonbool(key);
key += sizeof imap_key - 1;
if (!strcmp( "folder", key )) {

View File

@ -844,8 +844,9 @@ static int read_merge_config(const char *var, const char *value)
int namelen;
if (!strcmp(var, "merge.default")) {
if (value)
default_ll_merge = strdup(value);
if (!value)
return config_error_nonbool(var);
default_ll_merge = strdup(value);
return 0;
}
@ -878,14 +879,14 @@ static int read_merge_config(const char *var, const char *value)
if (!strcmp("name", ep)) {
if (!value)
return error("%s: lacks value", var);
return config_error_nonbool(var);
fn->description = strdup(value);
return 0;
}
if (!strcmp("driver", ep)) {
if (!value)
return error("%s: lacks value", var);
return config_error_nonbool(var);
/*
* merge.<name>.driver specifies the command line:
*
@ -908,7 +909,7 @@ static int read_merge_config(const char *var, const char *value)
if (!strcmp("recursive", ep)) {
if (!value)
return error("%s: lacks value", var);
return config_error_nonbool(var);
fn->recursive = strdup(value);
return 0;
}

View File

@ -222,15 +222,18 @@ static int handle_config(const char *key, const char *value)
subkey = strrchr(name, '.');
if (!subkey)
return 0;
if (!value)
return 0;
branch = make_branch(name, subkey - name);
if (!strcmp(subkey, ".remote")) {
if (!value)
return config_error_nonbool(key);
branch->remote_name = xstrdup(value);
if (branch == current_branch)
default_remote_name = branch->remote_name;
} else if (!strcmp(subkey, ".merge"))
} else if (!strcmp(subkey, ".merge")) {
if (!value)
return config_error_nonbool(key);
add_merge(branch, xstrdup(value));
}
return 0;
}
if (prefixcmp(key, "remote."))

View File

@ -372,6 +372,8 @@ int check_repository_format_version(const char *var, const char *value)
if (is_bare_repository_cfg == 1)
inside_work_tree = -1;
} else if (strcmp(var, "core.worktree") == 0) {
if (!value)
return config_error_nonbool(var);
if (git_work_tree_cfg)
free(git_work_tree_cfg);
git_work_tree_cfg = xstrdup(value);

View File

@ -71,6 +71,25 @@ EOF
test_expect_success 'non-match result' 'cmp .git/config expect'
cat > .git/config <<\EOF
[alpha]
bar = foo
[beta]
baz = multiple \
lines
EOF
test_expect_success 'unset with cont. lines' \
'git config --unset beta.baz'
cat > expect <<\EOF
[alpha]
bar = foo
[beta]
EOF
test_expect_success 'unset with cont. lines is correct' 'cmp .git/config expect'
cat > .git/config << EOF
[beta] ; silly comment # another comment
noIndent= sillyValue ; 'nother silly comment

32
t/t5304-prune.sh Normal file
View File

@ -0,0 +1,32 @@
#!/bin/sh
#
# Copyright (c) 2008 Johannes E. Schindelin
#
test_description='prune'
. ./test-lib.sh
test_expect_success setup '
: > file &&
git add file &&
test_tick &&
git commit -m initial &&
git gc
'
test_expect_success 'prune stale packs' '
orig_pack=$(echo .git/objects/pack/*.pack) &&
: > .git/objects/tmp_1.pack &&
: > .git/objects/tmp_2.pack &&
test-chmtime -86501 .git/objects/tmp_1.pack &&
git prune --expire 1.day &&
test -f $orig_pack &&
test -f .git/objects/tmp_2.pack &&
! test -f .git/objects/tmp_1.pack
'
test_done

View File

@ -254,6 +254,18 @@ test_expect_success 'bisect run & skip: find first bad' '
grep "$HASH6 is first bad commit" my_bisect_log.txt
'
test_expect_success 'bisect starting with a detached HEAD' '
git bisect reset &&
git checkout master^ &&
HEAD=$(git rev-parse --verify HEAD) &&
git bisect start &&
test $HEAD = $(cat .git/head-name) &&
git bisect reset &&
test $HEAD = $(git rev-parse --verify HEAD)
'
#
#
test_done

View File

@ -402,6 +402,8 @@ int git_status_config(const char *k, const char *v)
}
if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
int slot = parse_status_slot(k, 13);
if (!v)
return config_error_nonbool(k);
color_parse(v, k, wt_status_colors[slot]);
return 0;
}