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