parse: separate out parsing functions from config.h

The files config.{h,c} contain functions that have to do with parsing, but not config. In order to further reduce all-in-one headers, separate out functions in config.c that do not operate on config into its own file, parse.h, and update the include directives in the .c files that need only such functions accordingly. Signed-off-by: Calvin Wan <calvinwan@google.com> Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Calvin Wan committed Sep 29, 2023 at 14:20 UTC b1bda751739d90e1a94b47397676bcb8eebf16d5
18 files changed +219 -205
Makefile
+1
@@ -1091,6 +1091,7 @@ LIB_OBJS += pack-write.o
1091 LIB_OBJS += packfile.o
1092 LIB_OBJS += pager.o
1093 LIB_OBJS += parallel-checkout.o
1094 +LIB_OBJS += parse.o
1095 LIB_OBJS += parse-options-cb.o
1096 LIB_OBJS += parse-options.o
1097 LIB_OBJS += patch-delta.o
attr.c
+1 -1
@@ -7,7 +7,7 @@
7 */
8
9 #include "git-compat-util.h"
10 -#include "config.h"
10 +#include "parse.h"
11 #include "environment.h"
12 #include "exec-cmd.h"
13 #include "attr.h"
config.c
+1 -179
@@ -11,6 +11,7 @@
11 #include "date.h"
12 #include "branch.h"
13 #include "config.h"
14 +#include "parse.h"
15 #include "convert.h"
16 #include "environment.h"
17 #include "gettext.h"
@@ -1165,129 +1166,6 @@ static int git_parse_source(struct config_source *cs, config_fn_t fn,
1166 return error_return;
1167 }
1168
1168 -static uintmax_t get_unit_factor(const char *end)
1169 -{
1170 - if (!*end)
1171 - return 1;
1172 - else if (!strcasecmp(end, "k"))
1173 - return 1024;
1174 - else if (!strcasecmp(end, "m"))
1175 - return 1024 * 1024;
1176 - else if (!strcasecmp(end, "g"))
1177 - return 1024 * 1024 * 1024;
1178 - return 0;
1179 -}
1180 -
1181 -static int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
1182 -{
1183 - if (value && *value) {
1184 - char *end;
1185 - intmax_t val;
1186 - intmax_t factor;
1187 -
1188 - if (max < 0)
1189 - BUG("max must be a positive integer");
1190 -
1191 - errno = 0;
1192 - val = strtoimax(value, &end, 0);
1193 - if (errno == ERANGE)
1194 - return 0;
1195 - if (end == value) {
1196 - errno = EINVAL;
1197 - return 0;
1198 - }
1199 - factor = get_unit_factor(end);
1200 - if (!factor) {
1201 - errno = EINVAL;
1202 - return 0;
1203 - }
1204 - if ((val < 0 && -max / factor > val) ||
1205 - (val > 0 && max / factor < val)) {
1206 - errno = ERANGE;
1207 - return 0;
1208 - }
1209 - val *= factor;
1210 - *ret = val;
1211 - return 1;
1212 - }
1213 - errno = EINVAL;
1214 - return 0;
1215 -}
1216 -
1217 -static int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
1218 -{
1219 - if (value && *value) {
1220 - char *end;
1221 - uintmax_t val;
1222 - uintmax_t factor;
1223 -
1224 - /* negative values would be accepted by strtoumax */
1225 - if (strchr(value, '-')) {
1226 - errno = EINVAL;
1227 - return 0;
1228 - }
1229 - errno = 0;
1230 - val = strtoumax(value, &end, 0);
1231 - if (errno == ERANGE)
1232 - return 0;
1233 - if (end == value) {
1234 - errno = EINVAL;
1235 - return 0;
1236 - }
1237 - factor = get_unit_factor(end);
1238 - if (!factor) {
1239 - errno = EINVAL;
1240 - return 0;
1241 - }
1242 - if (unsigned_mult_overflows(factor, val) ||
1243 - factor * val > max) {
1244 - errno = ERANGE;
1245 - return 0;
1246 - }
1247 - val *= factor;
1248 - *ret = val;
1249 - return 1;
1250 - }
1251 - errno = EINVAL;
1252 - return 0;
1253 -}
1254 -
1255 -int git_parse_int(const char *value, int *ret)
1256 -{
1257 - intmax_t tmp;
1258 - if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(int)))
1259 - return 0;
1260 - *ret = tmp;
1261 - return 1;
1262 -}
1263 -
1264 -static int git_parse_int64(const char *value, int64_t *ret)
1265 -{
1266 - intmax_t tmp;
1267 - if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(int64_t)))
1268 - return 0;
1269 - *ret = tmp;
1270 - return 1;
1271 -}
1272 -
1273 -int git_parse_ulong(const char *value, unsigned long *ret)
1274 -{
1275 - uintmax_t tmp;
1276 - if (!git_parse_unsigned(value, &tmp, maximum_unsigned_value_of_type(long)))
1277 - return 0;
1278 - *ret = tmp;
1279 - return 1;
1280 -}
1281 -
1282 -int git_parse_ssize_t(const char *value, ssize_t *ret)
1283 -{
1284 - intmax_t tmp;
1285 - if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(ssize_t)))
1286 - return 0;
1287 - *ret = tmp;
1288 - return 1;
1289 -}
1290 -
1169 NORETURN
1170 static void die_bad_number(const char *name, const char *value,
1171 const struct key_value_info *kvi)
@@ -1363,23 +1241,6 @@ ssize_t git_config_ssize_t(const char *name, const char *value,
1241 return ret;
1242 }
1243
1366 -static int git_parse_maybe_bool_text(const char *value)
1367 -{
1368 - if (!value)
1369 - return 1;
1370 - if (!*value)
1371 - return 0;
1372 - if (!strcasecmp(value, "true")
1373 - || !strcasecmp(value, "yes")
1374 - || !strcasecmp(value, "on"))
1375 - return 1;
1376 - if (!strcasecmp(value, "false")
1377 - || !strcasecmp(value, "no")
1378 - || !strcasecmp(value, "off"))
1379 - return 0;
1380 - return -1;
1381 -}
1382 -
1244 static const struct fsync_component_name {
1245 const char *name;
1246 enum fsync_component component_bits;
@@ -1454,16 +1315,6 @@ next_name:
1315 return (current & ~negative) | positive;
1316 }
1317
1457 -int git_parse_maybe_bool(const char *value)
1458 -{
1459 - int v = git_parse_maybe_bool_text(value);
1460 - if (0 <= v)
1461 - return v;
1462 - if (git_parse_int(value, &v))
1463 - return !!v;
1464 - return -1;
1465 -}
1466 -
1318 int git_config_bool_or_int(const char *name, const char *value,
1319 const struct key_value_info *kvi, int *is_bool)
1320 {
@@ -2126,35 +1977,6 @@ void git_global_config(char **user_out, char **xdg_out)
1977 *xdg_out = xdg_config;
1978 }
1979
2129 -/*
2130 - * Parse environment variable 'k' as a boolean (in various
2131 - * possible spellings); if missing, use the default value 'def'.
2132 - */
2133 -int git_env_bool(const char *k, int def)
2134 -{
2135 - const char *v = getenv(k);
2136 - int val;
2137 - if (!v)
2138 - return def;
2139 - val = git_parse_maybe_bool(v);
2140 - if (val < 0)
2141 - die(_("bad boolean environment value '%s' for '%s'"),
2142 - v, k);
2143 - return val;
2144 -}
2145 -
2146 -/*
2147 - * Parse environment variable 'k' as ulong with possibly a unit
2148 - * suffix; if missing, use the default value 'val'.
2149 - */
2150 -unsigned long git_env_ulong(const char *k, unsigned long val)
2151 -{
2152 - const char *v = getenv(k);
2153 - if (v && !git_parse_ulong(v, &val))
2154 - die(_("failed to parse %s"), k);
2155 - return val;
2156 -}
2157 -
1980 int git_config_system(void)
1981 {
1982 return !git_env_bool("GIT_CONFIG_NOSYSTEM", 0);
config.h
+1 -13
@@ -4,7 +4,7 @@
4 #include "hashmap.h"
5 #include "string-list.h"
6 #include "repository.h"
7 -
7 +#include "parse.h"
8
9 /**
10 * The config API gives callers a way to access Git configuration files
@@ -243,16 +243,6 @@ int config_with_options(config_fn_t fn, void *,
243 * The following helper functions aid in parsing string values
244 */
245
246 -int git_parse_ssize_t(const char *, ssize_t *);
247 -int git_parse_ulong(const char *, unsigned long *);
248 -int git_parse_int(const char *value, int *ret);
249 -
250 -/**
251 - * Same as `git_config_bool`, except that it returns -1 on error rather
252 - * than dying.
253 - */
254 -int git_parse_maybe_bool(const char *);
255 -
246 /**
247 * Parse the string to an integer, including unit factors. Dies on error;
248 * otherwise, returns the parsed result.
@@ -385,8 +375,6 @@ int git_config_rename_section(const char *, const char *);
375 int git_config_rename_section_in_file(const char *, const char *, const char *);
376 int git_config_copy_section(const char *, const char *);
377 int git_config_copy_section_in_file(const char *, const char *, const char *);
388 -int git_env_bool(const char *, int);
389 -unsigned long git_env_ulong(const char *, unsigned long);
378 int git_config_system(void);
379 int config_error_nonbool(const char *);
380 #if defined(__GNUC__)
pack-objects.c
+1 -1
@@ -3,7 +3,7 @@
3 #include "pack.h"
4 #include "pack-objects.h"
5 #include "packfile.h"
6 -#include "config.h"
6 +#include "parse.h"
7
8 static uint32_t locate_object_entry_hash(struct packing_data *pdata,
9 const struct object_id *oid,
pack-revindex.c
+1 -1
@@ -6,7 +6,7 @@
6 #include "packfile.h"
7 #include "strbuf.h"
8 #include "trace2.h"
9 -#include "config.h"
9 +#include "parse.h"
10 #include "midx.h"
11 #include "csum-file.h"
12
parse-options.c
+2 -1
@@ -1,11 +1,12 @@
1 #include "git-compat-util.h"
2 #include "parse-options.h"
3 #include "abspath.h"
4 -#include "config.h"
4 +#include "parse.h"
5 #include "commit.h"
6 #include "color.h"
7 #include "gettext.h"
8 #include "strbuf.h"
9 +#include "string-list.h"
10 #include "utf8.h"
11
12 static int disallow_abbreviated_options;
parse.c new
+182
@@ -0,0 +1,182 @@
1 +#include "git-compat-util.h"
2 +#include "gettext.h"
3 +#include "parse.h"
4 +
5 +static uintmax_t get_unit_factor(const char *end)
6 +{
7 + if (!*end)
8 + return 1;
9 + else if (!strcasecmp(end, "k"))
10 + return 1024;
11 + else if (!strcasecmp(end, "m"))
12 + return 1024 * 1024;
13 + else if (!strcasecmp(end, "g"))
14 + return 1024 * 1024 * 1024;
15 + return 0;
16 +}
17 +
18 +int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
19 +{
20 + if (value && *value) {
21 + char *end;
22 + intmax_t val;
23 + intmax_t factor;
24 +
25 + if (max < 0)
26 + BUG("max must be a positive integer");
27 +
28 + errno = 0;
29 + val = strtoimax(value, &end, 0);
30 + if (errno == ERANGE)
31 + return 0;
32 + if (end == value) {
33 + errno = EINVAL;
34 + return 0;
35 + }
36 + factor = get_unit_factor(end);
37 + if (!factor) {
38 + errno = EINVAL;
39 + return 0;
40 + }
41 + if ((val < 0 && -max / factor > val) ||
42 + (val > 0 && max / factor < val)) {
43 + errno = ERANGE;
44 + return 0;
45 + }
46 + val *= factor;
47 + *ret = val;
48 + return 1;
49 + }
50 + errno = EINVAL;
51 + return 0;
52 +}
53 +
54 +static int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
55 +{
56 + if (value && *value) {
57 + char *end;
58 + uintmax_t val;
59 + uintmax_t factor;
60 +
61 + /* negative values would be accepted by strtoumax */
62 + if (strchr(value, '-')) {
63 + errno = EINVAL;
64 + return 0;
65 + }
66 + errno = 0;
67 + val = strtoumax(value, &end, 0);
68 + if (errno == ERANGE)
69 + return 0;
70 + if (end == value) {
71 + errno = EINVAL;
72 + return 0;
73 + }
74 + factor = get_unit_factor(end);
75 + if (!factor) {
76 + errno = EINVAL;
77 + return 0;
78 + }
79 + if (unsigned_mult_overflows(factor, val) ||
80 + factor * val > max) {
81 + errno = ERANGE;
82 + return 0;
83 + }
84 + val *= factor;
85 + *ret = val;
86 + return 1;
87 + }
88 + errno = EINVAL;
89 + return 0;
90 +}
91 +
92 +int git_parse_int(const char *value, int *ret)
93 +{
94 + intmax_t tmp;
95 + if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(int)))
96 + return 0;
97 + *ret = tmp;
98 + return 1;
99 +}
100 +
101 +int git_parse_int64(const char *value, int64_t *ret)
102 +{
103 + intmax_t tmp;
104 + if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(int64_t)))
105 + return 0;
106 + *ret = tmp;
107 + return 1;
108 +}
109 +
110 +int git_parse_ulong(const char *value, unsigned long *ret)
111 +{
112 + uintmax_t tmp;
113 + if (!git_parse_unsigned(value, &tmp, maximum_unsigned_value_of_type(long)))
114 + return 0;
115 + *ret = tmp;
116 + return 1;
117 +}
118 +
119 +int git_parse_ssize_t(const char *value, ssize_t *ret)
120 +{
121 + intmax_t tmp;
122 + if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(ssize_t)))
123 + return 0;
124 + *ret = tmp;
125 + return 1;
126 +}
127 +
128 +int git_parse_maybe_bool_text(const char *value)
129 +{
130 + if (!value)
131 + return 1;
132 + if (!*value)
133 + return 0;
134 + if (!strcasecmp(value, "true")
135 + || !strcasecmp(value, "yes")
136 + || !strcasecmp(value, "on"))
137 + return 1;
138 + if (!strcasecmp(value, "false")
139 + || !strcasecmp(value, "no")
140 + || !strcasecmp(value, "off"))
141 + return 0;
142 + return -1;
143 +}
144 +
145 +int git_parse_maybe_bool(const char *value)
146 +{
147 + int v = git_parse_maybe_bool_text(value);
148 + if (0 <= v)
149 + return v;
150 + if (git_parse_int(value, &v))
151 + return !!v;
152 + return -1;
153 +}
154 +
155 +/*
156 + * Parse environment variable 'k' as a boolean (in various
157 + * possible spellings); if missing, use the default value 'def'.
158 + */
159 +int git_env_bool(const char *k, int def)
160 +{
161 + const char *v = getenv(k);
162 + int val;
163 + if (!v)
164 + return def;
165 + val = git_parse_maybe_bool(v);
166 + if (val < 0)
167 + die(_("bad boolean environment value '%s' for '%s'"),
168 + v, k);
169 + return val;
170 +}
171 +
172 +/*
173 + * Parse environment variable 'k' as ulong with possibly a unit
174 + * suffix; if missing, use the default value 'val'.
175 + */
176 +unsigned long git_env_ulong(const char *k, unsigned long val)
177 +{
178 + const char *v = getenv(k);
179 + if (v && !git_parse_ulong(v, &val))
180 + die(_("failed to parse %s"), k);
181 + return val;
182 +}
parse.h new
+20
@@ -0,0 +1,20 @@
1 +#ifndef PARSE_H
2 +#define PARSE_H
3 +
4 +int git_parse_signed(const char *value, intmax_t *ret, intmax_t max);
5 +int git_parse_ssize_t(const char *, ssize_t *);
6 +int git_parse_ulong(const char *, unsigned long *);
7 +int git_parse_int(const char *value, int *ret);
8 +int git_parse_int64(const char *value, int64_t *ret);
9 +
10 +/**
11 + * Same as `git_config_bool`, except that it returns -1 on error rather
12 + * than dying.
13 + */
14 +int git_parse_maybe_bool(const char *);
15 +int git_parse_maybe_bool_text(const char *value);
16 +
17 +int git_env_bool(const char *, int);
18 +unsigned long git_env_ulong(const char *, unsigned long);
19 +
20 +#endif /* PARSE_H */
pathspec.c
+1 -1
@@ -1,6 +1,6 @@
1 #include "git-compat-util.h"
2 #include "abspath.h"
3 -#include "config.h"
3 +#include "parse.h"
4 #include "dir.h"
5 #include "environment.h"
6 #include "gettext.h"
preload-index.c
+1 -1
@@ -7,7 +7,7 @@
7 #include "environment.h"
8 #include "fsmonitor.h"
9 #include "gettext.h"
10 -#include "config.h"
10 +#include "parse.h"
11 #include "preload-index.h"
12 #include "progress.h"
13 #include "read-cache.h"
progress.c
+1 -1
@@ -17,7 +17,7 @@
17 #include "trace.h"
18 #include "trace2.h"
19 #include "utf8.h"
20 -#include "config.h"
20 +#include "parse.h"
21
22 #define TP_IDX_MAX 8
23
prompt.c
+1 -1
@@ -1,5 +1,5 @@
1 #include "git-compat-util.h"
2 -#include "config.h"
2 +#include "parse.h"
3 #include "environment.h"
4 #include "run-command.h"
5 #include "strbuf.h"
rebase.c
+1 -1
@@ -1,6 +1,6 @@
1 #include "git-compat-util.h"
2 #include "rebase.h"
3 -#include "config.h"
3 +#include "parse.h"
4 #include "gettext.h"
5
6 /*
t/helper/test-env-helper.c
+1 -1
@@ -1,5 +1,5 @@
1 #include "test-tool.h"
2 -#include "config.h"
2 +#include "parse.h"
3 #include "parse-options.h"
4
5 static char const * const env__helper_usage[] = {
unpack-trees.c
+1 -1
@@ -2,7 +2,7 @@
2 #include "advice.h"
3 #include "strvec.h"
4 #include "repository.h"
5 -#include "config.h"
5 +#include "parse.h"
6 #include "dir.h"
7 #include "environment.h"
8 #include "gettext.h"
wrapper.c
+1 -1
@@ -3,7 +3,7 @@
3 */
4 #include "git-compat-util.h"
5 #include "abspath.h"
6 -#include "config.h"
6 +#include "parse.h"
7 #include "gettext.h"
8 #include "repository.h"
9 #include "strbuf.h"
write-or-die.c
+1 -1
@@ -1,5 +1,5 @@
1 #include "git-compat-util.h"
2 -#include "config.h"
2 +#include "parse.h"
3 #include "run-command.h"
4 #include "write-or-die.h"
5