xref: /dpdk/app/test-eventdev/parser.c (revision 2df20a1d345a5fc0a1b6dc0317d11fc7b1fda7e7)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2016 Intel Corporation.
3  * Copyright(c) 2017 Cavium, Inc.
4  */
5 
6 #include <stdint.h>
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <ctype.h>
10 #include <getopt.h>
11 #include <errno.h>
12 #include <stdarg.h>
13 #include <string.h>
14 #include <libgen.h>
15 #include <unistd.h>
16 #include <sys/wait.h>
17 #include <stdbool.h>
18 
19 #include <rte_errno.h>
20 #include <rte_string_fns.h>
21 
22 #include "parser.h"
23 
24 static uint32_t
get_hex_val(char c)25 get_hex_val(char c)
26 {
27 	switch (c) {
28 	case '0': case '1': case '2': case '3': case '4': case '5':
29 	case '6': case '7': case '8': case '9':
30 		return c - '0';
31 	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
32 		return c - 'A' + 10;
33 	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
34 		return c - 'a' + 10;
35 	default:
36 		return 0;
37 	}
38 }
39 
40 int
parser_read_arg_bool(const char * p)41 parser_read_arg_bool(const char *p)
42 {
43 	p = rte_str_skip_leading_spaces(p);
44 	int result = -EINVAL;
45 
46 	if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
47 		((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
48 		p += 3;
49 		result = 1;
50 	}
51 
52 	if (((p[0] == 'o') && (p[1] == 'n')) ||
53 		((p[0] == 'O') && (p[1] == 'N'))) {
54 		p += 2;
55 		result = 1;
56 	}
57 
58 	if (((p[0] == 'n') && (p[1] == 'o')) ||
59 		((p[0] == 'N') && (p[1] == 'O'))) {
60 		p += 2;
61 		result = 0;
62 	}
63 
64 	if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
65 		((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
66 		p += 3;
67 		result = 0;
68 	}
69 
70 	p = rte_str_skip_leading_spaces(p);
71 
72 	if (p[0] != '\0')
73 		return -EINVAL;
74 
75 	return result;
76 }
77 
78 int
parser_read_uint64(uint64_t * value,const char * p)79 parser_read_uint64(uint64_t *value, const char *p)
80 {
81 	char *next;
82 	uint64_t val;
83 
84 	p = rte_str_skip_leading_spaces(p);
85 	if (!isdigit(*p))
86 		return -EINVAL;
87 
88 	val = strtoul(p, &next, 10);
89 	if (p == next)
90 		return -EINVAL;
91 
92 	p = next;
93 	switch (*p) {
94 	case 'T':
95 		val *= 1024ULL;
96 		/* fall through */
97 	case 'G':
98 		val *= 1024ULL;
99 		/* fall through */
100 	case 'M':
101 		val *= 1024ULL;
102 		/* fall through */
103 	case 'k':
104 	case 'K':
105 		val *= 1024ULL;
106 		p++;
107 		break;
108 	}
109 
110 	p = rte_str_skip_leading_spaces(p);
111 	if (*p != '\0')
112 		return -EINVAL;
113 
114 	*value = val;
115 	return 0;
116 }
117 
118 int
parser_read_int32(int32_t * value,const char * p)119 parser_read_int32(int32_t *value, const char *p)
120 {
121 	char *next;
122 	int32_t val;
123 
124 	p = rte_str_skip_leading_spaces(p);
125 	if (!isdigit(*p))
126 		return -EINVAL;
127 
128 	val = strtol(p, &next, 10);
129 	if (p == next)
130 		return -EINVAL;
131 
132 	*value = val;
133 	return 0;
134 }
135 
136 int
parser_read_uint64_hex(uint64_t * value,const char * p)137 parser_read_uint64_hex(uint64_t *value, const char *p)
138 {
139 	char *next;
140 	uint64_t val;
141 
142 	p = rte_str_skip_leading_spaces(p);
143 
144 	val = strtoul(p, &next, 16);
145 	if (p == next)
146 		return -EINVAL;
147 
148 	p = rte_str_skip_leading_spaces(next);
149 	if (*p != '\0')
150 		return -EINVAL;
151 
152 	*value = val;
153 	return 0;
154 }
155 
156 int
parser_read_uint32(uint32_t * value,const char * p)157 parser_read_uint32(uint32_t *value, const char *p)
158 {
159 	uint64_t val = 0;
160 	int ret = parser_read_uint64(&val, p);
161 
162 	if (ret < 0)
163 		return ret;
164 
165 	if (val > UINT32_MAX)
166 		return -ERANGE;
167 
168 	*value = val;
169 	return 0;
170 }
171 
172 int
parser_read_uint32_hex(uint32_t * value,const char * p)173 parser_read_uint32_hex(uint32_t *value, const char *p)
174 {
175 	uint64_t val = 0;
176 	int ret = parser_read_uint64_hex(&val, p);
177 
178 	if (ret < 0)
179 		return ret;
180 
181 	if (val > UINT32_MAX)
182 		return -ERANGE;
183 
184 	*value = val;
185 	return 0;
186 }
187 
188 int
parser_read_uint16(uint16_t * value,const char * p)189 parser_read_uint16(uint16_t *value, const char *p)
190 {
191 	uint64_t val = 0;
192 	int ret = parser_read_uint64(&val, p);
193 
194 	if (ret < 0)
195 		return ret;
196 
197 	if (val > UINT16_MAX)
198 		return -ERANGE;
199 
200 	*value = val;
201 	return 0;
202 }
203 
204 int
parser_read_uint16_hex(uint16_t * value,const char * p)205 parser_read_uint16_hex(uint16_t *value, const char *p)
206 {
207 	uint64_t val = 0;
208 	int ret = parser_read_uint64_hex(&val, p);
209 
210 	if (ret < 0)
211 		return ret;
212 
213 	if (val > UINT16_MAX)
214 		return -ERANGE;
215 
216 	*value = val;
217 	return 0;
218 }
219 
220 int
parser_read_uint8(uint8_t * value,const char * p)221 parser_read_uint8(uint8_t *value, const char *p)
222 {
223 	uint64_t val = 0;
224 	int ret = parser_read_uint64(&val, p);
225 
226 	if (ret < 0)
227 		return ret;
228 
229 	if (val > UINT8_MAX)
230 		return -ERANGE;
231 
232 	*value = val;
233 	return 0;
234 }
235 
236 int
parser_read_uint8_hex(uint8_t * value,const char * p)237 parser_read_uint8_hex(uint8_t *value, const char *p)
238 {
239 	uint64_t val = 0;
240 	int ret = parser_read_uint64_hex(&val, p);
241 
242 	if (ret < 0)
243 		return ret;
244 
245 	if (val > UINT8_MAX)
246 		return -ERANGE;
247 
248 	*value = val;
249 	return 0;
250 }
251 
252 int
parse_tokenize_string(char * string,char * tokens[],uint32_t * n_tokens)253 parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
254 {
255 	uint32_t i;
256 
257 	if ((string == NULL) ||
258 		(tokens == NULL) ||
259 		(*n_tokens < 1))
260 		return -EINVAL;
261 
262 	for (i = 0; i < *n_tokens; i++) {
263 		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
264 		if (tokens[i] == NULL)
265 			break;
266 	}
267 
268 	if ((i == *n_tokens) &&
269 		(strtok_r(string, PARSE_DELIMITER, &string) != NULL))
270 		return -E2BIG;
271 
272 	*n_tokens = i;
273 	return 0;
274 }
275 
276 int
parse_hex_string(const char * src,uint8_t * dst,uint32_t * size)277 parse_hex_string(const char *src, uint8_t *dst, uint32_t *size)
278 {
279 	uint32_t len, i;
280 	const char *c;
281 
282 	/* Check input parameters */
283 	if ((src == NULL) ||
284 		(dst == NULL) ||
285 		(size == NULL) ||
286 		(*size == 0))
287 		return -1;
288 
289 	len = strlen(src);
290 	if (((len & 3) != 0) ||
291 		(len > (*size) * 2))
292 		return -1;
293 	*size = len / 2;
294 
295 	for (c = src; *c != 0; c++) {
296 		if ((((*c) >= '0') && ((*c) <= '9')) ||
297 			(((*c) >= 'A') && ((*c) <= 'F')) ||
298 			(((*c) >= 'a') && ((*c) <= 'f')))
299 			continue;
300 
301 		return -1;
302 	}
303 
304 	/* Convert chars to bytes */
305 	for (i = 0; i < *size; i++)
306 		dst[i] = get_hex_val(src[2 * i]) * 16 +
307 			get_hex_val(src[2 * i + 1]);
308 
309 	return 0;
310 }
311 
312 int
parse_lcores_list(bool lcores[],int lcores_num,const char * corelist)313 parse_lcores_list(bool lcores[], int lcores_num, const char *corelist)
314 {
315 	int i, idx = 0;
316 	int min, max;
317 	char *end = NULL;
318 
319 	if (corelist == NULL)
320 		return -1;
321 	while (isblank(*corelist))
322 		corelist++;
323 	i = strlen(corelist);
324 	while ((i > 0) && isblank(corelist[i - 1]))
325 		i--;
326 
327 	/* Get list of lcores */
328 	min = RTE_MAX_LCORE;
329 	do {
330 		while (isblank(*corelist))
331 			corelist++;
332 		if (*corelist == '\0')
333 			return -1;
334 		idx = strtoul(corelist, &end, 10);
335 		if (idx < 0 || idx > lcores_num)
336 			return -1;
337 
338 		if (end == NULL)
339 			return -1;
340 		while (isblank(*end))
341 			end++;
342 		if (*end == '-') {
343 			min = idx;
344 		} else if ((*end == ',') || (*end == '\0')) {
345 			max = idx;
346 			if (min == RTE_MAX_LCORE)
347 				min = idx;
348 			for (idx = min; idx <= max; idx++) {
349 				if (lcores[idx] == 1)
350 					return -E2BIG;
351 				lcores[idx] = 1;
352 			}
353 
354 			min = RTE_MAX_LCORE;
355 		} else
356 			return -1;
357 		corelist = end + 1;
358 	} while (*end != '\0');
359 
360 	return 0;
361 }
362