]>
git.saurik.com Git - redis.git/blob - src/util.c
14 /* Glob-style pattern matching. */
15 int stringmatchlen(const char *pattern
, int patternLen
,
16 const char *string
, int stringLen
, int nocase
)
21 while (pattern
[1] == '*') {
28 if (stringmatchlen(pattern
+1, patternLen
-1,
29 string
, stringLen
, nocase
))
34 return 0; /* no match */
38 return 0; /* no match */
48 not = pattern
[0] == '^';
55 if (pattern
[0] == '\\') {
58 if (pattern
[0] == string
[0])
60 } else if (pattern
[0] == ']') {
62 } else if (patternLen
== 0) {
66 } else if (pattern
[1] == '-' && patternLen
>= 3) {
67 int start
= pattern
[0];
76 start
= tolower(start
);
82 if (c
>= start
&& c
<= end
)
86 if (pattern
[0] == string
[0])
89 if (tolower((int)pattern
[0]) == tolower((int)string
[0]))
99 return 0; /* no match */
105 if (patternLen
>= 2) {
112 if (pattern
[0] != string
[0])
113 return 0; /* no match */
115 if (tolower((int)pattern
[0]) != tolower((int)string
[0]))
116 return 0; /* no match */
124 if (stringLen
== 0) {
125 while(*pattern
== '*') {
132 if (patternLen
== 0 && stringLen
== 0)
137 int stringmatch(const char *pattern
, const char *string
, int nocase
) {
138 return stringmatchlen(pattern
,strlen(pattern
),string
,strlen(string
),nocase
);
141 /* Convert a string representing an amount of memory into the number of
142 * bytes, so for instance memtoll("1Gi") will return 1073741824 that is
145 * On parsing error, if *err is not NULL, it's set to 1, otherwise it's
147 long long memtoll(const char *p
, int *err
) {
150 long mul
; /* unit multiplier */
155 /* Search the first non digit character. */
158 while(*u
&& isdigit(*u
)) u
++;
159 if (*u
== '\0' || !strcasecmp(u
,"b")) {
161 } else if (!strcasecmp(u
,"k")) {
163 } else if (!strcasecmp(u
,"kb")) {
165 } else if (!strcasecmp(u
,"m")) {
167 } else if (!strcasecmp(u
,"mb")) {
169 } else if (!strcasecmp(u
,"g")) {
170 mul
= 1000L*1000*1000;
171 } else if (!strcasecmp(u
,"gb")) {
172 mul
= 1024L*1024*1024;
178 if (digits
>= sizeof(buf
)) {
182 memcpy(buf
,p
,digits
);
184 val
= strtoll(buf
,NULL
,10);
188 /* Convert a long long into a string. Returns the number of
189 * characters needed to represent the number, that can be shorter if passed
190 * buffer length is not enough to store the whole number. */
191 int ll2string(char *s
, size_t len
, long long value
) {
193 unsigned long long v
;
196 if (len
== 0) return 0;
197 v
= (value
< 0) ? -value
: value
;
198 p
= buf
+31; /* point to the last character */
203 if (value
< 0) *p
-- = '-';
206 if (l
+1 > len
) l
= len
-1; /* Make sure it fits, including the nul term */
212 /* Convert a string into a long long. Returns 1 if the string could be parsed
213 * into a (non-overflowing) long long, 0 otherwise. The value will be set to
214 * the parsed value when appropriate. */
215 int string2ll(const char *s
, size_t slen
, long long *value
) {
219 unsigned long long v
;
224 /* Special case: first and only digit is 0. */
225 if (slen
== 1 && p
[0] == '0') {
226 if (value
!= NULL
) *value
= 0;
234 /* Abort on only a negative sign. */
239 /* First digit should be 1-9, otherwise the string should just be 0. */
240 if (p
[0] >= '1' && p
[0] <= '9') {
243 } else if (p
[0] == '0' && slen
== 1) {
250 while (plen
< slen
&& p
[0] >= '0' && p
[0] <= '9') {
251 if (v
> (ULLONG_MAX
/ 10)) /* Overflow. */
255 if (v
> (ULLONG_MAX
- (p
[0]-'0'))) /* Overflow. */
262 /* Return if not all bytes were used. */
267 if (v
> ((unsigned long long)(-(LLONG_MIN
+1))+1)) /* Overflow. */
269 if (value
!= NULL
) *value
= -v
;
271 if (v
> LLONG_MAX
) /* Overflow. */
273 if (value
!= NULL
) *value
= v
;
278 /* Convert a string into a long. Returns 1 if the string could be parsed into a
279 * (non-overflowing) long, 0 otherwise. The value will be set to the parsed
280 * value when appropriate. */
281 int string2l(const char *s
, size_t slen
, long *lval
) {
284 if (!string2ll(s
,slen
,&llval
))
287 if (llval
< LONG_MIN
|| llval
> LONG_MAX
)
294 /* Convert a double to a string representation. Returns the number of bytes
295 * required. The representation should always be parsable by stdtod(3). */
296 int d2string(char *buf
, size_t len
, double value
) {
298 len
= snprintf(buf
,len
,"nan");
299 } else if (isinf(value
)) {
301 len
= snprintf(buf
,len
,"-inf");
303 len
= snprintf(buf
,len
,"inf");
304 } else if (value
== 0) {
305 /* See: http://en.wikipedia.org/wiki/Signed_zero, "Comparisons". */
307 len
= snprintf(buf
,len
,"-0");
309 len
= snprintf(buf
,len
,"0");
311 #if (DBL_MANT_DIG >= 52) && (LLONG_MAX == 0x7fffffffffffffffLL)
312 /* Check if the float is in a safe range to be casted into a
313 * long long. We are assuming that long long is 64 bit here.
314 * Also we are assuming that there are no implementations around where
315 * double has precision < 52 bit.
317 * Under this assumptions we test if a double is inside an interval
318 * where casting to long long is safe. Then using two castings we
319 * make sure the decimal part is zero. If all this is true we use
320 * integer printing function that is much faster. */
321 double min
= -4503599627370495; /* (2^52)-1 */
322 double max
= 4503599627370496; /* -(2^52) */
323 if (value
> min
&& value
< max
&& value
== ((double)((long long)value
)))
324 len
= ll2string(buf
,len
,(long long)value
);
327 len
= snprintf(buf
,len
,"%.17g",value
);
333 /* Generate the Redis "Run ID", a SHA1-sized random number that identifies a
334 * given execution of Redis, so that if you are talking with an instance
335 * having run_id == A, and you reconnect and it has run_id == B, you can be
336 * sure that it is either a different instance or it was restarted. */
337 void getRandomHexChars(char *p
, unsigned int len
) {
338 FILE *fp
= fopen("/dev/urandom","r");
339 char *charset
= "0123456789abcdef";
342 if (fp
== NULL
|| fread(p
,len
,1,fp
) == 0) {
343 /* If we can't read from /dev/urandom, do some reasonable effort
344 * in order to create some entropy, since this function is used to
345 * generate run_id and cluster instance IDs */
347 unsigned int l
= len
;
349 pid_t pid
= getpid();
351 /* Use time and PID to fill the initial array. */
352 gettimeofday(&tv
,NULL
);
353 if (l
>= sizeof(tv
.tv_usec
)) {
354 memcpy(x
,&tv
.tv_usec
,sizeof(tv
.tv_usec
));
355 l
-= sizeof(tv
.tv_usec
);
356 x
+= sizeof(tv
.tv_usec
);
358 if (l
>= sizeof(tv
.tv_sec
)) {
359 memcpy(x
,&tv
.tv_sec
,sizeof(tv
.tv_sec
));
360 l
-= sizeof(tv
.tv_sec
);
361 x
+= sizeof(tv
.tv_sec
);
363 if (l
>= sizeof(pid
)) {
364 memcpy(x
,&pid
,sizeof(pid
));
368 /* Finally xor it with rand() output, that was already seeded with
369 * time() at startup. */
370 for (j
= 0; j
< len
; j
++)
373 /* Turn it into hex digits taking just 4 bits out of 8 for every byte. */
374 for (j
= 0; j
< len
; j
++)
375 p
[j
] = charset
[p
[j
] & 0x0F];
379 #ifdef UTIL_TEST_MAIN
382 void test_string2ll(void) {
386 /* May not start with +. */
388 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
392 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
394 /* Trailing space. */
396 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
398 /* May not start with 0. */
400 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
403 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
407 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
411 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
415 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
419 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
422 strcpy(buf
,"-9223372036854775808");
423 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
424 assert(v
== LLONG_MIN
);
426 strcpy(buf
,"-9223372036854775809"); /* overflow */
427 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
429 strcpy(buf
,"9223372036854775807");
430 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
431 assert(v
== LLONG_MAX
);
433 strcpy(buf
,"9223372036854775808"); /* overflow */
434 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
437 void test_string2l(void) {
441 /* May not start with +. */
443 assert(string2l(buf
,strlen(buf
),&v
) == 0);
445 /* May not start with 0. */
447 assert(string2l(buf
,strlen(buf
),&v
) == 0);
450 assert(string2l(buf
,strlen(buf
),&v
) == 1);
454 assert(string2l(buf
,strlen(buf
),&v
) == 1);
458 assert(string2l(buf
,strlen(buf
),&v
) == 1);
462 assert(string2l(buf
,strlen(buf
),&v
) == 1);
466 assert(string2l(buf
,strlen(buf
),&v
) == 1);
469 #if LONG_MAX != LLONG_MAX
470 strcpy(buf
,"-2147483648");
471 assert(string2l(buf
,strlen(buf
),&v
) == 1);
472 assert(v
== LONG_MIN
);
474 strcpy(buf
,"-2147483649"); /* overflow */
475 assert(string2l(buf
,strlen(buf
),&v
) == 0);
477 strcpy(buf
,"2147483647");
478 assert(string2l(buf
,strlen(buf
),&v
) == 1);
479 assert(v
== LONG_MAX
);
481 strcpy(buf
,"2147483648"); /* overflow */
482 assert(string2l(buf
,strlen(buf
),&v
) == 0);
486 int main(int argc
, char **argv
) {