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