git

Форк
0
/
parse.c 
211 строк · 3.9 Кб
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_double(const char *value, double *ret)
129
{
130
	char *end;
131
	double val;
132
	uintmax_t factor;
133

134
	if (!value || !*value) {
135
		errno = EINVAL;
136
		return 0;
137
	}
138

139
	errno = 0;
140
	val = strtod(value, &end);
141
	if (errno == ERANGE)
142
		return 0;
143
	if (end == value) {
144
		errno = EINVAL;
145
		return 0;
146
	}
147
	factor = get_unit_factor(end);
148
	if (!factor) {
149
		errno = EINVAL;
150
		return 0;
151
	}
152
	val *= factor;
153
	*ret = val;
154
	return 1;
155
}
156

157
int git_parse_maybe_bool_text(const char *value)
158
{
159
	if (!value)
160
		return 1;
161
	if (!*value)
162
		return 0;
163
	if (!strcasecmp(value, "true")
164
	    || !strcasecmp(value, "yes")
165
	    || !strcasecmp(value, "on"))
166
		return 1;
167
	if (!strcasecmp(value, "false")
168
	    || !strcasecmp(value, "no")
169
	    || !strcasecmp(value, "off"))
170
		return 0;
171
	return -1;
172
}
173

174
int git_parse_maybe_bool(const char *value)
175
{
176
	int v = git_parse_maybe_bool_text(value);
177
	if (0 <= v)
178
		return v;
179
	if (git_parse_int(value, &v))
180
		return !!v;
181
	return -1;
182
}
183

184
/*
185
 * Parse environment variable 'k' as a boolean (in various
186
 * possible spellings); if missing, use the default value 'def'.
187
 */
188
int git_env_bool(const char *k, int def)
189
{
190
	const char *v = getenv(k);
191
	int val;
192
	if (!v)
193
		return def;
194
	val = git_parse_maybe_bool(v);
195
	if (val < 0)
196
		die(_("bad boolean environment value '%s' for '%s'"),
197
		    v, k);
198
	return val;
199
}
200

201
/*
202
 * Parse environment variable 'k' as ulong with possibly a unit
203
 * suffix; if missing, use the default value 'val'.
204
 */
205
unsigned long git_env_ulong(const char *k, unsigned long val)
206
{
207
	const char *v = getenv(k);
208
	if (v && !git_parse_ulong(v, &val))
209
		die(_("failed to parse %s"), k);
210
	return val;
211
}
212

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.