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_string_fns.h>
10 : :
11 : : #include <cmdline_parse.h>
12 : : #include <cmdline_parse_num.h>
13 : :
14 : : #include "test_cmdline.h"
15 : :
16 : : struct num_unsigned_str {
17 : : const char * str;
18 : : uint64_t result;
19 : : };
20 : :
21 : : struct num_signed_str {
22 : : const char * str;
23 : : int64_t result;
24 : : };
25 : :
26 : : const struct num_unsigned_str num_valid_positive_strs[] = {
27 : : /* decimal positive */
28 : : {"0", 0 },
29 : : {"127", INT8_MAX },
30 : : {"128", INT8_MAX + 1 },
31 : : {"255", UINT8_MAX },
32 : : {"256", UINT8_MAX + 1 },
33 : : {"32767", INT16_MAX },
34 : : {"32768", INT16_MAX + 1 },
35 : : {"65535", UINT16_MAX },
36 : : {"65536", UINT16_MAX + 1 },
37 : : {"2147483647", INT32_MAX },
38 : : {"2147483648", INT32_MAX + 1U },
39 : : {"4294967295", UINT32_MAX },
40 : : {"4294967296", UINT32_MAX + 1ULL },
41 : : {"9223372036854775807", INT64_MAX },
42 : : {"9223372036854775808", INT64_MAX + 1ULL},
43 : : {"18446744073709551615", UINT64_MAX },
44 : : /* hexadecimal (no leading zeroes) */
45 : : {"0x0", 0 },
46 : : {"0x7F", INT8_MAX },
47 : : {"0x80", INT8_MAX + 1 },
48 : : {"0xFF", UINT8_MAX },
49 : : {"0x100", UINT8_MAX + 1 },
50 : : {"0x7FFF", INT16_MAX },
51 : : {"0x8000", INT16_MAX + 1 },
52 : : {"0xFFFF", UINT16_MAX },
53 : : {"0x10000", UINT16_MAX + 1 },
54 : : {"0x7FFFFFFF", INT32_MAX },
55 : : {"0x80000000", INT32_MAX + 1U },
56 : : {"0xFFFFFFFF", UINT32_MAX },
57 : : {"0x100000000", UINT32_MAX + 1ULL },
58 : : {"0x7FFFFFFFFFFFFFFF", INT64_MAX },
59 : : {"0x8000000000000000", INT64_MAX + 1ULL},
60 : : {"0xFFFFFFFFFFFFFFFF", UINT64_MAX },
61 : : /* hexadecimal (with leading zeroes) */
62 : : {"0x00", 0 },
63 : : {"0x7F", INT8_MAX },
64 : : {"0x80", INT8_MAX + 1 },
65 : : {"0xFF", UINT8_MAX },
66 : : {"0x0100", UINT8_MAX + 1 },
67 : : {"0x7FFF", INT16_MAX },
68 : : {"0x8000", INT16_MAX + 1 },
69 : : {"0xFFFF", UINT16_MAX },
70 : : {"0x00010000", UINT16_MAX + 1 },
71 : : {"0x7FFFFFFF", INT32_MAX },
72 : : {"0x80000000", INT32_MAX + 1U },
73 : : {"0xFFFFFFFF", UINT32_MAX },
74 : : {"0x0000000100000000", UINT32_MAX + 1ULL },
75 : : {"0x7FFFFFFFFFFFFFFF", INT64_MAX },
76 : : {"0x8000000000000000", INT64_MAX + 1ULL},
77 : : {"0xFFFFFFFFFFFFFFFF", UINT64_MAX },
78 : : /* check all characters */
79 : : {"0x1234567890ABCDEF", 0x1234567890ABCDEFULL },
80 : : {"0x1234567890abcdef", 0x1234567890ABCDEFULL },
81 : : /* binary (no leading zeroes) */
82 : : {"0b0", 0 },
83 : : {"0b1111111", INT8_MAX },
84 : : {"0b10000000", INT8_MAX + 1 },
85 : : {"0b11111111", UINT8_MAX },
86 : : {"0b100000000", UINT8_MAX + 1 },
87 : : {"0b111111111111111", INT16_MAX },
88 : : {"0b1000000000000000", INT16_MAX + 1 },
89 : : {"0b1111111111111111", UINT16_MAX },
90 : : {"0b10000000000000000", UINT16_MAX + 1 },
91 : : {"0b1111111111111111111111111111111", INT32_MAX },
92 : : {"0b10000000000000000000000000000000", INT32_MAX + 1U },
93 : : {"0b11111111111111111111111111111111", UINT32_MAX },
94 : : {"0b100000000000000000000000000000000", UINT32_MAX + 1ULL },
95 : : {"0b111111111111111111111111111111111111111111111111111111111111111",
96 : : INT64_MAX },
97 : : {"0b1000000000000000000000000000000000000000000000000000000000000000",
98 : : INT64_MAX + 1ULL},
99 : : {"0b1111111111111111111111111111111111111111111111111111111111111111",
100 : : UINT64_MAX },
101 : : /* binary (with leading zeroes) */
102 : : {"0b01111111", INT8_MAX },
103 : : {"0b0000000100000000", UINT8_MAX + 1 },
104 : : {"0b0111111111111111", INT16_MAX },
105 : : {"0b00000000000000010000000000000000", UINT16_MAX + 1 },
106 : : {"0b01111111111111111111111111111111", INT32_MAX },
107 : : {"0b0000000000000000000000000000000100000000000000000000000000000000",
108 : : UINT32_MAX + 1ULL },
109 : : {"0b0111111111111111111111111111111111111111111111111111111111111111",
110 : : INT64_MAX },
111 : : /* octal */
112 : : {"00", 0 },
113 : : {"0177", INT8_MAX },
114 : : {"0200", INT8_MAX + 1 },
115 : : {"0377", UINT8_MAX },
116 : : {"0400", UINT8_MAX + 1 },
117 : : {"077777", INT16_MAX },
118 : : {"0100000", INT16_MAX + 1 },
119 : : {"0177777", UINT16_MAX },
120 : : {"0200000", UINT16_MAX + 1 },
121 : : {"017777777777", INT32_MAX },
122 : : {"020000000000", INT32_MAX + 1U },
123 : : {"037777777777", UINT32_MAX },
124 : : {"040000000000", UINT32_MAX + 1ULL },
125 : : {"0777777777777777777777", INT64_MAX },
126 : : {"01000000000000000000000", INT64_MAX + 1ULL},
127 : : {"01777777777777777777777", UINT64_MAX },
128 : : /* check all numbers */
129 : : {"012345670", 012345670 },
130 : : {"076543210", 076543210 },
131 : : };
132 : :
133 : : const struct num_signed_str num_valid_negative_strs[] = {
134 : : /* deciman negative */
135 : : {"-128", INT8_MIN },
136 : : {"-129", INT8_MIN - 1 },
137 : : {"-32768", INT16_MIN },
138 : : {"-32769", INT16_MIN - 1 },
139 : : {"-2147483648", INT32_MIN },
140 : : {"-2147483649", INT32_MIN - 1LL },
141 : : {"-9223372036854775808", INT64_MIN },
142 : : };
143 : :
144 : : const struct num_unsigned_str num_garbage_positive_strs[] = {
145 : : /* valid strings with garbage on the end, should still be valid */
146 : : /* decimal */
147 : : {"9223372036854775807\0garbage", INT64_MAX },
148 : : {"9223372036854775807\tgarbage", INT64_MAX },
149 : : {"9223372036854775807\rgarbage", INT64_MAX },
150 : : {"9223372036854775807\ngarbage", INT64_MAX },
151 : : {"9223372036854775807#garbage", INT64_MAX },
152 : : {"9223372036854775807 garbage", INT64_MAX },
153 : : /* hex */
154 : : {"0x7FFFFFFFFFFFFFFF\0garbage", INT64_MAX },
155 : : {"0x7FFFFFFFFFFFFFFF\tgarbage", INT64_MAX },
156 : : {"0x7FFFFFFFFFFFFFFF\rgarbage", INT64_MAX },
157 : : {"0x7FFFFFFFFFFFFFFF\ngarbage", INT64_MAX },
158 : : {"0x7FFFFFFFFFFFFFFF#garbage", INT64_MAX },
159 : : {"0x7FFFFFFFFFFFFFFF garbage", INT64_MAX },
160 : : /* binary */
161 : : {"0b1111111111111111111111111111111\0garbage", INT32_MAX },
162 : : {"0b1111111111111111111111111111111\rgarbage", INT32_MAX },
163 : : {"0b1111111111111111111111111111111\tgarbage", INT32_MAX },
164 : : {"0b1111111111111111111111111111111\ngarbage", INT32_MAX },
165 : : {"0b1111111111111111111111111111111#garbage", INT32_MAX },
166 : : {"0b1111111111111111111111111111111 garbage", INT32_MAX },
167 : : /* octal */
168 : : {"01777777777777777777777\0garbage", UINT64_MAX },
169 : : {"01777777777777777777777\rgarbage", UINT64_MAX },
170 : : {"01777777777777777777777\tgarbage", UINT64_MAX },
171 : : {"01777777777777777777777\ngarbage", UINT64_MAX },
172 : : {"01777777777777777777777#garbage", UINT64_MAX },
173 : : {"01777777777777777777777 garbage", UINT64_MAX },
174 : : };
175 : :
176 : : const struct num_signed_str num_garbage_negative_strs[] = {
177 : : /* valid strings with garbage on the end, should still be valid */
178 : : {"-9223372036854775808\0garbage", INT64_MIN },
179 : : {"-9223372036854775808\rgarbage", INT64_MIN },
180 : : {"-9223372036854775808\tgarbage", INT64_MIN },
181 : : {"-9223372036854775808\ngarbage", INT64_MIN },
182 : : {"-9223372036854775808#garbage", INT64_MIN },
183 : : {"-9223372036854775808 garbage", INT64_MIN },
184 : : };
185 : :
186 : : const char * num_invalid_strs[] = {
187 : : "18446744073709551616", /* out of range unsigned */
188 : : "-9223372036854775809", /* out of range negative signed */
189 : : "0x10000000000000000", /* out of range hex */
190 : : /* out of range binary */
191 : : "0b10000000000000000000000000000000000000000000000000000000000000000",
192 : : "020000000000000000000000", /* out of range octal */
193 : : /* wrong chars */
194 : : "0123456239",
195 : : "0x1234580AGE",
196 : : "0b0111010101g001",
197 : : "0b01110101017001",
198 : : /* false negative numbers */
199 : : "-12345F623",
200 : : "-0x1234580A",
201 : : "-0b0111010101",
202 : : /* too long (128+ chars) */
203 : : ("0b1111000011110000111100001111000011110000111100001111000011110000"
204 : : "1111000011110000111100001111000011110000111100001111000011110000"),
205 : : "1E3",
206 : : "0A",
207 : : "-B",
208 : : "+4",
209 : : "1.23G",
210 : : "",
211 : : " ",
212 : : "#",
213 : : "\r",
214 : : "\t",
215 : : "\n",
216 : : "\0",
217 : : };
218 : :
219 : : static int
220 : 920 : can_parse_unsigned(uint64_t expected_result, enum cmdline_numtype type)
221 : : {
222 [ + + + + : 920 : switch (type) {
+ + + + ]
223 : 115 : case RTE_UINT8:
224 [ + + ]: 115 : if (expected_result > UINT8_MAX)
225 : 94 : return 0;
226 : : break;
227 : 115 : case RTE_UINT16:
228 [ + + ]: 115 : if (expected_result > UINT16_MAX)
229 : 72 : return 0;
230 : : break;
231 : 115 : case RTE_UINT32:
232 [ + + ]: 115 : if (expected_result > UINT32_MAX)
233 : 42 : return 0;
234 : : break;
235 : 115 : case RTE_INT8:
236 [ + + ]: 115 : if (expected_result > INT8_MAX)
237 : 104 : return 0;
238 : : break;
239 : 115 : case RTE_INT16:
240 [ + + ]: 115 : if (expected_result > INT16_MAX)
241 : 82 : return 0;
242 : : break;
243 : 115 : case RTE_INT32:
244 [ + + ]: 115 : if (expected_result > INT32_MAX)
245 : 52 : return 0;
246 : : break;
247 : 115 : case RTE_INT64:
248 [ + + ]: 115 : if (expected_result > INT64_MAX)
249 : 16 : return 0;
250 : : break;
251 : : default:
252 : : return 1;
253 : : }
254 : : return 1;
255 : : }
256 : :
257 : : static int
258 : 104 : can_parse_signed(int64_t expected_result, enum cmdline_numtype type)
259 : : {
260 [ + + + + : 104 : switch (type) {
+ + + + ]
261 : 13 : case RTE_UINT8:
262 [ + - ]: 13 : if (expected_result > UINT8_MAX || expected_result < 0)
263 : 13 : return 0;
264 : : break;
265 : 13 : case RTE_UINT16:
266 [ + - ]: 13 : if (expected_result > UINT16_MAX || expected_result < 0)
267 : 13 : return 0;
268 : : break;
269 : 13 : case RTE_UINT32:
270 [ + - ]: 13 : if (expected_result > UINT32_MAX || expected_result < 0)
271 : 13 : return 0;
272 : : break;
273 : 13 : case RTE_UINT64:
274 [ + - ]: 13 : if (expected_result < 0)
275 : 13 : return 0;
276 : : break;
277 : 13 : case RTE_INT8:
278 [ + + ]: 13 : if (expected_result > INT8_MAX || expected_result < INT8_MIN)
279 : 12 : return 0;
280 : : break;
281 : 13 : case RTE_INT16:
282 [ + + ]: 13 : if (expected_result > INT16_MAX || expected_result < INT16_MIN)
283 : 10 : return 0;
284 : : break;
285 : 13 : case RTE_INT32:
286 [ + + ]: 13 : if (expected_result > INT32_MAX || expected_result < INT32_MIN)
287 : 8 : return 0;
288 : : break;
289 : : default:
290 : : return 1;
291 : : }
292 : : return 1;
293 : : }
294 : :
295 : : /* test invalid parameters */
296 : : int
297 : 1 : test_parse_num_invalid_param(void)
298 : : {
299 : : char buf[CMDLINE_TEST_BUFSIZE];
300 : : uint32_t result;
301 : : cmdline_parse_token_num_t token;
302 : : int ret = 0;
303 : :
304 : : /* set up a token */
305 : 1 : token.num_data.type = RTE_UINT32;
306 : :
307 : : /* copy string to buffer */
308 : : strlcpy(buf, num_valid_positive_strs[0].str, sizeof(buf));
309 : :
310 : : /* try all null */
311 : 1 : ret = cmdline_parse_num(NULL, NULL, NULL, 0);
312 [ - + ]: 1 : if (ret != -1) {
313 : : printf("Error: parser accepted null parameters!\n");
314 : 0 : return -1;
315 : : }
316 : :
317 : : /* try null token */
318 : 1 : ret = cmdline_parse_num(NULL, buf, (void*)&result, sizeof(result));
319 [ - + ]: 1 : if (ret != -1) {
320 : : printf("Error: parser accepted null token!\n");
321 : 0 : return -1;
322 : : }
323 : :
324 : : /* try null buf */
325 : 1 : ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token, NULL,
326 : : (void*)&result, sizeof(result));
327 [ - + ]: 1 : if (ret != -1) {
328 : : printf("Error: parser accepted null string!\n");
329 : 0 : return -1;
330 : : }
331 : :
332 : : /* try null result */
333 : 1 : ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token, buf,
334 : : NULL, 0);
335 [ - + ]: 1 : if (ret == -1) {
336 : : printf("Error: parser rejected null result!\n");
337 : 0 : return -1;
338 : : }
339 : :
340 : : /* test help function */
341 : : memset(&buf, 0, sizeof(buf));
342 : :
343 : : /* try all null */
344 : 1 : ret = cmdline_get_help_num(NULL, NULL, 0);
345 [ - + ]: 1 : if (ret != -1) {
346 : : printf("Error: help function accepted null parameters!\n");
347 : 0 : return -1;
348 : : }
349 : :
350 : : /* try null token */
351 : 1 : ret = cmdline_get_help_num(NULL, buf, sizeof(buf));
352 [ - + ]: 1 : if (ret != -1) {
353 : : printf("Error: help function accepted null token!\n");
354 : 0 : return -1;
355 : : }
356 : :
357 : : /* coverage! */
358 : 1 : ret = cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token, buf, sizeof(buf));
359 [ - + ]: 1 : if (ret < 0) {
360 : : printf("Error: help function failed with valid parameters!\n");
361 : 0 : return -1;
362 : : }
363 : :
364 : : return 0;
365 : : }
366 : : /* test valid parameters but invalid data */
367 : : int
368 : 1 : test_parse_num_invalid_data(void)
369 : : {
370 : : enum cmdline_numtype type;
371 : : int ret = 0;
372 : : unsigned i;
373 : : char buf[CMDLINE_TEST_BUFSIZE];
374 : : uint64_t result; /* pick largest buffer */
375 : : cmdline_parse_token_num_t token;
376 : :
377 : : /* cycle through all possible parsed types */
378 [ + + ]: 9 : for (type = RTE_UINT8; type <= RTE_INT64; type++) {
379 : 8 : token.num_data.type = type;
380 : :
381 : : /* test full strings */
382 [ + + ]: 208 : for (i = 0; i < RTE_DIM(num_invalid_strs); i++) {
383 : :
384 : : memset(&result, 0, sizeof(uint64_t));
385 : : memset(&buf, 0, sizeof(buf));
386 : :
387 : 200 : ret = cmdline_parse_num((cmdline_parse_token_hdr_t*)&token,
388 : : num_invalid_strs[i], (void*)&result, sizeof(result));
389 [ - + ]: 200 : if (ret != -1) {
390 : : /* get some info about what we are trying to parse */
391 : 0 : cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token,
392 : : buf, sizeof(buf));
393 : :
394 : 0 : printf("Error: parsing %s as %s succeeded!\n",
395 : : num_invalid_strs[i], buf);
396 : 0 : return -1;
397 : : }
398 : : }
399 : : }
400 : : return 0;
401 : : }
402 : :
403 : : /* test valid parameters and data */
404 : : int
405 : 1 : test_parse_num_valid(void)
406 : : {
407 : : int ret = 0;
408 : : enum cmdline_numtype type;
409 : : unsigned i;
410 : : char buf[CMDLINE_TEST_BUFSIZE];
411 : : uint64_t result;
412 : : cmdline_parse_token_num_t token;
413 : :
414 : : /** valid strings **/
415 : :
416 : : /* cycle through all possible parsed types */
417 [ + + ]: 9 : for (type = RTE_UINT8; type <= RTE_INT64; type++) {
418 : 8 : token.num_data.type = type;
419 : :
420 : : /* test positive strings */
421 [ + + ]: 736 : for (i = 0; i < RTE_DIM(num_valid_positive_strs); i++) {
422 : 728 : result = 0;
423 : : memset(&buf, 0, sizeof(buf));
424 : :
425 : 728 : cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token,
426 : : buf, sizeof(buf));
427 : :
428 : 728 : ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token,
429 : 728 : num_valid_positive_strs[i].str,
430 : : (void*)&result, sizeof(result));
431 : :
432 : : /* if it should have passed but didn't, or if it should have failed but didn't */
433 [ - + ]: 728 : if ((ret < 0) == (can_parse_unsigned(num_valid_positive_strs[i].result, type) > 0)) {
434 : : printf("Error: parser behaves unexpectedly when parsing %s as %s!\n",
435 : : num_valid_positive_strs[i].str, buf);
436 : 0 : return -1;
437 : : }
438 : : /* check if result matches what it should have matched
439 : : * since unsigned numbers don't care about number of bits, we can just convert
440 : : * everything to uint64_t without any worries. */
441 [ + + - + ]: 728 : if (ret > 0 && num_valid_positive_strs[i].result != result) {
442 : : printf("Error: parsing %s as %s failed: result mismatch!\n",
443 : : num_valid_positive_strs[i].str, buf);
444 : 0 : return -1;
445 : : }
446 : : }
447 : :
448 : : /* test negative strings */
449 [ + + ]: 64 : for (i = 0; i < RTE_DIM(num_valid_negative_strs); i++) {
450 : 56 : result = 0;
451 : : memset(&buf, 0, sizeof(buf));
452 : :
453 : 56 : cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token,
454 : : buf, sizeof(buf));
455 : :
456 : 56 : ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token,
457 : 56 : num_valid_negative_strs[i].str,
458 : : (void*)&result, sizeof(result));
459 : :
460 : : /* if it should have passed but didn't, or if it should have failed but didn't */
461 [ - + ]: 56 : if ((ret < 0) == (can_parse_signed(num_valid_negative_strs[i].result, type) > 0)) {
462 : : printf("Error: parser behaves unexpectedly when parsing %s as %s!\n",
463 : : num_valid_negative_strs[i].str, buf);
464 : 0 : return -1;
465 : : }
466 : : /* check if result matches what it should have matched
467 : : * the result is signed in this case, so we have to account for that */
468 [ + + ]: 56 : if (ret > 0) {
469 : : /* detect negative */
470 [ + + + + ]: 16 : switch (type) {
471 : 1 : case RTE_INT8:
472 : 1 : result = (int8_t) result;
473 : 1 : break;
474 : 3 : case RTE_INT16:
475 : 3 : result = (int16_t) result;
476 : 3 : break;
477 : 5 : case RTE_INT32:
478 : 5 : result = (int32_t) result;
479 : 5 : break;
480 : : default:
481 : : break;
482 : : }
483 [ + - ]: 16 : if (num_valid_negative_strs[i].result == (int64_t) result)
484 : 16 : continue;
485 : : printf("Error: parsing %s as %s failed: result mismatch!\n",
486 : : num_valid_negative_strs[i].str, buf);
487 : 0 : return -1;
488 : : }
489 : : }
490 : : }
491 : :
492 : : /** garbage strings **/
493 : :
494 : : /* cycle through all possible parsed types */
495 [ + + ]: 9 : for (type = RTE_UINT8; type <= RTE_INT64; type++) {
496 : 8 : token.num_data.type = type;
497 : :
498 : : /* test positive garbage strings */
499 [ + + ]: 200 : for (i = 0; i < RTE_DIM(num_garbage_positive_strs); i++) {
500 : 192 : result = 0;
501 : : memset(&buf, 0, sizeof(buf));
502 : :
503 : 192 : cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token,
504 : : buf, sizeof(buf));
505 : :
506 : 192 : ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token,
507 : 192 : num_garbage_positive_strs[i].str,
508 : : (void*)&result, sizeof(result));
509 : :
510 : : /* if it should have passed but didn't, or if it should have failed but didn't */
511 [ - + ]: 192 : if ((ret < 0) == (can_parse_unsigned(num_garbage_positive_strs[i].result, type) > 0)) {
512 : : printf("Error: parser behaves unexpectedly when parsing %s as %s!\n",
513 : : num_garbage_positive_strs[i].str, buf);
514 : 0 : return -1;
515 : : }
516 : : /* check if result matches what it should have matched
517 : : * since unsigned numbers don't care about number of bits, we can just convert
518 : : * everything to uint64_t without any worries. */
519 [ + + - + ]: 192 : if (ret > 0 && num_garbage_positive_strs[i].result != result) {
520 : : printf("Error: parsing %s as %s failed: result mismatch!\n",
521 : : num_garbage_positive_strs[i].str, buf);
522 : 0 : return -1;
523 : : }
524 : : }
525 : :
526 : : /* test negative strings */
527 [ + + ]: 56 : for (i = 0; i < RTE_DIM(num_garbage_negative_strs); i++) {
528 : 48 : result = 0;
529 : : memset(&buf, 0, sizeof(buf));
530 : :
531 : 48 : cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token,
532 : : buf, sizeof(buf));
533 : :
534 : 48 : ret = cmdline_parse_num((cmdline_parse_token_hdr_t*) &token,
535 : 48 : num_garbage_negative_strs[i].str,
536 : : (void*)&result, sizeof(result));
537 : :
538 : : /* if it should have passed but didn't, or if it should have failed but didn't */
539 [ - + ]: 48 : if ((ret < 0) == (can_parse_signed(num_garbage_negative_strs[i].result, type) > 0)) {
540 : : printf("Error: parser behaves unexpectedly when parsing %s as %s!\n",
541 : : num_garbage_negative_strs[i].str, buf);
542 : 0 : return -1;
543 : : }
544 : : /* check if result matches what it should have matched
545 : : * the result is signed in this case, so we have to account for that */
546 [ + + ]: 48 : if (ret > 0) {
547 : : /* detect negative */
548 [ - - - + ]: 6 : switch (type) {
549 : 0 : case RTE_INT8:
550 [ # # ]: 0 : if (result & (INT8_MAX + 1))
551 : 0 : result |= 0xFFFFFFFFFFFFFF00ULL;
552 : : break;
553 : 0 : case RTE_INT16:
554 [ # # ]: 0 : if (result & (INT16_MAX + 1))
555 : 0 : result |= 0xFFFFFFFFFFFF0000ULL;
556 : : break;
557 : 0 : case RTE_INT32:
558 [ # # ]: 0 : if (result & (INT32_MAX + 1ULL))
559 : 0 : result |= 0xFFFFFFFF00000000ULL;
560 : : break;
561 : : default:
562 : : break;
563 : : }
564 [ + - ]: 6 : if (num_garbage_negative_strs[i].result == (int64_t) result)
565 : 6 : continue;
566 : : printf("Error: parsing %s as %s failed: result mismatch!\n",
567 : : num_garbage_negative_strs[i].str, buf);
568 : 0 : return -1;
569 : : }
570 : : }
571 : : }
572 : :
573 : : memset(&buf, 0, sizeof(buf));
574 : :
575 : : /* coverage! */
576 : 1 : cmdline_get_help_num((cmdline_parse_token_hdr_t*)&token,
577 : : buf, sizeof(buf));
578 : :
579 : 1 : return 0;
580 : : }
|