199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation
399a2dd95SBruce Richardson */
499a2dd95SBruce Richardson
5*72b452c5SDmitry Kozlyuk #include <ctype.h>
699a2dd95SBruce Richardson #include <errno.h>
7*72b452c5SDmitry Kozlyuk #include <stdio.h>
8*72b452c5SDmitry Kozlyuk #include <stdlib.h>
999a2dd95SBruce Richardson
1099a2dd95SBruce Richardson #include <rte_string_fns.h>
11dbba7c9eSThomas Monjalon #include <rte_errno.h>
1299a2dd95SBruce Richardson
1399a2dd95SBruce Richardson /* split string into tokens */
1499a2dd95SBruce Richardson int
rte_strsplit(char * string,int stringlen,char ** tokens,int maxtokens,char delim)1599a2dd95SBruce Richardson rte_strsplit(char *string, int stringlen,
1699a2dd95SBruce Richardson char **tokens, int maxtokens, char delim)
1799a2dd95SBruce Richardson {
1899a2dd95SBruce Richardson int i, tok = 0;
1999a2dd95SBruce Richardson int tokstart = 1; /* first token is right at start of string */
2099a2dd95SBruce Richardson
2199a2dd95SBruce Richardson if (string == NULL || tokens == NULL)
2299a2dd95SBruce Richardson goto einval_error;
2399a2dd95SBruce Richardson
2499a2dd95SBruce Richardson for (i = 0; i < stringlen; i++) {
2599a2dd95SBruce Richardson if (string[i] == '\0' || tok >= maxtokens)
2699a2dd95SBruce Richardson break;
2799a2dd95SBruce Richardson if (tokstart) {
2899a2dd95SBruce Richardson tokstart = 0;
2999a2dd95SBruce Richardson tokens[tok++] = &string[i];
3099a2dd95SBruce Richardson }
3199a2dd95SBruce Richardson if (string[i] == delim) {
3299a2dd95SBruce Richardson string[i] = '\0';
3399a2dd95SBruce Richardson tokstart = 1;
3499a2dd95SBruce Richardson }
3599a2dd95SBruce Richardson }
3699a2dd95SBruce Richardson return tok;
3799a2dd95SBruce Richardson
3899a2dd95SBruce Richardson einval_error:
3999a2dd95SBruce Richardson errno = EINVAL;
4099a2dd95SBruce Richardson return -1;
4199a2dd95SBruce Richardson }
4299a2dd95SBruce Richardson
4399a2dd95SBruce Richardson /* Copy src string into dst.
4499a2dd95SBruce Richardson *
4599a2dd95SBruce Richardson * Return negative value and NUL-terminate if dst is too short,
4699a2dd95SBruce Richardson * Otherwise return number of bytes copied.
4799a2dd95SBruce Richardson */
4899a2dd95SBruce Richardson ssize_t
rte_strscpy(char * dst,const char * src,size_t dsize)4999a2dd95SBruce Richardson rte_strscpy(char *dst, const char *src, size_t dsize)
5099a2dd95SBruce Richardson {
5199a2dd95SBruce Richardson size_t nleft = dsize;
5299a2dd95SBruce Richardson size_t res = 0;
5399a2dd95SBruce Richardson
5499a2dd95SBruce Richardson /* Copy as many bytes as will fit. */
5599a2dd95SBruce Richardson while (nleft != 0) {
5699a2dd95SBruce Richardson dst[res] = src[res];
5799a2dd95SBruce Richardson if (src[res] == '\0')
5899a2dd95SBruce Richardson return res;
5999a2dd95SBruce Richardson res++;
6099a2dd95SBruce Richardson nleft--;
6199a2dd95SBruce Richardson }
6299a2dd95SBruce Richardson
6399a2dd95SBruce Richardson /* Not enough room in dst, set NUL and return error. */
6499a2dd95SBruce Richardson if (res != 0)
6599a2dd95SBruce Richardson dst[res - 1] = '\0';
66dbba7c9eSThomas Monjalon rte_errno = E2BIG;
67dbba7c9eSThomas Monjalon return -rte_errno;
6899a2dd95SBruce Richardson }
69347623c9SDmitry Kozlyuk
70347623c9SDmitry Kozlyuk uint64_t
rte_str_to_size(const char * str)71347623c9SDmitry Kozlyuk rte_str_to_size(const char *str)
72347623c9SDmitry Kozlyuk {
73347623c9SDmitry Kozlyuk char *endptr;
74347623c9SDmitry Kozlyuk unsigned long long size;
75347623c9SDmitry Kozlyuk
76347623c9SDmitry Kozlyuk while (isspace((int)*str))
77347623c9SDmitry Kozlyuk str++;
78347623c9SDmitry Kozlyuk if (*str == '-')
79347623c9SDmitry Kozlyuk return 0;
80347623c9SDmitry Kozlyuk
81347623c9SDmitry Kozlyuk errno = 0;
82347623c9SDmitry Kozlyuk size = strtoull(str, &endptr, 0);
83347623c9SDmitry Kozlyuk if (errno)
84347623c9SDmitry Kozlyuk return 0;
85347623c9SDmitry Kozlyuk
86347623c9SDmitry Kozlyuk if (*endptr == ' ')
87347623c9SDmitry Kozlyuk endptr++; /* allow 1 space gap */
88347623c9SDmitry Kozlyuk
89347623c9SDmitry Kozlyuk switch (*endptr) {
90347623c9SDmitry Kozlyuk case 'G': case 'g':
91347623c9SDmitry Kozlyuk size *= 1024; /* fall-through */
92347623c9SDmitry Kozlyuk case 'M': case 'm':
93347623c9SDmitry Kozlyuk size *= 1024; /* fall-through */
94347623c9SDmitry Kozlyuk case 'K': case 'k':
95347623c9SDmitry Kozlyuk size *= 1024; /* fall-through */
96347623c9SDmitry Kozlyuk default:
97347623c9SDmitry Kozlyuk break;
98347623c9SDmitry Kozlyuk }
99347623c9SDmitry Kozlyuk return size;
100347623c9SDmitry Kozlyuk }
101