]>
git.saurik.com Git - redis.git/blob - src/util.c
13 /* Glob-style pattern matching. */
14 int stringmatchlen(const char *pattern
, int patternLen
,
15 const char *string
, int stringLen
, int nocase
)
20 while (pattern
[1] == '*') {
27 if (stringmatchlen(pattern
+1, patternLen
-1,
28 string
, stringLen
, nocase
))
33 return 0; /* no match */
37 return 0; /* no match */
47 not = pattern
[0] == '^';
54 if (pattern
[0] == '\\') {
57 if (pattern
[0] == string
[0])
59 } else if (pattern
[0] == ']') {
61 } else if (patternLen
== 0) {
65 } else if (pattern
[1] == '-' && patternLen
>= 3) {
66 int start
= pattern
[0];
75 start
= tolower(start
);
81 if (c
>= start
&& c
<= end
)
85 if (pattern
[0] == string
[0])
88 if (tolower((int)pattern
[0]) == tolower((int)string
[0]))
98 return 0; /* no match */
104 if (patternLen
>= 2) {
111 if (pattern
[0] != string
[0])
112 return 0; /* no match */
114 if (tolower((int)pattern
[0]) != tolower((int)string
[0]))
115 return 0; /* no match */
123 if (stringLen
== 0) {
124 while(*pattern
== '*') {
131 if (patternLen
== 0 && stringLen
== 0)
136 int stringmatch(const char *pattern
, const char *string
, int nocase
) {
137 return stringmatchlen(pattern
,strlen(pattern
),string
,strlen(string
),nocase
);
140 /* Convert a string representing an amount of memory into the number of
141 * bytes, so for instance memtoll("1Gi") will return 1073741824 that is
144 * On parsing error, if *err is not NULL, it's set to 1, otherwise it's
146 long long memtoll(const char *p
, int *err
) {
149 long mul
; /* unit multiplier */
154 /* Search the first non digit character. */
157 while(*u
&& isdigit(*u
)) u
++;
158 if (*u
== '\0' || !strcasecmp(u
,"b")) {
160 } else if (!strcasecmp(u
,"k")) {
162 } else if (!strcasecmp(u
,"kb")) {
164 } else if (!strcasecmp(u
,"m")) {
166 } else if (!strcasecmp(u
,"mb")) {
168 } else if (!strcasecmp(u
,"g")) {
169 mul
= 1000L*1000*1000;
170 } else if (!strcasecmp(u
,"gb")) {
171 mul
= 1024L*1024*1024;
177 if (digits
>= sizeof(buf
)) {
181 memcpy(buf
,p
,digits
);
183 val
= strtoll(buf
,NULL
,10);
187 /* Convert a long long into a string. Returns the number of
188 * characters needed to represent the number, that can be shorter if passed
189 * buffer length is not enough to store the whole number. */
190 int ll2string(char *s
, size_t len
, long long value
) {
192 unsigned long long v
;
195 if (len
== 0) return 0;
196 v
= (value
< 0) ? -value
: value
;
197 p
= buf
+31; /* point to the last character */
202 if (value
< 0) *p
-- = '-';
205 if (l
+1 > len
) l
= len
-1; /* Make sure it fits, including the nul term */
211 /* Convert a string into a long long. Returns 1 if the string could be parsed
212 * into a (non-overflowing) long long, 0 otherwise. The value will be set to
213 * the parsed value when appropriate. */
214 int string2ll(const char *s
, size_t slen
, long long *value
) {
218 unsigned long long v
;
223 /* Special case: first and only digit is 0. */
224 if (slen
== 1 && p
[0] == '0') {
225 if (value
!= NULL
) *value
= 0;
233 /* Abort on only a negative sign. */
238 /* First digit should be 1-9, otherwise the string should just be 0. */
239 if (p
[0] >= '1' && p
[0] <= '9') {
242 } else if (p
[0] == '0' && slen
== 1) {
249 while (plen
< slen
&& p
[0] >= '0' && p
[0] <= '9') {
250 if (v
> (ULLONG_MAX
/ 10)) /* Overflow. */
254 if (v
> (ULLONG_MAX
- (p
[0]-'0'))) /* Overflow. */
261 /* Return if not all bytes were used. */
266 if (v
> ((unsigned long long)(-(LLONG_MIN
+1))+1)) /* Overflow. */
268 if (value
!= NULL
) *value
= -v
;
270 if (v
> LLONG_MAX
) /* Overflow. */
272 if (value
!= NULL
) *value
= v
;
277 /* Convert a string into a long. Returns 1 if the string could be parsed into a
278 * (non-overflowing) long, 0 otherwise. The value will be set to the parsed
279 * value when appropriate. */
280 int string2l(const char *s
, size_t slen
, long *lval
) {
283 if (!string2ll(s
,slen
,&llval
))
286 if (llval
< LONG_MIN
|| llval
> LONG_MAX
)
293 /* Convert a double to a string representation. Returns the number of bytes
294 * required. The representation should always be parsable by stdtod(3). */
295 int d2string(char *buf
, size_t len
, double value
) {
297 len
= snprintf(buf
,len
,"nan");
298 } else if (isinf(value
)) {
300 len
= snprintf(buf
,len
,"-inf");
302 len
= snprintf(buf
,len
,"inf");
303 } else if (value
== 0) {
304 /* See: http://en.wikipedia.org/wiki/Signed_zero, "Comparisons". */
306 len
= snprintf(buf
,len
,"-0");
308 len
= snprintf(buf
,len
,"0");
310 #if (DBL_MANT_DIG >= 52) && (LLONG_MAX == 0x7fffffffffffffffLL)
311 /* Check if the float is in a safe range to be casted into a
312 * long long. We are assuming that long long is 64 bit here.
313 * Also we are assuming that there are no implementations around where
314 * double has precision < 52 bit.
316 * Under this assumptions we test if a double is inside an interval
317 * where casting to long long is safe. Then using two castings we
318 * make sure the decimal part is zero. If all this is true we use
319 * integer printing function that is much faster. */
320 double min
= -4503599627370495; /* (2^52)-1 */
321 double max
= 4503599627370496; /* -(2^52) */
322 if (val
> min
&& val
< max
&& value
== ((double)((long long)value
)))
323 len
= ll2string(buf
,len
,(long long)value
);
326 len
= snprintf(buf
,len
,"%.17g",value
);
332 /* Generate the Redis "Run ID", a SHA1-sized random number that identifies a
333 * given execution of Redis, so that if you are talking with an instance
334 * having run_id == A, and you reconnect and it has run_id == B, you can be
335 * sure that it is either a different instance or it was restarted. */
336 void getRandomHexChars(char *p
, unsigned int len
) {
337 FILE *fp
= fopen("/dev/urandom","r");
338 char *charset
= "0123456789abcdef";
341 if (fp
== NULL
|| fread(p
,len
,1,fp
) == 0) {
342 /* If we can't read from /dev/urandom, do some reasonable effort
343 * in order to create some entropy, since this function is used to
344 * generate run_id and cluster instance IDs */
346 unsigned int l
= len
;
348 pid_t pid
= getpid();
350 /* Use time and PID to fill the initial array. */
351 gettimeofday(&tv
,NULL
);
352 if (l
>= sizeof(tv
.tv_usec
)) {
353 memcpy(x
,&tv
.tv_usec
,sizeof(tv
.tv_usec
));
354 l
-= sizeof(tv
.tv_usec
);
355 x
+= sizeof(tv
.tv_usec
);
357 if (l
>= sizeof(tv
.tv_sec
)) {
358 memcpy(x
,&tv
.tv_sec
,sizeof(tv
.tv_sec
));
359 l
-= sizeof(tv
.tv_sec
);
360 x
+= sizeof(tv
.tv_sec
);
362 if (l
>= sizeof(pid
)) {
363 memcpy(x
,&pid
,sizeof(pid
));
367 /* Finally xor it with rand() output, that was already seeded with
368 * time() at startup. */
369 for (j
= 0; j
< len
; j
++)
372 /* Turn it into hex digits taking just 4 bits out of 8 for every byte. */
373 for (j
= 0; j
< len
; j
++)
374 p
[j
] = charset
[p
[j
] & 0x0F];
378 #ifdef UTIL_TEST_MAIN
381 void test_string2ll(void) {
385 /* May not start with +. */
387 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
391 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
393 /* Trailing space. */
395 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
397 /* May not start with 0. */
399 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
402 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
406 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
410 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
414 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
418 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
421 strcpy(buf
,"-9223372036854775808");
422 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
423 assert(v
== LLONG_MIN
);
425 strcpy(buf
,"-9223372036854775809"); /* overflow */
426 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
428 strcpy(buf
,"9223372036854775807");
429 assert(string2ll(buf
,strlen(buf
),&v
) == 1);
430 assert(v
== LLONG_MAX
);
432 strcpy(buf
,"9223372036854775808"); /* overflow */
433 assert(string2ll(buf
,strlen(buf
),&v
) == 0);
436 void test_string2l(void) {
440 /* May not start with +. */
442 assert(string2l(buf
,strlen(buf
),&v
) == 0);
444 /* May not start with 0. */
446 assert(string2l(buf
,strlen(buf
),&v
) == 0);
449 assert(string2l(buf
,strlen(buf
),&v
) == 1);
453 assert(string2l(buf
,strlen(buf
),&v
) == 1);
457 assert(string2l(buf
,strlen(buf
),&v
) == 1);
461 assert(string2l(buf
,strlen(buf
),&v
) == 1);
465 assert(string2l(buf
,strlen(buf
),&v
) == 1);
468 #if LONG_MAX != LLONG_MAX
469 strcpy(buf
,"-2147483648");
470 assert(string2l(buf
,strlen(buf
),&v
) == 1);
471 assert(v
== LONG_MIN
);
473 strcpy(buf
,"-2147483649"); /* overflow */
474 assert(string2l(buf
,strlen(buf
),&v
) == 0);
476 strcpy(buf
,"2147483647");
477 assert(string2l(buf
,strlen(buf
),&v
) == 1);
478 assert(v
== LONG_MAX
);
480 strcpy(buf
,"2147483648"); /* overflow */
481 assert(string2l(buf
,strlen(buf
),&v
) == 0);
485 int main(int argc
, char **argv
) {