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