]>
git.saurik.com Git - redis.git/blob - src/util.c
  11 /* Glob-style pattern matching. */ 
  12 int stringmatchlen(const char *pattern
, int patternLen
, 
  13         const char *string
, int stringLen
, int nocase
) 
  18             while (pattern
[1] == '*') { 
  25                 if (stringmatchlen(pattern
+1, patternLen
-1, 
  26                             string
, stringLen
, nocase
)) 
  31             return 0; /* no match */ 
  35                 return 0; /* no match */ 
  45             not = pattern
[0] == '^'; 
  52                 if (pattern
[0] == '\\') { 
  55                     if (pattern
[0] == string
[0]) 
  57                 } else if (pattern
[0] == ']') { 
  59                 } else if (patternLen 
== 0) { 
  63                 } else if (pattern
[1] == '-' && patternLen 
>= 3) { 
  64                     int start 
= pattern
[0]; 
  73                         start 
= tolower(start
); 
  79                     if (c 
>= start 
&& c 
<= end
) 
  83                         if (pattern
[0] == string
[0]) 
  86                         if (tolower((int)pattern
[0]) == tolower((int)string
[0])) 
  96                 return 0; /* no match */ 
 102             if (patternLen 
>= 2) { 
 109                 if (pattern
[0] != string
[0]) 
 110                     return 0; /* no match */ 
 112                 if (tolower((int)pattern
[0]) != tolower((int)string
[0])) 
 113                     return 0; /* no match */ 
 121         if (stringLen 
== 0) { 
 122             while(*pattern 
== '*') { 
 129     if (patternLen 
== 0 && stringLen 
== 0) 
 134 int stringmatch(const char *pattern
, const char *string
, int nocase
) { 
 135     return stringmatchlen(pattern
,strlen(pattern
),string
,strlen(string
),nocase
); 
 138 /* Convert a string representing an amount of memory into the number of 
 139  * bytes, so for instance memtoll("1Gi") will return 1073741824 that is 
 142  * On parsing error, if *err is not NULL, it's set to 1, otherwise it's 
 144 long long memtoll(const char *p
, int *err
) { 
 147     long mul
; /* unit multiplier */ 
 152     /* Search the first non digit character. */ 
 155     while(*u 
&& isdigit(*u
)) u
++; 
 156     if (*u 
== '\0' || !strcasecmp(u
,"b")) { 
 158     } else if (!strcasecmp(u
,"k")) { 
 160     } else if (!strcasecmp(u
,"kb")) { 
 162     } else if (!strcasecmp(u
,"m")) { 
 164     } else if (!strcasecmp(u
,"mb")) { 
 166     } else if (!strcasecmp(u
,"g")) { 
 167         mul 
= 1000L*1000*1000; 
 168     } else if (!strcasecmp(u
,"gb")) { 
 169         mul 
= 1024L*1024*1024; 
 175     if (digits 
>= sizeof(buf
)) { 
 179     memcpy(buf
,p
,digits
); 
 181     val 
= strtoll(buf
,NULL
,10); 
 185 /* Convert a long long into a string. Returns the number of 
 186  * characters needed to represent the number, that can be shorter if passed 
 187  * buffer length is not enough to store the whole number. */ 
 188 int ll2string(char *s
, size_t len
, long long value
) { 
 190     unsigned long long v
; 
 193     if (len 
== 0) return 0; 
 194     v 
= (value 
< 0) ? -value 
: value
; 
 195     p 
= buf
+31; /* point to the last character */ 
 200     if (value 
< 0) *p
-- = '-'; 
 203     if (l
+1 > len
) l 
= len
-1; /* Make sure it fits, including the nul term */ 
 209 /* Convert a string into a long long. Returns 1 if the string could be parsed 
 210  * into a (non-overflowing) long long, 0 otherwise. The value will be set to 
 211  * the parsed value when appropriate. */ 
 212 int string2ll(char *s
, size_t slen
, long long *value
) { 
 216     unsigned long long v
; 
 221     /* Special case: first and only digit is 0. */ 
 222     if (slen 
== 1 && p
[0] == '0') { 
 223         if (value 
!= NULL
) *value 
= 0; 
 231         /* Abort on only a negative sign. */ 
 236     /* First digit should be 1-9, otherwise the string should just be 0. */ 
 237     if (p
[0] >= '1' && p
[0] <= '9') { 
 240     } else if (p
[0] == '0' && slen 
== 1) { 
 247     while (plen 
< slen 
&& p
[0] >= '0' && p
[0] <= '9') { 
 248         if (v 
> (ULLONG_MAX 
/ 10)) /* Overflow. */ 
 252         if (v 
> (ULLONG_MAX 
- (p
[0]-'0'))) /* Overflow. */ 
 259     /* Return if not all bytes were used. */ 
 264         if (v 
> ((unsigned long long)(-(LLONG_MIN
+1))+1)) /* Overflow. */ 
 266         if (value 
!= NULL
) *value 
= -v
; 
 268         if (v 
> LLONG_MAX
) /* Overflow. */ 
 270         if (value 
!= NULL
) *value 
= v
; 
 275 /* Convert a string into a long. Returns 1 if the string could be parsed into a 
 276  * (non-overflowing) long, 0 otherwise. The value will be set to the parsed 
 277  * value when appropriate. */ 
 278 int string2l(char *s
, size_t slen
, long *lval
) { 
 281     if (!string2ll(s
,slen
,&llval
)) 
 284     if (llval 
< LONG_MIN 
|| llval 
> LONG_MAX
) 
 291 /* Convert a double to a string representation. Returns the number of bytes 
 292  * required. The representation should always be parsable by stdtod(3). */ 
 293 int d2string(char *buf
, size_t len
, double value
) { 
 295         len 
= snprintf(buf
,len
,"nan"); 
 296     } else if (isinf(value
)) { 
 298             len 
= snprintf(buf
,len
,"-inf"); 
 300             len 
= snprintf(buf
,len
,"inf"); 
 301     } else if (value 
== 0) { 
 302         /* See: http://en.wikipedia.org/wiki/Signed_zero, "Comparisons". */ 
 304             len 
= snprintf(buf
,len
,"-0"); 
 306             len 
= snprintf(buf
,len
,"0"); 
 308 #if (DBL_MANT_DIG >= 52) && (LLONG_MAX == 0x7fffffffffffffffLL) 
 309         /* Check if the float is in a safe range to be casted into a 
 310          * long long. We are assuming that long long is 64 bit here. 
 311          * Also we are assuming that there are no implementations around where 
 312          * double has precision < 52 bit. 
 314          * Under this assumptions we test if a double is inside an interval 
 315          * where casting to long long is safe. Then using two castings we 
 316          * make sure the decimal part is zero. If all this is true we use 
 317          * integer printing function that is much faster. */ 
 318         double min 
= -4503599627370495; /* (2^52)-1 */ 
 319         double max 
= 4503599627370496; /* -(2^52) */ 
 320         if (val 
> min 
&& val 
< max 
&& value 
== ((double)((long long)value
))) 
 321             len 
= ll2string(buf
,len
,(long long)value
); 
 324             len 
= snprintf(buf
,len
,"%.17g",value
); 
 330 #ifdef UTIL_TEST_MAIN 
 333 void test_string2ll(void) { 
 337     /* May not start with +. */ 
 339     assert(string2ll(buf
,strlen(buf
),&v
) == 0); 
 343     assert(string2ll(buf
,strlen(buf
),&v
) == 0); 
 345     /* Trailing space. */ 
 347     assert(string2ll(buf
,strlen(buf
),&v
) == 0); 
 349     /* May not start with 0. */ 
 351     assert(string2ll(buf
,strlen(buf
),&v
) == 0); 
 354     assert(string2ll(buf
,strlen(buf
),&v
) == 1); 
 358     assert(string2ll(buf
,strlen(buf
),&v
) == 1); 
 362     assert(string2ll(buf
,strlen(buf
),&v
) == 1); 
 366     assert(string2ll(buf
,strlen(buf
),&v
) == 1); 
 370     assert(string2ll(buf
,strlen(buf
),&v
) == 1); 
 373     strcpy(buf
,"-9223372036854775808"); 
 374     assert(string2ll(buf
,strlen(buf
),&v
) == 1); 
 375     assert(v 
== LLONG_MIN
); 
 377     strcpy(buf
,"-9223372036854775809"); /* overflow */ 
 378     assert(string2ll(buf
,strlen(buf
),&v
) == 0); 
 380     strcpy(buf
,"9223372036854775807"); 
 381     assert(string2ll(buf
,strlen(buf
),&v
) == 1); 
 382     assert(v 
== LLONG_MAX
); 
 384     strcpy(buf
,"9223372036854775808"); /* overflow */ 
 385     assert(string2ll(buf
,strlen(buf
),&v
) == 0); 
 388 void test_string2l(void) { 
 392     /* May not start with +. */ 
 394     assert(string2l(buf
,strlen(buf
),&v
) == 0); 
 396     /* May not start with 0. */ 
 398     assert(string2l(buf
,strlen(buf
),&v
) == 0); 
 401     assert(string2l(buf
,strlen(buf
),&v
) == 1); 
 405     assert(string2l(buf
,strlen(buf
),&v
) == 1); 
 409     assert(string2l(buf
,strlen(buf
),&v
) == 1); 
 413     assert(string2l(buf
,strlen(buf
),&v
) == 1); 
 417     assert(string2l(buf
,strlen(buf
),&v
) == 1); 
 420 #if LONG_MAX != LLONG_MAX 
 421     strcpy(buf
,"-2147483648"); 
 422     assert(string2l(buf
,strlen(buf
),&v
) == 1); 
 423     assert(v 
== LONG_MIN
); 
 425     strcpy(buf
,"-2147483649"); /* overflow */ 
 426     assert(string2l(buf
,strlen(buf
),&v
) == 0); 
 428     strcpy(buf
,"2147483647"); 
 429     assert(string2l(buf
,strlen(buf
),&v
) == 1); 
 430     assert(v 
== LONG_MAX
); 
 432     strcpy(buf
,"2147483648"); /* overflow */ 
 433     assert(string2l(buf
,strlen(buf
),&v
) == 0); 
 437 int main(int argc
, char **argv
) {