File Coverage

deps/libgit2/src/libgit2/config_cache.c
Criterion Covered Total %
statement 26 28 92.8
branch 11 14 78.5
condition n/a
subroutine n/a
pod n/a
total 37 42 88.1


line stmt bran cond sub pod time code
1             /*
2             * Copyright (C) the libgit2 contributors. All rights reserved.
3             *
4             * This file is part of libgit2, distributed under the GNU GPL v2 with
5             * a Linking Exception. For full terms see the included COPYING file.
6             */
7              
8             #include "common.h"
9              
10             #include "futils.h"
11             #include "repository.h"
12             #include "config.h"
13             #include "git2/config.h"
14             #include "vector.h"
15             #include "filter.h"
16              
17             struct map_data {
18             const char *name;
19             git_configmap *maps;
20             size_t map_count;
21             int default_value;
22             };
23              
24             /*
25             * core.eol
26             * Sets the line ending type to use in the working directory for
27             * files that have the text property set. Alternatives are lf, crlf
28             * and native, which uses the platform's native line ending. The default
29             * value is native. See gitattributes(5) for more information on
30             * end-of-line conversion.
31             */
32             static git_configmap _configmap_eol[] = {
33             {GIT_CONFIGMAP_FALSE, NULL, GIT_EOL_UNSET},
34             {GIT_CONFIGMAP_STRING, "lf", GIT_EOL_LF},
35             {GIT_CONFIGMAP_STRING, "crlf", GIT_EOL_CRLF},
36             {GIT_CONFIGMAP_STRING, "native", GIT_EOL_NATIVE}
37             };
38              
39             /*
40             * core.autocrlf
41             * Setting this variable to "true" is almost the same as setting
42             * the text attribute to "auto" on all files except that text files are
43             * not guaranteed to be normalized: files that contain CRLF in the
44             * repository will not be touched. Use this setting if you want to have
45             * CRLF line endings in your working directory even though the repository
46             * does not have normalized line endings. This variable can be set to input,
47             * in which case no output conversion is performed.
48             */
49             static git_configmap _configmap_autocrlf[] = {
50             {GIT_CONFIGMAP_FALSE, NULL, GIT_AUTO_CRLF_FALSE},
51             {GIT_CONFIGMAP_TRUE, NULL, GIT_AUTO_CRLF_TRUE},
52             {GIT_CONFIGMAP_STRING, "input", GIT_AUTO_CRLF_INPUT}
53             };
54              
55             static git_configmap _configmap_safecrlf[] = {
56             {GIT_CONFIGMAP_FALSE, NULL, GIT_SAFE_CRLF_FALSE},
57             {GIT_CONFIGMAP_TRUE, NULL, GIT_SAFE_CRLF_FAIL},
58             {GIT_CONFIGMAP_STRING, "warn", GIT_SAFE_CRLF_WARN}
59             };
60              
61             static git_configmap _configmap_logallrefupdates[] = {
62             {GIT_CONFIGMAP_FALSE, NULL, GIT_LOGALLREFUPDATES_FALSE},
63             {GIT_CONFIGMAP_TRUE, NULL, GIT_LOGALLREFUPDATES_TRUE},
64             {GIT_CONFIGMAP_STRING, "always", GIT_LOGALLREFUPDATES_ALWAYS},
65             };
66              
67             /*
68             * Generic map for integer values
69             */
70             static git_configmap _configmap_int[] = {
71             {GIT_CONFIGMAP_INT32, NULL, 0},
72             };
73              
74             static struct map_data _configmaps[] = {
75             {"core.autocrlf", _configmap_autocrlf, ARRAY_SIZE(_configmap_autocrlf), GIT_AUTO_CRLF_DEFAULT},
76             {"core.eol", _configmap_eol, ARRAY_SIZE(_configmap_eol), GIT_EOL_DEFAULT},
77             {"core.symlinks", NULL, 0, GIT_SYMLINKS_DEFAULT },
78             {"core.ignorecase", NULL, 0, GIT_IGNORECASE_DEFAULT },
79             {"core.filemode", NULL, 0, GIT_FILEMODE_DEFAULT },
80             {"core.ignorestat", NULL, 0, GIT_IGNORESTAT_DEFAULT },
81             {"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             {"core.safecrlf", _configmap_safecrlf, ARRAY_SIZE(_configmap_safecrlf), GIT_SAFE_CRLF_DEFAULT},
85             {"core.logallrefupdates", _configmap_logallrefupdates, ARRAY_SIZE(_configmap_logallrefupdates), GIT_LOGALLREFUPDATES_DEFAULT},
86             {"core.protecthfs", NULL, 0, GIT_PROTECTHFS_DEFAULT },
87             {"core.protectntfs", NULL, 0, GIT_PROTECTNTFS_DEFAULT },
88             {"core.fsyncobjectfiles", NULL, 0, GIT_FSYNCOBJECTFILES_DEFAULT },
89             {"core.longpaths", NULL, 0, GIT_LONGPATHS_DEFAULT },
90             };
91              
92 1501           int git_config__configmap_lookup(int *out, git_config *config, git_configmap_item item)
93             {
94 1501           int error = 0;
95 1501           struct map_data *data = &_configmaps[(int)item];
96             git_config_entry *entry;
97              
98 1501 50         if ((error = git_config__lookup_entry(&entry, config, data->name, false)) < 0)
99 0           return error;
100              
101 1501 100         if (!entry)
102 1163           *out = data->default_value;
103 338 100         else if (data->maps)
104 23           error = git_config_lookup_map_value(
105 46           out, data->maps, data->map_count, entry->value);
106             else
107 315           error = git_config_parse_bool(out, entry->value);
108              
109 1501           git_config_entry_free(entry);
110 1501           return error;
111             }
112              
113 4364           int git_repository__configmap_lookup(int *out, git_repository *repo, git_configmap_item item)
114             {
115 4364           intptr_t value = (intptr_t)git_atomic_load(repo->configmap_cache[(int)item]);
116              
117 4364           *out = (int)value;
118              
119 4364 100         if (value == GIT_CONFIGMAP_NOT_CACHED) {
120             git_config *config;
121 309           intptr_t oldval = value;
122             int error;
123              
124 309 50         if ((error = git_repository_config__weakptr(&config, repo)) < 0 ||
    50          
125 309           (error = git_config__configmap_lookup(out, config, item)) < 0)
126 0           return error;
127              
128 309           value = *out;
129 309           git_atomic_compare_and_swap(&repo->configmap_cache[(int)item], (void *)oldval, (void *)value);
130             }
131              
132 4364           return 0;
133             }
134              
135 147           void git_repository__configmap_lookup_cache_clear(git_repository *repo)
136             {
137             int i;
138              
139 2352 100         for (i = 0; i < GIT_CONFIGMAP_CACHE_MAX; ++i)
140 2205           repo->configmap_cache[i] = GIT_CONFIGMAP_NOT_CACHED;
141 147           }
142