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