]>
git.saurik.com Git - redis.git/blob - src/util.c
9 /* Glob-style pattern matching. */
10 int stringmatchlen(const char *pattern
, int patternLen
,
11 const char *string
, int stringLen
, int nocase
)
16 while (pattern
[1] == '*') {
23 if (stringmatchlen(pattern
+1, patternLen
-1,
24 string
, stringLen
, nocase
))
29 return 0; /* no match */
33 return 0; /* no match */
43 not = pattern
[0] == '^';
50 if (pattern
[0] == '\\') {
53 if (pattern
[0] == string
[0])
55 } else if (pattern
[0] == ']') {
57 } else if (patternLen
== 0) {
61 } else if (pattern
[1] == '-' && patternLen
>= 3) {
62 int start
= pattern
[0];
71 start
= tolower(start
);
77 if (c
>= start
&& c
<= end
)
81 if (pattern
[0] == string
[0])
84 if (tolower((int)pattern
[0]) == tolower((int)string
[0]))
94 return 0; /* no match */
100 if (patternLen
>= 2) {
107 if (pattern
[0] != string
[0])
108 return 0; /* no match */
110 if (tolower((int)pattern
[0]) != tolower((int)string
[0]))
111 return 0; /* no match */
119 if (stringLen
== 0) {
120 while(*pattern
== '*') {
127 if (patternLen
== 0 && stringLen
== 0)
132 int stringmatch(const char *pattern
, const char *string
, int nocase
) {
133 return stringmatchlen(pattern
,strlen(pattern
),string
,strlen(string
),nocase
);
136 /* Convert a string representing an amount of memory into the number of
137 * bytes, so for instance memtoll("1Gi") will return 1073741824 that is
140 * On parsing error, if *err is not NULL, it's set to 1, otherwise it's
142 long long memtoll(const char *p
, int *err
) {
145 long mul
; /* unit multiplier */
150 /* Search the first non digit character. */
153 while(*u
&& isdigit(*u
)) u
++;
154 if (*u
== '\0' || !strcasecmp(u
,"b")) {
156 } else if (!strcasecmp(u
,"k")) {
158 } else if (!strcasecmp(u
,"kb")) {
160 } else if (!strcasecmp(u
,"m")) {
162 } else if (!strcasecmp(u
,"mb")) {
164 } else if (!strcasecmp(u
,"g")) {
165 mul
= 1000L*1000*1000;
166 } else if (!strcasecmp(u
,"gb")) {
167 mul
= 1024L*1024*1024;
173 if (digits
>= sizeof(buf
)) {
177 memcpy(buf
,p
,digits
);
179 val
= strtoll(buf
,NULL
,10);
183 /* Convert a long long into a string. Returns the number of
184 * characters needed to represent the number, that can be shorter if passed
185 * buffer length is not enough to store the whole number. */
186 int ll2string(char *s
, size_t len
, long long value
) {
188 unsigned long long v
;
191 if (len
== 0) return 0;
192 v
= (value
< 0) ? -value
: value
;
193 p
= buf
+31; /* point to the last character */
198 if (value
< 0) *p
-- = '-';
201 if (l
+1 > len
) l
= len
-1; /* Make sure it fits, including the nul term */
207 /* Convert a string into a long long. Returns 1 if the string could be parsed
208 * into a (non-overflowing) long long, 0 otherwise. The value will be set to
209 * the parsed value when appropriate. */
210 int string2ll(char *s
, size_t slen
, long long *value
) {
214 unsigned long long v
;
219 /* Special case: first and only digit is 0. */
220 if (slen
== 1 && p
[0] == '0') {
221 if (value
!= NULL
) *value
= 0;
229 /* Abort on only a negative sign. */
234 /* First digit should be 1-9, otherwise the string should just be 0. */
235 if (p
[0] >= '1' && p
[0] <= '9') {
238 } else if (p
[0] == '0' && slen
== 1) {
245 while (plen
< slen
&& p
[0] >= '0' && p
[0] <= '9') {
246 if (v
> (ULLONG_MAX
/ 10)) /* Overflow. */
250 if (v
> (ULLONG_MAX
- (p
[0]-'0'))) /* Overflow. */
257 /* Return if not all bytes were used. */
262 if (v
> ((unsigned long long)(-(LLONG_MIN
+1))+1)) /* Overflow. */
264 if (value
!= NULL
) *value
= -v
;
266 if (v
> LLONG_MAX
) /* Overflow. */
268 if (value
!= NULL
) *value
= v
;
273 /* Convert a string into a long. Returns 1 if the string could be parsed into a
274 * (non-overflowing) long, 0 otherwise. The value will be set to the parsed
275 * value when appropriate. */
276 int string2l(char *s
, size_t slen
, long *lval
) {
279 if (!string2ll(s
,slen
,&llval
))
282 if (llval
< LONG_MIN
|| llval
> LONG_MAX
)
289 /* Convert a double to a string representation. Returns the number of bytes
290 * required. The representation should always be parsable by stdtod(3). */
291 int d2string(char *buf
, size_t len
, double value
) {
293 len
= snprintf(buf
,len
,"nan");
294 } else if (isinf(value
)) {
296 len
= snprintf(buf
,len
,"-inf");
298 len
= snprintf(buf
,len
,"inf");
299 } else if (value
== 0) {
300 /* See: http://en.wikipedia.org/wiki/Signed_zero, "Comparisons". */
302 len
= snprintf(buf
,len
,"-0");
304 len
= snprintf(buf
,len
,"0");
306 #if (DBL_MANT_DIG >= 52) && (LLONG_MAX == 0x7fffffffffffffffLL)
307 /* Check if the float is in a safe range to be casted into a
308 * long long. We are assuming that long long is 64 bit here.
309 * Also we are assuming that there are no implementations around where
310 * double has precision < 52 bit.
312 * Under this assumptions we test if a double is inside an interval
313 * where casting to long long is safe. Then using two castings we
314 * make sure the decimal part is zero. If all this is true we use
315 * integer printing function that is much faster. */
316 double min
= -4503599627370495; /* (2^52)-1 */
317 double max
= 4503599627370496; /* -(2^52) */
318 if (val
> min
&& val
< max
&& value
== ((double)((long long)value
)))
319 len
= ll2string(buf
,len
,(long long)value
);
322 len
= snprintf(buf
,len
,"%.17g",value
);
328 #ifdef UTIL_TEST_MAIN
331 void test_string2ll(void) {
335 /* May not start with +. */
337 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
339 /* May not start with 0. */
341 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
344 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
348 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
352 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
356 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
360 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
363 strcpy(buf
,"-9223372036854775808");
364 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
365 assert(v
== LLONG_MIN
);
367 strcpy(buf
,"-9223372036854775809"); /* overflow */
368 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
370 strcpy(buf
,"9223372036854775807");
371 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
372 assert(v
== LLONG_MAX
);
374 strcpy(buf
,"9223372036854775808"); /* overflow */
375 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
378 void test_string2l(void) {
382 /* May not start with +. */
384 assert(string2l(buf
,strlen(buf
),&v
) == 0);
386 /* May not start with 0. */
388 assert(string2l(buf
,strlen(buf
),&v
) == 0);
391 assert(string2l(buf
,strlen(buf
),&v
) == 1);
395 assert(string2l(buf
,strlen(buf
),&v
) == 1);
399 assert(string2l(buf
,strlen(buf
),&v
) == 1);
403 assert(string2l(buf
,strlen(buf
),&v
) == 1);
407 assert(string2l(buf
,strlen(buf
),&v
) == 1);
410 #if LONG_MAX != LLONG_MAX
411 strcpy(buf
,"-2147483648");
412 assert(string2l(buf
,strlen(buf
),&v
) == 1);
413 assert(v
== LONG_MIN
);
415 strcpy(buf
,"-2147483649"); /* overflow */
416 assert(string2l(buf
,strlen(buf
),&v
) == 0);
418 strcpy(buf
,"2147483647");
419 assert(string2l(buf
,strlen(buf
),&v
) == 1);
420 assert(v
== LONG_MAX
);
422 strcpy(buf
,"2147483648"); /* overflow */
423 assert(string2l(buf
,strlen(buf
),&v
) == 0);
427 int main(int argc
, char **argv
) {