]>
git.saurik.com Git - redis.git/blob - src/util.c
5 /* Glob-style pattern matching. */
6 int stringmatchlen(const char *pattern
, int patternLen
,
7 const char *string
, int stringLen
, int nocase
)
12 while (pattern
[1] == '*') {
19 if (stringmatchlen(pattern
+1, patternLen
-1,
20 string
, stringLen
, nocase
))
25 return 0; /* no match */
29 return 0; /* no match */
39 not = pattern
[0] == '^';
46 if (pattern
[0] == '\\') {
49 if (pattern
[0] == string
[0])
51 } else if (pattern
[0] == ']') {
53 } else if (patternLen
== 0) {
57 } else if (pattern
[1] == '-' && patternLen
>= 3) {
58 int start
= pattern
[0];
67 start
= tolower(start
);
73 if (c
>= start
&& c
<= end
)
77 if (pattern
[0] == string
[0])
80 if (tolower((int)pattern
[0]) == tolower((int)string
[0]))
90 return 0; /* no match */
96 if (patternLen
>= 2) {
103 if (pattern
[0] != string
[0])
104 return 0; /* no match */
106 if (tolower((int)pattern
[0]) != tolower((int)string
[0]))
107 return 0; /* no match */
115 if (stringLen
== 0) {
116 while(*pattern
== '*') {
123 if (patternLen
== 0 && stringLen
== 0)
128 int stringmatch(const char *pattern
, const char *string
, int nocase
) {
129 return stringmatchlen(pattern
,strlen(pattern
),string
,strlen(string
),nocase
);
132 /* Convert a string representing an amount of memory into the number of
133 * bytes, so for instance memtoll("1Gi") will return 1073741824 that is
136 * On parsing error, if *err is not NULL, it's set to 1, otherwise it's
138 long long memtoll(const char *p
, int *err
) {
141 long mul
; /* unit multiplier */
146 /* Search the first non digit character. */
149 while(*u
&& isdigit(*u
)) u
++;
150 if (*u
== '\0' || !strcasecmp(u
,"b")) {
152 } else if (!strcasecmp(u
,"k")) {
154 } else if (!strcasecmp(u
,"kb")) {
156 } else if (!strcasecmp(u
,"m")) {
158 } else if (!strcasecmp(u
,"mb")) {
160 } else if (!strcasecmp(u
,"g")) {
161 mul
= 1000L*1000*1000;
162 } else if (!strcasecmp(u
,"gb")) {
163 mul
= 1024L*1024*1024;
169 if (digits
>= sizeof(buf
)) {
173 memcpy(buf
,p
,digits
);
175 val
= strtoll(buf
,NULL
,10);
179 /* Convert a long long into a string. Returns the number of
180 * characters needed to represent the number, that can be shorter if passed
181 * buffer length is not enough to store the whole number. */
182 int ll2string(char *s
, size_t len
, long long value
) {
184 unsigned long long v
;
187 if (len
== 0) return 0;
188 v
= (value
< 0) ? -value
: value
;
189 p
= buf
+31; /* point to the last character */
194 if (value
< 0) *p
-- = '-';
197 if (l
+1 > len
) l
= len
-1; /* Make sure it fits, including the nul term */
203 /* Check if the sds string 's' can be represented by a long long
204 * (that is, is a number that fits into long without any other space or
205 * character before or after the digits, so that converting this number
206 * back to a string will result in the same bytes as the original string).
208 * If so, the function returns REDIS_OK and *llongval is set to the value
209 * of the number. Otherwise REDIS_ERR is returned */
210 int isStringRepresentableAsLongLong(sds s
, long long *llongval
) {
211 char buf
[32], *endptr
;
215 value
= strtoll(s
, &endptr
, 10);
216 if (endptr
[0] != '\0') return REDIS_ERR
;
217 slen
= ll2string(buf
,32,value
);
219 /* If the number converted back into a string is not identical
220 * then it's not possible to encode the string as integer */
221 if (sdslen(s
) != (unsigned)slen
|| memcmp(buf
,s
,slen
)) return REDIS_ERR
;
222 if (llongval
) *llongval
= value
;
226 int isStringRepresentableAsLong(sds s
, long *longval
) {
229 if (isStringRepresentableAsLongLong(s
,&ll
) == REDIS_ERR
) return REDIS_ERR
;
230 if (ll
< LONG_MIN
|| ll
> LONG_MAX
) return REDIS_ERR
;
235 int isObjectRepresentableAsLongLong(robj
*o
, long long *llongval
) {
236 redisAssert(o
->type
== REDIS_STRING
);
237 if (o
->encoding
== REDIS_ENCODING_INT
) {
238 if (llongval
) *llongval
= (long) o
->ptr
;
241 return isStringRepresentableAsLongLong(o
->ptr
,llongval
);