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