7 * Parse (\d+)(b|B|kb|KB|mb|MB|gb|GB|tb|TB) (e.g. "256MB")
8 * and return its numeric value
10 s64
perf_atoll(const char *str
)
13 s64 length
= -1, unit
= 1;
18 for (i
= 1; i
< strlen(str
); i
++) {
24 if (str
[i
+ 1] != 'B')
29 if (str
[i
+ 1] != 'b')
35 if (str
[i
+ 1] != 'B')
40 if (str
[i
+ 1] != 'b')
46 if (str
[i
+ 1] != 'B')
51 if (str
[i
+ 1] != 'b')
57 if (str
[i
+ 1] != 'B')
62 if (str
[i
+ 1] != 'b')
67 case '\0': /* only specified figures */
77 length
= atoll(str
) * unit
;
87 * Helper function for splitting a string into an argv-like array.
88 * originally copied from lib/argv_split.c
90 static const char *skip_sep(const char *cp
)
92 while (*cp
&& isspace(*cp
))
98 static const char *skip_arg(const char *cp
)
100 while (*cp
&& !isspace(*cp
))
106 static int count_argc(const char *str
)
122 * argv_free - free an argv
123 * @argv - the argument vector to be freed
125 * Frees an argv and the strings it points to.
127 void argv_free(char **argv
)
130 for (p
= argv
; *p
; p
++)
137 * argv_split - split a string at whitespace, returning an argv
138 * @str: the string to be split
139 * @argcp: returned argument count
141 * Returns an array of pointers to strings which are split out from
142 * @str. This is performed by strictly splitting on white-space; no
143 * quote processing is performed. Multiple whitespace characters are
144 * considered to be a single argument separator. The returned array
145 * is always NULL-terminated. Returns NULL on memory allocation
148 char **argv_split(const char *str
, int *argcp
)
150 int argc
= count_argc(str
);
151 char **argv
= zalloc(sizeof(*argv
) * (argc
+1));
171 t
= strndup(p
, str
-p
);
187 /* Character class matching */
188 static bool __match_charclass(const char *pat
, char c
, const char **npat
)
190 bool complement
= false, ret
= true;
196 if (*pat
++ == c
) /* First character is special */
199 while (*pat
&& *pat
!= ']') { /* Matching */
200 if (*pat
== '-' && *(pat
+ 1) != ']') { /* Range */
201 if (*(pat
- 1) <= c
&& c
<= *(pat
+ 1))
203 if (*(pat
- 1) > *(pat
+ 1))
206 } else if (*pat
++ == c
)
214 while (*pat
&& *pat
!= ']') /* Searching closing */
219 return complement
? !ret
: ret
;
225 /* Glob/lazy pattern matching */
226 static bool __match_glob(const char *str
, const char *pat
, bool ignore_space
)
228 while (*str
&& *pat
&& *pat
!= '*') {
230 /* Ignore spaces for lazy matching */
240 if (*pat
== '?') { /* Matches any single character */
244 } else if (*pat
== '[') /* Character classes/Ranges */
245 if (__match_charclass(pat
+ 1, *str
, &pat
)) {
250 else if (*pat
== '\\') /* Escaped char match as normal char */
252 if (*str
++ != *pat
++)
255 /* Check wild card */
259 if (!*pat
) /* Tail wild card matches all */
262 if (__match_glob(str
++, pat
, ignore_space
))
265 return !*str
&& !*pat
;
269 * strglobmatch - glob expression pattern matching
270 * @str: the target string to match
271 * @pat: the pattern string to match
273 * This returns true if the @str matches @pat. @pat can includes wildcards
274 * ('*','?') and character classes ([CHARS], complementation and ranges are
275 * also supported). Also, this supports escape character ('\') to use special
276 * characters as normal character.
278 * Note: if @pat syntax is broken, this always returns false.
280 bool strglobmatch(const char *str
, const char *pat
)
282 return __match_glob(str
, pat
, false);
286 * strlazymatch - matching pattern strings lazily with glob pattern
287 * @str: the target string to match
288 * @pat: the pattern string to match
290 * This is similar to strglobmatch, except this ignores spaces in
293 bool strlazymatch(const char *str
, const char *pat
)
295 return __match_glob(str
, pat
, true);
299 * strtailcmp - Compare the tail of two strings
300 * @s1: 1st string to be compared
301 * @s2: 2nd string to be compared
303 * Return 0 if whole of either string is same as another's tail part.
305 int strtailcmp(const char *s1
, const char *s2
)
309 while (--i1
>= 0 && --i2
>= 0) {
310 if (s1
[i1
] != s2
[i2
])
311 return s1
[i1
] - s2
[i2
];