Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2014 Intel Corporation
3 : : */
4 : :
5 : : #include <stdio.h>
6 : : #include <string.h>
7 : : #include <inttypes.h>
8 : :
9 : : #include <rte_common.h>
10 : : #include <rte_string_fns.h>
11 : :
12 : : #include <cmdline_parse.h>
13 : : #include <cmdline_parse_string.h>
14 : :
15 : : #include "test_cmdline.h"
16 : :
17 : : /* structures needed to run tests */
18 : :
19 : : struct string_elt_str {
20 : : const char * str; /* parsed string */
21 : : const char * result; /* expected string */
22 : : int idx; /* position at which result is expected to be */
23 : : };
24 : :
25 : : struct string_elt_str string_elt_strs[] = {
26 : : {"one#two#three", "three", 2},
27 : : {"one#two with spaces#three", "three", 2},
28 : : {"one#two\twith\ttabs#three", "three", 2},
29 : : {"one#two\rwith\rreturns#three", "three", 2},
30 : : {"one#two\nwith\nnewlines#three", "three", 2},
31 : : {"one#two#three", "one", 0},
32 : : {"one#two#three", "two", 1},
33 : : {"one#two\0three", "two", 1},
34 : : {"one#two with spaces#three", "two with spaces", 1},
35 : : {"one#two\twith\ttabs#three", "two\twith\ttabs", 1},
36 : : {"one#two\rwith\rreturns#three", "two\rwith\rreturns", 1},
37 : : {"one#two\nwith\nnewlines#three", "two\nwith\nnewlines", 1},
38 : : };
39 : :
40 : : #if (CMDLINE_TEST_BUFSIZE < STR_TOKEN_SIZE) \
41 : : || (CMDLINE_TEST_BUFSIZE < STR_MULTI_TOKEN_SIZE)
42 : : #undef CMDLINE_TEST_BUFSIZE
43 : : #define CMDLINE_TEST_BUFSIZE RTE_MAX_T(STR_TOKEN_SIZE, STR_MULTI_TOKEN_SIZE, size_t)
44 : : #endif
45 : :
46 : : struct string_nb_str {
47 : : const char * str; /* parsed string */
48 : : int nb_strs; /* expected number of strings in str */
49 : : };
50 : :
51 : : struct string_nb_str string_nb_strs[] = {
52 : : {"one#two#three", 3},
53 : : {"one", 1},
54 : : {"one# \t two \r # three \n #four", 4},
55 : : };
56 : :
57 : :
58 : :
59 : : struct string_parse_str {
60 : : const char * str; /* parsed string */
61 : : const char * fixed_str; /* parsing mode (any, fixed or multi) */
62 : : const char * result; /* expected result */
63 : : };
64 : :
65 : : struct string_parse_str string_parse_strs[] = {
66 : : {"one", NULL, "one"}, /* any string */
67 : : {"two", "one#two#three", "two"}, /* multiple choice string */
68 : : {"three", "three", "three"}, /* fixed string */
69 : : {"three", "one#two with\rgarbage\tcharacters\n#three", "three"},
70 : : {"two with\rgarbage\tcharacters\n",
71 : : "one#two with\rgarbage\tcharacters\n#three",
72 : : "two with\rgarbage\tcharacters\n"},
73 : : {"one two", "one", "one"}, /* fixed string */
74 : : {"one two", TOKEN_STRING_MULTI, "one two"}, /* multi string */
75 : : {"one two", NULL, "one"}, /* any string */
76 : : {"one two #three", TOKEN_STRING_MULTI, "one two "},
77 : : /* multi string with comment */
78 : : };
79 : :
80 : :
81 : :
82 : : struct string_invalid_str {
83 : : const char * str; /* parsed string */
84 : : const char * fixed_str; /* parsing mode (any, fixed or multi) */
85 : : };
86 : :
87 : : struct string_invalid_str string_invalid_strs[] = {
88 : : {"invalid", "one"}, /* fixed string */
89 : : {"invalid", "one#two#three"}, /* multiple choice string */
90 : : {"invalid", "invalidone"}, /* string that starts the same */
91 : : {"invalidone", "invalid"}, /* string that starts the same */
92 : : {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
93 : : "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
94 : : "toolong!!!", NULL },
95 : : {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
96 : : "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
97 : : "toolong!!!", "fixed" },
98 : : {"toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
99 : : "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
100 : : "toolong!!!", "multi#choice#string" },
101 : : {"invalid",
102 : : "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
103 : : "toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!toolong!!!"
104 : : "toolong!!!" },
105 : : {"", "invalid"}
106 : : };
107 : :
108 : :
109 : :
110 : : const char * string_help_strs[] = {
111 : : NULL,
112 : : "fixed_str",
113 : : "multi#str",
114 : : };
115 : :
116 : : #define SMALL_BUF 8
117 : :
118 : : /* test invalid parameters */
119 : : int
120 : 1 : test_parse_string_invalid_param(void)
121 : : {
122 : : cmdline_parse_token_string_t token;
123 : : int result;
124 : : char buf[CMDLINE_TEST_BUFSIZE];
125 : :
126 : : memset(&token, 0, sizeof(token));
127 : :
128 : : snprintf(buf, sizeof(buf), "buffer");
129 : :
130 : : /* test null token */
131 [ - + ]: 1 : if (cmdline_get_help_string(
132 : : NULL, buf, 0) != -1) {
133 : : printf("Error: function accepted null token!\n");
134 : 0 : return -1;
135 : : }
136 [ - + ]: 1 : if (cmdline_complete_get_elt_string(
137 : : NULL, 0, buf, 0) != -1) {
138 : : printf("Error: function accepted null token!\n");
139 : 0 : return -1;
140 : : }
141 [ - + ]: 1 : if (cmdline_complete_get_nb_string(NULL) != -1) {
142 : : printf("Error: function accepted null token!\n");
143 : 0 : return -1;
144 : : }
145 [ - + ]: 1 : if (cmdline_parse_string(NULL, buf, NULL, 0) != -1) {
146 : : printf("Error: function accepted null token!\n");
147 : 0 : return -1;
148 : : }
149 : : /* test null buffer */
150 [ - + ]: 1 : if (cmdline_complete_get_elt_string(
151 : : (cmdline_parse_token_hdr_t*)&token, 0, NULL, 0) != -1) {
152 : : printf("Error: function accepted null buffer!\n");
153 : 0 : return -1;
154 : : }
155 [ - + ]: 1 : if (cmdline_parse_string(
156 : : (cmdline_parse_token_hdr_t*)&token, NULL,
157 : : (void*)&result, sizeof(result)) != -1) {
158 : : printf("Error: function accepted null buffer!\n");
159 : 0 : return -1;
160 : : }
161 [ - + ]: 1 : if (cmdline_get_help_string(
162 : : (cmdline_parse_token_hdr_t*)&token, NULL, 0) != -1) {
163 : : printf("Error: function accepted null buffer!\n");
164 : 0 : return -1;
165 : : }
166 : : /* test null result */
167 [ - + ]: 1 : if (cmdline_parse_string(
168 : : (cmdline_parse_token_hdr_t*)&token, buf, NULL, 0) == -1) {
169 : : printf("Error: function rejected null result!\n");
170 : 0 : return -1;
171 : : }
172 : : /* test negative index */
173 [ - + ]: 1 : if (cmdline_complete_get_elt_string(
174 : : (cmdline_parse_token_hdr_t*)&token, -1, buf, 0) != -1) {
175 : : printf("Error: function accepted negative index!\n");
176 : 0 : return -1;
177 : : }
178 : : return 0;
179 : : }
180 : :
181 : : /* test valid parameters but invalid data */
182 : : int
183 : 1 : test_parse_string_invalid_data(void)
184 : : {
185 : : cmdline_parse_token_string_t token;
186 : : cmdline_parse_token_string_t help_token;
187 : : char buf[CMDLINE_TEST_BUFSIZE];
188 : : char help_str[CMDLINE_TEST_BUFSIZE];
189 : : char small_buf[SMALL_BUF];
190 : : unsigned i;
191 : :
192 : : /* test parsing invalid strings */
193 [ + + ]: 10 : for (i = 0; i < RTE_DIM(string_invalid_strs); i++) {
194 : : memset(&token, 0, sizeof(token));
195 : : memset(buf, 0, sizeof(buf));
196 : :
197 : : /* prepare test token data */
198 : 9 : token.string_data.str = string_invalid_strs[i].fixed_str;
199 : :
200 [ - + ]: 9 : if (cmdline_parse_string((cmdline_parse_token_hdr_t*)&token,
201 : : string_invalid_strs[i].str, (void*)buf,
202 : : sizeof(buf)) != -1) {
203 : : memset(help_str, 0, sizeof(help_str));
204 : : memset(&help_token, 0, sizeof(help_token));
205 : :
206 : : help_token.string_data.str = string_invalid_strs[i].fixed_str;
207 : :
208 : : /* get parse type so we can give a good error message */
209 : 0 : cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str,
210 : : sizeof(help_str));
211 : :
212 : 0 : printf("Error: parsing %s as %s succeeded!\n",
213 : : string_invalid_strs[i].str, help_str);
214 : 0 : return -1;
215 : : }
216 : : }
217 : :
218 : : /* misc tests (big comments signify test cases) */
219 : : memset(&token, 0, sizeof(token));
220 : : memset(small_buf, 0, sizeof(small_buf));
221 : :
222 : : /*
223 : : * try to get element from a null token
224 : : */
225 : : token.string_data.str = NULL;
226 [ - + ]: 1 : if (cmdline_complete_get_elt_string(
227 : : (cmdline_parse_token_hdr_t*)&token, 1,
228 : : buf, sizeof(buf)) != -1) {
229 : : printf("Error: getting token from null token string!\n");
230 : 0 : return -1;
231 : : }
232 : :
233 : : /*
234 : : * try to get element into a buffer that is too small
235 : : */
236 : 1 : token.string_data.str = "too_small_buffer";
237 [ - + ]: 1 : if (cmdline_complete_get_elt_string(
238 : : (cmdline_parse_token_hdr_t*)&token, 0,
239 : : small_buf, sizeof(small_buf)) != -1) {
240 : : printf("Error: writing token into too small a buffer succeeded!\n");
241 : 0 : return -1;
242 : : }
243 : :
244 : : /*
245 : : * get help string written into a buffer smaller than help string
246 : : * truncation should occur
247 : : */
248 : 1 : token.string_data.str = NULL;
249 [ - + ]: 1 : if (cmdline_get_help_string(
250 : : (cmdline_parse_token_hdr_t*)&token,
251 : : small_buf, sizeof(small_buf)) == -1) {
252 : : printf("Error: writing help string into too small a buffer failed!\n");
253 : 0 : return -1;
254 : : }
255 : : /* get help string for "any string" so we can compare it with small_buf */
256 : 1 : cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str,
257 : : sizeof(help_str));
258 [ - + ]: 1 : if (strncmp(small_buf, help_str, sizeof(small_buf) - 1)) {
259 : : printf("Error: help string mismatch!\n");
260 : 0 : return -1;
261 : : }
262 : : /* check null terminator */
263 [ - + ]: 1 : if (small_buf[sizeof(small_buf) - 1] != '\0') {
264 : : printf("Error: small buffer doesn't have a null terminator!\n");
265 : 0 : return -1;
266 : : }
267 : :
268 : : /*
269 : : * try to count tokens in a null token
270 : : */
271 : 1 : token.string_data.str = NULL;
272 [ - + ]: 1 : if (cmdline_complete_get_nb_string(
273 : : (cmdline_parse_token_hdr_t*)&token) != 0) {
274 : : printf("Error: getting token count from null token succeeded!\n");
275 : 0 : return -1;
276 : : }
277 : :
278 : : return 0;
279 : : }
280 : :
281 : : /* test valid parameters and data */
282 : : int
283 : 1 : test_parse_string_valid(void)
284 : : {
285 : : cmdline_parse_token_string_t token;
286 : : cmdline_parse_token_string_t help_token;
287 : : char buf[CMDLINE_TEST_BUFSIZE];
288 : : char help_str[CMDLINE_TEST_BUFSIZE];
289 : : unsigned i;
290 : :
291 : : /* test parsing strings */
292 [ + + ]: 10 : for (i = 0; i < RTE_DIM(string_parse_strs); i++) {
293 : : memset(&token, 0, sizeof(token));
294 : : memset(buf, 0, sizeof(buf));
295 : :
296 : 9 : token.string_data.str = string_parse_strs[i].fixed_str;
297 : :
298 [ - + ]: 9 : if (cmdline_parse_string((cmdline_parse_token_hdr_t*)&token,
299 : : string_parse_strs[i].str, (void*)buf,
300 : : sizeof(buf)) < 0) {
301 : :
302 : : /* clean help data */
303 : : memset(&help_token, 0, sizeof(help_token));
304 : : memset(help_str, 0, sizeof(help_str));
305 : :
306 : : /* prepare help token */
307 : 0 : help_token.string_data.str = string_parse_strs[i].fixed_str;
308 : :
309 : : /* get help string so that we get an informative error message */
310 : 0 : cmdline_get_help_string((cmdline_parse_token_hdr_t*)&token, help_str,
311 : : sizeof(help_str));
312 : :
313 : 0 : printf("Error: parsing %s as %s failed!\n",
314 : : string_parse_strs[i].str, help_str);
315 : 0 : return -1;
316 : : }
317 [ - + ]: 9 : if (strcmp(buf, string_parse_strs[i].result) != 0) {
318 : : printf("Error: result mismatch!\n");
319 : 0 : return -1;
320 : : }
321 : : }
322 : :
323 : : /* get number of string tokens and verify it's correct */
324 [ + + ]: 4 : for (i = 0; i < RTE_DIM(string_nb_strs); i++) {
325 : : memset(&token, 0, sizeof(token));
326 : :
327 : 3 : token.string_data.str = string_nb_strs[i].str;
328 : :
329 : 3 : if (cmdline_complete_get_nb_string(
330 : : (cmdline_parse_token_hdr_t*)&token) <
331 [ - + ]: 3 : string_nb_strs[i].nb_strs) {
332 : : printf("Error: strings count mismatch!\n");
333 : 0 : return -1;
334 : : }
335 : : }
336 : :
337 : : /* get token at specified position and verify it's correct */
338 [ + + ]: 13 : for (i = 0; i < RTE_DIM(string_elt_strs); i++) {
339 : : memset(&token, 0, sizeof(token));
340 : : memset(buf, 0, sizeof(buf));
341 : :
342 : 12 : token.string_data.str = string_elt_strs[i].str;
343 : :
344 [ - + ]: 12 : if (cmdline_complete_get_elt_string(
345 : : (cmdline_parse_token_hdr_t*)&token, string_elt_strs[i].idx,
346 : : buf, sizeof(buf)) < 0) {
347 : : printf("Error: getting string element failed!\n");
348 : 0 : return -1;
349 : : }
350 [ - + ]: 12 : if (strncmp(buf, string_elt_strs[i].result,
351 : : sizeof(buf)) != 0) {
352 : : printf("Error: result mismatch!\n");
353 : 0 : return -1;
354 : : }
355 : : }
356 : :
357 : : /* cover all cases with help strings */
358 [ + + ]: 4 : for (i = 0; i < RTE_DIM(string_help_strs); i++) {
359 : : memset(&help_token, 0, sizeof(help_token));
360 : : memset(help_str, 0, sizeof(help_str));
361 : 3 : help_token.string_data.str = string_help_strs[i];
362 [ - + ]: 3 : if (cmdline_get_help_string((cmdline_parse_token_hdr_t*)&help_token,
363 : : help_str, sizeof(help_str)) < 0) {
364 : : printf("Error: help operation failed!\n");
365 : 0 : return -1;
366 : : }
367 : : }
368 : :
369 : : return 0;
370 : : }
|