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