xref: /dpdk/app/test/test_string_fns.c (revision 2df20a1d345a5fc0a1b6dc0317d11fc7b1fda7e7)
1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson  * Copyright(c) 2010-2014 Intel Corporation
3a9de470cSBruce Richardson  */
4a9de470cSBruce Richardson 
5a9de470cSBruce Richardson #include <stdio.h>
6a9de470cSBruce Richardson #include <stdarg.h>
7a9de470cSBruce Richardson #include <stddef.h>
8a9de470cSBruce Richardson #include <errno.h>
9a9de470cSBruce Richardson #include <string.h>
10a9de470cSBruce Richardson 
11a9de470cSBruce Richardson #include <rte_string_fns.h>
12a9de470cSBruce Richardson 
13a9de470cSBruce Richardson #include "test.h"
14a9de470cSBruce Richardson 
15a9de470cSBruce Richardson #define LOG(...) do {\
16a9de470cSBruce Richardson 	fprintf(stderr, "%s() ln %d: ", __func__, __LINE__); \
17a9de470cSBruce Richardson 	fprintf(stderr, __VA_ARGS__); \
18a9de470cSBruce Richardson } while(0)
19a9de470cSBruce Richardson 
20a9de470cSBruce Richardson #define DATA_BYTE 'a'
21a9de470cSBruce Richardson 
22a9de470cSBruce Richardson static int
test_rte_strsplit(void)23a9de470cSBruce Richardson test_rte_strsplit(void)
24a9de470cSBruce Richardson {
25a9de470cSBruce Richardson 	int i;
26a9de470cSBruce Richardson 	do {
27a9de470cSBruce Richardson 		/* =======================================================
28a9de470cSBruce Richardson 		 * split a mac address correct number of splits requested
29a9de470cSBruce Richardson 		 * =======================================================*/
30a9de470cSBruce Richardson 		char test_string[] = "54:65:76:87:98:90";
31a9de470cSBruce Richardson 		char *splits[6];
32a9de470cSBruce Richardson 
33a9de470cSBruce Richardson 		LOG("Source string: '%s', to split on ':'\n", test_string);
34a9de470cSBruce Richardson 		if (rte_strsplit(test_string, sizeof(test_string),
35a9de470cSBruce Richardson 				splits, 6, ':') != 6) {
36a9de470cSBruce Richardson 			LOG("Error splitting mac address\n");
37a9de470cSBruce Richardson 			return -1;
38a9de470cSBruce Richardson 		}
39a9de470cSBruce Richardson 		for (i = 0; i < 6; i++)
40a9de470cSBruce Richardson 			LOG("Token %d = %s\n", i + 1, splits[i]);
41a9de470cSBruce Richardson 	} while (0);
42a9de470cSBruce Richardson 
43a9de470cSBruce Richardson 
44a9de470cSBruce Richardson 	do {
45a9de470cSBruce Richardson 		/* =======================================================
46a9de470cSBruce Richardson 		 * split on spaces smaller number of splits requested
47a9de470cSBruce Richardson 		 * =======================================================*/
48a9de470cSBruce Richardson 		char test_string[] = "54 65 76 87 98 90";
49a9de470cSBruce Richardson 		char *splits[6];
50a9de470cSBruce Richardson 
51a9de470cSBruce Richardson 		LOG("Source string: '%s', to split on ' '\n", test_string);
52a9de470cSBruce Richardson 		if (rte_strsplit(test_string, sizeof(test_string),
53a9de470cSBruce Richardson 				splits, 3, ' ') != 3) {
54a9de470cSBruce Richardson 			LOG("Error splitting mac address for max 2 splits\n");
55a9de470cSBruce Richardson 			return -1;
56a9de470cSBruce Richardson 		}
57a9de470cSBruce Richardson 		for (i = 0; i < 3; i++)
58a9de470cSBruce Richardson 			LOG("Token %d = %s\n", i + 1, splits[i]);
59a9de470cSBruce Richardson 	} while (0);
60a9de470cSBruce Richardson 
61a9de470cSBruce Richardson 	do {
62a9de470cSBruce Richardson 		/* =======================================================
63a9de470cSBruce Richardson 		 * split on commas - more splits than commas requested
64a9de470cSBruce Richardson 		 * =======================================================*/
65a9de470cSBruce Richardson 		char test_string[] = "a,b,c,d";
66a9de470cSBruce Richardson 		char *splits[6];
67a9de470cSBruce Richardson 
68a9de470cSBruce Richardson 		LOG("Source string: '%s', to split on ','\n", test_string);
69a9de470cSBruce Richardson 		if (rte_strsplit(test_string, sizeof(test_string),
70a9de470cSBruce Richardson 				splits, 6, ',') != 4) {
71a9de470cSBruce Richardson 			LOG("Error splitting %s on ','\n", test_string);
72a9de470cSBruce Richardson 			return -1;
73a9de470cSBruce Richardson 		}
74a9de470cSBruce Richardson 		for (i = 0; i < 4; i++)
75a9de470cSBruce Richardson 			LOG("Token %d = %s\n", i + 1, splits[i]);
76a9de470cSBruce Richardson 	} while(0);
77a9de470cSBruce Richardson 
78a9de470cSBruce Richardson 	do {
79a9de470cSBruce Richardson 		/* =======================================================
80a9de470cSBruce Richardson 		 * Try splitting on non-existent character.
81a9de470cSBruce Richardson 		 * =======================================================*/
82a9de470cSBruce Richardson 		char test_string[] = "a,b,c,d";
83a9de470cSBruce Richardson 		char *splits[6];
84a9de470cSBruce Richardson 
85a9de470cSBruce Richardson 		LOG("Source string: '%s', to split on ' '\n", test_string);
86a9de470cSBruce Richardson 		if (rte_strsplit(test_string, sizeof(test_string),
87a9de470cSBruce Richardson 				splits, 6, ' ') != 1) {
88a9de470cSBruce Richardson 			LOG("Error splitting %s on ' '\n", test_string);
89a9de470cSBruce Richardson 			return -1;
90a9de470cSBruce Richardson 		}
91a9de470cSBruce Richardson 		LOG("String not split\n");
92a9de470cSBruce Richardson 	} while(0);
93a9de470cSBruce Richardson 
94a9de470cSBruce Richardson 	do {
95a9de470cSBruce Richardson 		/* =======================================================
96a9de470cSBruce Richardson 		 * Invalid / edge case parameter checks
97a9de470cSBruce Richardson 		 * =======================================================*/
98a9de470cSBruce Richardson 		char test_string[] = "a,b,c,d";
99a9de470cSBruce Richardson 		char *splits[6];
100a9de470cSBruce Richardson 
101a9de470cSBruce Richardson 		if (rte_strsplit(NULL, 0, splits, 6, ',') >= 0
102a9de470cSBruce Richardson 				|| errno != EINVAL){
103a9de470cSBruce Richardson 			LOG("Error: rte_strsplit accepted NULL string parameter\n");
104a9de470cSBruce Richardson 			return -1;
105a9de470cSBruce Richardson 		}
106a9de470cSBruce Richardson 
107a9de470cSBruce Richardson 		if (rte_strsplit(test_string, sizeof(test_string), NULL, 0, ',') >= 0
108a9de470cSBruce Richardson 				|| errno != EINVAL){
109a9de470cSBruce Richardson 			LOG("Error: rte_strsplit accepted NULL array parameter\n");
110a9de470cSBruce Richardson 			return -1;
111a9de470cSBruce Richardson 		}
112a9de470cSBruce Richardson 
113a9de470cSBruce Richardson 		errno = 0;
114a9de470cSBruce Richardson 		if (rte_strsplit(test_string, 0, splits, 6, ',') != 0 || errno != 0) {
115a9de470cSBruce Richardson 			LOG("Error: rte_strsplit did not accept 0 length string\n");
116a9de470cSBruce Richardson 			return -1;
117a9de470cSBruce Richardson 		}
118a9de470cSBruce Richardson 
119a9de470cSBruce Richardson 		if (rte_strsplit(test_string, sizeof(test_string), splits, 0, ',') != 0
120a9de470cSBruce Richardson 				|| errno != 0) {
121a9de470cSBruce Richardson 			LOG("Error: rte_strsplit did not accept 0 length array\n");
122a9de470cSBruce Richardson 			return -1;
123a9de470cSBruce Richardson 		}
124a9de470cSBruce Richardson 
125a9de470cSBruce Richardson 		LOG("Parameter test cases passed\n");
126a9de470cSBruce Richardson 	} while(0);
127a9de470cSBruce Richardson 
128a9de470cSBruce Richardson 	LOG("%s - PASSED\n", __func__);
129a9de470cSBruce Richardson 	return 0;
130a9de470cSBruce Richardson }
131a9de470cSBruce Richardson 
132a9de470cSBruce Richardson static int
test_rte_strlcat(void)133a9de470cSBruce Richardson test_rte_strlcat(void)
134a9de470cSBruce Richardson {
135a9de470cSBruce Richardson 	/* only run actual unit tests if we have system-provided strlcat */
136a9de470cSBruce Richardson #if defined(__BSD_VISIBLE) || defined(RTE_USE_LIBBSD)
137a9de470cSBruce Richardson #define BUF_LEN 32
138a9de470cSBruce Richardson 	const char dst[BUF_LEN] = "Test string";
139a9de470cSBruce Richardson 	const char src[] = " appended";
140a9de470cSBruce Richardson 	char bsd_dst[BUF_LEN];
141a9de470cSBruce Richardson 	char rte_dst[BUF_LEN];
142a9de470cSBruce Richardson 	size_t i, bsd_ret, rte_ret;
143a9de470cSBruce Richardson 
144a9de470cSBruce Richardson 	LOG("dst = '%s', strlen(dst) = %zu\n", dst, strlen(dst));
145a9de470cSBruce Richardson 	LOG("src = '%s', strlen(src) = %zu\n", src, strlen(src));
146a9de470cSBruce Richardson 	LOG("---\n");
147a9de470cSBruce Richardson 
148a9de470cSBruce Richardson 	for (i = 0; i < BUF_LEN; i++) {
149a9de470cSBruce Richardson 		/* initialize destination buffers */
150a9de470cSBruce Richardson 		memcpy(bsd_dst, dst, BUF_LEN);
151a9de470cSBruce Richardson 		memcpy(rte_dst, dst, BUF_LEN);
152a9de470cSBruce Richardson 		/* compare implementations */
153a9de470cSBruce Richardson 		bsd_ret = strlcat(bsd_dst, src, i);
154a9de470cSBruce Richardson 		rte_ret = rte_strlcat(rte_dst, src, i);
155a9de470cSBruce Richardson 		if (bsd_ret != rte_ret) {
156a9de470cSBruce Richardson 			LOG("Incorrect retval for buf length = %zu\n", i);
157a9de470cSBruce Richardson 			LOG("BSD: '%zu', rte: '%zu'\n", bsd_ret, rte_ret);
158a9de470cSBruce Richardson 			return -1;
159a9de470cSBruce Richardson 		}
160a9de470cSBruce Richardson 		if (memcmp(bsd_dst, rte_dst, BUF_LEN) != 0) {
161a9de470cSBruce Richardson 			LOG("Resulting buffers don't match\n");
162a9de470cSBruce Richardson 			LOG("BSD: '%s', rte: '%s'\n", bsd_dst, rte_dst);
163a9de470cSBruce Richardson 			return -1;
164a9de470cSBruce Richardson 		}
165a9de470cSBruce Richardson 		LOG("buffer size = %zu: dst = '%s', ret = %zu\n",
166a9de470cSBruce Richardson 			i, rte_dst, rte_ret);
167a9de470cSBruce Richardson 	}
168a9de470cSBruce Richardson 	LOG("Checked %zu combinations\n", i);
169a9de470cSBruce Richardson #undef BUF_LEN
170a9de470cSBruce Richardson #endif /* defined(__BSD_VISIBLE) || defined(RTE_USE_LIBBSD) */
171a9de470cSBruce Richardson 
172a9de470cSBruce Richardson 	return 0;
173a9de470cSBruce Richardson }
174a9de470cSBruce Richardson 
175a9de470cSBruce Richardson static int
test_rte_str_skip_leading_spaces(void)176*2df20a1dSDavid Marchand test_rte_str_skip_leading_spaces(void)
177*2df20a1dSDavid Marchand {
178*2df20a1dSDavid Marchand 	static const char empty[] = "";
179*2df20a1dSDavid Marchand 	static const char nowhitespace[] = "Thereisreallynowhitespace";
180*2df20a1dSDavid Marchand 	static const char somewhitespaces[] = " \f\n\r\t\vThere are some whitespaces";
181*2df20a1dSDavid Marchand 	const char *p;
182*2df20a1dSDavid Marchand 
183*2df20a1dSDavid Marchand 	LOG("Checking '%s'\n", empty);
184*2df20a1dSDavid Marchand 	p = rte_str_skip_leading_spaces(empty);
185*2df20a1dSDavid Marchand 	if (p != empty) {
186*2df20a1dSDavid Marchand 		LOG("Returned address '%s' does not match expected result\n", p);
187*2df20a1dSDavid Marchand 		return -1;
188*2df20a1dSDavid Marchand 	}
189*2df20a1dSDavid Marchand 	LOG("Got expected '%s'\n", p);
190*2df20a1dSDavid Marchand 	LOG("Checking '%s'\n", nowhitespace);
191*2df20a1dSDavid Marchand 	p = rte_str_skip_leading_spaces(nowhitespace);
192*2df20a1dSDavid Marchand 	if (p != nowhitespace) {
193*2df20a1dSDavid Marchand 		LOG("Returned address '%s' does not match expected result\n", p);
194*2df20a1dSDavid Marchand 		return -1;
195*2df20a1dSDavid Marchand 	}
196*2df20a1dSDavid Marchand 	LOG("Got expected '%s'\n", p);
197*2df20a1dSDavid Marchand 	LOG("Checking '%s'\n", somewhitespaces);
198*2df20a1dSDavid Marchand 	p = rte_str_skip_leading_spaces(somewhitespaces);
199*2df20a1dSDavid Marchand 	if (p != strchr(somewhitespaces, 'T')) {
200*2df20a1dSDavid Marchand 		LOG("Returned address '%s' does not match expected result\n", p);
201*2df20a1dSDavid Marchand 		return -1;
202*2df20a1dSDavid Marchand 	}
203*2df20a1dSDavid Marchand 	LOG("Got expected '%s'\n", p);
204*2df20a1dSDavid Marchand 
205*2df20a1dSDavid Marchand 	return 0;
206*2df20a1dSDavid Marchand }
207*2df20a1dSDavid Marchand 
208*2df20a1dSDavid Marchand static int
test_string_fns(void)209a9de470cSBruce Richardson test_string_fns(void)
210a9de470cSBruce Richardson {
211a9de470cSBruce Richardson 	if (test_rte_strsplit() < 0)
212a9de470cSBruce Richardson 		return -1;
213a9de470cSBruce Richardson 	if (test_rte_strlcat() < 0)
214a9de470cSBruce Richardson 		return -1;
215*2df20a1dSDavid Marchand 	if (test_rte_str_skip_leading_spaces() < 0)
216*2df20a1dSDavid Marchand 		return -1;
217a9de470cSBruce Richardson 	return 0;
218a9de470cSBruce Richardson }
219a9de470cSBruce Richardson 
220e0a8442cSBruce Richardson REGISTER_FAST_TEST(string_autotest, true, true, test_string_fns);
221