1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "util.h"
2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "linux/string.h"
3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define K 1024LL
5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * perf_atoll()
7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Parse (\d+)(b|B|kb|KB|mb|MB|gb|GB|tb|TB) (e.g. "256MB")
8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * and return its numeric value
9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengs64 perf_atoll(const char *str)
11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	unsigned int i;
13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	s64 length = -1, unit = 1;
14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!isdigit(str[0]))
16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out_err;
17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 1; i < strlen(str); i++) {
19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		switch (str[i]) {
20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case 'B':
21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case 'b':
22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case 'K':
24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (str[i + 1] != 'B')
25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_err;
26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto kilo;
28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case 'k':
29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (str[i + 1] != 'b')
30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_err;
31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengkilo:
32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			unit = K;
33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case 'M':
35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (str[i + 1] != 'B')
36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_err;
37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto mega;
39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case 'm':
40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (str[i + 1] != 'b')
41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_err;
42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengmega:
43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			unit = K * K;
44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case 'G':
46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (str[i + 1] != 'B')
47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_err;
48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto giga;
50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case 'g':
51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (str[i + 1] != 'b')
52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_err;
53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chenggiga:
54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			unit = K * K * K;
55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case 'T':
57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (str[i + 1] != 'B')
58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_err;
59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			else
60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto tera;
61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case 't':
62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (str[i + 1] != 'b')
63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_err;
64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtera:
65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			unit = K * K * K * K;
66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		case '\0':	/* only specified figures */
68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			unit = 1;
69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		default:
71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (!isdigit(str[i]))
72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto out_err;
73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	length = atoll(str) * unit;
78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	goto out;
79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout_err:
81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	length = -1;
82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout:
83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return length;
84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Helper function for splitting a string into an argv-like array.
88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * originally copied from lib/argv_split.c
89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic const char *skip_sep(const char *cp)
91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (*cp && isspace(*cp))
93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		cp++;
94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return cp;
96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic const char *skip_arg(const char *cp)
99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (*cp && !isspace(*cp))
101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		cp++;
102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return cp;
104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int count_argc(const char *str)
107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int count = 0;
109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (*str) {
111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		str = skip_sep(str);
112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (*str) {
113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			count++;
114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			str = skip_arg(str);
115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return count;
119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * argv_free - free an argv
123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @argv - the argument vector to be freed
124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Frees an argv and the strings it points to.
126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid argv_free(char **argv)
128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char **p;
130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (p = argv; *p; p++)
131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(*p);
132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	free(argv);
134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * argv_split - split a string at whitespace, returning an argv
138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @str: the string to be split
139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @argcp: returned argument count
140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Returns an array of pointers to strings which are split out from
142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @str.  This is performed by strictly splitting on white-space; no
143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * quote processing is performed.  Multiple whitespace characters are
144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * considered to be a single argument separator.  The returned array
145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * is always NULL-terminated.  Returns NULL on memory allocation
146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * failure.
147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengchar **argv_split(const char *str, int *argcp)
149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int argc = count_argc(str);
151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char **argv = zalloc(sizeof(*argv) * (argc+1));
152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char **argvp;
153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (argv == NULL)
155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (argcp)
158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*argcp = argc;
159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	argvp = argv;
161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (*str) {
163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		str = skip_sep(str);
164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (*str) {
166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			const char *p = str;
167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			char *t;
168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			str = skip_arg(str);
170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			t = strndup(p, str-p);
172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (t == NULL)
173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto fail;
174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			*argvp++ = t;
175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*argvp = NULL;
178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout:
180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return argv;
181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengfail:
183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	argv_free(argv);
184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return NULL;
185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* Character class matching */
188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic bool __match_charclass(const char *pat, char c, const char **npat)
189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	bool complement = false, ret = true;
191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (*pat == '!') {
193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		complement = true;
194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pat++;
195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (*pat++ == c)	/* First character is special */
197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto end;
198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (*pat && *pat != ']') {	/* Matching */
200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (*pat == '-' && *(pat + 1) != ']') {	/* Range */
201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (*(pat - 1) <= c && c <= *(pat + 1))
202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto end;
203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (*(pat - 1) > *(pat + 1))
204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				goto error;
205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pat += 2;
206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else if (*pat++ == c)
207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto end;
208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!*pat)
210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto error;
211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ret = false;
212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengend:
214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (*pat && *pat != ']')	/* Searching closing */
215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		pat++;
216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!*pat)
217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto error;
218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*npat = pat + 1;
219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return complement ? !ret : ret;
220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengerror:
222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return false;
223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* Glob/lazy pattern matching */
226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic bool __match_glob(const char *str, const char *pat, bool ignore_space)
227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (*str && *pat && *pat != '*') {
229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (ignore_space) {
230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			/* Ignore spaces for lazy matching */
231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (isspace(*str)) {
232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				str++;
233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				continue;
234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (isspace(*pat)) {
236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				pat++;
237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				continue;
238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			}
239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (*pat == '?') {	/* Matches any single character */
241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			str++;
242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pat++;
243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			continue;
244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		} else if (*pat == '[')	/* Character classes/Ranges */
245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (__match_charclass(pat + 1, *str, &pat)) {
246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				str++;
247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				continue;
248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			} else
249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				return false;
250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		else if (*pat == '\\') /* Escaped char match as normal char */
251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pat++;
252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (*str++ != *pat++)
253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return false;
254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Check wild card */
256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (*pat == '*') {
257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		while (*pat == '*')
258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			pat++;
259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!*pat)	/* Tail wild card matches all */
260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return true;
261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		while (*str)
262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			if (__match_glob(str++, pat, ignore_space))
263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				return true;
264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return !*str && !*pat;
266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * strglobmatch - glob expression pattern matching
270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @str: the target string to match
271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pat: the pattern string to match
272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This returns true if the @str matches @pat. @pat can includes wildcards
274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ('*','?') and character classes ([CHARS], complementation and ranges are
275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * also supported). Also, this supports escape character ('\') to use special
276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * characters as normal character.
277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Note: if @pat syntax is broken, this always returns false.
279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool strglobmatch(const char *str, const char *pat)
281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __match_glob(str, pat, false);
283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * strlazymatch - matching pattern strings lazily with glob pattern
287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @str: the target string to match
288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @pat: the pattern string to match
289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This is similar to strglobmatch, except this ignores spaces in
291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * the target string.
292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengbool strlazymatch(const char *str, const char *pat)
294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return __match_glob(str, pat, true);
296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * strtailcmp - Compare the tail of two strings
300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s1: 1st string to be compared
301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s2: 2nd string to be compared
302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Return 0 if whole of either string is same as another's tail part.
304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint strtailcmp(const char *s1, const char *s2)
306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i1 = strlen(s1);
308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i2 = strlen(s2);
309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (--i1 >= 0 && --i2 >= 0) {
310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (s1[i1] != s2[i2])
311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return s1[i1] - s2[i2];
312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * strxfrchar - Locate and replace character in @s
318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s:    The string to be searched/changed.
319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @from: Source character to be replaced.
320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @to:   Destination character.
321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Return pointer to the changed string.
323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengchar *strxfrchar(char *s, char from, char to)
325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *p = s;
327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while ((p = strchr(p, from)) != NULL)
329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*p++ = to;
330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return s;
332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ltrim - Removes leading whitespace from @s.
336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: The string to be stripped.
337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Return pointer to the first non-whitespace character in @s.
339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengchar *ltrim(char *s)
341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int len = strlen(s);
343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (len && isspace(*s)) {
345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		len--;
346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		s++;
347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return s;
350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * rtrim - Removes trailing whitespace from @s.
354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: The string to be stripped.
355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng *
356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Note that the first trailing whitespace is replaced with a %NUL-terminator
357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * in the given string @s. Returns @s.
358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengchar *rtrim(char *s)
360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	size_t size = strlen(s);
362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *end;
363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!size)
365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return s;
366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	end = s + size - 1;
368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	while (end >= s && isspace(*end))
369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		end--;
370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	*(end + 1) = '\0';
371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return s;
373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * memdup - duplicate region of memory
377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @src: memory region to duplicate
378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @len: memory region length
379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid *memdup(const void *src, size_t len)
381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	void *p;
383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	p = malloc(len);
385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (p)
386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		memcpy(p, src, len);
387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return p;
389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/**
392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * str_append - reallocate string and append another
393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: pointer to string pointer
394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @len: pointer to len (initialized)
395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @a: string to append.
396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint str_append(char **s, int *len, const char *a)
398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int olen = *s ? strlen(*s) : 0;
400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int nlen = olen + strlen(a) + 1;
401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (*len < nlen) {
402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*len = *len * 2;
403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (*len < nlen)
404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			*len = nlen;
405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		*s = realloc(*s, *len);
406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (!*s)
407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return -ENOMEM;
408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (olen == 0)
409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			**s = 0;
410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	strcat(*s, a);
412e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
413e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
414