xref: /f-stack/dpdk/app/test-eventdev/parser.c (revision 2bfe3f2e)
1*2bfe3f2eSlogwang /*-
2*2bfe3f2eSlogwang  *   BSD LICENSE
3*2bfe3f2eSlogwang  *
4*2bfe3f2eSlogwang  *   Copyright(c) 2016 Intel Corporation. All rights reserved.
5*2bfe3f2eSlogwang  *   Copyright(c) 2017 Cavium, Inc. All rights reserved.
6*2bfe3f2eSlogwang  *   All rights reserved.
7*2bfe3f2eSlogwang  *
8*2bfe3f2eSlogwang  *   Redistribution and use in source and binary forms, with or without
9*2bfe3f2eSlogwang  *   modification, are permitted provided that the following conditions
10*2bfe3f2eSlogwang  *   are met:
11*2bfe3f2eSlogwang  *
12*2bfe3f2eSlogwang  *     * Redistributions of source code must retain the above copyright
13*2bfe3f2eSlogwang  *       notice, this list of conditions and the following disclaimer.
14*2bfe3f2eSlogwang  *     * Redistributions in binary form must reproduce the above copyright
15*2bfe3f2eSlogwang  *       notice, this list of conditions and the following disclaimer in
16*2bfe3f2eSlogwang  *       the documentation and/or other materials provided with the
17*2bfe3f2eSlogwang  *       distribution.
18*2bfe3f2eSlogwang  *     * Neither the name of Intel Corporation nor the names of its
19*2bfe3f2eSlogwang  *       contributors may be used to endorse or promote products derived
20*2bfe3f2eSlogwang  *       from this software without specific prior written permission.
21*2bfe3f2eSlogwang  *
22*2bfe3f2eSlogwang  *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23*2bfe3f2eSlogwang  *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24*2bfe3f2eSlogwang  *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25*2bfe3f2eSlogwang  *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26*2bfe3f2eSlogwang  *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27*2bfe3f2eSlogwang  *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28*2bfe3f2eSlogwang  *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29*2bfe3f2eSlogwang  *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30*2bfe3f2eSlogwang  *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31*2bfe3f2eSlogwang  *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32*2bfe3f2eSlogwang  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*2bfe3f2eSlogwang  */
34*2bfe3f2eSlogwang 
35*2bfe3f2eSlogwang #include <stdint.h>
36*2bfe3f2eSlogwang #include <stdlib.h>
37*2bfe3f2eSlogwang #include <stdio.h>
38*2bfe3f2eSlogwang #include <ctype.h>
39*2bfe3f2eSlogwang #include <getopt.h>
40*2bfe3f2eSlogwang #include <errno.h>
41*2bfe3f2eSlogwang #include <stdarg.h>
42*2bfe3f2eSlogwang #include <string.h>
43*2bfe3f2eSlogwang #include <libgen.h>
44*2bfe3f2eSlogwang #include <unistd.h>
45*2bfe3f2eSlogwang #include <sys/wait.h>
46*2bfe3f2eSlogwang #include <stdbool.h>
47*2bfe3f2eSlogwang 
48*2bfe3f2eSlogwang #include <rte_errno.h>
49*2bfe3f2eSlogwang #include <rte_string_fns.h>
50*2bfe3f2eSlogwang 
51*2bfe3f2eSlogwang #include "parser.h"
52*2bfe3f2eSlogwang 
53*2bfe3f2eSlogwang static uint32_t
54*2bfe3f2eSlogwang get_hex_val(char c)
55*2bfe3f2eSlogwang {
56*2bfe3f2eSlogwang 	switch (c) {
57*2bfe3f2eSlogwang 	case '0': case '1': case '2': case '3': case '4': case '5':
58*2bfe3f2eSlogwang 	case '6': case '7': case '8': case '9':
59*2bfe3f2eSlogwang 		return c - '0';
60*2bfe3f2eSlogwang 	case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
61*2bfe3f2eSlogwang 		return c - 'A' + 10;
62*2bfe3f2eSlogwang 	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
63*2bfe3f2eSlogwang 		return c - 'a' + 10;
64*2bfe3f2eSlogwang 	default:
65*2bfe3f2eSlogwang 		return 0;
66*2bfe3f2eSlogwang 	}
67*2bfe3f2eSlogwang }
68*2bfe3f2eSlogwang 
69*2bfe3f2eSlogwang int
70*2bfe3f2eSlogwang parser_read_arg_bool(const char *p)
71*2bfe3f2eSlogwang {
72*2bfe3f2eSlogwang 	p = skip_white_spaces(p);
73*2bfe3f2eSlogwang 	int result = -EINVAL;
74*2bfe3f2eSlogwang 
75*2bfe3f2eSlogwang 	if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
76*2bfe3f2eSlogwang 		((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
77*2bfe3f2eSlogwang 		p += 3;
78*2bfe3f2eSlogwang 		result = 1;
79*2bfe3f2eSlogwang 	}
80*2bfe3f2eSlogwang 
81*2bfe3f2eSlogwang 	if (((p[0] == 'o') && (p[1] == 'n')) ||
82*2bfe3f2eSlogwang 		((p[0] == 'O') && (p[1] == 'N'))) {
83*2bfe3f2eSlogwang 		p += 2;
84*2bfe3f2eSlogwang 		result = 1;
85*2bfe3f2eSlogwang 	}
86*2bfe3f2eSlogwang 
87*2bfe3f2eSlogwang 	if (((p[0] == 'n') && (p[1] == 'o')) ||
88*2bfe3f2eSlogwang 		((p[0] == 'N') && (p[1] == 'O'))) {
89*2bfe3f2eSlogwang 		p += 2;
90*2bfe3f2eSlogwang 		result = 0;
91*2bfe3f2eSlogwang 	}
92*2bfe3f2eSlogwang 
93*2bfe3f2eSlogwang 	if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
94*2bfe3f2eSlogwang 		((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
95*2bfe3f2eSlogwang 		p += 3;
96*2bfe3f2eSlogwang 		result = 0;
97*2bfe3f2eSlogwang 	}
98*2bfe3f2eSlogwang 
99*2bfe3f2eSlogwang 	p = skip_white_spaces(p);
100*2bfe3f2eSlogwang 
101*2bfe3f2eSlogwang 	if (p[0] != '\0')
102*2bfe3f2eSlogwang 		return -EINVAL;
103*2bfe3f2eSlogwang 
104*2bfe3f2eSlogwang 	return result;
105*2bfe3f2eSlogwang }
106*2bfe3f2eSlogwang 
107*2bfe3f2eSlogwang int
108*2bfe3f2eSlogwang parser_read_uint64(uint64_t *value, const char *p)
109*2bfe3f2eSlogwang {
110*2bfe3f2eSlogwang 	char *next;
111*2bfe3f2eSlogwang 	uint64_t val;
112*2bfe3f2eSlogwang 
113*2bfe3f2eSlogwang 	p = skip_white_spaces(p);
114*2bfe3f2eSlogwang 	if (!isdigit(*p))
115*2bfe3f2eSlogwang 		return -EINVAL;
116*2bfe3f2eSlogwang 
117*2bfe3f2eSlogwang 	val = strtoul(p, &next, 10);
118*2bfe3f2eSlogwang 	if (p == next)
119*2bfe3f2eSlogwang 		return -EINVAL;
120*2bfe3f2eSlogwang 
121*2bfe3f2eSlogwang 	p = next;
122*2bfe3f2eSlogwang 	switch (*p) {
123*2bfe3f2eSlogwang 	case 'T':
124*2bfe3f2eSlogwang 		val *= 1024ULL;
125*2bfe3f2eSlogwang 		/* fall through */
126*2bfe3f2eSlogwang 	case 'G':
127*2bfe3f2eSlogwang 		val *= 1024ULL;
128*2bfe3f2eSlogwang 		/* fall through */
129*2bfe3f2eSlogwang 	case 'M':
130*2bfe3f2eSlogwang 		val *= 1024ULL;
131*2bfe3f2eSlogwang 		/* fall through */
132*2bfe3f2eSlogwang 	case 'k':
133*2bfe3f2eSlogwang 	case 'K':
134*2bfe3f2eSlogwang 		val *= 1024ULL;
135*2bfe3f2eSlogwang 		p++;
136*2bfe3f2eSlogwang 		break;
137*2bfe3f2eSlogwang 	}
138*2bfe3f2eSlogwang 
139*2bfe3f2eSlogwang 	p = skip_white_spaces(p);
140*2bfe3f2eSlogwang 	if (*p != '\0')
141*2bfe3f2eSlogwang 		return -EINVAL;
142*2bfe3f2eSlogwang 
143*2bfe3f2eSlogwang 	*value = val;
144*2bfe3f2eSlogwang 	return 0;
145*2bfe3f2eSlogwang }
146*2bfe3f2eSlogwang 
147*2bfe3f2eSlogwang int
148*2bfe3f2eSlogwang parser_read_int32(int32_t *value, const char *p)
149*2bfe3f2eSlogwang {
150*2bfe3f2eSlogwang 	char *next;
151*2bfe3f2eSlogwang 	int32_t val;
152*2bfe3f2eSlogwang 
153*2bfe3f2eSlogwang 	p = skip_white_spaces(p);
154*2bfe3f2eSlogwang 	if (!isdigit(*p))
155*2bfe3f2eSlogwang 		return -EINVAL;
156*2bfe3f2eSlogwang 
157*2bfe3f2eSlogwang 	val = strtol(p, &next, 10);
158*2bfe3f2eSlogwang 	if (p == next)
159*2bfe3f2eSlogwang 		return -EINVAL;
160*2bfe3f2eSlogwang 
161*2bfe3f2eSlogwang 	*value = val;
162*2bfe3f2eSlogwang 	return 0;
163*2bfe3f2eSlogwang }
164*2bfe3f2eSlogwang 
165*2bfe3f2eSlogwang int
166*2bfe3f2eSlogwang parser_read_uint64_hex(uint64_t *value, const char *p)
167*2bfe3f2eSlogwang {
168*2bfe3f2eSlogwang 	char *next;
169*2bfe3f2eSlogwang 	uint64_t val;
170*2bfe3f2eSlogwang 
171*2bfe3f2eSlogwang 	p = skip_white_spaces(p);
172*2bfe3f2eSlogwang 
173*2bfe3f2eSlogwang 	val = strtoul(p, &next, 16);
174*2bfe3f2eSlogwang 	if (p == next)
175*2bfe3f2eSlogwang 		return -EINVAL;
176*2bfe3f2eSlogwang 
177*2bfe3f2eSlogwang 	p = skip_white_spaces(next);
178*2bfe3f2eSlogwang 	if (*p != '\0')
179*2bfe3f2eSlogwang 		return -EINVAL;
180*2bfe3f2eSlogwang 
181*2bfe3f2eSlogwang 	*value = val;
182*2bfe3f2eSlogwang 	return 0;
183*2bfe3f2eSlogwang }
184*2bfe3f2eSlogwang 
185*2bfe3f2eSlogwang int
186*2bfe3f2eSlogwang parser_read_uint32(uint32_t *value, const char *p)
187*2bfe3f2eSlogwang {
188*2bfe3f2eSlogwang 	uint64_t val = 0;
189*2bfe3f2eSlogwang 	int ret = parser_read_uint64(&val, p);
190*2bfe3f2eSlogwang 
191*2bfe3f2eSlogwang 	if (ret < 0)
192*2bfe3f2eSlogwang 		return ret;
193*2bfe3f2eSlogwang 
194*2bfe3f2eSlogwang 	if (val > UINT32_MAX)
195*2bfe3f2eSlogwang 		return -ERANGE;
196*2bfe3f2eSlogwang 
197*2bfe3f2eSlogwang 	*value = val;
198*2bfe3f2eSlogwang 	return 0;
199*2bfe3f2eSlogwang }
200*2bfe3f2eSlogwang 
201*2bfe3f2eSlogwang int
202*2bfe3f2eSlogwang parser_read_uint32_hex(uint32_t *value, const char *p)
203*2bfe3f2eSlogwang {
204*2bfe3f2eSlogwang 	uint64_t val = 0;
205*2bfe3f2eSlogwang 	int ret = parser_read_uint64_hex(&val, p);
206*2bfe3f2eSlogwang 
207*2bfe3f2eSlogwang 	if (ret < 0)
208*2bfe3f2eSlogwang 		return ret;
209*2bfe3f2eSlogwang 
210*2bfe3f2eSlogwang 	if (val > UINT32_MAX)
211*2bfe3f2eSlogwang 		return -ERANGE;
212*2bfe3f2eSlogwang 
213*2bfe3f2eSlogwang 	*value = val;
214*2bfe3f2eSlogwang 	return 0;
215*2bfe3f2eSlogwang }
216*2bfe3f2eSlogwang 
217*2bfe3f2eSlogwang int
218*2bfe3f2eSlogwang parser_read_uint16(uint16_t *value, const char *p)
219*2bfe3f2eSlogwang {
220*2bfe3f2eSlogwang 	uint64_t val = 0;
221*2bfe3f2eSlogwang 	int ret = parser_read_uint64(&val, p);
222*2bfe3f2eSlogwang 
223*2bfe3f2eSlogwang 	if (ret < 0)
224*2bfe3f2eSlogwang 		return ret;
225*2bfe3f2eSlogwang 
226*2bfe3f2eSlogwang 	if (val > UINT16_MAX)
227*2bfe3f2eSlogwang 		return -ERANGE;
228*2bfe3f2eSlogwang 
229*2bfe3f2eSlogwang 	*value = val;
230*2bfe3f2eSlogwang 	return 0;
231*2bfe3f2eSlogwang }
232*2bfe3f2eSlogwang 
233*2bfe3f2eSlogwang int
234*2bfe3f2eSlogwang parser_read_uint16_hex(uint16_t *value, const char *p)
235*2bfe3f2eSlogwang {
236*2bfe3f2eSlogwang 	uint64_t val = 0;
237*2bfe3f2eSlogwang 	int ret = parser_read_uint64_hex(&val, p);
238*2bfe3f2eSlogwang 
239*2bfe3f2eSlogwang 	if (ret < 0)
240*2bfe3f2eSlogwang 		return ret;
241*2bfe3f2eSlogwang 
242*2bfe3f2eSlogwang 	if (val > UINT16_MAX)
243*2bfe3f2eSlogwang 		return -ERANGE;
244*2bfe3f2eSlogwang 
245*2bfe3f2eSlogwang 	*value = val;
246*2bfe3f2eSlogwang 	return 0;
247*2bfe3f2eSlogwang }
248*2bfe3f2eSlogwang 
249*2bfe3f2eSlogwang int
250*2bfe3f2eSlogwang parser_read_uint8(uint8_t *value, const char *p)
251*2bfe3f2eSlogwang {
252*2bfe3f2eSlogwang 	uint64_t val = 0;
253*2bfe3f2eSlogwang 	int ret = parser_read_uint64(&val, p);
254*2bfe3f2eSlogwang 
255*2bfe3f2eSlogwang 	if (ret < 0)
256*2bfe3f2eSlogwang 		return ret;
257*2bfe3f2eSlogwang 
258*2bfe3f2eSlogwang 	if (val > UINT8_MAX)
259*2bfe3f2eSlogwang 		return -ERANGE;
260*2bfe3f2eSlogwang 
261*2bfe3f2eSlogwang 	*value = val;
262*2bfe3f2eSlogwang 	return 0;
263*2bfe3f2eSlogwang }
264*2bfe3f2eSlogwang 
265*2bfe3f2eSlogwang int
266*2bfe3f2eSlogwang parser_read_uint8_hex(uint8_t *value, const char *p)
267*2bfe3f2eSlogwang {
268*2bfe3f2eSlogwang 	uint64_t val = 0;
269*2bfe3f2eSlogwang 	int ret = parser_read_uint64_hex(&val, p);
270*2bfe3f2eSlogwang 
271*2bfe3f2eSlogwang 	if (ret < 0)
272*2bfe3f2eSlogwang 		return ret;
273*2bfe3f2eSlogwang 
274*2bfe3f2eSlogwang 	if (val > UINT8_MAX)
275*2bfe3f2eSlogwang 		return -ERANGE;
276*2bfe3f2eSlogwang 
277*2bfe3f2eSlogwang 	*value = val;
278*2bfe3f2eSlogwang 	return 0;
279*2bfe3f2eSlogwang }
280*2bfe3f2eSlogwang 
281*2bfe3f2eSlogwang int
282*2bfe3f2eSlogwang parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
283*2bfe3f2eSlogwang {
284*2bfe3f2eSlogwang 	uint32_t i;
285*2bfe3f2eSlogwang 
286*2bfe3f2eSlogwang 	if ((string == NULL) ||
287*2bfe3f2eSlogwang 		(tokens == NULL) ||
288*2bfe3f2eSlogwang 		(*n_tokens < 1))
289*2bfe3f2eSlogwang 		return -EINVAL;
290*2bfe3f2eSlogwang 
291*2bfe3f2eSlogwang 	for (i = 0; i < *n_tokens; i++) {
292*2bfe3f2eSlogwang 		tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
293*2bfe3f2eSlogwang 		if (tokens[i] == NULL)
294*2bfe3f2eSlogwang 			break;
295*2bfe3f2eSlogwang 	}
296*2bfe3f2eSlogwang 
297*2bfe3f2eSlogwang 	if ((i == *n_tokens) &&
298*2bfe3f2eSlogwang 		(strtok_r(string, PARSE_DELIMITER, &string) != NULL))
299*2bfe3f2eSlogwang 		return -E2BIG;
300*2bfe3f2eSlogwang 
301*2bfe3f2eSlogwang 	*n_tokens = i;
302*2bfe3f2eSlogwang 	return 0;
303*2bfe3f2eSlogwang }
304*2bfe3f2eSlogwang 
305*2bfe3f2eSlogwang int
306*2bfe3f2eSlogwang parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
307*2bfe3f2eSlogwang {
308*2bfe3f2eSlogwang 	char *c;
309*2bfe3f2eSlogwang 	uint32_t len, i;
310*2bfe3f2eSlogwang 
311*2bfe3f2eSlogwang 	/* Check input parameters */
312*2bfe3f2eSlogwang 	if ((src == NULL) ||
313*2bfe3f2eSlogwang 		(dst == NULL) ||
314*2bfe3f2eSlogwang 		(size == NULL) ||
315*2bfe3f2eSlogwang 		(*size == 0))
316*2bfe3f2eSlogwang 		return -1;
317*2bfe3f2eSlogwang 
318*2bfe3f2eSlogwang 	len = strlen(src);
319*2bfe3f2eSlogwang 	if (((len & 3) != 0) ||
320*2bfe3f2eSlogwang 		(len > (*size) * 2))
321*2bfe3f2eSlogwang 		return -1;
322*2bfe3f2eSlogwang 	*size = len / 2;
323*2bfe3f2eSlogwang 
324*2bfe3f2eSlogwang 	for (c = src; *c != 0; c++) {
325*2bfe3f2eSlogwang 		if ((((*c) >= '0') && ((*c) <= '9')) ||
326*2bfe3f2eSlogwang 			(((*c) >= 'A') && ((*c) <= 'F')) ||
327*2bfe3f2eSlogwang 			(((*c) >= 'a') && ((*c) <= 'f')))
328*2bfe3f2eSlogwang 			continue;
329*2bfe3f2eSlogwang 
330*2bfe3f2eSlogwang 		return -1;
331*2bfe3f2eSlogwang 	}
332*2bfe3f2eSlogwang 
333*2bfe3f2eSlogwang 	/* Convert chars to bytes */
334*2bfe3f2eSlogwang 	for (i = 0; i < *size; i++)
335*2bfe3f2eSlogwang 		dst[i] = get_hex_val(src[2 * i]) * 16 +
336*2bfe3f2eSlogwang 			get_hex_val(src[2 * i + 1]);
337*2bfe3f2eSlogwang 
338*2bfe3f2eSlogwang 	return 0;
339*2bfe3f2eSlogwang }
340*2bfe3f2eSlogwang 
341*2bfe3f2eSlogwang int
342*2bfe3f2eSlogwang parse_lcores_list(bool lcores[], const char *corelist)
343*2bfe3f2eSlogwang {
344*2bfe3f2eSlogwang 	int i, idx = 0;
345*2bfe3f2eSlogwang 	int min, max;
346*2bfe3f2eSlogwang 	char *end = NULL;
347*2bfe3f2eSlogwang 
348*2bfe3f2eSlogwang 	if (corelist == NULL)
349*2bfe3f2eSlogwang 		return -1;
350*2bfe3f2eSlogwang 	while (isblank(*corelist))
351*2bfe3f2eSlogwang 		corelist++;
352*2bfe3f2eSlogwang 	i = strlen(corelist);
353*2bfe3f2eSlogwang 	while ((i > 0) && isblank(corelist[i - 1]))
354*2bfe3f2eSlogwang 		i--;
355*2bfe3f2eSlogwang 
356*2bfe3f2eSlogwang 	/* Get list of lcores */
357*2bfe3f2eSlogwang 	min = RTE_MAX_LCORE;
358*2bfe3f2eSlogwang 	do {
359*2bfe3f2eSlogwang 		while (isblank(*corelist))
360*2bfe3f2eSlogwang 			corelist++;
361*2bfe3f2eSlogwang 		if (*corelist == '\0')
362*2bfe3f2eSlogwang 			return -1;
363*2bfe3f2eSlogwang 		idx = strtoul(corelist, &end, 10);
364*2bfe3f2eSlogwang 
365*2bfe3f2eSlogwang 		if (end == NULL)
366*2bfe3f2eSlogwang 			return -1;
367*2bfe3f2eSlogwang 		while (isblank(*end))
368*2bfe3f2eSlogwang 			end++;
369*2bfe3f2eSlogwang 		if (*end == '-') {
370*2bfe3f2eSlogwang 			min = idx;
371*2bfe3f2eSlogwang 		} else if ((*end == ',') || (*end == '\0')) {
372*2bfe3f2eSlogwang 			max = idx;
373*2bfe3f2eSlogwang 			if (min == RTE_MAX_LCORE)
374*2bfe3f2eSlogwang 				min = idx;
375*2bfe3f2eSlogwang 			for (idx = min; idx <= max; idx++) {
376*2bfe3f2eSlogwang 				if (lcores[idx] == 1)
377*2bfe3f2eSlogwang 					return -E2BIG;
378*2bfe3f2eSlogwang 				lcores[idx] = 1;
379*2bfe3f2eSlogwang 			}
380*2bfe3f2eSlogwang 
381*2bfe3f2eSlogwang 			min = RTE_MAX_LCORE;
382*2bfe3f2eSlogwang 		} else
383*2bfe3f2eSlogwang 			return -1;
384*2bfe3f2eSlogwang 		corelist = end + 1;
385*2bfe3f2eSlogwang 	} while (*end != '\0');
386*2bfe3f2eSlogwang 
387*2bfe3f2eSlogwang 	return 0;
388*2bfe3f2eSlogwang }
389