config_cache.c 4.36 KB
Newer Older
Vicent Martí committed
1
/*
Edward Thomson committed
2
 * Copyright (C) the libgit2 contributors. All rights reserved.
Vicent Martí committed
3 4 5 6 7 8
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#include "common.h"
9

10
#include "futils.h"
11
#include "repository.h"
Vicent Martí committed
12 13 14 15 16 17
#include "config.h"
#include "git2/config.h"
#include "vector.h"
#include "filter.h"

struct map_data {
18 19
	const char *name;
	git_configmap *maps;
Vicent Martí committed
20 21 22 23 24 25 26 27
	size_t map_count;
	int default_value;
};

/*
 *	core.eol
 *		Sets the line ending type to use in the working directory for
 *	files that have the text property set. Alternatives are lf, crlf
Vicent Marti committed
28
 *	and native, which uses the platform's native line ending. The default
Vicent Martí committed
29
 *	value is native. See gitattributes(5) for more information on
30
 *	end-of-line conversion.
Vicent Martí committed
31
 */
32 33 34 35 36
static git_configmap _configmap_eol[] = {
	{GIT_CONFIGMAP_FALSE, NULL, GIT_EOL_UNSET},
	{GIT_CONFIGMAP_STRING, "lf", GIT_EOL_LF},
	{GIT_CONFIGMAP_STRING, "crlf", GIT_EOL_CRLF},
	{GIT_CONFIGMAP_STRING, "native", GIT_EOL_NATIVE}
Vicent Martí committed
37 38 39 40
};

/*
 *	core.autocrlf
41
 *		Setting this variable to "true" is almost the same as setting
Vicent Martí committed
42 43 44 45 46 47 48
 *	the text attribute to "auto" on all files except that text files are
 *	not guaranteed to be normalized: files that contain CRLF in the
 *	repository will not be touched. Use this setting if you want to have
 *	CRLF line endings in your working directory even though the repository
 *	does not have normalized line endings. This variable can be set to input,
 *	in which case no output conversion is performed.
 */
49 50 51 52
static git_configmap _configmap_autocrlf[] = {
	{GIT_CONFIGMAP_FALSE, NULL, GIT_AUTO_CRLF_FALSE},
	{GIT_CONFIGMAP_TRUE, NULL, GIT_AUTO_CRLF_TRUE},
	{GIT_CONFIGMAP_STRING, "input", GIT_AUTO_CRLF_INPUT}
Vicent Martí committed
53 54
};

55 56 57 58
static git_configmap _configmap_safecrlf[] = {
	{GIT_CONFIGMAP_FALSE, NULL, GIT_SAFE_CRLF_FALSE},
	{GIT_CONFIGMAP_TRUE, NULL, GIT_SAFE_CRLF_FAIL},
	{GIT_CONFIGMAP_STRING, "warn", GIT_SAFE_CRLF_WARN}
59 60
};

61 62 63 64
static git_configmap _configmap_logallrefupdates[] = {
	{GIT_CONFIGMAP_FALSE, NULL, GIT_LOGALLREFUPDATES_FALSE},
	{GIT_CONFIGMAP_TRUE, NULL, GIT_LOGALLREFUPDATES_TRUE},
	{GIT_CONFIGMAP_STRING, "always", GIT_LOGALLREFUPDATES_ALWAYS},
65 66
};

67 68 69
/*
 * Generic map for integer values
 */
70 71
static git_configmap _configmap_int[] = {
	{GIT_CONFIGMAP_INT32, NULL, 0},
72 73
};

74 75 76
static struct map_data _configmaps[] = {
	{"core.autocrlf", _configmap_autocrlf, ARRAY_SIZE(_configmap_autocrlf), GIT_AUTO_CRLF_DEFAULT},
	{"core.eol", _configmap_eol, ARRAY_SIZE(_configmap_eol), GIT_EOL_DEFAULT},
77 78 79 80 81
	{"core.symlinks", NULL, 0, GIT_SYMLINKS_DEFAULT },
	{"core.ignorecase", NULL, 0, GIT_IGNORECASE_DEFAULT },
	{"core.filemode", NULL, 0, GIT_FILEMODE_DEFAULT },
	{"core.ignorestat", NULL, 0, GIT_IGNORESTAT_DEFAULT },
	{"core.trustctime", NULL, 0, GIT_TRUSTCTIME_DEFAULT },
82
	{"core.abbrev", _configmap_int, 1, GIT_ABBREV_DEFAULT },
83
	{"core.precomposeunicode", NULL, 0, GIT_PRECOMPOSE_DEFAULT },
84 85
	{"core.safecrlf", _configmap_safecrlf, ARRAY_SIZE(_configmap_safecrlf), GIT_SAFE_CRLF_DEFAULT},
	{"core.logallrefupdates", _configmap_logallrefupdates, ARRAY_SIZE(_configmap_logallrefupdates), GIT_LOGALLREFUPDATES_DEFAULT},
86 87
	{"core.protecthfs", NULL, 0, GIT_PROTECTHFS_DEFAULT },
	{"core.protectntfs", NULL, 0, GIT_PROTECTNTFS_DEFAULT },
88
	{"core.fsyncobjectfiles", NULL, 0, GIT_FSYNCOBJECTFILES_DEFAULT },
Vicent Martí committed
89 90
};

91
int git_config__configmap_lookup(int *out, git_config *config, git_configmap_item item)
92 93
{
	int error = 0;
94
	struct map_data *data = &_configmaps[(int)item];
95
	git_config_entry *entry;
96

97
	if ((error = git_config__lookup_entry(&entry, config, data->name, false)) < 0)
98
		return error;
99 100 101 102 103 104 105 106 107

	if (!entry)
		*out = data->default_value;
	else if (data->maps)
		error = git_config_lookup_map_value(
			out, data->maps, data->map_count, entry->value);
	else
		error = git_config_parse_bool(out, entry->value);

108
	git_config_entry_free(entry);
109 110 111
	return error;
}

112
int git_repository__configmap_lookup(int *out, git_repository *repo, git_configmap_item item)
Vicent Martí committed
113
{
114
	*out = repo->configmap_cache[(int)item];
Vicent Martí committed
115

116
	if (*out == GIT_CONFIGMAP_NOT_CACHED) {
Vicent Martí committed
117
		int error;
118
		git_config *config;
119

120
		if ((error = git_repository_config__weakptr(&config, repo)) < 0 ||
121
			(error = git_config__configmap_lookup(out, config, item)) < 0)
Vicent Martí committed
122 123
			return error;

124
		repo->configmap_cache[(int)item] = *out;
Vicent Martí committed
125 126
	}

127
	return 0;
Vicent Martí committed
128 129
}

130
void git_repository__configmap_lookup_cache_clear(git_repository *repo)
Vicent Martí committed
131 132 133
{
	int i;

134 135
	for (i = 0; i < GIT_CONFIGMAP_CACHE_MAX; ++i)
		repo->configmap_cache[i] = GIT_CONFIGMAP_NOT_CACHED;
Vicent Martí committed
136 137
}