xref: /dpdk/lib/eal/common/eal_common_string_fns.c (revision 347623c9c7cd4ff95c9e734d743e4247e5aaa01a)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright(c) 2010-2014 Intel Corporation
399a2dd95SBruce Richardson  */
499a2dd95SBruce Richardson 
599a2dd95SBruce Richardson #include <stdio.h>
699a2dd95SBruce Richardson #include <errno.h>
799a2dd95SBruce Richardson 
899a2dd95SBruce Richardson #include <rte_string_fns.h>
9dbba7c9eSThomas Monjalon #include <rte_errno.h>
1099a2dd95SBruce Richardson 
1199a2dd95SBruce Richardson /* split string into tokens */
1299a2dd95SBruce Richardson int
1399a2dd95SBruce Richardson rte_strsplit(char *string, int stringlen,
1499a2dd95SBruce Richardson 	     char **tokens, int maxtokens, char delim)
1599a2dd95SBruce Richardson {
1699a2dd95SBruce Richardson 	int i, tok = 0;
1799a2dd95SBruce Richardson 	int tokstart = 1; /* first token is right at start of string */
1899a2dd95SBruce Richardson 
1999a2dd95SBruce Richardson 	if (string == NULL || tokens == NULL)
2099a2dd95SBruce Richardson 		goto einval_error;
2199a2dd95SBruce Richardson 
2299a2dd95SBruce Richardson 	for (i = 0; i < stringlen; i++) {
2399a2dd95SBruce Richardson 		if (string[i] == '\0' || tok >= maxtokens)
2499a2dd95SBruce Richardson 			break;
2599a2dd95SBruce Richardson 		if (tokstart) {
2699a2dd95SBruce Richardson 			tokstart = 0;
2799a2dd95SBruce Richardson 			tokens[tok++] = &string[i];
2899a2dd95SBruce Richardson 		}
2999a2dd95SBruce Richardson 		if (string[i] == delim) {
3099a2dd95SBruce Richardson 			string[i] = '\0';
3199a2dd95SBruce Richardson 			tokstart = 1;
3299a2dd95SBruce Richardson 		}
3399a2dd95SBruce Richardson 	}
3499a2dd95SBruce Richardson 	return tok;
3599a2dd95SBruce Richardson 
3699a2dd95SBruce Richardson einval_error:
3799a2dd95SBruce Richardson 	errno = EINVAL;
3899a2dd95SBruce Richardson 	return -1;
3999a2dd95SBruce Richardson }
4099a2dd95SBruce Richardson 
4199a2dd95SBruce Richardson /* Copy src string into dst.
4299a2dd95SBruce Richardson  *
4399a2dd95SBruce Richardson  * Return negative value and NUL-terminate if dst is too short,
4499a2dd95SBruce Richardson  * Otherwise return number of bytes copied.
4599a2dd95SBruce Richardson  */
4699a2dd95SBruce Richardson ssize_t
4799a2dd95SBruce Richardson rte_strscpy(char *dst, const char *src, size_t dsize)
4899a2dd95SBruce Richardson {
4999a2dd95SBruce Richardson 	size_t nleft = dsize;
5099a2dd95SBruce Richardson 	size_t res = 0;
5199a2dd95SBruce Richardson 
5299a2dd95SBruce Richardson 	/* Copy as many bytes as will fit. */
5399a2dd95SBruce Richardson 	while (nleft != 0) {
5499a2dd95SBruce Richardson 		dst[res] = src[res];
5599a2dd95SBruce Richardson 		if (src[res] == '\0')
5699a2dd95SBruce Richardson 			return res;
5799a2dd95SBruce Richardson 		res++;
5899a2dd95SBruce Richardson 		nleft--;
5999a2dd95SBruce Richardson 	}
6099a2dd95SBruce Richardson 
6199a2dd95SBruce Richardson 	/* Not enough room in dst, set NUL and return error. */
6299a2dd95SBruce Richardson 	if (res != 0)
6399a2dd95SBruce Richardson 		dst[res - 1] = '\0';
64dbba7c9eSThomas Monjalon 	rte_errno = E2BIG;
65dbba7c9eSThomas Monjalon 	return -rte_errno;
6699a2dd95SBruce Richardson }
67*347623c9SDmitry Kozlyuk 
68*347623c9SDmitry Kozlyuk uint64_t
69*347623c9SDmitry Kozlyuk rte_str_to_size(const char *str)
70*347623c9SDmitry Kozlyuk {
71*347623c9SDmitry Kozlyuk 	char *endptr;
72*347623c9SDmitry Kozlyuk 	unsigned long long size;
73*347623c9SDmitry Kozlyuk 
74*347623c9SDmitry Kozlyuk 	while (isspace((int)*str))
75*347623c9SDmitry Kozlyuk 		str++;
76*347623c9SDmitry Kozlyuk 	if (*str == '-')
77*347623c9SDmitry Kozlyuk 		return 0;
78*347623c9SDmitry Kozlyuk 
79*347623c9SDmitry Kozlyuk 	errno = 0;
80*347623c9SDmitry Kozlyuk 	size = strtoull(str, &endptr, 0);
81*347623c9SDmitry Kozlyuk 	if (errno)
82*347623c9SDmitry Kozlyuk 		return 0;
83*347623c9SDmitry Kozlyuk 
84*347623c9SDmitry Kozlyuk 	if (*endptr == ' ')
85*347623c9SDmitry Kozlyuk 		endptr++; /* allow 1 space gap */
86*347623c9SDmitry Kozlyuk 
87*347623c9SDmitry Kozlyuk 	switch (*endptr) {
88*347623c9SDmitry Kozlyuk 	case 'G': case 'g':
89*347623c9SDmitry Kozlyuk 		size *= 1024; /* fall-through */
90*347623c9SDmitry Kozlyuk 	case 'M': case 'm':
91*347623c9SDmitry Kozlyuk 		size *= 1024; /* fall-through */
92*347623c9SDmitry Kozlyuk 	case 'K': case 'k':
93*347623c9SDmitry Kozlyuk 		size *= 1024; /* fall-through */
94*347623c9SDmitry Kozlyuk 	default:
95*347623c9SDmitry Kozlyuk 		break;
96*347623c9SDmitry Kozlyuk 	}
97*347623c9SDmitry Kozlyuk 	return size;
98*347623c9SDmitry Kozlyuk }
99