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