1 /*
2 * cutils.c unit-tests
3 *
4 * Copyright Red Hat
5 *
6 * Authors:
7 * Eduardo Habkost <ehabkost@redhat.com>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 * THE SOFTWARE.
26 */
27
28 #include <math.h>
29
30 #include "qemu/osdep.h"
31 #include "qemu/cutils.h"
32 #include "qemu/units.h"
33
test_parse_uint_null(void)34 static void test_parse_uint_null(void)
35 {
36 uint64_t i = 999;
37 const char *endptr = "somewhere";
38 int r;
39
40 r = parse_uint(NULL, &endptr, 0, &i);
41
42 g_assert_cmpint(r, ==, -EINVAL);
43 g_assert_cmpuint(i, ==, 0);
44 g_assert_null(endptr);
45 }
46
test_parse_uint_empty(void)47 static void test_parse_uint_empty(void)
48 {
49 uint64_t i = 999;
50 const char *endptr = "somewhere";
51 const char *str = "";
52 int r;
53
54 r = parse_uint(str, &endptr, 0, &i);
55
56 g_assert_cmpint(r, ==, -EINVAL);
57 g_assert_cmpuint(i, ==, 0);
58 g_assert_true(endptr == str);
59 }
60
test_parse_uint_whitespace(void)61 static void test_parse_uint_whitespace(void)
62 {
63 uint64_t i = 999;
64 const char *endptr = "somewhere";
65 const char *str = " \t ";
66 int r;
67
68 r = parse_uint(str, &endptr, 0, &i);
69
70 g_assert_cmpint(r, ==, -EINVAL);
71 g_assert_cmpuint(i, ==, 0);
72 g_assert_true(endptr == str);
73 }
74
75
test_parse_uint_invalid(void)76 static void test_parse_uint_invalid(void)
77 {
78 uint64_t i = 999;
79 const char *endptr = "somewhere";
80 const char *str = " \t xxx";
81 int r;
82
83 r = parse_uint(str, &endptr, 0, &i);
84
85 g_assert_cmpint(r, ==, -EINVAL);
86 g_assert_cmpuint(i, ==, 0);
87 g_assert_true(endptr == str);
88 }
89
90
test_parse_uint_trailing(void)91 static void test_parse_uint_trailing(void)
92 {
93 uint64_t i = 999;
94 const char *endptr = "somewhere";
95 const char *str = "123xxx";
96 int r;
97
98 r = parse_uint(str, &endptr, 0, &i);
99
100 g_assert_cmpint(r, ==, 0);
101 g_assert_cmpuint(i, ==, 123);
102 g_assert_true(endptr == str + 3);
103 }
104
test_parse_uint_correct(void)105 static void test_parse_uint_correct(void)
106 {
107 uint64_t i = 999;
108 const char *endptr = "somewhere";
109 const char *str = "123";
110 int r;
111
112 r = parse_uint(str, &endptr, 0, &i);
113
114 g_assert_cmpint(r, ==, 0);
115 g_assert_cmpuint(i, ==, 123);
116 g_assert_true(endptr == str + strlen(str));
117 }
118
test_parse_uint_octal(void)119 static void test_parse_uint_octal(void)
120 {
121 uint64_t i = 999;
122 const char *endptr = "somewhere";
123 const char *str = "0123";
124 int r;
125
126 r = parse_uint(str, &endptr, 0, &i);
127
128 g_assert_cmpint(r, ==, 0);
129 g_assert_cmpuint(i, ==, 0123);
130 g_assert_true(endptr == str + strlen(str));
131 }
132
test_parse_uint_decimal(void)133 static void test_parse_uint_decimal(void)
134 {
135 uint64_t i = 999;
136 const char *endptr = "somewhere";
137 const char *str = "0123";
138 int r;
139
140 r = parse_uint(str, &endptr, 10, &i);
141
142 g_assert_cmpint(r, ==, 0);
143 g_assert_cmpuint(i, ==, 123);
144 g_assert_true(endptr == str + strlen(str));
145 }
146
test_parse_uint_llong_max(void)147 static void test_parse_uint_llong_max(void)
148 {
149 uint64_t i = 999;
150 const char *endptr = "somewhere";
151 char *str = g_strdup_printf("%llu", (unsigned long long)LLONG_MAX + 1);
152 int r;
153
154 r = parse_uint(str, &endptr, 0, &i);
155
156 g_assert_cmpint(r, ==, 0);
157 g_assert_cmpuint(i, ==, (unsigned long long)LLONG_MAX + 1);
158 g_assert_true(endptr == str + strlen(str));
159
160 g_free(str);
161 }
162
test_parse_uint_max(void)163 static void test_parse_uint_max(void)
164 {
165 uint64_t i = 999;
166 const char *endptr = "somewhere";
167 char *str = g_strdup_printf("%llu", ULLONG_MAX);
168 int r;
169
170 r = parse_uint(str, &endptr, 0, &i);
171
172 g_assert_cmpint(r, ==, 0);
173 g_assert_cmpuint(i, ==, ULLONG_MAX);
174 g_assert_true(endptr == str + strlen(str));
175
176 g_free(str);
177 }
178
test_parse_uint_overflow(void)179 static void test_parse_uint_overflow(void)
180 {
181 uint64_t i;
182 const char *endptr;
183 const char *str;
184 int r;
185
186 i = 999;
187 endptr = "somewhere";
188 str = "99999999999999999999999999999999999999";
189 r = parse_uint(str, &endptr, 0, &i);
190 g_assert_cmpint(r, ==, -ERANGE);
191 g_assert_cmpuint(i, ==, ULLONG_MAX);
192 g_assert_true(endptr == str + strlen(str));
193
194 i = 999;
195 endptr = "somewhere";
196 str = "0x10000000000000000"; /* 65 bits, 64-bit sign bit clear */
197 r = parse_uint(str, &endptr, 0, &i);
198 g_assert_cmpint(r, ==, -ERANGE);
199 g_assert_cmpuint(i, ==, ULLONG_MAX);
200 g_assert_true(endptr == str + strlen(str));
201
202 i = 999;
203 endptr = "somewhere";
204 str = "0x18000000080000000"; /* 65 bits, 64-bit sign bit set */
205 r = parse_uint(str, &endptr, 0, &i);
206 g_assert_cmpint(r, ==, -ERANGE);
207 g_assert_cmpuint(i, ==, ULLONG_MAX);
208 g_assert_true(endptr == str + strlen(str));
209 }
210
test_parse_uint_negative(void)211 static void test_parse_uint_negative(void)
212 {
213 uint64_t i;
214 const char *endptr;
215 const char *str;
216 int r;
217
218 i = 999;
219 endptr = "somewhere";
220 str = " \t -321";
221 r = parse_uint(str, &endptr, 0, &i);
222 g_assert_cmpint(r, ==, -ERANGE);
223 g_assert_cmpuint(i, ==, 0);
224 g_assert_true(endptr == str + strlen(str));
225
226 i = 999;
227 endptr = "somewhere";
228 str = "-0xffffffff00000001";
229 r = parse_uint(str, &endptr, 0, &i);
230 g_assert_cmpint(r, ==, -ERANGE);
231 g_assert_cmpuint(i, ==, 0);
232 g_assert_true(endptr == str + strlen(str));
233 }
234
test_parse_uint_negzero(void)235 static void test_parse_uint_negzero(void)
236 {
237 uint64_t i = 999;
238 const char *endptr = "somewhere";
239 const char *str = " -0";
240 int r;
241
242 r = parse_uint(str, &endptr, 0, &i);
243
244 g_assert_cmpint(r, ==, -ERANGE);
245 g_assert_cmpuint(i, ==, 0);
246 g_assert_true(endptr == str + strlen(str));
247 }
248
test_parse_uint_full_trailing(void)249 static void test_parse_uint_full_trailing(void)
250 {
251 uint64_t i = 999;
252 const char *str = "123xxx";
253 int r;
254
255 r = parse_uint_full(str, 0, &i);
256
257 g_assert_cmpint(r, ==, -EINVAL);
258 g_assert_cmpuint(i, ==, 0);
259 }
260
test_parse_uint_full_correct(void)261 static void test_parse_uint_full_correct(void)
262 {
263 uint64_t i = 999;
264 const char *str = "123";
265 int r;
266
267 r = parse_uint_full(str, 0, &i);
268
269 g_assert_cmpint(r, ==, 0);
270 g_assert_cmpuint(i, ==, 123);
271 }
272
test_parse_uint_full_erange_junk(void)273 static void test_parse_uint_full_erange_junk(void)
274 {
275 /* EINVAL has priority over ERANGE */
276 uint64_t i = 999;
277 const char *str = "-2junk";
278 int r;
279
280 r = parse_uint_full(str, 0, &i);
281
282 g_assert_cmpint(r, ==, -EINVAL);
283 g_assert_cmpuint(i, ==, 0);
284 }
285
test_parse_uint_full_null(void)286 static void test_parse_uint_full_null(void)
287 {
288 uint64_t i = 999;
289 const char *str = NULL;
290 int r;
291
292 r = parse_uint_full(str, 0, &i);
293
294 g_assert_cmpint(r, ==, -EINVAL);
295 g_assert_cmpuint(i, ==, 0);
296 }
297
test_qemu_strtoi_correct(void)298 static void test_qemu_strtoi_correct(void)
299 {
300 const char *str = "12345 foo";
301 char f = 'X';
302 const char *endptr = &f;
303 int res = 999;
304 int err;
305
306 err = qemu_strtoi(str, &endptr, 0, &res);
307
308 g_assert_cmpint(err, ==, 0);
309 g_assert_cmpint(res, ==, 12345);
310 g_assert_true(endptr == str + 5);
311 }
312
test_qemu_strtoi_null(void)313 static void test_qemu_strtoi_null(void)
314 {
315 char f = 'X';
316 const char *endptr = &f;
317 int res = 999;
318 int err;
319
320 err = qemu_strtoi(NULL, &endptr, 0, &res);
321
322 g_assert_cmpint(err, ==, -EINVAL);
323 g_assert_cmpint(res, ==, 0);
324 g_assert_null(endptr);
325 }
326
test_qemu_strtoi_empty(void)327 static void test_qemu_strtoi_empty(void)
328 {
329 const char *str = "";
330 char f = 'X';
331 const char *endptr = &f;
332 int res = 999;
333 int err;
334
335 err = qemu_strtoi(str, &endptr, 0, &res);
336
337 g_assert_cmpint(err, ==, -EINVAL);
338 g_assert_cmpint(res, ==, 0);
339 g_assert_true(endptr == str);
340 }
341
test_qemu_strtoi_whitespace(void)342 static void test_qemu_strtoi_whitespace(void)
343 {
344 const char *str = " \t ";
345 char f = 'X';
346 const char *endptr = &f;
347 int res = 999;
348 int err;
349
350 err = qemu_strtoi(str, &endptr, 0, &res);
351
352 g_assert_cmpint(err, ==, -EINVAL);
353 g_assert_cmpint(res, ==, 0);
354 g_assert_true(endptr == str);
355 }
356
test_qemu_strtoi_invalid(void)357 static void test_qemu_strtoi_invalid(void)
358 {
359 const char *str = " xxxx \t abc";
360 char f = 'X';
361 const char *endptr = &f;
362 int res = 999;
363 int err;
364
365 err = qemu_strtoi(str, &endptr, 0, &res);
366
367 g_assert_cmpint(err, ==, -EINVAL);
368 g_assert_cmpint(res, ==, 0);
369 g_assert_true(endptr == str);
370 }
371
test_qemu_strtoi_trailing(void)372 static void test_qemu_strtoi_trailing(void)
373 {
374 const char *str = "123xxx";
375 char f = 'X';
376 const char *endptr = &f;
377 int res = 999;
378 int err;
379
380 err = qemu_strtoi(str, &endptr, 0, &res);
381
382 g_assert_cmpint(err, ==, 0);
383 g_assert_cmpint(res, ==, 123);
384 g_assert_true(endptr == str + 3);
385 }
386
test_qemu_strtoi_octal(void)387 static void test_qemu_strtoi_octal(void)
388 {
389 const char *str = "0123";
390 char f = 'X';
391 const char *endptr = &f;
392 int res = 999;
393 int err;
394
395 err = qemu_strtoi(str, &endptr, 8, &res);
396
397 g_assert_cmpint(err, ==, 0);
398 g_assert_cmpint(res, ==, 0123);
399 g_assert_true(endptr == str + strlen(str));
400
401 res = 999;
402 endptr = &f;
403 err = qemu_strtoi(str, &endptr, 0, &res);
404
405 g_assert_cmpint(err, ==, 0);
406 g_assert_cmpint(res, ==, 0123);
407 g_assert_true(endptr == str + strlen(str));
408 }
409
test_qemu_strtoi_decimal(void)410 static void test_qemu_strtoi_decimal(void)
411 {
412 const char *str = "0123";
413 char f = 'X';
414 const char *endptr = &f;
415 int res = 999;
416 int err;
417
418 err = qemu_strtoi(str, &endptr, 10, &res);
419
420 g_assert_cmpint(err, ==, 0);
421 g_assert_cmpint(res, ==, 123);
422 g_assert_true(endptr == str + strlen(str));
423
424 str = "123";
425 res = 999;
426 endptr = &f;
427 err = qemu_strtoi(str, &endptr, 0, &res);
428
429 g_assert_cmpint(err, ==, 0);
430 g_assert_cmpint(res, ==, 123);
431 g_assert_true(endptr == str + strlen(str));
432 }
433
test_qemu_strtoi_hex(void)434 static void test_qemu_strtoi_hex(void)
435 {
436 const char *str = "0123";
437 char f = 'X';
438 const char *endptr = &f;
439 int res = 999;
440 int err;
441
442 err = qemu_strtoi(str, &endptr, 16, &res);
443
444 g_assert_cmpint(err, ==, 0);
445 g_assert_cmpint(res, ==, 0x123);
446 g_assert_true(endptr == str + strlen(str));
447
448 str = "0x123";
449 res = 999;
450 endptr = &f;
451 err = qemu_strtoi(str, &endptr, 0, &res);
452
453 g_assert_cmpint(err, ==, 0);
454 g_assert_cmpint(res, ==, 0x123);
455 g_assert_true(endptr == str + strlen(str));
456
457 str = "0x";
458 res = 999;
459 endptr = &f;
460 err = qemu_strtoi(str, &endptr, 16, &res);
461
462 g_assert_cmpint(err, ==, 0);
463 g_assert_cmpint(res, ==, 0);
464 g_assert_true(endptr == str + 1);
465 }
466
test_qemu_strtoi_max(void)467 static void test_qemu_strtoi_max(void)
468 {
469 char *str = g_strdup_printf("%d", INT_MAX);
470 char f = 'X';
471 const char *endptr = &f;
472 int res = 999;
473 int err;
474
475 err = qemu_strtoi(str, &endptr, 0, &res);
476
477 g_assert_cmpint(err, ==, 0);
478 g_assert_cmpint(res, ==, INT_MAX);
479 g_assert_true(endptr == str + strlen(str));
480 g_free(str);
481 }
482
test_qemu_strtoi_overflow(void)483 static void test_qemu_strtoi_overflow(void)
484 {
485 const char *str;
486 const char *endptr;
487 int res;
488 int err;
489
490 str = "2147483648"; /* INT_MAX + 1ll */
491 endptr = "somewhere";
492 res = 999;
493 err = qemu_strtoi(str, &endptr, 0, &res);
494 g_assert_cmpint(err, ==, -ERANGE);
495 g_assert_cmpint(res, ==, INT_MAX);
496 g_assert_true(endptr == str + strlen(str));
497
498 str = "0x7fffffffffffffff"; /* LLONG_MAX */
499 endptr = "somewhere";
500 res = 999;
501 err = qemu_strtoi(str, &endptr, 0, &res);
502 g_assert_cmpint(err, ==, -ERANGE);
503 g_assert_cmpint(res, ==, INT_MAX);
504 g_assert_true(endptr == str + strlen(str));
505
506 str = "0x8000000000000000"; /* (uint64_t)LLONG_MIN */
507 endptr = "somewhere";
508 res = 999;
509 err = qemu_strtoi(str, &endptr, 0, &res);
510 g_assert_cmpint(err, ==, -ERANGE);
511 g_assert_cmpint(res, ==, INT_MAX);
512 g_assert_true(endptr == str + strlen(str));
513
514 str = "0x10000000000000000"; /* 65 bits, 32-bit sign bit clear */
515 endptr = "somewhere";
516 res = 999;
517 err = qemu_strtoi(str, &endptr, 0, &res);
518 g_assert_cmpint(err, ==, -ERANGE);
519 g_assert_cmpint(res, ==, INT_MAX);
520 g_assert_true(endptr == str + strlen(str));
521
522 str = "0x18000000080000000"; /* 65 bits, 32-bit sign bit set */
523 endptr = "somewhere";
524 res = 999;
525 err = qemu_strtoi(str, &endptr, 0, &res);
526 g_assert_cmpint(err, ==, -ERANGE);
527 g_assert_cmpint(res, ==, INT_MAX);
528 g_assert_true(endptr == str + strlen(str));
529 }
530
test_qemu_strtoi_min(void)531 static void test_qemu_strtoi_min(void)
532 {
533 char *str = g_strdup_printf("%d", INT_MIN);
534 char f = 'X';
535 const char *endptr = &f;
536 int res = 999;
537 int err;
538
539 err = qemu_strtoi(str, &endptr, 0, &res);
540
541 g_assert_cmpint(err, ==, 0);
542 g_assert_cmpint(res, ==, INT_MIN);
543 g_assert_true(endptr == str + strlen(str));
544 g_free(str);
545 }
546
test_qemu_strtoi_underflow(void)547 static void test_qemu_strtoi_underflow(void)
548 {
549 const char *str;
550 const char *endptr;
551 int res;
552 int err;
553
554 str = "-2147483649"; /* INT_MIN - 1ll */
555 endptr = "somewhere";
556 res = 999;
557 err = qemu_strtoi(str, &endptr, 0, &res);
558 g_assert_cmpint(err, ==, -ERANGE);
559 g_assert_cmpint(res, ==, INT_MIN);
560 g_assert_true(endptr == str + strlen(str));
561
562 str = "-0x7fffffffffffffff"; /* -LLONG_MAX */
563 endptr = "somewhere";
564 res = 999;
565 err = qemu_strtoi(str, &endptr, 0, &res);
566 g_assert_cmpint(err, ==, -ERANGE);
567 g_assert_cmpint(res, ==, INT_MIN);
568 g_assert_true(endptr == str + strlen(str));
569
570 str = "-0x8000000000000000"; /* (uint64_t)LLONG_MIN */
571 endptr = "somewhere";
572 res = 999;
573 err = qemu_strtoi(str, &endptr, 0, &res);
574 g_assert_cmpint(err, ==, -ERANGE);
575 g_assert_cmpint(res, ==, INT_MIN);
576 g_assert_true(endptr == str + strlen(str));
577
578 str = "-18446744073709551615"; /* -UINT64_MAX (not 1) */
579 endptr = "somewhere";
580 res = 999;
581 err = qemu_strtoi(str, &endptr, 0, &res);
582 g_assert_cmpint(err, ==, -ERANGE);
583 g_assert_cmpint(res, ==, INT_MIN);
584 g_assert_true(endptr == str + strlen(str));
585
586 str = "-0x10000000000000000"; /* 65 bits, 32-bit sign bit clear */
587 endptr = "somewhere";
588 res = 999;
589 err = qemu_strtoi(str, &endptr, 0, &res);
590 g_assert_cmpint(err, ==, -ERANGE);
591 g_assert_cmpint(res, ==, INT_MIN);
592 g_assert_true(endptr == str + strlen(str));
593
594 str = "-0x18000000080000000"; /* 65 bits, 32-bit sign bit set */
595 endptr = "somewhere";
596 res = 999;
597 err = qemu_strtoi(str, &endptr, 0, &res);
598 g_assert_cmpint(err, ==, -ERANGE);
599 g_assert_cmpint(res, ==, INT_MIN);
600 g_assert_true(endptr == str + strlen(str));
601 }
602
test_qemu_strtoi_negative(void)603 static void test_qemu_strtoi_negative(void)
604 {
605 const char *str;
606 const char *endptr;
607 int res;
608 int err;
609
610 str = " \t -321";
611 endptr = "somewhere";
612 res = 999;
613 err = qemu_strtoi(str, &endptr, 0, &res);
614 g_assert_cmpint(err, ==, 0);
615 g_assert_cmpint(res, ==, -321);
616 g_assert_true(endptr == str + strlen(str));
617
618 str = "-2147483648"; /* INT_MIN */
619 endptr = "somewhere";
620 res = 999;
621 err = qemu_strtoi(str, &endptr, 0, &res);
622 g_assert_cmpint(err, ==, 0);
623 g_assert_cmpint(res, ==, INT_MIN);
624 g_assert_true(endptr == str + strlen(str));
625 }
626
test_qemu_strtoi_negzero(void)627 static void test_qemu_strtoi_negzero(void)
628 {
629 const char *str = " -0";
630 char f = 'X';
631 const char *endptr = &f;
632 int res = 999;
633 int err;
634
635 err = qemu_strtoi(str, &endptr, 0, &res);
636
637 g_assert_cmpint(err, ==, 0);
638 g_assert_cmpint(res, ==, 0);
639 g_assert_true(endptr == str + strlen(str));
640 }
641
test_qemu_strtoi_full_correct(void)642 static void test_qemu_strtoi_full_correct(void)
643 {
644 const char *str = "123";
645 int res = 999;
646 int err;
647
648 err = qemu_strtoi(str, NULL, 0, &res);
649
650 g_assert_cmpint(err, ==, 0);
651 g_assert_cmpint(res, ==, 123);
652 }
653
test_qemu_strtoi_full_null(void)654 static void test_qemu_strtoi_full_null(void)
655 {
656 char f = 'X';
657 const char *endptr = &f;
658 int res = 999;
659 int err;
660
661 err = qemu_strtoi(NULL, &endptr, 0, &res);
662
663 g_assert_cmpint(err, ==, -EINVAL);
664 g_assert_cmpint(res, ==, 0);
665 g_assert_null(endptr);
666 }
667
test_qemu_strtoi_full_empty(void)668 static void test_qemu_strtoi_full_empty(void)
669 {
670 const char *str = "";
671 int res = 999;
672 int err;
673
674 err = qemu_strtoi(str, NULL, 0, &res);
675
676 g_assert_cmpint(err, ==, -EINVAL);
677 g_assert_cmpint(res, ==, 0);
678 }
679
test_qemu_strtoi_full_negative(void)680 static void test_qemu_strtoi_full_negative(void)
681 {
682 const char *str = " \t -321";
683 int res = 999;
684 int err;
685
686 err = qemu_strtoi(str, NULL, 0, &res);
687
688 g_assert_cmpint(err, ==, 0);
689 g_assert_cmpint(res, ==, -321);
690 }
691
test_qemu_strtoi_full_negzero(void)692 static void test_qemu_strtoi_full_negzero(void)
693 {
694 const char *str = " -0";
695 int res = 999;
696 int err;
697
698 err = qemu_strtoi(str, NULL, 0, &res);
699
700 g_assert_cmpint(err, ==, 0);
701 g_assert_cmpint(res, ==, 0);
702 }
703
test_qemu_strtoi_full_trailing(void)704 static void test_qemu_strtoi_full_trailing(void)
705 {
706 const char *str = "123xxx";
707 int res = 999;
708 int err;
709
710 err = qemu_strtoi(str, NULL, 0, &res);
711
712 g_assert_cmpint(err, ==, -EINVAL);
713 g_assert_cmpint(res, ==, 123);
714 }
715
test_qemu_strtoi_full_max(void)716 static void test_qemu_strtoi_full_max(void)
717 {
718 char *str = g_strdup_printf("%d", INT_MAX);
719 int res = 999;
720 int err;
721
722 err = qemu_strtoi(str, NULL, 0, &res);
723
724 g_assert_cmpint(err, ==, 0);
725 g_assert_cmpint(res, ==, INT_MAX);
726 g_free(str);
727 }
728
test_qemu_strtoi_full_erange_junk(void)729 static void test_qemu_strtoi_full_erange_junk(void)
730 {
731 /* EINVAL has priority over ERANGE */
732 const char *str = "-9999999999junk";
733 int res = 999;
734 int err;
735
736 err = qemu_strtoi(str, NULL, 0, &res);
737
738 g_assert_cmpint(err, ==, -EINVAL);
739 g_assert_cmpint(res, ==, INT_MIN);
740 }
741
test_qemu_strtoui_correct(void)742 static void test_qemu_strtoui_correct(void)
743 {
744 const char *str = "12345 foo";
745 char f = 'X';
746 const char *endptr = &f;
747 unsigned int res = 999;
748 int err;
749
750 err = qemu_strtoui(str, &endptr, 0, &res);
751
752 g_assert_cmpint(err, ==, 0);
753 g_assert_cmpuint(res, ==, 12345);
754 g_assert_true(endptr == str + 5);
755 }
756
test_qemu_strtoui_null(void)757 static void test_qemu_strtoui_null(void)
758 {
759 char f = 'X';
760 const char *endptr = &f;
761 unsigned int res = 999;
762 int err;
763
764 err = qemu_strtoui(NULL, &endptr, 0, &res);
765
766 g_assert_cmpint(err, ==, -EINVAL);
767 g_assert_cmpuint(res, ==, 0);
768 g_assert_null(endptr);
769 }
770
test_qemu_strtoui_empty(void)771 static void test_qemu_strtoui_empty(void)
772 {
773 const char *str = "";
774 char f = 'X';
775 const char *endptr = &f;
776 unsigned int res = 999;
777 int err;
778
779 err = qemu_strtoui(str, &endptr, 0, &res);
780
781 g_assert_cmpint(err, ==, -EINVAL);
782 g_assert_cmpuint(res, ==, 0);
783 g_assert_true(endptr == str);
784 }
785
test_qemu_strtoui_whitespace(void)786 static void test_qemu_strtoui_whitespace(void)
787 {
788 const char *str = " \t ";
789 char f = 'X';
790 const char *endptr = &f;
791 unsigned int res = 999;
792 int err;
793
794 err = qemu_strtoui(str, &endptr, 0, &res);
795
796 g_assert_cmpint(err, ==, -EINVAL);
797 g_assert_cmpuint(res, ==, 0);
798 g_assert_true(endptr == str);
799 }
800
test_qemu_strtoui_invalid(void)801 static void test_qemu_strtoui_invalid(void)
802 {
803 const char *str = " xxxx \t abc";
804 char f = 'X';
805 const char *endptr = &f;
806 unsigned int res = 999;
807 int err;
808
809 err = qemu_strtoui(str, &endptr, 0, &res);
810
811 g_assert_cmpint(err, ==, -EINVAL);
812 g_assert_cmpuint(res, ==, 0);
813 g_assert_true(endptr == str);
814 }
815
test_qemu_strtoui_trailing(void)816 static void test_qemu_strtoui_trailing(void)
817 {
818 const char *str = "123xxx";
819 char f = 'X';
820 const char *endptr = &f;
821 unsigned int res = 999;
822 int err;
823
824 err = qemu_strtoui(str, &endptr, 0, &res);
825
826 g_assert_cmpint(err, ==, 0);
827 g_assert_cmpuint(res, ==, 123);
828 g_assert_true(endptr == str + 3);
829 }
830
test_qemu_strtoui_octal(void)831 static void test_qemu_strtoui_octal(void)
832 {
833 const char *str = "0123";
834 char f = 'X';
835 const char *endptr = &f;
836 unsigned int res = 999;
837 int err;
838
839 err = qemu_strtoui(str, &endptr, 8, &res);
840
841 g_assert_cmpint(err, ==, 0);
842 g_assert_cmpuint(res, ==, 0123);
843 g_assert_true(endptr == str + strlen(str));
844
845 res = 999;
846 endptr = &f;
847 err = qemu_strtoui(str, &endptr, 0, &res);
848
849 g_assert_cmpint(err, ==, 0);
850 g_assert_cmpuint(res, ==, 0123);
851 g_assert_true(endptr == str + strlen(str));
852 }
853
test_qemu_strtoui_decimal(void)854 static void test_qemu_strtoui_decimal(void)
855 {
856 const char *str = "0123";
857 char f = 'X';
858 const char *endptr = &f;
859 unsigned int res = 999;
860 int err;
861
862 err = qemu_strtoui(str, &endptr, 10, &res);
863
864 g_assert_cmpint(err, ==, 0);
865 g_assert_cmpuint(res, ==, 123);
866 g_assert_true(endptr == str + strlen(str));
867
868 str = "123";
869 res = 999;
870 endptr = &f;
871 err = qemu_strtoui(str, &endptr, 0, &res);
872
873 g_assert_cmpint(err, ==, 0);
874 g_assert_cmpuint(res, ==, 123);
875 g_assert_true(endptr == str + strlen(str));
876 }
877
test_qemu_strtoui_hex(void)878 static void test_qemu_strtoui_hex(void)
879 {
880 const char *str = "0123";
881 char f = 'X';
882 const char *endptr = &f;
883 unsigned int res = 999;
884 int err;
885
886 err = qemu_strtoui(str, &endptr, 16, &res);
887
888 g_assert_cmpint(err, ==, 0);
889 g_assert_cmphex(res, ==, 0x123);
890 g_assert_true(endptr == str + strlen(str));
891
892 str = "0x123";
893 res = 999;
894 endptr = &f;
895 err = qemu_strtoui(str, &endptr, 0, &res);
896
897 g_assert_cmpint(err, ==, 0);
898 g_assert_cmphex(res, ==, 0x123);
899 g_assert_true(endptr == str + strlen(str));
900
901 str = "0x";
902 res = 999;
903 endptr = &f;
904 err = qemu_strtoui(str, &endptr, 16, &res);
905
906 g_assert_cmpint(err, ==, 0);
907 g_assert_cmphex(res, ==, 0);
908 g_assert_true(endptr == str + 1);
909 }
910
test_qemu_strtoui_wrap(void)911 static void test_qemu_strtoui_wrap(void)
912 {
913 /* wraparound is consistent with 32-bit strtoul */
914 const char *str = "-4294967295"; /* 1 mod 2^32 */
915 char f = 'X';
916 const char *endptr = &f;
917 unsigned int res = 999;
918 int err;
919
920 err = qemu_strtoui(str, &endptr, 0, &res);
921
922 g_assert_cmpint(err, ==, 0);
923 g_assert_cmphex(res, ==, 1);
924 g_assert_true(endptr == str + strlen(str));
925 }
926
test_qemu_strtoui_max(void)927 static void test_qemu_strtoui_max(void)
928 {
929 char *str = g_strdup_printf("%u", UINT_MAX);
930 char f = 'X';
931 const char *endptr = &f;
932 unsigned int res = 999;
933 int err;
934
935 err = qemu_strtoui(str, &endptr, 0, &res);
936
937 g_assert_cmpint(err, ==, 0);
938 g_assert_cmphex(res, ==, UINT_MAX);
939 g_assert_true(endptr == str + strlen(str));
940 g_free(str);
941 }
942
test_qemu_strtoui_overflow(void)943 static void test_qemu_strtoui_overflow(void)
944 {
945 const char *str;
946 const char *endptr;
947 unsigned int res;
948 int err;
949
950 str = "4294967296"; /* UINT_MAX + 1ll */
951 endptr = "somewhere";
952 res = 999;
953 err = qemu_strtoui(str, &endptr, 0, &res);
954 g_assert_cmpint(err, ==, -ERANGE);
955 g_assert_cmpuint(res, ==, UINT_MAX);
956 g_assert_true(endptr == str + strlen(str));
957
958 str = "0x7fffffffffffffff"; /* LLONG_MAX */
959 endptr = "somewhere";
960 res = 999;
961 err = qemu_strtoui(str, &endptr, 0, &res);
962 g_assert_cmpint(err, ==, -ERANGE);
963 g_assert_cmpuint(res, ==, UINT_MAX);
964 g_assert_true(endptr == str + strlen(str));
965
966 str = "0x8000000000000000"; /* (uint64_t)LLONG_MIN */
967 endptr = "somewhere";
968 res = 999;
969 err = qemu_strtoui(str, &endptr, 0, &res);
970 g_assert_cmpint(err, ==, -ERANGE);
971 g_assert_cmpuint(res, ==, UINT_MAX);
972 g_assert_true(endptr == str + strlen(str));
973
974 str = "0xffffffff00000001"; /* ULLONG_MAX - UINT_MAX + 1 (not 1) */
975 endptr = "somewhere";
976 res = 999;
977 err = qemu_strtoui(str, &endptr, 0, &res);
978 g_assert_cmpint(err, ==, -ERANGE);
979 g_assert_cmpuint(res, ==, UINT_MAX);
980 g_assert_true(endptr == str + strlen(str));
981
982 str = "0xfffffffffffffffe"; /* ULLONG_MAX - 1 (not UINT_MAX - 1) */
983 endptr = "somewhere";
984 res = 999;
985 err = qemu_strtoui(str, &endptr, 0, &res);
986 g_assert_cmpint(err, ==, -ERANGE);
987 g_assert_cmpuint(res, ==, UINT_MAX);
988 g_assert_true(endptr == str + strlen(str));
989
990 str = "0x10000000000000000"; /* 65 bits, 32-bit sign bit clear */
991 endptr = "somewhere";
992 res = 999;
993 err = qemu_strtoui(str, &endptr, 0, &res);
994 g_assert_cmpint(err, ==, -ERANGE);
995 g_assert_cmpuint(res, ==, UINT_MAX);
996 g_assert_true(endptr == str + strlen(str));
997
998 str = "0x18000000080000000"; /* 65 bits, 32-bit sign bit set */
999 endptr = "somewhere";
1000 res = 999;
1001 err = qemu_strtoui(str, &endptr, 0, &res);
1002 g_assert_cmpint(err, ==, -ERANGE);
1003 g_assert_cmpuint(res, ==, UINT_MAX);
1004 g_assert_true(endptr == str + strlen(str));
1005 }
1006
test_qemu_strtoui_underflow(void)1007 static void test_qemu_strtoui_underflow(void)
1008 {
1009 const char *str;
1010 const char *endptr;
1011 unsigned int res;
1012 int err;
1013
1014 str = "-4294967296"; /* -(long long)UINT_MAX - 1ll */
1015 endptr = "somewhere";
1016 res = 999;
1017 err = qemu_strtoui(str, &endptr, 0, &res);
1018 g_assert_cmpint(err, ==, -ERANGE);
1019 g_assert_cmpuint(res, ==, UINT_MAX);
1020 g_assert_true(endptr == str + strlen(str));
1021
1022 str = "-18446744073709551615"; /* -UINT64_MAX (not -(-1)) */
1023 endptr = "somewhere";
1024 res = 999;
1025 err = qemu_strtoui(str, &endptr, 0, &res);
1026 g_assert_cmpint(err, ==, -ERANGE);
1027 g_assert_cmpuint(res, ==, UINT_MAX);
1028 g_assert_true(endptr == str + strlen(str));
1029
1030 str = "-0xffffffff00000002";
1031 endptr = "somewhere";
1032 res = 999;
1033 err = qemu_strtoui(str, &endptr, 0, &res);
1034 g_assert_cmpint(err, ==, -ERANGE);
1035 g_assert_cmpuint(res, ==, UINT_MAX);
1036 g_assert_true(endptr == str + strlen(str));
1037
1038 str = "-0x10000000000000000"; /* 65 bits, 32-bit sign bit clear */
1039 endptr = "somewhere";
1040 res = 999;
1041 err = qemu_strtoui(str, &endptr, 0, &res);
1042 g_assert_cmpint(err, ==, -ERANGE);
1043 g_assert_cmpuint(res, ==, UINT_MAX);
1044 g_assert_true(endptr == str + strlen(str));
1045
1046 str = "-0x18000000080000000"; /* 65 bits, 32-bit sign bit set */
1047 endptr = "somewhere";
1048 res = 999;
1049 err = qemu_strtoui(str, &endptr, 0, &res);
1050 g_assert_cmpint(err, ==, -ERANGE);
1051 g_assert_cmpuint(res, ==, UINT_MAX);
1052 g_assert_true(endptr == str + strlen(str));
1053 }
1054
test_qemu_strtoui_negative(void)1055 static void test_qemu_strtoui_negative(void)
1056 {
1057 const char *str = " \t -321";
1058 char f = 'X';
1059 const char *endptr = &f;
1060 unsigned int res = 999;
1061 int err;
1062
1063 err = qemu_strtoui(str, &endptr, 0, &res);
1064
1065 g_assert_cmpint(err, ==, 0);
1066 g_assert_cmpuint(res, ==, (unsigned int)-321);
1067 g_assert_true(endptr == str + strlen(str));
1068 }
1069
test_qemu_strtoui_negzero(void)1070 static void test_qemu_strtoui_negzero(void)
1071 {
1072 const char *str = " -0";
1073 char f = 'X';
1074 const char *endptr = &f;
1075 unsigned int res = 999;
1076 int err;
1077
1078 err = qemu_strtoui(str, &endptr, 0, &res);
1079
1080 g_assert_cmpint(err, ==, 0);
1081 g_assert_cmpuint(res, ==, 0);
1082 g_assert_true(endptr == str + strlen(str));
1083 }
1084
test_qemu_strtoui_full_correct(void)1085 static void test_qemu_strtoui_full_correct(void)
1086 {
1087 const char *str = "123";
1088 unsigned int res = 999;
1089 int err;
1090
1091 err = qemu_strtoui(str, NULL, 0, &res);
1092
1093 g_assert_cmpint(err, ==, 0);
1094 g_assert_cmpuint(res, ==, 123);
1095 }
1096
test_qemu_strtoui_full_null(void)1097 static void test_qemu_strtoui_full_null(void)
1098 {
1099 unsigned int res = 999;
1100 int err;
1101
1102 err = qemu_strtoui(NULL, NULL, 0, &res);
1103
1104 g_assert_cmpint(err, ==, -EINVAL);
1105 g_assert_cmpuint(res, ==, 0);
1106 }
1107
test_qemu_strtoui_full_empty(void)1108 static void test_qemu_strtoui_full_empty(void)
1109 {
1110 const char *str = "";
1111 unsigned int res = 999;
1112 int err;
1113
1114 err = qemu_strtoui(str, NULL, 0, &res);
1115
1116 g_assert_cmpint(err, ==, -EINVAL);
1117 g_assert_cmpuint(res, ==, 0);
1118 }
1119
test_qemu_strtoui_full_negative(void)1120 static void test_qemu_strtoui_full_negative(void)
1121 {
1122 const char *str = " \t -321";
1123 unsigned int res = 999;
1124 int err;
1125
1126 err = qemu_strtoui(str, NULL, 0, &res);
1127 g_assert_cmpint(err, ==, 0);
1128 g_assert_cmpuint(res, ==, (unsigned int)-321);
1129 }
1130
test_qemu_strtoui_full_negzero(void)1131 static void test_qemu_strtoui_full_negzero(void)
1132 {
1133 const char *str = " -0";
1134 unsigned int res = 999;
1135 int err;
1136
1137 err = qemu_strtoui(str, NULL, 0, &res);
1138 g_assert_cmpint(err, ==, 0);
1139 g_assert_cmpuint(res, ==, 0);
1140 }
1141
test_qemu_strtoui_full_trailing(void)1142 static void test_qemu_strtoui_full_trailing(void)
1143 {
1144 const char *str = "123xxx";
1145 unsigned int res = 999;
1146 int err;
1147
1148 err = qemu_strtoui(str, NULL, 0, &res);
1149
1150 g_assert_cmpint(err, ==, -EINVAL);
1151 g_assert_cmpuint(res, ==, 123);
1152 }
1153
test_qemu_strtoui_full_max(void)1154 static void test_qemu_strtoui_full_max(void)
1155 {
1156 char *str = g_strdup_printf("%u", UINT_MAX);
1157 unsigned int res = 999;
1158 int err;
1159
1160 err = qemu_strtoui(str, NULL, 0, &res);
1161
1162 g_assert_cmpint(err, ==, 0);
1163 g_assert_cmphex(res, ==, UINT_MAX);
1164 g_free(str);
1165 }
1166
test_qemu_strtoui_full_erange_junk(void)1167 static void test_qemu_strtoui_full_erange_junk(void)
1168 {
1169 /* EINVAL has priority over ERANGE */
1170 const char *str = "-9999999999junk";
1171 unsigned int res = 999;
1172 int err;
1173
1174 err = qemu_strtoui(str, NULL, 0, &res);
1175
1176 g_assert_cmpint(err, ==, -EINVAL);
1177 g_assert_cmpuint(res, ==, UINT_MAX);
1178 }
1179
test_qemu_strtol_correct(void)1180 static void test_qemu_strtol_correct(void)
1181 {
1182 const char *str = "12345 foo";
1183 char f = 'X';
1184 const char *endptr = &f;
1185 long res = 999;
1186 int err;
1187
1188 err = qemu_strtol(str, &endptr, 0, &res);
1189
1190 g_assert_cmpint(err, ==, 0);
1191 g_assert_cmpint(res, ==, 12345);
1192 g_assert_true(endptr == str + 5);
1193 }
1194
test_qemu_strtol_null(void)1195 static void test_qemu_strtol_null(void)
1196 {
1197 char f = 'X';
1198 const char *endptr = &f;
1199 long res = 999;
1200 int err;
1201
1202 err = qemu_strtol(NULL, &endptr, 0, &res);
1203
1204 g_assert_cmpint(err, ==, -EINVAL);
1205 g_assert_cmpint(res, ==, 0);
1206 g_assert_null(endptr);
1207 }
1208
test_qemu_strtol_empty(void)1209 static void test_qemu_strtol_empty(void)
1210 {
1211 const char *str = "";
1212 char f = 'X';
1213 const char *endptr = &f;
1214 long res = 999;
1215 int err;
1216
1217 err = qemu_strtol(str, &endptr, 0, &res);
1218
1219 g_assert_cmpint(err, ==, -EINVAL);
1220 g_assert_cmpint(res, ==, 0);
1221 g_assert_true(endptr == str);
1222 }
1223
test_qemu_strtol_whitespace(void)1224 static void test_qemu_strtol_whitespace(void)
1225 {
1226 const char *str = " \t ";
1227 char f = 'X';
1228 const char *endptr = &f;
1229 long res = 999;
1230 int err;
1231
1232 err = qemu_strtol(str, &endptr, 0, &res);
1233
1234 g_assert_cmpint(err, ==, -EINVAL);
1235 g_assert_cmpint(res, ==, 0);
1236 g_assert_true(endptr == str);
1237 }
1238
test_qemu_strtol_invalid(void)1239 static void test_qemu_strtol_invalid(void)
1240 {
1241 const char *str = " xxxx \t abc";
1242 char f = 'X';
1243 const char *endptr = &f;
1244 long res = 999;
1245 int err;
1246
1247 err = qemu_strtol(str, &endptr, 0, &res);
1248
1249 g_assert_cmpint(err, ==, -EINVAL);
1250 g_assert_cmpint(res, ==, 0);
1251 g_assert_true(endptr == str);
1252 }
1253
test_qemu_strtol_trailing(void)1254 static void test_qemu_strtol_trailing(void)
1255 {
1256 const char *str = "123xxx";
1257 char f = 'X';
1258 const char *endptr = &f;
1259 long res = 999;
1260 int err;
1261
1262 err = qemu_strtol(str, &endptr, 0, &res);
1263
1264 g_assert_cmpint(err, ==, 0);
1265 g_assert_cmpint(res, ==, 123);
1266 g_assert_true(endptr == str + 3);
1267 }
1268
test_qemu_strtol_octal(void)1269 static void test_qemu_strtol_octal(void)
1270 {
1271 const char *str = "0123";
1272 char f = 'X';
1273 const char *endptr = &f;
1274 long res = 999;
1275 int err;
1276
1277 err = qemu_strtol(str, &endptr, 8, &res);
1278
1279 g_assert_cmpint(err, ==, 0);
1280 g_assert_cmpint(res, ==, 0123);
1281 g_assert_true(endptr == str + strlen(str));
1282
1283 res = 999;
1284 endptr = &f;
1285 err = qemu_strtol(str, &endptr, 0, &res);
1286
1287 g_assert_cmpint(err, ==, 0);
1288 g_assert_cmpint(res, ==, 0123);
1289 g_assert_true(endptr == str + strlen(str));
1290 }
1291
test_qemu_strtol_decimal(void)1292 static void test_qemu_strtol_decimal(void)
1293 {
1294 const char *str = "0123";
1295 char f = 'X';
1296 const char *endptr = &f;
1297 long res = 999;
1298 int err;
1299
1300 err = qemu_strtol(str, &endptr, 10, &res);
1301
1302 g_assert_cmpint(err, ==, 0);
1303 g_assert_cmpint(res, ==, 123);
1304 g_assert_true(endptr == str + strlen(str));
1305
1306 str = "123";
1307 res = 999;
1308 endptr = &f;
1309 err = qemu_strtol(str, &endptr, 0, &res);
1310
1311 g_assert_cmpint(err, ==, 0);
1312 g_assert_cmpint(res, ==, 123);
1313 g_assert_true(endptr == str + strlen(str));
1314 }
1315
test_qemu_strtol_hex(void)1316 static void test_qemu_strtol_hex(void)
1317 {
1318 const char *str = "0123";
1319 char f = 'X';
1320 const char *endptr = &f;
1321 long res = 999;
1322 int err;
1323
1324 err = qemu_strtol(str, &endptr, 16, &res);
1325
1326 g_assert_cmpint(err, ==, 0);
1327 g_assert_cmpint(res, ==, 0x123);
1328 g_assert_true(endptr == str + strlen(str));
1329
1330 str = "0x123";
1331 res = 999;
1332 endptr = &f;
1333 err = qemu_strtol(str, &endptr, 0, &res);
1334
1335 g_assert_cmpint(err, ==, 0);
1336 g_assert_cmpint(res, ==, 0x123);
1337 g_assert_true(endptr == str + strlen(str));
1338
1339 str = "0x";
1340 res = 999;
1341 endptr = &f;
1342 err = qemu_strtol(str, &endptr, 16, &res);
1343
1344 g_assert_cmpint(err, ==, 0);
1345 g_assert_cmpint(res, ==, 0);
1346 g_assert_true(endptr == str + 1);
1347 }
1348
test_qemu_strtol_max(void)1349 static void test_qemu_strtol_max(void)
1350 {
1351 char *str = g_strdup_printf("%ld", LONG_MAX);
1352 char f = 'X';
1353 const char *endptr = &f;
1354 long res = 999;
1355 int err;
1356
1357 err = qemu_strtol(str, &endptr, 0, &res);
1358
1359 g_assert_cmpint(err, ==, 0);
1360 g_assert_cmpint(res, ==, LONG_MAX);
1361 g_assert_true(endptr == str + strlen(str));
1362 g_free(str);
1363 }
1364
test_qemu_strtol_overflow(void)1365 static void test_qemu_strtol_overflow(void)
1366 {
1367 const char *str;
1368 const char *endptr;
1369 long res;
1370 int err;
1371
1372 /* 1 more than LONG_MAX */
1373 str = LONG_MAX == INT_MAX ? "2147483648" : "9223372036854775808";
1374 endptr = "somewhere";
1375 res = 999;
1376 err = qemu_strtol(str, &endptr, 0, &res);
1377 g_assert_cmpint(err, ==, -ERANGE);
1378 g_assert_cmpint(res, ==, LONG_MAX);
1379 g_assert_true(endptr == str + strlen(str));
1380
1381 if (LONG_MAX == INT_MAX) {
1382 str = "0xffffffff00000001"; /* ULLONG_MAX - UINT_MAX + 1 (not 1) */
1383 endptr = "somewhere";
1384 res = 999;
1385 err = qemu_strtol(str, &endptr, 0, &res);
1386 g_assert_cmpint(err, ==, -ERANGE);
1387 g_assert_cmpint(res, ==, LONG_MAX);
1388 g_assert_true(endptr == str + strlen(str));
1389 }
1390
1391 str = "0x10000000000000000"; /* 65 bits, either sign bit position clear */
1392 endptr = "somewhere";
1393 res = 999;
1394 err = qemu_strtol(str, &endptr, 0, &res);
1395 g_assert_cmpint(err, ==, -ERANGE);
1396 g_assert_cmpint(res, ==, LONG_MAX);
1397 g_assert_true(endptr == str + strlen(str));
1398
1399 str = "0x18000000080000000"; /* 65 bits, either sign bit position set */
1400 endptr = "somewhere";
1401 res = 999;
1402 err = qemu_strtol(str, &endptr, 0, &res);
1403 g_assert_cmpint(err, ==, -ERANGE);
1404 g_assert_cmpint(res, ==, LONG_MAX);
1405 g_assert_true(endptr == str + strlen(str));
1406 }
1407
test_qemu_strtol_min(void)1408 static void test_qemu_strtol_min(void)
1409 {
1410 char *str = g_strdup_printf("%ld", LONG_MIN);
1411 char f = 'X';
1412 const char *endptr = &f;
1413 long res = 999;
1414 int err;
1415
1416 err = qemu_strtol(str, &endptr, 0, &res);
1417
1418 g_assert_cmpint(err, ==, 0);
1419 g_assert_cmpint(res, ==, LONG_MIN);
1420 g_assert_true(endptr == str + strlen(str));
1421 g_free(str);
1422 }
1423
test_qemu_strtol_underflow(void)1424 static void test_qemu_strtol_underflow(void)
1425 {
1426 const char *str;
1427 const char *endptr;
1428 long res;
1429 int err;
1430
1431 /* 1 less than LONG_MIN */
1432 str = LONG_MIN == INT_MIN ? "-2147483649" : "-9223372036854775809";
1433 endptr = "somewhere";
1434 res = 999;
1435 err = qemu_strtol(str, &endptr, 0, &res);
1436 g_assert_cmpint(err, ==, -ERANGE);
1437 g_assert_cmpint(res, ==, LONG_MIN);
1438 g_assert_true(endptr == str + strlen(str));
1439
1440 if (LONG_MAX == INT_MAX) {
1441 str = "-18446744073709551615"; /* -UINT64_MAX (not 1) */
1442 endptr = "somewhere";
1443 res = 999;
1444 err = qemu_strtol(str, &endptr, 0, &res);
1445 g_assert_cmpint(err, ==, -ERANGE);
1446 g_assert_cmpint(res, ==, LONG_MIN);
1447 g_assert_true(endptr == str + strlen(str));
1448 }
1449
1450 str = "-0x10000000000000000"; /* 65 bits, either sign bit position clear */
1451 endptr = "somewhere";
1452 res = 999;
1453 err = qemu_strtol(str, &endptr, 0, &res);
1454 g_assert_cmpint(err, ==, -ERANGE);
1455 g_assert_cmpint(res, ==, LONG_MIN);
1456 g_assert_true(endptr == str + strlen(str));
1457
1458 str = "-0x18000000080000000"; /* 65 bits, either sign bit position set */
1459 endptr = "somewhere";
1460 res = 999;
1461 err = qemu_strtol(str, &endptr, 0, &res);
1462 g_assert_cmpint(err, ==, -ERANGE);
1463 g_assert_cmpint(res, ==, LONG_MIN);
1464 g_assert_true(endptr == str + strlen(str));
1465 }
1466
test_qemu_strtol_negative(void)1467 static void test_qemu_strtol_negative(void)
1468 {
1469 const char *str = " \t -321";
1470 char f = 'X';
1471 const char *endptr = &f;
1472 long res = 999;
1473 int err;
1474
1475 err = qemu_strtol(str, &endptr, 0, &res);
1476
1477 g_assert_cmpint(err, ==, 0);
1478 g_assert_cmpint(res, ==, -321);
1479 g_assert_true(endptr == str + strlen(str));
1480 }
1481
test_qemu_strtol_negzero(void)1482 static void test_qemu_strtol_negzero(void)
1483 {
1484 const char *str = " -0";
1485 char f = 'X';
1486 const char *endptr = &f;
1487 long res = 999;
1488 int err;
1489
1490 err = qemu_strtol(str, &endptr, 0, &res);
1491
1492 g_assert_cmpint(err, ==, 0);
1493 g_assert_cmpint(res, ==, 0);
1494 g_assert_true(endptr == str + strlen(str));
1495 }
1496
test_qemu_strtol_full_correct(void)1497 static void test_qemu_strtol_full_correct(void)
1498 {
1499 const char *str = "123";
1500 long res = 999;
1501 int err;
1502
1503 err = qemu_strtol(str, NULL, 0, &res);
1504
1505 g_assert_cmpint(err, ==, 0);
1506 g_assert_cmpint(res, ==, 123);
1507 }
1508
test_qemu_strtol_full_null(void)1509 static void test_qemu_strtol_full_null(void)
1510 {
1511 char f = 'X';
1512 const char *endptr = &f;
1513 long res = 999;
1514 int err;
1515
1516 err = qemu_strtol(NULL, &endptr, 0, &res);
1517
1518 g_assert_cmpint(err, ==, -EINVAL);
1519 g_assert_cmpint(res, ==, 0);
1520 g_assert_null(endptr);
1521 }
1522
test_qemu_strtol_full_empty(void)1523 static void test_qemu_strtol_full_empty(void)
1524 {
1525 const char *str = "";
1526 long res = 999L;
1527 int err;
1528
1529 err = qemu_strtol(str, NULL, 0, &res);
1530
1531 g_assert_cmpint(err, ==, -EINVAL);
1532 g_assert_cmpint(res, ==, 0);
1533 }
1534
test_qemu_strtol_full_negative(void)1535 static void test_qemu_strtol_full_negative(void)
1536 {
1537 const char *str = " \t -321";
1538 long res = 999;
1539 int err;
1540
1541 err = qemu_strtol(str, NULL, 0, &res);
1542
1543 g_assert_cmpint(err, ==, 0);
1544 g_assert_cmpint(res, ==, -321);
1545 }
1546
test_qemu_strtol_full_negzero(void)1547 static void test_qemu_strtol_full_negzero(void)
1548 {
1549 const char *str = " -0";
1550 long res = 999;
1551 int err;
1552
1553 err = qemu_strtol(str, NULL, 0, &res);
1554
1555 g_assert_cmpint(err, ==, 0);
1556 g_assert_cmpint(res, ==, 0);
1557 }
1558
test_qemu_strtol_full_trailing(void)1559 static void test_qemu_strtol_full_trailing(void)
1560 {
1561 const char *str = "123xxx";
1562 long res = 999;
1563 int err;
1564
1565 err = qemu_strtol(str, NULL, 0, &res);
1566
1567 g_assert_cmpint(err, ==, -EINVAL);
1568 g_assert_cmpint(res, ==, 123);
1569 }
1570
test_qemu_strtol_full_max(void)1571 static void test_qemu_strtol_full_max(void)
1572 {
1573 char *str = g_strdup_printf("%ld", LONG_MAX);
1574 long res = 999;
1575 int err;
1576
1577 err = qemu_strtol(str, NULL, 0, &res);
1578
1579 g_assert_cmpint(err, ==, 0);
1580 g_assert_cmpint(res, ==, LONG_MAX);
1581 g_free(str);
1582 }
1583
test_qemu_strtol_full_erange_junk(void)1584 static void test_qemu_strtol_full_erange_junk(void)
1585 {
1586 /* EINVAL has priority over ERANGE */
1587 const char *str = "-99999999999999999999junk";
1588 long res = 999;
1589 int err;
1590
1591 err = qemu_strtol(str, NULL, 0, &res);
1592
1593 g_assert_cmpint(err, ==, -EINVAL);
1594 g_assert_cmpint(res, ==, LONG_MIN);
1595 }
1596
test_qemu_strtoul_correct(void)1597 static void test_qemu_strtoul_correct(void)
1598 {
1599 const char *str = "12345 foo";
1600 char f = 'X';
1601 const char *endptr = &f;
1602 unsigned long res = 999;
1603 int err;
1604
1605 err = qemu_strtoul(str, &endptr, 0, &res);
1606
1607 g_assert_cmpint(err, ==, 0);
1608 g_assert_cmpuint(res, ==, 12345);
1609 g_assert_true(endptr == str + 5);
1610 }
1611
test_qemu_strtoul_null(void)1612 static void test_qemu_strtoul_null(void)
1613 {
1614 char f = 'X';
1615 const char *endptr = &f;
1616 unsigned long res = 999;
1617 int err;
1618
1619 err = qemu_strtoul(NULL, &endptr, 0, &res);
1620
1621 g_assert_cmpint(err, ==, -EINVAL);
1622 g_assert_cmpuint(res, ==, 0);
1623 g_assert_null(endptr);
1624 }
1625
test_qemu_strtoul_empty(void)1626 static void test_qemu_strtoul_empty(void)
1627 {
1628 const char *str = "";
1629 char f = 'X';
1630 const char *endptr = &f;
1631 unsigned long res = 999;
1632 int err;
1633
1634 err = qemu_strtoul(str, &endptr, 0, &res);
1635
1636 g_assert_cmpint(err, ==, -EINVAL);
1637 g_assert_cmpuint(res, ==, 0);
1638 g_assert_true(endptr == str);
1639 }
1640
test_qemu_strtoul_whitespace(void)1641 static void test_qemu_strtoul_whitespace(void)
1642 {
1643 const char *str = " \t ";
1644 char f = 'X';
1645 const char *endptr = &f;
1646 unsigned long res = 999;
1647 int err;
1648
1649 err = qemu_strtoul(str, &endptr, 0, &res);
1650
1651 g_assert_cmpint(err, ==, -EINVAL);
1652 g_assert_cmpuint(res, ==, 0);
1653 g_assert_true(endptr == str);
1654 }
1655
test_qemu_strtoul_invalid(void)1656 static void test_qemu_strtoul_invalid(void)
1657 {
1658 const char *str = " xxxx \t abc";
1659 char f = 'X';
1660 const char *endptr = &f;
1661 unsigned long res = 999;
1662 int err;
1663
1664 err = qemu_strtoul(str, &endptr, 0, &res);
1665
1666 g_assert_cmpint(err, ==, -EINVAL);
1667 g_assert_cmpuint(res, ==, 0);
1668 g_assert_true(endptr == str);
1669 }
1670
test_qemu_strtoul_trailing(void)1671 static void test_qemu_strtoul_trailing(void)
1672 {
1673 const char *str = "123xxx";
1674 char f = 'X';
1675 const char *endptr = &f;
1676 unsigned long res = 999;
1677 int err;
1678
1679 err = qemu_strtoul(str, &endptr, 0, &res);
1680
1681 g_assert_cmpint(err, ==, 0);
1682 g_assert_cmpuint(res, ==, 123);
1683 g_assert_true(endptr == str + 3);
1684 }
1685
test_qemu_strtoul_octal(void)1686 static void test_qemu_strtoul_octal(void)
1687 {
1688 const char *str = "0123";
1689 char f = 'X';
1690 const char *endptr = &f;
1691 unsigned long res = 999;
1692 int err;
1693
1694 err = qemu_strtoul(str, &endptr, 8, &res);
1695
1696 g_assert_cmpint(err, ==, 0);
1697 g_assert_cmpuint(res, ==, 0123);
1698 g_assert_true(endptr == str + strlen(str));
1699
1700 res = 999;
1701 endptr = &f;
1702 err = qemu_strtoul(str, &endptr, 0, &res);
1703
1704 g_assert_cmpint(err, ==, 0);
1705 g_assert_cmpuint(res, ==, 0123);
1706 g_assert_true(endptr == str + strlen(str));
1707 }
1708
test_qemu_strtoul_decimal(void)1709 static void test_qemu_strtoul_decimal(void)
1710 {
1711 const char *str = "0123";
1712 char f = 'X';
1713 const char *endptr = &f;
1714 unsigned long res = 999;
1715 int err;
1716
1717 err = qemu_strtoul(str, &endptr, 10, &res);
1718
1719 g_assert_cmpint(err, ==, 0);
1720 g_assert_cmpuint(res, ==, 123);
1721 g_assert_true(endptr == str + strlen(str));
1722
1723 str = "123";
1724 res = 999;
1725 endptr = &f;
1726 err = qemu_strtoul(str, &endptr, 0, &res);
1727
1728 g_assert_cmpint(err, ==, 0);
1729 g_assert_cmpuint(res, ==, 123);
1730 g_assert_true(endptr == str + strlen(str));
1731 }
1732
test_qemu_strtoul_hex(void)1733 static void test_qemu_strtoul_hex(void)
1734 {
1735 const char *str = "0123";
1736 char f = 'X';
1737 const char *endptr = &f;
1738 unsigned long res = 999;
1739 int err;
1740
1741 err = qemu_strtoul(str, &endptr, 16, &res);
1742
1743 g_assert_cmpint(err, ==, 0);
1744 g_assert_cmphex(res, ==, 0x123);
1745 g_assert_true(endptr == str + strlen(str));
1746
1747 str = "0x123";
1748 res = 999;
1749 endptr = &f;
1750 err = qemu_strtoul(str, &endptr, 0, &res);
1751
1752 g_assert_cmpint(err, ==, 0);
1753 g_assert_cmphex(res, ==, 0x123);
1754 g_assert_true(endptr == str + strlen(str));
1755
1756 str = "0x";
1757 res = 999;
1758 endptr = &f;
1759 err = qemu_strtoul(str, &endptr, 16, &res);
1760
1761 g_assert_cmpint(err, ==, 0);
1762 g_assert_cmphex(res, ==, 0);
1763 g_assert_true(endptr == str + 1);
1764 }
1765
test_qemu_strtoul_wrap(void)1766 static void test_qemu_strtoul_wrap(void)
1767 {
1768 const char *str;
1769 char f = 'X';
1770 const char *endptr = &f;
1771 unsigned long res = 999;
1772 int err;
1773
1774 /* 1 mod 2^(sizeof(long)*8) */
1775 str = LONG_MAX == INT_MAX ? "-4294967295" : "-18446744073709551615";
1776 err = qemu_strtoul(str, &endptr, 0, &res);
1777
1778 g_assert_cmpint(err, ==, 0);
1779 g_assert_cmphex(res, ==, 1);
1780 g_assert_true(endptr == str + strlen(str));
1781 }
1782
test_qemu_strtoul_max(void)1783 static void test_qemu_strtoul_max(void)
1784 {
1785 char *str = g_strdup_printf("%lu", ULONG_MAX);
1786 char f = 'X';
1787 const char *endptr = &f;
1788 unsigned long res = 999;
1789 int err;
1790
1791 err = qemu_strtoul(str, &endptr, 0, &res);
1792
1793 g_assert_cmpint(err, ==, 0);
1794 g_assert_cmphex(res, ==, ULONG_MAX);
1795 g_assert_true(endptr == str + strlen(str));
1796 g_free(str);
1797 }
1798
test_qemu_strtoul_overflow(void)1799 static void test_qemu_strtoul_overflow(void)
1800 {
1801 const char *str;
1802 const char *endptr;
1803 unsigned long res;
1804 int err;
1805
1806 /* 1 more than ULONG_MAX */
1807 str = ULONG_MAX == UINT_MAX ? "4294967296" : "18446744073709551616";
1808 endptr = "somewhere";
1809 res = 999;
1810 err = qemu_strtoul(str, &endptr, 0, &res);
1811 g_assert_cmpint(err, ==, -ERANGE);
1812 g_assert_cmpuint(res, ==, ULONG_MAX);
1813 g_assert_true(endptr == str + strlen(str));
1814
1815 if (LONG_MAX == INT_MAX) {
1816 str = "0xffffffff00000001"; /* UINT64_MAX - UINT_MAX + 1 (not 1) */
1817 endptr = "somewhere";
1818 res = 999;
1819 err = qemu_strtoul(str, &endptr, 0, &res);
1820 g_assert_cmpint(err, ==, -ERANGE);
1821 g_assert_cmpuint(res, ==, ULONG_MAX);
1822 g_assert_true(endptr == str + strlen(str));
1823 }
1824
1825 str = "0x10000000000000000"; /* 65 bits, either sign bit position clear */
1826 endptr = "somewhere";
1827 res = 999;
1828 err = qemu_strtoul(str, &endptr, 0, &res);
1829 g_assert_cmpint(err, ==, -ERANGE);
1830 g_assert_cmpuint(res, ==, ULONG_MAX);
1831 g_assert_true(endptr == str + strlen(str));
1832
1833 str = "0x18000000080000000"; /* 65 bits, either sign bit position set */
1834 endptr = "somewhere";
1835 res = 999;
1836 err = qemu_strtoul(str, &endptr, 0, &res);
1837 g_assert_cmpint(err, ==, -ERANGE);
1838 g_assert_cmpuint(res, ==, ULONG_MAX);
1839 g_assert_true(endptr == str + strlen(str));
1840 }
1841
test_qemu_strtoul_underflow(void)1842 static void test_qemu_strtoul_underflow(void)
1843 {
1844 const char *str;
1845 const char *endptr;
1846 unsigned long res;
1847 int err;
1848
1849 /* 1 less than -ULONG_MAX */
1850 str = ULONG_MAX == UINT_MAX ? "-4294967296" : "-18446744073709551616";
1851 endptr = "somewhere";
1852 res = 999;
1853 err = qemu_strtoul(str, &endptr, 0, &res);
1854 g_assert_cmpint(err, ==, -ERANGE);
1855 g_assert_cmpuint(res, ==, ULONG_MAX);
1856 g_assert_true(endptr == str + strlen(str));
1857
1858 if (LONG_MAX == INT_MAX) {
1859 str = "-0xffffffff00000002";
1860 endptr = "somewhere";
1861 res = 999;
1862 err = qemu_strtoul(str, &endptr, 0, &res);
1863 g_assert_cmpint(err, ==, -ERANGE);
1864 g_assert_cmpuint(res, ==, ULONG_MAX);
1865 g_assert_true(endptr == str + strlen(str));
1866 }
1867
1868 str = "-0x10000000000000000"; /* 65 bits, either sign bit position clear */
1869 endptr = "somewhere";
1870 res = 999;
1871 err = qemu_strtoul(str, &endptr, 0, &res);
1872 g_assert_cmpint(err, ==, -ERANGE);
1873 g_assert_cmpuint(res, ==, ULONG_MAX);
1874 g_assert_true(endptr == str + strlen(str));
1875
1876 str = "-0x18000000080000000"; /* 65 bits, either sign bit position set */
1877 endptr = "somewhere";
1878 res = 999;
1879 err = qemu_strtoul(str, &endptr, 0, &res);
1880 g_assert_cmpint(err, ==, -ERANGE);
1881 g_assert_cmpuint(res, ==, ULONG_MAX);
1882 g_assert_true(endptr == str + strlen(str));
1883 }
1884
test_qemu_strtoul_negative(void)1885 static void test_qemu_strtoul_negative(void)
1886 {
1887 const char *str = " \t -321";
1888 char f = 'X';
1889 const char *endptr = &f;
1890 unsigned long res = 999;
1891 int err;
1892
1893 err = qemu_strtoul(str, &endptr, 0, &res);
1894
1895 g_assert_cmpint(err, ==, 0);
1896 g_assert_cmpuint(res, ==, -321ul);
1897 g_assert_true(endptr == str + strlen(str));
1898 }
1899
test_qemu_strtoul_negzero(void)1900 static void test_qemu_strtoul_negzero(void)
1901 {
1902 const char *str = " -0";
1903 char f = 'X';
1904 const char *endptr = &f;
1905 unsigned long res = 999;
1906 int err;
1907
1908 err = qemu_strtoul(str, &endptr, 0, &res);
1909
1910 g_assert_cmpint(err, ==, 0);
1911 g_assert_cmpuint(res, ==, 0);
1912 g_assert_true(endptr == str + strlen(str));
1913 }
1914
test_qemu_strtoul_full_correct(void)1915 static void test_qemu_strtoul_full_correct(void)
1916 {
1917 const char *str = "123";
1918 unsigned long res = 999;
1919 int err;
1920
1921 err = qemu_strtoul(str, NULL, 0, &res);
1922
1923 g_assert_cmpint(err, ==, 0);
1924 g_assert_cmpuint(res, ==, 123);
1925 }
1926
test_qemu_strtoul_full_null(void)1927 static void test_qemu_strtoul_full_null(void)
1928 {
1929 unsigned long res = 999;
1930 int err;
1931
1932 err = qemu_strtoul(NULL, NULL, 0, &res);
1933
1934 g_assert_cmpint(err, ==, -EINVAL);
1935 g_assert_cmpuint(res, ==, 0);
1936 }
1937
test_qemu_strtoul_full_empty(void)1938 static void test_qemu_strtoul_full_empty(void)
1939 {
1940 const char *str = "";
1941 unsigned long res = 999;
1942 int err;
1943
1944 err = qemu_strtoul(str, NULL, 0, &res);
1945
1946 g_assert_cmpint(err, ==, -EINVAL);
1947 g_assert_cmpuint(res, ==, 0);
1948 }
1949
test_qemu_strtoul_full_negative(void)1950 static void test_qemu_strtoul_full_negative(void)
1951 {
1952 const char *str = " \t -321";
1953 unsigned long res = 999;
1954 int err;
1955
1956 err = qemu_strtoul(str, NULL, 0, &res);
1957 g_assert_cmpint(err, ==, 0);
1958 g_assert_cmpuint(res, ==, -321ul);
1959 }
1960
test_qemu_strtoul_full_negzero(void)1961 static void test_qemu_strtoul_full_negzero(void)
1962 {
1963 const char *str = " -0";
1964 unsigned long res = 999;
1965 int err;
1966
1967 err = qemu_strtoul(str, NULL, 0, &res);
1968 g_assert_cmpint(err, ==, 0);
1969 g_assert_cmpuint(res, ==, 0);
1970 }
1971
test_qemu_strtoul_full_trailing(void)1972 static void test_qemu_strtoul_full_trailing(void)
1973 {
1974 const char *str = "123xxx";
1975 unsigned long res = 999;
1976 int err;
1977
1978 err = qemu_strtoul(str, NULL, 0, &res);
1979
1980 g_assert_cmpint(err, ==, -EINVAL);
1981 g_assert_cmpuint(res, ==, 123);
1982 }
1983
test_qemu_strtoul_full_max(void)1984 static void test_qemu_strtoul_full_max(void)
1985 {
1986 char *str = g_strdup_printf("%lu", ULONG_MAX);
1987 unsigned long res = 999;
1988 int err;
1989
1990 err = qemu_strtoul(str, NULL, 0, &res);
1991
1992 g_assert_cmpint(err, ==, 0);
1993 g_assert_cmphex(res, ==, ULONG_MAX);
1994 g_free(str);
1995 }
1996
test_qemu_strtoul_full_erange_junk(void)1997 static void test_qemu_strtoul_full_erange_junk(void)
1998 {
1999 /* EINVAL has priority over ERANGE */
2000 const char *str = "-99999999999999999999junk";
2001 unsigned long res = 999;
2002 int err;
2003
2004 err = qemu_strtoul(str, NULL, 0, &res);
2005
2006 g_assert_cmpint(err, ==, -EINVAL);
2007 g_assert_cmpuint(res, ==, ULONG_MAX);
2008 }
2009
test_qemu_strtoi64_correct(void)2010 static void test_qemu_strtoi64_correct(void)
2011 {
2012 const char *str = "12345 foo";
2013 char f = 'X';
2014 const char *endptr = &f;
2015 int64_t res = 999;
2016 int err;
2017
2018 err = qemu_strtoi64(str, &endptr, 0, &res);
2019
2020 g_assert_cmpint(err, ==, 0);
2021 g_assert_cmpint(res, ==, 12345);
2022 g_assert_true(endptr == str + 5);
2023 }
2024
test_qemu_strtoi64_null(void)2025 static void test_qemu_strtoi64_null(void)
2026 {
2027 char f = 'X';
2028 const char *endptr = &f;
2029 int64_t res = 999;
2030 int err;
2031
2032 err = qemu_strtoi64(NULL, &endptr, 0, &res);
2033
2034 g_assert_cmpint(err, ==, -EINVAL);
2035 g_assert_cmpint(res, ==, 0);
2036 g_assert_null(endptr);
2037 }
2038
test_qemu_strtoi64_empty(void)2039 static void test_qemu_strtoi64_empty(void)
2040 {
2041 const char *str = "";
2042 char f = 'X';
2043 const char *endptr = &f;
2044 int64_t res = 999;
2045 int err;
2046
2047 err = qemu_strtoi64(str, &endptr, 0, &res);
2048
2049 g_assert_cmpint(err, ==, -EINVAL);
2050 g_assert_cmpint(res, ==, 0);
2051 g_assert_true(endptr == str);
2052 }
2053
test_qemu_strtoi64_whitespace(void)2054 static void test_qemu_strtoi64_whitespace(void)
2055 {
2056 const char *str = " \t ";
2057 char f = 'X';
2058 const char *endptr = &f;
2059 int64_t res = 999;
2060 int err;
2061
2062 err = qemu_strtoi64(str, &endptr, 0, &res);
2063
2064 g_assert_cmpint(err, ==, -EINVAL);
2065 g_assert_cmpint(res, ==, 0);
2066 g_assert_true(endptr == str);
2067 }
2068
test_qemu_strtoi64_invalid(void)2069 static void test_qemu_strtoi64_invalid(void)
2070 {
2071 const char *str = " xxxx \t abc";
2072 char f = 'X';
2073 const char *endptr = &f;
2074 int64_t res = 999;
2075 int err;
2076
2077 err = qemu_strtoi64(str, &endptr, 0, &res);
2078
2079 g_assert_cmpint(err, ==, -EINVAL);
2080 g_assert_cmpint(res, ==, 0);
2081 g_assert_true(endptr == str);
2082 }
2083
test_qemu_strtoi64_trailing(void)2084 static void test_qemu_strtoi64_trailing(void)
2085 {
2086 const char *str = "123xxx";
2087 char f = 'X';
2088 const char *endptr = &f;
2089 int64_t res = 999;
2090 int err;
2091
2092 err = qemu_strtoi64(str, &endptr, 0, &res);
2093
2094 g_assert_cmpint(err, ==, 0);
2095 g_assert_cmpint(res, ==, 123);
2096 g_assert_true(endptr == str + 3);
2097 }
2098
test_qemu_strtoi64_octal(void)2099 static void test_qemu_strtoi64_octal(void)
2100 {
2101 const char *str = "0123";
2102 char f = 'X';
2103 const char *endptr = &f;
2104 int64_t res = 999;
2105 int err;
2106
2107 err = qemu_strtoi64(str, &endptr, 8, &res);
2108
2109 g_assert_cmpint(err, ==, 0);
2110 g_assert_cmpint(res, ==, 0123);
2111 g_assert_true(endptr == str + strlen(str));
2112
2113 endptr = &f;
2114 res = 999;
2115 err = qemu_strtoi64(str, &endptr, 0, &res);
2116
2117 g_assert_cmpint(err, ==, 0);
2118 g_assert_cmpint(res, ==, 0123);
2119 g_assert_true(endptr == str + strlen(str));
2120 }
2121
test_qemu_strtoi64_decimal(void)2122 static void test_qemu_strtoi64_decimal(void)
2123 {
2124 const char *str = "0123";
2125 char f = 'X';
2126 const char *endptr = &f;
2127 int64_t res = 999;
2128 int err;
2129
2130 err = qemu_strtoi64(str, &endptr, 10, &res);
2131
2132 g_assert_cmpint(err, ==, 0);
2133 g_assert_cmpint(res, ==, 123);
2134 g_assert_true(endptr == str + strlen(str));
2135
2136 str = "123";
2137 endptr = &f;
2138 res = 999;
2139 err = qemu_strtoi64(str, &endptr, 0, &res);
2140
2141 g_assert_cmpint(err, ==, 0);
2142 g_assert_cmpint(res, ==, 123);
2143 g_assert_true(endptr == str + strlen(str));
2144 }
2145
test_qemu_strtoi64_hex(void)2146 static void test_qemu_strtoi64_hex(void)
2147 {
2148 const char *str = "0123";
2149 char f = 'X';
2150 const char *endptr = &f;
2151 int64_t res = 999;
2152 int err;
2153
2154 err = qemu_strtoi64(str, &endptr, 16, &res);
2155
2156 g_assert_cmpint(err, ==, 0);
2157 g_assert_cmpint(res, ==, 0x123);
2158 g_assert_true(endptr == str + strlen(str));
2159
2160 str = "0x123";
2161 endptr = &f;
2162 res = 999;
2163 err = qemu_strtoi64(str, &endptr, 0, &res);
2164
2165 g_assert_cmpint(err, ==, 0);
2166 g_assert_cmpint(res, ==, 0x123);
2167 g_assert_true(endptr == str + strlen(str));
2168
2169 str = "0x";
2170 endptr = &f;
2171 res = 999;
2172 err = qemu_strtoi64(str, &endptr, 16, &res);
2173
2174 g_assert_cmpint(err, ==, 0);
2175 g_assert_cmpint(res, ==, 0);
2176 g_assert_true(endptr == str + 1);
2177 }
2178
test_qemu_strtoi64_max(void)2179 static void test_qemu_strtoi64_max(void)
2180 {
2181 char *str = g_strdup_printf("%lld", LLONG_MAX);
2182 char f = 'X';
2183 const char *endptr = &f;
2184 int64_t res = 999;
2185 int err;
2186
2187 err = qemu_strtoi64(str, &endptr, 0, &res);
2188
2189 g_assert_cmpint(err, ==, 0);
2190 g_assert_cmpint(res, ==, LLONG_MAX);
2191 g_assert_true(endptr == str + strlen(str));
2192 g_free(str);
2193 }
2194
test_qemu_strtoi64_overflow(void)2195 static void test_qemu_strtoi64_overflow(void)
2196 {
2197 const char *str;
2198 const char *endptr;
2199 int64_t res;
2200 int err;
2201
2202 str = "9223372036854775808"; /* 1 more than INT64_MAX */
2203 endptr = "somewhere";
2204 res = 999;
2205 err = qemu_strtoi64(str, &endptr, 0, &res);
2206 g_assert_cmpint(err, ==, -ERANGE);
2207 g_assert_cmpint(res, ==, INT64_MAX);
2208 g_assert_true(endptr == str + strlen(str));
2209
2210 str = "0x10000000000000000"; /* 65 bits, 64-bit sign bit clear */
2211 endptr = "somewhere";
2212 res = 999;
2213 err = qemu_strtoi64(str, &endptr, 0, &res);
2214 g_assert_cmpint(err, ==, -ERANGE);
2215 g_assert_cmpint(res, ==, INT64_MAX);
2216 g_assert_true(endptr == str + strlen(str));
2217
2218 str = "0x18000000080000000"; /* 65 bits, 64-bit sign bit set */
2219 endptr = "somewhere";
2220 res = 999;
2221 err = qemu_strtoi64(str, &endptr, 0, &res);
2222 g_assert_cmpint(err, ==, -ERANGE);
2223 g_assert_cmpint(res, ==, INT64_MAX);
2224 g_assert_true(endptr == str + strlen(str));
2225 }
2226
test_qemu_strtoi64_min(void)2227 static void test_qemu_strtoi64_min(void)
2228 {
2229 char *str = g_strdup_printf("%lld", LLONG_MIN);
2230 char f = 'X';
2231 const char *endptr = &f;
2232 int64_t res = 999;
2233 int err;
2234
2235 err = qemu_strtoi64(str, &endptr, 0, &res);
2236
2237 g_assert_cmpint(err, ==, 0);
2238 g_assert_cmpint(res, ==, LLONG_MIN);
2239 g_assert_true(endptr == str + strlen(str));
2240 g_free(str);
2241 }
2242
test_qemu_strtoi64_underflow(void)2243 static void test_qemu_strtoi64_underflow(void)
2244 {
2245 const char *str;
2246 const char *endptr;
2247 int64_t res;
2248 int err;
2249
2250 str = "-9223372036854775809"; /* 1 less than INT64_MIN */
2251 endptr = "somewhere";
2252 res = 999;
2253 err = qemu_strtoi64(str, &endptr, 0, &res);
2254 g_assert_cmpint(err, ==, -ERANGE);
2255 g_assert_cmpint(res, ==, INT64_MIN);
2256 g_assert_true(endptr == str + strlen(str));
2257
2258 str = "-0x10000000000000000"; /* 65 bits, 64-bit sign bit clear */
2259 endptr = "somewhere";
2260 res = 999;
2261 err = qemu_strtoi64(str, &endptr, 0, &res);
2262 g_assert_cmpint(err, ==, -ERANGE);
2263 g_assert_cmpint(res, ==, INT64_MIN);
2264 g_assert_true(endptr == str + strlen(str));
2265
2266 str = "-0x18000000080000000"; /* 65 bits, 64-bit sign bit set */
2267 endptr = "somewhere";
2268 res = 999;
2269 err = qemu_strtoi64(str, &endptr, 0, &res);
2270 g_assert_cmpint(err, ==, -ERANGE);
2271 g_assert_cmpint(res, ==, INT64_MIN);
2272 g_assert_true(endptr == str + strlen(str));
2273 }
2274
test_qemu_strtoi64_negative(void)2275 static void test_qemu_strtoi64_negative(void)
2276 {
2277 const char *str = " \t -321";
2278 char f = 'X';
2279 const char *endptr = &f;
2280 int64_t res = 999;
2281 int err;
2282
2283 err = qemu_strtoi64(str, &endptr, 0, &res);
2284
2285 g_assert_cmpint(err, ==, 0);
2286 g_assert_cmpint(res, ==, -321);
2287 g_assert_true(endptr == str + strlen(str));
2288 }
2289
test_qemu_strtoi64_negzero(void)2290 static void test_qemu_strtoi64_negzero(void)
2291 {
2292 const char *str = " -0";
2293 char f = 'X';
2294 const char *endptr = &f;
2295 int64_t res = 999;
2296 int err;
2297
2298 err = qemu_strtoi64(str, &endptr, 0, &res);
2299
2300 g_assert_cmpint(err, ==, 0);
2301 g_assert_cmpint(res, ==, 0);
2302 g_assert_true(endptr == str + strlen(str));
2303 }
2304
test_qemu_strtoi64_full_correct(void)2305 static void test_qemu_strtoi64_full_correct(void)
2306 {
2307 const char *str = "123";
2308 int64_t res = 999;
2309 int err;
2310
2311 err = qemu_strtoi64(str, NULL, 0, &res);
2312
2313 g_assert_cmpint(err, ==, 0);
2314 g_assert_cmpint(res, ==, 123);
2315 }
2316
test_qemu_strtoi64_full_null(void)2317 static void test_qemu_strtoi64_full_null(void)
2318 {
2319 int64_t res = 999;
2320 int err;
2321
2322 err = qemu_strtoi64(NULL, NULL, 0, &res);
2323
2324 g_assert_cmpint(err, ==, -EINVAL);
2325 g_assert_cmpint(res, ==, 0);
2326 }
2327
test_qemu_strtoi64_full_empty(void)2328 static void test_qemu_strtoi64_full_empty(void)
2329 {
2330 const char *str = "";
2331 int64_t res = 999;
2332 int err;
2333
2334 err = qemu_strtoi64(str, NULL, 0, &res);
2335
2336 g_assert_cmpint(err, ==, -EINVAL);
2337 g_assert_cmpint(res, ==, 0);
2338 }
2339
test_qemu_strtoi64_full_negative(void)2340 static void test_qemu_strtoi64_full_negative(void)
2341 {
2342 const char *str = " \t -321";
2343 int64_t res = 999;
2344 int err;
2345
2346 err = qemu_strtoi64(str, NULL, 0, &res);
2347
2348 g_assert_cmpint(err, ==, 0);
2349 g_assert_cmpint(res, ==, -321);
2350 }
2351
test_qemu_strtoi64_full_negzero(void)2352 static void test_qemu_strtoi64_full_negzero(void)
2353 {
2354 const char *str = " -0";
2355 int64_t res = 999;
2356 int err;
2357
2358 err = qemu_strtoi64(str, NULL, 0, &res);
2359
2360 g_assert_cmpint(err, ==, 0);
2361 g_assert_cmpint(res, ==, 0);
2362 }
2363
test_qemu_strtoi64_full_trailing(void)2364 static void test_qemu_strtoi64_full_trailing(void)
2365 {
2366 const char *str = "123xxx";
2367 int64_t res = 999;
2368 int err;
2369
2370 err = qemu_strtoi64(str, NULL, 0, &res);
2371
2372 g_assert_cmpint(err, ==, -EINVAL);
2373 g_assert_cmpint(res, ==, 123);
2374 }
2375
test_qemu_strtoi64_full_max(void)2376 static void test_qemu_strtoi64_full_max(void)
2377 {
2378
2379 char *str = g_strdup_printf("%lld", LLONG_MAX);
2380 int64_t res = 999;
2381 int err;
2382
2383 err = qemu_strtoi64(str, NULL, 0, &res);
2384
2385 g_assert_cmpint(err, ==, 0);
2386 g_assert_cmpint(res, ==, LLONG_MAX);
2387 g_free(str);
2388 }
2389
test_qemu_strtoi64_full_erange_junk(void)2390 static void test_qemu_strtoi64_full_erange_junk(void)
2391 {
2392 /* EINVAL has priority over ERANGE */
2393 const char *str = "-99999999999999999999junk";
2394 int64_t res = 999;
2395 int err;
2396
2397 err = qemu_strtoi64(str, NULL, 0, &res);
2398
2399 g_assert_cmpint(err, ==, -EINVAL);
2400 g_assert_cmpint(res, ==, INT64_MIN);
2401 }
2402
test_qemu_strtou64_correct(void)2403 static void test_qemu_strtou64_correct(void)
2404 {
2405 const char *str = "12345 foo";
2406 char f = 'X';
2407 const char *endptr = &f;
2408 uint64_t res = 999;
2409 int err;
2410
2411 err = qemu_strtou64(str, &endptr, 0, &res);
2412
2413 g_assert_cmpint(err, ==, 0);
2414 g_assert_cmpuint(res, ==, 12345);
2415 g_assert_true(endptr == str + 5);
2416 }
2417
test_qemu_strtou64_null(void)2418 static void test_qemu_strtou64_null(void)
2419 {
2420 char f = 'X';
2421 const char *endptr = &f;
2422 uint64_t res = 999;
2423 int err;
2424
2425 err = qemu_strtou64(NULL, &endptr, 0, &res);
2426
2427 g_assert_cmpint(err, ==, -EINVAL);
2428 g_assert_cmpuint(res, ==, 0);
2429 g_assert_null(endptr);
2430 }
2431
test_qemu_strtou64_empty(void)2432 static void test_qemu_strtou64_empty(void)
2433 {
2434 const char *str = "";
2435 char f = 'X';
2436 const char *endptr = &f;
2437 uint64_t res = 999;
2438 int err;
2439
2440 err = qemu_strtou64(str, &endptr, 0, &res);
2441
2442 g_assert_cmpint(err, ==, -EINVAL);
2443 g_assert_cmpuint(res, ==, 0);
2444 g_assert_true(endptr == str);
2445 }
2446
test_qemu_strtou64_whitespace(void)2447 static void test_qemu_strtou64_whitespace(void)
2448 {
2449 const char *str = " \t ";
2450 char f = 'X';
2451 const char *endptr = &f;
2452 uint64_t res = 999;
2453 int err;
2454
2455 err = qemu_strtou64(str, &endptr, 0, &res);
2456
2457 g_assert_cmpint(err, ==, -EINVAL);
2458 g_assert_cmpuint(res, ==, 0);
2459 g_assert_true(endptr == str);
2460 }
2461
test_qemu_strtou64_invalid(void)2462 static void test_qemu_strtou64_invalid(void)
2463 {
2464 const char *str = " xxxx \t abc";
2465 char f = 'X';
2466 const char *endptr = &f;
2467 uint64_t res = 999;
2468 int err;
2469
2470 err = qemu_strtou64(str, &endptr, 0, &res);
2471
2472 g_assert_cmpint(err, ==, -EINVAL);
2473 g_assert_cmpuint(res, ==, 0);
2474 g_assert_true(endptr == str);
2475 }
2476
test_qemu_strtou64_trailing(void)2477 static void test_qemu_strtou64_trailing(void)
2478 {
2479 const char *str = "123xxx";
2480 char f = 'X';
2481 const char *endptr = &f;
2482 uint64_t res = 999;
2483 int err;
2484
2485 err = qemu_strtou64(str, &endptr, 0, &res);
2486
2487 g_assert_cmpint(err, ==, 0);
2488 g_assert_cmpuint(res, ==, 123);
2489 g_assert_true(endptr == str + 3);
2490 }
2491
test_qemu_strtou64_octal(void)2492 static void test_qemu_strtou64_octal(void)
2493 {
2494 const char *str = "0123";
2495 char f = 'X';
2496 const char *endptr = &f;
2497 uint64_t res = 999;
2498 int err;
2499
2500 err = qemu_strtou64(str, &endptr, 8, &res);
2501
2502 g_assert_cmpint(err, ==, 0);
2503 g_assert_cmpuint(res, ==, 0123);
2504 g_assert_true(endptr == str + strlen(str));
2505
2506 endptr = &f;
2507 res = 999;
2508 err = qemu_strtou64(str, &endptr, 0, &res);
2509
2510 g_assert_cmpint(err, ==, 0);
2511 g_assert_cmpuint(res, ==, 0123);
2512 g_assert_true(endptr == str + strlen(str));
2513 }
2514
test_qemu_strtou64_decimal(void)2515 static void test_qemu_strtou64_decimal(void)
2516 {
2517 const char *str = "0123";
2518 char f = 'X';
2519 const char *endptr = &f;
2520 uint64_t res = 999;
2521 int err;
2522
2523 err = qemu_strtou64(str, &endptr, 10, &res);
2524
2525 g_assert_cmpint(err, ==, 0);
2526 g_assert_cmpuint(res, ==, 123);
2527 g_assert_true(endptr == str + strlen(str));
2528
2529 str = "123";
2530 endptr = &f;
2531 res = 999;
2532 err = qemu_strtou64(str, &endptr, 0, &res);
2533
2534 g_assert_cmpint(err, ==, 0);
2535 g_assert_cmpuint(res, ==, 123);
2536 g_assert_true(endptr == str + strlen(str));
2537 }
2538
test_qemu_strtou64_hex(void)2539 static void test_qemu_strtou64_hex(void)
2540 {
2541 const char *str = "0123";
2542 char f = 'X';
2543 const char *endptr = &f;
2544 uint64_t res = 999;
2545 int err;
2546
2547 err = qemu_strtou64(str, &endptr, 16, &res);
2548
2549 g_assert_cmpint(err, ==, 0);
2550 g_assert_cmphex(res, ==, 0x123);
2551 g_assert_true(endptr == str + strlen(str));
2552
2553 str = "0x123";
2554 endptr = &f;
2555 res = 999;
2556 err = qemu_strtou64(str, &endptr, 0, &res);
2557
2558 g_assert_cmpint(err, ==, 0);
2559 g_assert_cmphex(res, ==, 0x123);
2560 g_assert_true(endptr == str + strlen(str));
2561
2562 str = "0x";
2563 endptr = &f;
2564 res = 999;
2565 err = qemu_strtou64(str, &endptr, 16, &res);
2566
2567 g_assert_cmpint(err, ==, 0);
2568 g_assert_cmphex(res, ==, 0);
2569 g_assert_true(endptr == str + 1);
2570 }
2571
test_qemu_strtou64_wrap(void)2572 static void test_qemu_strtou64_wrap(void)
2573 {
2574 const char *str = "-18446744073709551615"; /* 1 mod 2^64 */
2575 char f = 'X';
2576 const char *endptr = &f;
2577 uint64_t res = 999;
2578 int err;
2579
2580 err = qemu_strtou64(str, &endptr, 0, &res);
2581
2582 g_assert_cmpint(err, ==, 0);
2583 g_assert_cmpuint(res, ==, 1);
2584 g_assert_true(endptr == str + strlen(str));
2585 }
2586
test_qemu_strtou64_max(void)2587 static void test_qemu_strtou64_max(void)
2588 {
2589 char *str = g_strdup_printf("%llu", ULLONG_MAX);
2590 char f = 'X';
2591 const char *endptr = &f;
2592 uint64_t res = 999;
2593 int err;
2594
2595 err = qemu_strtou64(str, &endptr, 0, &res);
2596
2597 g_assert_cmpint(err, ==, 0);
2598 g_assert_cmphex(res, ==, ULLONG_MAX);
2599 g_assert_true(endptr == str + strlen(str));
2600 g_free(str);
2601 }
2602
test_qemu_strtou64_overflow(void)2603 static void test_qemu_strtou64_overflow(void)
2604 {
2605 const char *str;
2606 const char *endptr;
2607 uint64_t res;
2608 int err;
2609
2610 str = "18446744073709551616"; /* 1 more than UINT64_MAX */
2611 endptr = "somewhere";
2612 res = 999;
2613 err = qemu_strtou64(str, &endptr, 0, &res);
2614 g_assert_cmpint(err, ==, -ERANGE);
2615 g_assert_cmpuint(res, ==, UINT64_MAX);
2616 g_assert_true(endptr == str + strlen(str));
2617
2618 str = "0x10000000000000000"; /* 65 bits, 64-bit sign bit clear */
2619 endptr = "somewhere";
2620 res = 999;
2621 err = qemu_strtou64(str, &endptr, 0, &res);
2622 g_assert_cmpint(err, ==, -ERANGE);
2623 g_assert_cmpuint(res, ==, UINT64_MAX);
2624 g_assert_true(endptr == str + strlen(str));
2625
2626 str = "0x18000000080000000"; /* 65 bits, 64-bit sign bit set */
2627 endptr = "somewhere";
2628 res = 999;
2629 err = qemu_strtou64(str, &endptr, 0, &res);
2630 g_assert_cmpint(err, ==, -ERANGE);
2631 g_assert_cmpuint(res, ==, UINT64_MAX);
2632 g_assert_true(endptr == str + strlen(str));
2633 }
2634
test_qemu_strtou64_underflow(void)2635 static void test_qemu_strtou64_underflow(void)
2636 {
2637 const char *str;
2638 const char *endptr;
2639 uint64_t res;
2640 int err;
2641
2642 str = "-99999999999999999999999999999999999999999999";
2643 endptr = "somewhere";
2644 res = 999;
2645 err = qemu_strtou64(str, &endptr, 0, &res);
2646 g_assert_cmpint(err, ==, -ERANGE);
2647 g_assert_cmpuint(res, ==, UINT64_MAX);
2648 g_assert_true(endptr == str + strlen(str));
2649
2650 str = "-0x10000000000000000"; /* 65 bits, 64-bit sign bit clear */
2651 endptr = "somewhere";
2652 res = 999;
2653 err = qemu_strtou64(str, &endptr, 0, &res);
2654 g_assert_cmpint(err, ==, -ERANGE);
2655 g_assert_cmpuint(res, ==, UINT64_MAX);
2656 g_assert_true(endptr == str + strlen(str));
2657
2658 str = "-0x18000000080000000"; /* 65 bits, 64-bit sign bit set */
2659 endptr = "somewhere";
2660 res = 999;
2661 err = qemu_strtou64(str, &endptr, 0, &res);
2662 g_assert_cmpint(err, ==, -ERANGE);
2663 g_assert_cmpuint(res, ==, UINT64_MAX);
2664 g_assert_true(endptr == str + strlen(str));
2665 }
2666
test_qemu_strtou64_negative(void)2667 static void test_qemu_strtou64_negative(void)
2668 {
2669 const char *str = " \t -321";
2670 char f = 'X';
2671 const char *endptr = &f;
2672 uint64_t res = 999;
2673 int err;
2674
2675 err = qemu_strtou64(str, &endptr, 0, &res);
2676
2677 g_assert_cmpint(err, ==, 0);
2678 g_assert_cmpuint(res, ==, -321ull);
2679 g_assert_true(endptr == str + strlen(str));
2680 }
2681
test_qemu_strtou64_negzero(void)2682 static void test_qemu_strtou64_negzero(void)
2683 {
2684 const char *str = " -0";
2685 char f = 'X';
2686 const char *endptr = &f;
2687 uint64_t res = 999;
2688 int err;
2689
2690 err = qemu_strtou64(str, &endptr, 0, &res);
2691
2692 g_assert_cmpint(err, ==, 0);
2693 g_assert_cmpuint(res, ==, 0);
2694 g_assert_true(endptr == str + strlen(str));
2695 }
2696
test_qemu_strtou64_full_correct(void)2697 static void test_qemu_strtou64_full_correct(void)
2698 {
2699 const char *str = "18446744073709551614";
2700 uint64_t res = 999;
2701 int err;
2702
2703 err = qemu_strtou64(str, NULL, 0, &res);
2704
2705 g_assert_cmpint(err, ==, 0);
2706 g_assert_cmpuint(res, ==, 18446744073709551614ull);
2707 }
2708
test_qemu_strtou64_full_null(void)2709 static void test_qemu_strtou64_full_null(void)
2710 {
2711 uint64_t res = 999;
2712 int err;
2713
2714 err = qemu_strtou64(NULL, NULL, 0, &res);
2715
2716 g_assert_cmpint(err, ==, -EINVAL);
2717 g_assert_cmpuint(res, ==, 0);
2718 }
2719
test_qemu_strtou64_full_empty(void)2720 static void test_qemu_strtou64_full_empty(void)
2721 {
2722 const char *str = "";
2723 uint64_t res = 999;
2724 int err;
2725
2726 err = qemu_strtou64(str, NULL, 0, &res);
2727
2728 g_assert_cmpint(err, ==, -EINVAL);
2729 g_assert_cmpuint(res, ==, 0);
2730 }
2731
test_qemu_strtou64_full_negative(void)2732 static void test_qemu_strtou64_full_negative(void)
2733 {
2734 const char *str = " \t -321";
2735 uint64_t res = 999;
2736 int err;
2737
2738 err = qemu_strtou64(str, NULL, 0, &res);
2739
2740 g_assert_cmpint(err, ==, 0);
2741 g_assert_cmpuint(res, ==, -321ull);
2742 }
2743
test_qemu_strtou64_full_negzero(void)2744 static void test_qemu_strtou64_full_negzero(void)
2745 {
2746 const char *str = " -0";
2747 uint64_t res = 999;
2748 int err;
2749
2750 err = qemu_strtou64(str, NULL, 0, &res);
2751
2752 g_assert_cmpint(err, ==, 0);
2753 g_assert_cmpuint(res, ==, 0);
2754 }
2755
test_qemu_strtou64_full_trailing(void)2756 static void test_qemu_strtou64_full_trailing(void)
2757 {
2758 const char *str = "18446744073709551614xxxxxx";
2759 uint64_t res = 999;
2760 int err;
2761
2762 err = qemu_strtou64(str, NULL, 0, &res);
2763
2764 g_assert_cmpint(err, ==, -EINVAL);
2765 g_assert_cmpuint(res, ==, 18446744073709551614ULL);
2766 }
2767
test_qemu_strtou64_full_max(void)2768 static void test_qemu_strtou64_full_max(void)
2769 {
2770 char *str = g_strdup_printf("%lld", ULLONG_MAX);
2771 uint64_t res = 999;
2772 int err;
2773
2774 err = qemu_strtou64(str, NULL, 0, &res);
2775
2776 g_assert_cmpint(err, ==, 0);
2777 g_assert_cmphex(res, ==, ULLONG_MAX);
2778 g_free(str);
2779 }
2780
test_qemu_strtou64_full_erange_junk(void)2781 static void test_qemu_strtou64_full_erange_junk(void)
2782 {
2783 /* EINVAL has priority over ERANGE */
2784 const char *str = "-99999999999999999999junk";
2785 uint64_t res = 999;
2786 int err;
2787
2788 err = qemu_strtou64(str, NULL, 0, &res);
2789
2790 g_assert_cmpint(err, ==, -EINVAL);
2791 g_assert_cmpuint(res, ==, UINT64_MAX);
2792 }
2793
test_qemu_strtod_simple(void)2794 static void test_qemu_strtod_simple(void)
2795 {
2796 const char *str;
2797 const char *endptr;
2798 int err;
2799 double res;
2800
2801 /* no radix or exponent */
2802 str = "1";
2803 endptr = "somewhere";
2804 res = 999;
2805 err = qemu_strtod(str, &endptr, &res);
2806 g_assert_cmpint(err, ==, 0);
2807 g_assert_cmpfloat(res, ==, 1.0);
2808 g_assert_true(endptr == str + 1);
2809
2810 /* leading space and sign */
2811 str = " -0.0";
2812 endptr = "somewhere";
2813 res = 999;
2814 err = qemu_strtod(str, &endptr, &res);
2815 g_assert_cmpint(err, ==, 0);
2816 g_assert_cmpfloat(res, ==, -0.0);
2817 g_assert_true(signbit(res));
2818 g_assert_true(endptr == str + 5);
2819
2820 /* fraction only */
2821 str = "+.5";
2822 endptr = "somewhere";
2823 res = 999;
2824 err = qemu_strtod(str, &endptr, &res);
2825 g_assert_cmpint(err, ==, 0);
2826 g_assert_cmpfloat(res, ==, 0.5);
2827 g_assert_true(endptr == str + 3);
2828
2829 /* exponent */
2830 str = "1.e+1";
2831 endptr = "somewhere";
2832 res = 999;
2833 err = qemu_strtod(str, &endptr, &res);
2834 g_assert_cmpint(err, ==, 0);
2835 g_assert_cmpfloat(res, ==, 10.0);
2836 g_assert_true(endptr == str + 5);
2837
2838 /* hex without radix */
2839 str = "0x10";
2840 endptr = "somewhere";
2841 res = 999;
2842 err = qemu_strtod(str, &endptr, &res);
2843 g_assert_cmpint(err, ==, 0);
2844 g_assert_cmpfloat(res, ==, 16.0);
2845 g_assert_true(endptr == str + 4);
2846 }
2847
test_qemu_strtod_einval(void)2848 static void test_qemu_strtod_einval(void)
2849 {
2850 const char *str;
2851 const char *endptr;
2852 int err;
2853 double res;
2854
2855 /* empty */
2856 str = "";
2857 endptr = "somewhere";
2858 res = 999;
2859 err = qemu_strtod(str, &endptr, &res);
2860 g_assert_cmpint(err, ==, -EINVAL);
2861 g_assert_cmpfloat(res, ==, 0.0);
2862 g_assert_false(signbit(res));
2863 g_assert_true(endptr == str);
2864
2865 /* NULL */
2866 str = NULL;
2867 endptr = "random";
2868 res = 999;
2869 err = qemu_strtod(str, &endptr, &res);
2870 g_assert_cmpint(err, ==, -EINVAL);
2871 g_assert_cmpfloat(res, ==, 0.0);
2872 g_assert_false(signbit(res));
2873 g_assert_null(endptr);
2874
2875 /* not recognizable */
2876 str = " junk";
2877 endptr = "somewhere";
2878 res = 999;
2879 err = qemu_strtod(str, &endptr, &res);
2880 g_assert_cmpint(err, ==, -EINVAL);
2881 g_assert_cmpfloat(res, ==, 0.0);
2882 g_assert_false(signbit(res));
2883 g_assert_true(endptr == str);
2884 }
2885
test_qemu_strtod_erange(void)2886 static void test_qemu_strtod_erange(void)
2887 {
2888 const char *str;
2889 const char *endptr;
2890 int err;
2891 double res;
2892
2893 /* overflow */
2894 str = "9e999";
2895 endptr = "somewhere";
2896 res = 999;
2897 err = qemu_strtod(str, &endptr, &res);
2898 g_assert_cmpint(err, ==, -ERANGE);
2899 g_assert_cmpfloat(res, ==, HUGE_VAL);
2900 g_assert_true(endptr == str + 5);
2901
2902 str = "-9e+999";
2903 endptr = "somewhere";
2904 res = 999;
2905 err = qemu_strtod(str, &endptr, &res);
2906 g_assert_cmpint(err, ==, -ERANGE);
2907 g_assert_cmpfloat(res, ==, -HUGE_VAL);
2908 g_assert_true(endptr == str + 7);
2909
2910 /* underflow */
2911 str = "-9e-999";
2912 endptr = "somewhere";
2913 res = 999;
2914 err = qemu_strtod(str, &endptr, &res);
2915 g_assert_cmpint(err, ==, -ERANGE);
2916 g_assert_cmpfloat(res, >=, -DBL_MIN);
2917 g_assert_cmpfloat(res, <=, -0.0);
2918 g_assert_true(signbit(res));
2919 g_assert_true(endptr == str + 7);
2920 }
2921
test_qemu_strtod_nonfinite(void)2922 static void test_qemu_strtod_nonfinite(void)
2923 {
2924 const char *str;
2925 const char *endptr;
2926 int err;
2927 double res;
2928
2929 /* infinity */
2930 str = "inf";
2931 endptr = "somewhere";
2932 res = 999;
2933 err = qemu_strtod(str, &endptr, &res);
2934 g_assert_cmpint(err, ==, 0);
2935 g_assert_true(isinf(res));
2936 g_assert_false(signbit(res));
2937 g_assert_true(endptr == str + 3);
2938
2939 str = "-infinity";
2940 endptr = "somewhere";
2941 res = 999;
2942 err = qemu_strtod(str, &endptr, &res);
2943 g_assert_cmpint(err, ==, 0);
2944 g_assert_true(isinf(res));
2945 g_assert_true(signbit(res));
2946 g_assert_true(endptr == str + 9);
2947
2948 /* not a number */
2949 str = " NaN";
2950 endptr = "somewhere";
2951 res = 999;
2952 err = qemu_strtod(str, &endptr, &res);
2953 g_assert_cmpint(err, ==, 0);
2954 g_assert_true(isnan(res));
2955 g_assert_true(endptr == str + 4);
2956 }
2957
test_qemu_strtod_trailing(void)2958 static void test_qemu_strtod_trailing(void)
2959 {
2960 const char *str;
2961 const char *endptr;
2962 int err;
2963 double res;
2964
2965 /* trailing whitespace */
2966 str = "1. ";
2967 endptr = "somewhere";
2968 res = 999;
2969 err = qemu_strtod(str, &endptr, &res);
2970 g_assert_cmpint(err, ==, 0);
2971 g_assert_cmpfloat(res, ==, 1.0);
2972 g_assert_true(endptr == str + 2);
2973
2974 endptr = "somewhere";
2975 res = 999;
2976 err = qemu_strtod(str, NULL, &res);
2977 g_assert_cmpint(err, ==, -EINVAL);
2978 g_assert_cmpfloat(res, ==, 1.0);
2979
2980 /* trailing e is not an exponent */
2981 str = ".5e";
2982 endptr = "somewhere";
2983 res = 999;
2984 err = qemu_strtod(str, &endptr, &res);
2985 g_assert_cmpint(err, ==, 0);
2986 g_assert_cmpfloat(res, ==, 0.5);
2987 g_assert_true(endptr == str + 2);
2988
2989 endptr = "somewhere";
2990 res = 999;
2991 err = qemu_strtod(str, NULL, &res);
2992 g_assert_cmpint(err, ==, -EINVAL);
2993 g_assert_cmpfloat(res, ==, 0.5);
2994
2995 /* trailing ( not part of long NaN */
2996 str = "nan(";
2997 endptr = "somewhere";
2998 res = 999;
2999 err = qemu_strtod(str, &endptr, &res);
3000 g_assert_cmpint(err, ==, 0);
3001 g_assert_true(isnan(res));
3002 g_assert_true(endptr == str + 3);
3003
3004 endptr = "somewhere";
3005 res = 999;
3006 err = qemu_strtod(str, NULL, &res);
3007 g_assert_cmpint(err, ==, -EINVAL);
3008 g_assert_true(isnan(res));
3009 }
3010
test_qemu_strtod_erange_junk(void)3011 static void test_qemu_strtod_erange_junk(void)
3012 {
3013 const char *str;
3014 const char *endptr;
3015 int err;
3016 double res;
3017
3018 /* ERANGE with trailing junk... */
3019 str = "1e-999junk";
3020 endptr = "somewhere";
3021 res = 999;
3022 err = qemu_strtod(str, &endptr, &res);
3023 g_assert_cmpint(err, ==, -ERANGE);
3024 g_assert_cmpfloat(res, <=, DBL_MIN);
3025 g_assert_cmpfloat(res, >=, 0.0);
3026 g_assert_false(signbit(res));
3027 g_assert_true(endptr == str + 6);
3028
3029 /* ...has less priority than EINVAL when full parse not possible */
3030 endptr = "somewhere";
3031 res = 999;
3032 err = qemu_strtod(str, NULL, &res);
3033 g_assert_cmpint(err, ==, -EINVAL);
3034 g_assert_cmpfloat(res, ==, 0.0);
3035 g_assert_false(signbit(res));
3036 }
3037
test_qemu_strtod_finite_simple(void)3038 static void test_qemu_strtod_finite_simple(void)
3039 {
3040 const char *str;
3041 const char *endptr;
3042 int err;
3043 double res;
3044
3045 /* no radix or exponent */
3046 str = "1";
3047 endptr = "somewhere";
3048 res = 999;
3049 err = qemu_strtod_finite(str, &endptr, &res);
3050 g_assert_cmpint(err, ==, 0);
3051 g_assert_cmpfloat(res, ==, 1.0);
3052 g_assert_true(endptr == str + 1);
3053
3054 /* leading space and sign */
3055 str = " -0.0";
3056 endptr = "somewhere";
3057 res = 999;
3058 err = qemu_strtod_finite(str, &endptr, &res);
3059 g_assert_cmpint(err, ==, 0);
3060 g_assert_cmpfloat(res, ==, -0.0);
3061 g_assert_true(signbit(res));
3062 g_assert_true(endptr == str + 5);
3063
3064 /* fraction only */
3065 str = "+.5";
3066 endptr = "somewhere";
3067 res = 999;
3068 err = qemu_strtod_finite(str, &endptr, &res);
3069 g_assert_cmpint(err, ==, 0);
3070 g_assert_cmpfloat(res, ==, 0.5);
3071 g_assert_true(endptr == str + 3);
3072
3073 /* exponent */
3074 str = "1.e+1";
3075 endptr = "somewhere";
3076 res = 999;
3077 err = qemu_strtod_finite(str, &endptr, &res);
3078 g_assert_cmpint(err, ==, 0);
3079 g_assert_cmpfloat(res, ==, 10.0);
3080 g_assert_true(endptr == str + 5);
3081
3082 /* hex without radix */
3083 str = "0x10";
3084 endptr = "somewhere";
3085 res = 999;
3086 err = qemu_strtod(str, &endptr, &res);
3087 g_assert_cmpint(err, ==, 0);
3088 g_assert_cmpfloat(res, ==, 16.0);
3089 g_assert_true(endptr == str + 4);
3090 }
3091
test_qemu_strtod_finite_einval(void)3092 static void test_qemu_strtod_finite_einval(void)
3093 {
3094 const char *str;
3095 const char *endptr;
3096 int err;
3097 double res;
3098
3099 /* empty */
3100 str = "";
3101 endptr = "somewhere";
3102 res = 999;
3103 err = qemu_strtod_finite(str, &endptr, &res);
3104 g_assert_cmpint(err, ==, -EINVAL);
3105 g_assert_cmpfloat(res, ==, 0.0);
3106 g_assert_false(signbit(res));
3107 g_assert_true(endptr == str);
3108
3109 /* NULL */
3110 str = NULL;
3111 endptr = "random";
3112 res = 999;
3113 err = qemu_strtod_finite(str, &endptr, &res);
3114 g_assert_cmpint(err, ==, -EINVAL);
3115 g_assert_cmpfloat(res, ==, 0.0);
3116 g_assert_false(signbit(res));
3117 g_assert_null(endptr);
3118
3119 /* not recognizable */
3120 str = " junk";
3121 endptr = "somewhere";
3122 res = 999;
3123 err = qemu_strtod_finite(str, &endptr, &res);
3124 g_assert_cmpint(err, ==, -EINVAL);
3125 g_assert_cmpfloat(res, ==, 0.0);
3126 g_assert_false(signbit(res));
3127 g_assert_true(endptr == str);
3128 }
3129
test_qemu_strtod_finite_erange(void)3130 static void test_qemu_strtod_finite_erange(void)
3131 {
3132 const char *str;
3133 const char *endptr;
3134 int err;
3135 double res;
3136
3137 /* overflow turns into EINVAL */
3138 str = "9e999";
3139 endptr = "somewhere";
3140 res = 999;
3141 err = qemu_strtod_finite(str, &endptr, &res);
3142 g_assert_cmpint(err, ==, -EINVAL);
3143 g_assert_cmpfloat(res, ==, 0.0);
3144 g_assert_false(signbit(res));
3145 g_assert_true(endptr == str);
3146
3147 str = "-9e+999";
3148 endptr = "somewhere";
3149 res = 999;
3150 err = qemu_strtod_finite(str, &endptr, &res);
3151 g_assert_cmpint(err, ==, -EINVAL);
3152 g_assert_cmpfloat(res, ==, 0.0);
3153 g_assert_false(signbit(res));
3154 g_assert_true(endptr == str);
3155
3156 /* underflow is still possible */
3157 str = "-9e-999";
3158 endptr = "somewhere";
3159 res = 999;
3160 err = qemu_strtod_finite(str, &endptr, &res);
3161 g_assert_cmpint(err, ==, -ERANGE);
3162 g_assert_cmpfloat(res, >=, -DBL_MIN);
3163 g_assert_cmpfloat(res, <=, -0.0);
3164 g_assert_true(signbit(res));
3165 g_assert_true(endptr == str + 7);
3166 }
3167
test_qemu_strtod_finite_nonfinite(void)3168 static void test_qemu_strtod_finite_nonfinite(void)
3169 {
3170 const char *str;
3171 const char *endptr;
3172 int err;
3173 double res;
3174
3175 /* infinity */
3176 str = "inf";
3177 endptr = "somewhere";
3178 res = 999;
3179 err = qemu_strtod_finite(str, &endptr, &res);
3180 g_assert_cmpint(err, ==, -EINVAL);
3181 g_assert_cmpfloat(res, ==, 0.0);
3182 g_assert_false(signbit(res));
3183 g_assert_true(endptr == str);
3184
3185 str = "-infinity";
3186 endptr = "somewhere";
3187 res = 999;
3188 err = qemu_strtod_finite(str, &endptr, &res);
3189 g_assert_cmpint(err, ==, -EINVAL);
3190 g_assert_cmpfloat(res, ==, 0.0);
3191 g_assert_false(signbit(res));
3192 g_assert_true(endptr == str);
3193
3194 /* not a number */
3195 str = " NaN";
3196 endptr = "somewhere";
3197 res = 999;
3198 err = qemu_strtod_finite(str, &endptr, &res);
3199 g_assert_cmpint(err, ==, -EINVAL);
3200 g_assert_cmpfloat(res, ==, 0.0);
3201 g_assert_false(signbit(res));
3202 g_assert_true(endptr == str);
3203 }
3204
test_qemu_strtod_finite_trailing(void)3205 static void test_qemu_strtod_finite_trailing(void)
3206 {
3207 const char *str;
3208 const char *endptr;
3209 int err;
3210 double res;
3211
3212 /* trailing whitespace */
3213 str = "1. ";
3214 endptr = "somewhere";
3215 res = 999;
3216 err = qemu_strtod_finite(str, &endptr, &res);
3217 g_assert_cmpint(err, ==, 0);
3218 g_assert_cmpfloat(res, ==, 1.0);
3219 g_assert_true(endptr == str + 2);
3220
3221 endptr = "somewhere";
3222 res = 999;
3223 err = qemu_strtod_finite(str, NULL, &res);
3224 g_assert_cmpint(err, ==, -EINVAL);
3225 g_assert_cmpfloat(res, ==, 1.0);
3226 g_assert_false(signbit(res));
3227
3228 /* trailing e is not an exponent */
3229 str = ".5e";
3230 endptr = "somewhere";
3231 res = 999;
3232 err = qemu_strtod_finite(str, &endptr, &res);
3233 g_assert_cmpint(err, ==, 0);
3234 g_assert_cmpfloat(res, ==, 0.5);
3235 g_assert_true(endptr == str + 2);
3236
3237 endptr = "somewhere";
3238 res = 999;
3239 err = qemu_strtod_finite(str, NULL, &res);
3240 g_assert_cmpint(err, ==, -EINVAL);
3241 g_assert_cmpfloat(res, ==, 0.5);
3242
3243 /* trailing ( not part of long NaN */
3244 str = "nan(";
3245 endptr = "somewhere";
3246 res = 999;
3247 err = qemu_strtod_finite(str, &endptr, &res);
3248 g_assert_cmpint(err, ==, -EINVAL);
3249 g_assert_cmpfloat(res, ==, 0.0);
3250 g_assert_false(signbit(res));
3251 g_assert_true(endptr == str);
3252
3253 endptr = "somewhere";
3254 res = 999;
3255 err = qemu_strtod_finite(str, NULL, &res);
3256 g_assert_cmpint(err, ==, -EINVAL);
3257 g_assert_cmpfloat(res, ==, 0.0);
3258 g_assert_false(signbit(res));
3259 }
3260
test_qemu_strtod_finite_erange_junk(void)3261 static void test_qemu_strtod_finite_erange_junk(void)
3262 {
3263 const char *str;
3264 const char *endptr;
3265 int err;
3266 double res;
3267
3268 /* ERANGE with trailing junk... */
3269 str = "1e-999junk";
3270 endptr = "somewhere";
3271 res = 999;
3272 err = qemu_strtod_finite(str, &endptr, &res);
3273 g_assert_cmpint(err, ==, -ERANGE);
3274 g_assert_cmpfloat(res, <=, DBL_MIN);
3275 g_assert_cmpfloat(res, >=, 0.0);
3276 g_assert_false(signbit(res));
3277 g_assert_true(endptr == str + 6);
3278
3279 /* ...has less priority than EINVAL when full parse not possible */
3280 endptr = "somewhere";
3281 res = 999;
3282 err = qemu_strtod_finite(str, NULL, &res);
3283 g_assert_cmpint(err, ==, -EINVAL);
3284 g_assert_cmpfloat(res, ==, 0.0);
3285 g_assert_false(signbit(res));
3286 }
3287
3288 typedef int (*qemu_strtosz_fn)(const char *, const char **, uint64_t *);
do_strtosz_full(const char * str,qemu_strtosz_fn fn,int exp_ptr_ret,uint64_t exp_ptr_val,size_t exp_ptr_offset,int exp_null_ret,uint64_t exp_null_val)3289 static void do_strtosz_full(const char *str, qemu_strtosz_fn fn,
3290 int exp_ptr_ret, uint64_t exp_ptr_val,
3291 size_t exp_ptr_offset, int exp_null_ret,
3292 uint64_t exp_null_val)
3293 {
3294 const char *endptr = "somewhere";
3295 uint64_t val = 0xbaadf00d;
3296 int ret;
3297
3298 ret = fn(str, &endptr, &val);
3299 g_assert_cmpint(ret, ==, exp_ptr_ret);
3300 g_assert_cmpuint(val, ==, exp_ptr_val);
3301 if (str) {
3302 g_assert_true(endptr == str + exp_ptr_offset);
3303 } else {
3304 g_assert_cmpint(exp_ptr_offset, ==, 0);
3305 g_assert_null(endptr);
3306 }
3307
3308 val = 0xbaadf00d;
3309 ret = fn(str, NULL, &val);
3310 g_assert_cmpint(ret, ==, exp_null_ret);
3311 g_assert_cmpuint(val, ==, exp_null_val);
3312 }
3313
do_strtosz(const char * str,int exp_ret,uint64_t exp_val,size_t exp_offset)3314 static void do_strtosz(const char *str, int exp_ret, uint64_t exp_val,
3315 size_t exp_offset)
3316 {
3317 do_strtosz_full(str, qemu_strtosz, exp_ret, exp_val, exp_offset,
3318 exp_ret, exp_val);
3319 }
3320
do_strtosz_MiB(const char * str,int exp_ret,uint64_t exp_val,size_t exp_offset)3321 static void do_strtosz_MiB(const char *str, int exp_ret, uint64_t exp_val,
3322 size_t exp_offset)
3323 {
3324 do_strtosz_full(str, qemu_strtosz_MiB, exp_ret, exp_val, exp_offset,
3325 exp_ret, exp_val);
3326 }
3327
do_strtosz_metric(const char * str,int exp_ret,uint64_t exp_val,size_t exp_offset)3328 static void do_strtosz_metric(const char *str, int exp_ret, uint64_t exp_val,
3329 size_t exp_offset)
3330 {
3331 do_strtosz_full(str, qemu_strtosz_metric, exp_ret, exp_val, exp_offset,
3332 exp_ret, exp_val);
3333 }
3334
test_qemu_strtosz_simple(void)3335 static void test_qemu_strtosz_simple(void)
3336 {
3337 do_strtosz("0", 0, 0, 1);
3338
3339 /* Leading 0 gives decimal results, not octal */
3340 do_strtosz("08", 0, 8, 2);
3341
3342 /* Leading space and + are ignored */
3343 do_strtosz(" +12345", 0, 12345, 7);
3344
3345 /* 2^53-1 */
3346 do_strtosz("9007199254740991", 0, 0x1fffffffffffffULL, 16);
3347
3348 /* 2^53 */
3349 do_strtosz("9007199254740992", 0, 0x20000000000000ULL, 16);
3350
3351 /* 2^53+1 */
3352 do_strtosz("9007199254740993", 0, 0x20000000000001ULL, 16);
3353
3354 /* 0xfffffffffffff800 (53 msbs set) */
3355 do_strtosz("18446744073709549568", 0, 0xfffffffffffff800ULL, 20);
3356
3357 /* 0xfffffffffffffbff */
3358 do_strtosz("18446744073709550591", 0, 0xfffffffffffffbffULL, 20);
3359
3360 /* 0xffffffffffffffff */
3361 do_strtosz("18446744073709551615", 0, 0xffffffffffffffffULL, 20);
3362 }
3363
test_qemu_strtosz_hex(void)3364 static void test_qemu_strtosz_hex(void)
3365 {
3366 do_strtosz("0x0", 0, 0, 3);
3367
3368 do_strtosz("0xab", 0, 171, 4);
3369
3370 do_strtosz(" +0xae", 0, 174, 6);
3371 }
3372
test_qemu_strtosz_units(void)3373 static void test_qemu_strtosz_units(void)
3374 {
3375 /* default scale depends on function */
3376 do_strtosz("1", 0, 1, 1);
3377 do_strtosz_MiB("1", 0, MiB, 1);
3378 do_strtosz_metric("1", 0, 1, 1);
3379
3380 /* Explicit byte suffix works for all functions */
3381 do_strtosz("1B", 0, 1, 2);
3382 do_strtosz_MiB("1B", 0, 1, 2);
3383 do_strtosz_metric("1B", 0, 1, 2);
3384
3385 /* Expose the scale */
3386 do_strtosz("1K", 0, KiB, 2);
3387 do_strtosz_MiB("1K", 0, KiB, 2);
3388 do_strtosz_metric("1K", 0, 1000, 2);
3389
3390 /* Other suffixes, see also test_qemu_strtosz_metric */
3391 do_strtosz("1M", 0, MiB, 2);
3392 do_strtosz("1G", 0, GiB, 2);
3393 do_strtosz("1T", 0, TiB, 2);
3394 do_strtosz("1P", 0, PiB, 2);
3395 do_strtosz("1E", 0, EiB, 2);
3396 }
3397
test_qemu_strtosz_float(void)3398 static void test_qemu_strtosz_float(void)
3399 {
3400 do_strtosz("0.5E", 0, EiB / 2, 4);
3401
3402 /* Implied M suffix okay */
3403 do_strtosz_MiB("0.5", 0, MiB / 2, 3);
3404
3405 /* For convenience, a fraction of 0 is tolerated even on bytes */
3406 do_strtosz("1.0B", 0, 1, 4);
3407
3408 /* An empty fraction tail is tolerated */
3409 do_strtosz("1.k", 0, 1024, 3);
3410
3411 /* An empty fraction head is tolerated */
3412 do_strtosz(" .5k", 0, 512, 4);
3413
3414 /* For convenience, we permit values that are not byte-exact */
3415 do_strtosz("12.345M", 0, (uint64_t) (12.345 * MiB + 0.5), 7);
3416
3417 /* Fraction tail can round up */
3418 do_strtosz("1.9999k", 0, 2048, 7);
3419 do_strtosz("1.9999999999999999999999999999999999999999999999999999k", 0,
3420 2048, 55);
3421
3422 /* ERANGE underflow in the fraction tail does not matter for 'k' */
3423 do_strtosz("1."
3424 "00000000000000000000000000000000000000000000000000"
3425 "00000000000000000000000000000000000000000000000000"
3426 "00000000000000000000000000000000000000000000000000"
3427 "00000000000000000000000000000000000000000000000000"
3428 "00000000000000000000000000000000000000000000000000"
3429 "00000000000000000000000000000000000000000000000000"
3430 "00000000000000000000000000000000000000000000000000"
3431 "1k", 0, 1024, 354);
3432 }
3433
test_qemu_strtosz_invalid(void)3434 static void test_qemu_strtosz_invalid(void)
3435 {
3436 do_strtosz(NULL, -EINVAL, 0, 0);
3437
3438 /* Must parse at least one digit */
3439 do_strtosz("", -EINVAL, 0, 0);
3440 do_strtosz(" \t ", -EINVAL, 0, 0);
3441 do_strtosz(".", -EINVAL, 0, 0);
3442 do_strtosz(" .", -EINVAL, 0, 0);
3443 do_strtosz(" .k", -EINVAL, 0, 0);
3444 do_strtosz("inf", -EINVAL, 0, 0);
3445 do_strtosz("NaN", -EINVAL, 0, 0);
3446
3447 /* Lone suffix is not okay */
3448 do_strtosz("k", -EINVAL, 0, 0);
3449 do_strtosz(" M", -EINVAL, 0, 0);
3450
3451 /* Fractional values require scale larger than bytes */
3452 do_strtosz("1.1B", -EINVAL, 0, 0);
3453 do_strtosz("1.1", -EINVAL, 0, 0);
3454
3455 /* 'B' cannot have any nonzero fraction, even with rounding or underflow */
3456 do_strtosz("1.00001B", -EINVAL, 0, 0);
3457 do_strtosz("1.00000000000000000001B", -EINVAL, 0, 0);
3458 do_strtosz("1."
3459 "00000000000000000000000000000000000000000000000000"
3460 "00000000000000000000000000000000000000000000000000"
3461 "00000000000000000000000000000000000000000000000000"
3462 "00000000000000000000000000000000000000000000000000"
3463 "00000000000000000000000000000000000000000000000000"
3464 "00000000000000000000000000000000000000000000000000"
3465 "00000000000000000000000000000000000000000000000000"
3466 "1B", -EINVAL, 0, 0);
3467
3468 /* No hex fractions */
3469 do_strtosz("0x1.8k", -EINVAL, 0, 0);
3470 do_strtosz("0x1.k", -EINVAL, 0, 0);
3471
3472 /* No hex suffixes */
3473 do_strtosz("0x18M", -EINVAL, 0, 0);
3474 do_strtosz("0x1p1", -EINVAL, 0, 0);
3475
3476 /* decimal in place of scaling suffix */
3477 do_strtosz("1.1.k", -EINVAL, 0, 0);
3478 do_strtosz("1.1.", -EINVAL, 0, 0);
3479 }
3480
test_qemu_strtosz_trailing(void)3481 static void test_qemu_strtosz_trailing(void)
3482 {
3483 /* Trailing whitespace */
3484 do_strtosz_full("1k ", qemu_strtosz, 0, 1024, 2, -EINVAL, 0);
3485
3486 /* Unknown suffix overrides even implied scale*/
3487 do_strtosz_full("123xxx", qemu_strtosz, 0, 123, 3, -EINVAL, 0);
3488
3489 /* Implied scale allows partial parse */
3490 do_strtosz_full("123xxx", qemu_strtosz_MiB, 0, 123 * MiB, 3, -EINVAL, 0);
3491 do_strtosz_full("1.5.k", qemu_strtosz_MiB, 0, 1.5 * MiB, 3, -EINVAL, 0);
3492
3493 /* Junk after one-byte suffix */
3494 do_strtosz_full("1kiB", qemu_strtosz, 0, 1024, 2, -EINVAL, 0);
3495
3496 /* Incomplete hex is an unknown suffix */
3497 do_strtosz_full("0x", qemu_strtosz, 0, 0, 1, -EINVAL, 0);
3498
3499 /* Hex literals use only one leading zero */
3500 do_strtosz_full("00x1", qemu_strtosz, 0, 0, 2, -EINVAL, 0);
3501
3502 /* No support for binary literals; 'b' is valid suffix */
3503 do_strtosz_full("0b1000", qemu_strtosz, 0, 0, 2, -EINVAL, 0);
3504
3505 /* Junk after decimal */
3506 do_strtosz_full("0.NaN", qemu_strtosz, 0, 0, 2, -EINVAL, 0);
3507
3508 /* Although negatives are invalid, '-' may be in trailing junk */
3509 do_strtosz_full("123-45", qemu_strtosz, 0, 123, 3, -EINVAL, 0);
3510 do_strtosz_full(" 123 - 45", qemu_strtosz, 0, 123, 4, -EINVAL, 0);
3511
3512 /* Parse stops at 'e', which is not a floating point exponent */
3513 do_strtosz_full("1.5e1k", qemu_strtosz, 0, EiB * 1.5, 4, -EINVAL, 0);
3514 do_strtosz_full("1.5E+0k", qemu_strtosz, 0, EiB * 1.5, 4, -EINVAL, 0);
3515 do_strtosz_full("1.5E999", qemu_strtosz, 0, EiB * 1.5, 4, -EINVAL, 0);
3516 }
3517
test_qemu_strtosz_erange(void)3518 static void test_qemu_strtosz_erange(void)
3519 {
3520 /* no negative values */
3521 do_strtosz(" -0", -ERANGE, 0, 3);
3522 do_strtosz("-1", -ERANGE, 0, 2);
3523 do_strtosz_full("-2M", qemu_strtosz, -ERANGE, 0, 2, -EINVAL, 0);
3524 do_strtosz(" -.0", -ERANGE, 0, 4);
3525 do_strtosz_full("-.1k", qemu_strtosz, -ERANGE, 0, 3, -EINVAL, 0);
3526 do_strtosz_full(" -."
3527 "00000000000000000000000000000000000000000000000000"
3528 "00000000000000000000000000000000000000000000000000"
3529 "00000000000000000000000000000000000000000000000000"
3530 "00000000000000000000000000000000000000000000000000"
3531 "00000000000000000000000000000000000000000000000000"
3532 "00000000000000000000000000000000000000000000000000"
3533 "00000000000000000000000000000000000000000000000000"
3534 "1M", qemu_strtosz, -ERANGE, 0, 354, -EINVAL, 0);
3535
3536 /* 2^64; see strtosz_simple for 2^64-1 */
3537 do_strtosz("18446744073709551616", -ERANGE, 0, 20);
3538
3539 do_strtosz("20E", -ERANGE, 0, 3);
3540
3541 /* Fraction tail can cause ERANGE overflow */
3542 do_strtosz("15.9999999999999999999999999999999999999999999999999999E",
3543 -ERANGE, 0, 56);
3544
3545 /* EINVAL has priority over ERANGE */
3546 do_strtosz_full("100000Pjunk", qemu_strtosz, -ERANGE, 0, 7, -EINVAL, 0);
3547 }
3548
test_qemu_strtosz_metric(void)3549 static void test_qemu_strtosz_metric(void)
3550 {
3551 do_strtosz_metric("12345k", 0, 12345000, 6);
3552 do_strtosz_metric("12.345M", 0, 12345000, 7);
3553
3554 /* Fraction is affected by floating-point rounding */
3555 /* This would be 0xfffffffffffffbff with infinite precision */
3556 do_strtosz_metric("18.446744073709550591E", 0, 0xfffffffffffffc0cULL, 22);
3557 }
3558
test_freq_to_str(void)3559 static void test_freq_to_str(void)
3560 {
3561 char *str;
3562
3563 str = freq_to_str(999);
3564 g_assert_cmpstr(str, ==, "999 Hz");
3565 g_free(str);
3566
3567 str = freq_to_str(1000);
3568 g_assert_cmpstr(str, ==, "1 KHz");
3569 g_free(str);
3570
3571 str = freq_to_str(1010);
3572 g_assert_cmpstr(str, ==, "1.01 KHz");
3573 g_free(str);
3574 }
3575
test_size_to_str(void)3576 static void test_size_to_str(void)
3577 {
3578 char *str;
3579
3580 str = size_to_str(0);
3581 g_assert_cmpstr(str, ==, "0 B");
3582 g_free(str);
3583
3584 str = size_to_str(1);
3585 g_assert_cmpstr(str, ==, "1 B");
3586 g_free(str);
3587
3588 str = size_to_str(1016);
3589 g_assert_cmpstr(str, ==, "0.992 KiB");
3590 g_free(str);
3591
3592 str = size_to_str(1024);
3593 g_assert_cmpstr(str, ==, "1 KiB");
3594 g_free(str);
3595
3596 str = size_to_str(512ull << 20);
3597 g_assert_cmpstr(str, ==, "512 MiB");
3598 g_free(str);
3599 }
3600
test_iec_binary_prefix(void)3601 static void test_iec_binary_prefix(void)
3602 {
3603 g_assert_cmpstr(iec_binary_prefix(0), ==, "");
3604 g_assert_cmpstr(iec_binary_prefix(10), ==, "Ki");
3605 g_assert_cmpstr(iec_binary_prefix(20), ==, "Mi");
3606 g_assert_cmpstr(iec_binary_prefix(30), ==, "Gi");
3607 g_assert_cmpstr(iec_binary_prefix(40), ==, "Ti");
3608 g_assert_cmpstr(iec_binary_prefix(50), ==, "Pi");
3609 g_assert_cmpstr(iec_binary_prefix(60), ==, "Ei");
3610 }
3611
test_si_prefix(void)3612 static void test_si_prefix(void)
3613 {
3614 g_assert_cmpstr(si_prefix(-18), ==, "a");
3615 g_assert_cmpstr(si_prefix(-15), ==, "f");
3616 g_assert_cmpstr(si_prefix(-12), ==, "p");
3617 g_assert_cmpstr(si_prefix(-9), ==, "n");
3618 g_assert_cmpstr(si_prefix(-6), ==, "u");
3619 g_assert_cmpstr(si_prefix(-3), ==, "m");
3620 g_assert_cmpstr(si_prefix(0), ==, "");
3621 g_assert_cmpstr(si_prefix(3), ==, "K");
3622 g_assert_cmpstr(si_prefix(6), ==, "M");
3623 g_assert_cmpstr(si_prefix(9), ==, "G");
3624 g_assert_cmpstr(si_prefix(12), ==, "T");
3625 g_assert_cmpstr(si_prefix(15), ==, "P");
3626 g_assert_cmpstr(si_prefix(18), ==, "E");
3627 }
3628
main(int argc,char ** argv)3629 int main(int argc, char **argv)
3630 {
3631 g_test_init(&argc, &argv, NULL);
3632
3633 g_test_add_func("/cutils/parse_uint/null", test_parse_uint_null);
3634 g_test_add_func("/cutils/parse_uint/empty", test_parse_uint_empty);
3635 g_test_add_func("/cutils/parse_uint/whitespace",
3636 test_parse_uint_whitespace);
3637 g_test_add_func("/cutils/parse_uint/invalid", test_parse_uint_invalid);
3638 g_test_add_func("/cutils/parse_uint/trailing", test_parse_uint_trailing);
3639 g_test_add_func("/cutils/parse_uint/correct", test_parse_uint_correct);
3640 g_test_add_func("/cutils/parse_uint/octal", test_parse_uint_octal);
3641 g_test_add_func("/cutils/parse_uint/decimal", test_parse_uint_decimal);
3642 g_test_add_func("/cutils/parse_uint/llong_max", test_parse_uint_llong_max);
3643 g_test_add_func("/cutils/parse_uint/max", test_parse_uint_max);
3644 g_test_add_func("/cutils/parse_uint/overflow", test_parse_uint_overflow);
3645 g_test_add_func("/cutils/parse_uint/negative", test_parse_uint_negative);
3646 g_test_add_func("/cutils/parse_uint/negzero", test_parse_uint_negzero);
3647 g_test_add_func("/cutils/parse_uint_full/trailing",
3648 test_parse_uint_full_trailing);
3649 g_test_add_func("/cutils/parse_uint_full/correct",
3650 test_parse_uint_full_correct);
3651 g_test_add_func("/cutils/parse_uint_full/erange_junk",
3652 test_parse_uint_full_erange_junk);
3653 g_test_add_func("/cutils/parse_uint_full/null",
3654 test_parse_uint_full_null);
3655
3656 /* qemu_strtoi() tests */
3657 g_test_add_func("/cutils/qemu_strtoi/correct",
3658 test_qemu_strtoi_correct);
3659 g_test_add_func("/cutils/qemu_strtoi/null",
3660 test_qemu_strtoi_null);
3661 g_test_add_func("/cutils/qemu_strtoi/empty",
3662 test_qemu_strtoi_empty);
3663 g_test_add_func("/cutils/qemu_strtoi/whitespace",
3664 test_qemu_strtoi_whitespace);
3665 g_test_add_func("/cutils/qemu_strtoi/invalid",
3666 test_qemu_strtoi_invalid);
3667 g_test_add_func("/cutils/qemu_strtoi/trailing",
3668 test_qemu_strtoi_trailing);
3669 g_test_add_func("/cutils/qemu_strtoi/octal",
3670 test_qemu_strtoi_octal);
3671 g_test_add_func("/cutils/qemu_strtoi/decimal",
3672 test_qemu_strtoi_decimal);
3673 g_test_add_func("/cutils/qemu_strtoi/hex",
3674 test_qemu_strtoi_hex);
3675 g_test_add_func("/cutils/qemu_strtoi/max",
3676 test_qemu_strtoi_max);
3677 g_test_add_func("/cutils/qemu_strtoi/overflow",
3678 test_qemu_strtoi_overflow);
3679 g_test_add_func("/cutils/qemu_strtoi/min",
3680 test_qemu_strtoi_min);
3681 g_test_add_func("/cutils/qemu_strtoi/underflow",
3682 test_qemu_strtoi_underflow);
3683 g_test_add_func("/cutils/qemu_strtoi/negative",
3684 test_qemu_strtoi_negative);
3685 g_test_add_func("/cutils/qemu_strtoi/negzero",
3686 test_qemu_strtoi_negzero);
3687 g_test_add_func("/cutils/qemu_strtoi_full/correct",
3688 test_qemu_strtoi_full_correct);
3689 g_test_add_func("/cutils/qemu_strtoi_full/null",
3690 test_qemu_strtoi_full_null);
3691 g_test_add_func("/cutils/qemu_strtoi_full/empty",
3692 test_qemu_strtoi_full_empty);
3693 g_test_add_func("/cutils/qemu_strtoi_full/negative",
3694 test_qemu_strtoi_full_negative);
3695 g_test_add_func("/cutils/qemu_strtoi_full/negzero",
3696 test_qemu_strtoi_full_negzero);
3697 g_test_add_func("/cutils/qemu_strtoi_full/trailing",
3698 test_qemu_strtoi_full_trailing);
3699 g_test_add_func("/cutils/qemu_strtoi_full/max",
3700 test_qemu_strtoi_full_max);
3701 g_test_add_func("/cutils/qemu_strtoi_full/erange_junk",
3702 test_qemu_strtoi_full_erange_junk);
3703
3704 /* qemu_strtoui() tests */
3705 g_test_add_func("/cutils/qemu_strtoui/correct",
3706 test_qemu_strtoui_correct);
3707 g_test_add_func("/cutils/qemu_strtoui/null",
3708 test_qemu_strtoui_null);
3709 g_test_add_func("/cutils/qemu_strtoui/empty",
3710 test_qemu_strtoui_empty);
3711 g_test_add_func("/cutils/qemu_strtoui/whitespace",
3712 test_qemu_strtoui_whitespace);
3713 g_test_add_func("/cutils/qemu_strtoui/invalid",
3714 test_qemu_strtoui_invalid);
3715 g_test_add_func("/cutils/qemu_strtoui/trailing",
3716 test_qemu_strtoui_trailing);
3717 g_test_add_func("/cutils/qemu_strtoui/octal",
3718 test_qemu_strtoui_octal);
3719 g_test_add_func("/cutils/qemu_strtoui/decimal",
3720 test_qemu_strtoui_decimal);
3721 g_test_add_func("/cutils/qemu_strtoui/hex",
3722 test_qemu_strtoui_hex);
3723 g_test_add_func("/cutils/qemu_strtoui/wrap",
3724 test_qemu_strtoui_wrap);
3725 g_test_add_func("/cutils/qemu_strtoui/max",
3726 test_qemu_strtoui_max);
3727 g_test_add_func("/cutils/qemu_strtoui/overflow",
3728 test_qemu_strtoui_overflow);
3729 g_test_add_func("/cutils/qemu_strtoui/underflow",
3730 test_qemu_strtoui_underflow);
3731 g_test_add_func("/cutils/qemu_strtoui/negative",
3732 test_qemu_strtoui_negative);
3733 g_test_add_func("/cutils/qemu_strtoui/negzero",
3734 test_qemu_strtoui_negzero);
3735 g_test_add_func("/cutils/qemu_strtoui_full/correct",
3736 test_qemu_strtoui_full_correct);
3737 g_test_add_func("/cutils/qemu_strtoui_full/null",
3738 test_qemu_strtoui_full_null);
3739 g_test_add_func("/cutils/qemu_strtoui_full/empty",
3740 test_qemu_strtoui_full_empty);
3741 g_test_add_func("/cutils/qemu_strtoui_full/negative",
3742 test_qemu_strtoui_full_negative);
3743 g_test_add_func("/cutils/qemu_strtoui_full/negzero",
3744 test_qemu_strtoui_full_negzero);
3745 g_test_add_func("/cutils/qemu_strtoui_full/trailing",
3746 test_qemu_strtoui_full_trailing);
3747 g_test_add_func("/cutils/qemu_strtoui_full/max",
3748 test_qemu_strtoui_full_max);
3749 g_test_add_func("/cutils/qemu_strtoui_full/erange_junk",
3750 test_qemu_strtoui_full_erange_junk);
3751
3752 /* qemu_strtol() tests */
3753 g_test_add_func("/cutils/qemu_strtol/correct",
3754 test_qemu_strtol_correct);
3755 g_test_add_func("/cutils/qemu_strtol/null",
3756 test_qemu_strtol_null);
3757 g_test_add_func("/cutils/qemu_strtol/empty",
3758 test_qemu_strtol_empty);
3759 g_test_add_func("/cutils/qemu_strtol/whitespace",
3760 test_qemu_strtol_whitespace);
3761 g_test_add_func("/cutils/qemu_strtol/invalid",
3762 test_qemu_strtol_invalid);
3763 g_test_add_func("/cutils/qemu_strtol/trailing",
3764 test_qemu_strtol_trailing);
3765 g_test_add_func("/cutils/qemu_strtol/octal",
3766 test_qemu_strtol_octal);
3767 g_test_add_func("/cutils/qemu_strtol/decimal",
3768 test_qemu_strtol_decimal);
3769 g_test_add_func("/cutils/qemu_strtol/hex",
3770 test_qemu_strtol_hex);
3771 g_test_add_func("/cutils/qemu_strtol/max",
3772 test_qemu_strtol_max);
3773 g_test_add_func("/cutils/qemu_strtol/overflow",
3774 test_qemu_strtol_overflow);
3775 g_test_add_func("/cutils/qemu_strtol/min",
3776 test_qemu_strtol_min);
3777 g_test_add_func("/cutils/qemu_strtol/underflow",
3778 test_qemu_strtol_underflow);
3779 g_test_add_func("/cutils/qemu_strtol/negative",
3780 test_qemu_strtol_negative);
3781 g_test_add_func("/cutils/qemu_strtol/negzero",
3782 test_qemu_strtol_negzero);
3783 g_test_add_func("/cutils/qemu_strtol_full/correct",
3784 test_qemu_strtol_full_correct);
3785 g_test_add_func("/cutils/qemu_strtol_full/null",
3786 test_qemu_strtol_full_null);
3787 g_test_add_func("/cutils/qemu_strtol_full/empty",
3788 test_qemu_strtol_full_empty);
3789 g_test_add_func("/cutils/qemu_strtol_full/negative",
3790 test_qemu_strtol_full_negative);
3791 g_test_add_func("/cutils/qemu_strtol_full/negzero",
3792 test_qemu_strtol_full_negzero);
3793 g_test_add_func("/cutils/qemu_strtol_full/trailing",
3794 test_qemu_strtol_full_trailing);
3795 g_test_add_func("/cutils/qemu_strtol_full/max",
3796 test_qemu_strtol_full_max);
3797 g_test_add_func("/cutils/qemu_strtol_full/erange_junk",
3798 test_qemu_strtol_full_erange_junk);
3799
3800 /* qemu_strtoul() tests */
3801 g_test_add_func("/cutils/qemu_strtoul/correct",
3802 test_qemu_strtoul_correct);
3803 g_test_add_func("/cutils/qemu_strtoul/null",
3804 test_qemu_strtoul_null);
3805 g_test_add_func("/cutils/qemu_strtoul/empty",
3806 test_qemu_strtoul_empty);
3807 g_test_add_func("/cutils/qemu_strtoul/whitespace",
3808 test_qemu_strtoul_whitespace);
3809 g_test_add_func("/cutils/qemu_strtoul/invalid",
3810 test_qemu_strtoul_invalid);
3811 g_test_add_func("/cutils/qemu_strtoul/trailing",
3812 test_qemu_strtoul_trailing);
3813 g_test_add_func("/cutils/qemu_strtoul/octal",
3814 test_qemu_strtoul_octal);
3815 g_test_add_func("/cutils/qemu_strtoul/decimal",
3816 test_qemu_strtoul_decimal);
3817 g_test_add_func("/cutils/qemu_strtoul/hex",
3818 test_qemu_strtoul_hex);
3819 g_test_add_func("/cutils/qemu_strtoul/wrap",
3820 test_qemu_strtoul_wrap);
3821 g_test_add_func("/cutils/qemu_strtoul/max",
3822 test_qemu_strtoul_max);
3823 g_test_add_func("/cutils/qemu_strtoul/overflow",
3824 test_qemu_strtoul_overflow);
3825 g_test_add_func("/cutils/qemu_strtoul/underflow",
3826 test_qemu_strtoul_underflow);
3827 g_test_add_func("/cutils/qemu_strtoul/negative",
3828 test_qemu_strtoul_negative);
3829 g_test_add_func("/cutils/qemu_strtoul/negzero",
3830 test_qemu_strtoul_negzero);
3831 g_test_add_func("/cutils/qemu_strtoul_full/correct",
3832 test_qemu_strtoul_full_correct);
3833 g_test_add_func("/cutils/qemu_strtoul_full/null",
3834 test_qemu_strtoul_full_null);
3835 g_test_add_func("/cutils/qemu_strtoul_full/empty",
3836 test_qemu_strtoul_full_empty);
3837 g_test_add_func("/cutils/qemu_strtoul_full/negative",
3838 test_qemu_strtoul_full_negative);
3839 g_test_add_func("/cutils/qemu_strtoul_full/negzero",
3840 test_qemu_strtoul_full_negzero);
3841 g_test_add_func("/cutils/qemu_strtoul_full/trailing",
3842 test_qemu_strtoul_full_trailing);
3843 g_test_add_func("/cutils/qemu_strtoul_full/max",
3844 test_qemu_strtoul_full_max);
3845 g_test_add_func("/cutils/qemu_strtoul_full/erange_junk",
3846 test_qemu_strtoul_full_erange_junk);
3847
3848 /* qemu_strtoi64() tests */
3849 g_test_add_func("/cutils/qemu_strtoi64/correct",
3850 test_qemu_strtoi64_correct);
3851 g_test_add_func("/cutils/qemu_strtoi64/null",
3852 test_qemu_strtoi64_null);
3853 g_test_add_func("/cutils/qemu_strtoi64/empty",
3854 test_qemu_strtoi64_empty);
3855 g_test_add_func("/cutils/qemu_strtoi64/whitespace",
3856 test_qemu_strtoi64_whitespace);
3857 g_test_add_func("/cutils/qemu_strtoi64/invalid",
3858 test_qemu_strtoi64_invalid);
3859 g_test_add_func("/cutils/qemu_strtoi64/trailing",
3860 test_qemu_strtoi64_trailing);
3861 g_test_add_func("/cutils/qemu_strtoi64/octal",
3862 test_qemu_strtoi64_octal);
3863 g_test_add_func("/cutils/qemu_strtoi64/decimal",
3864 test_qemu_strtoi64_decimal);
3865 g_test_add_func("/cutils/qemu_strtoi64/hex",
3866 test_qemu_strtoi64_hex);
3867 g_test_add_func("/cutils/qemu_strtoi64/max",
3868 test_qemu_strtoi64_max);
3869 g_test_add_func("/cutils/qemu_strtoi64/overflow",
3870 test_qemu_strtoi64_overflow);
3871 g_test_add_func("/cutils/qemu_strtoi64/min",
3872 test_qemu_strtoi64_min);
3873 g_test_add_func("/cutils/qemu_strtoi64/underflow",
3874 test_qemu_strtoi64_underflow);
3875 g_test_add_func("/cutils/qemu_strtoi64/negative",
3876 test_qemu_strtoi64_negative);
3877 g_test_add_func("/cutils/qemu_strtoi64/negzero",
3878 test_qemu_strtoi64_negzero);
3879 g_test_add_func("/cutils/qemu_strtoi64_full/correct",
3880 test_qemu_strtoi64_full_correct);
3881 g_test_add_func("/cutils/qemu_strtoi64_full/null",
3882 test_qemu_strtoi64_full_null);
3883 g_test_add_func("/cutils/qemu_strtoi64_full/empty",
3884 test_qemu_strtoi64_full_empty);
3885 g_test_add_func("/cutils/qemu_strtoi64_full/negative",
3886 test_qemu_strtoi64_full_negative);
3887 g_test_add_func("/cutils/qemu_strtoi64_full/negzero",
3888 test_qemu_strtoi64_full_negzero);
3889 g_test_add_func("/cutils/qemu_strtoi64_full/trailing",
3890 test_qemu_strtoi64_full_trailing);
3891 g_test_add_func("/cutils/qemu_strtoi64_full/max",
3892 test_qemu_strtoi64_full_max);
3893 g_test_add_func("/cutils/qemu_strtoi64_full/erange_junk",
3894 test_qemu_strtoi64_full_erange_junk);
3895
3896 /* qemu_strtou64() tests */
3897 g_test_add_func("/cutils/qemu_strtou64/correct",
3898 test_qemu_strtou64_correct);
3899 g_test_add_func("/cutils/qemu_strtou64/null",
3900 test_qemu_strtou64_null);
3901 g_test_add_func("/cutils/qemu_strtou64/empty",
3902 test_qemu_strtou64_empty);
3903 g_test_add_func("/cutils/qemu_strtou64/whitespace",
3904 test_qemu_strtou64_whitespace);
3905 g_test_add_func("/cutils/qemu_strtou64/invalid",
3906 test_qemu_strtou64_invalid);
3907 g_test_add_func("/cutils/qemu_strtou64/trailing",
3908 test_qemu_strtou64_trailing);
3909 g_test_add_func("/cutils/qemu_strtou64/octal",
3910 test_qemu_strtou64_octal);
3911 g_test_add_func("/cutils/qemu_strtou64/decimal",
3912 test_qemu_strtou64_decimal);
3913 g_test_add_func("/cutils/qemu_strtou64/hex",
3914 test_qemu_strtou64_hex);
3915 g_test_add_func("/cutils/qemu_strtou64/wrap",
3916 test_qemu_strtou64_wrap);
3917 g_test_add_func("/cutils/qemu_strtou64/max",
3918 test_qemu_strtou64_max);
3919 g_test_add_func("/cutils/qemu_strtou64/overflow",
3920 test_qemu_strtou64_overflow);
3921 g_test_add_func("/cutils/qemu_strtou64/underflow",
3922 test_qemu_strtou64_underflow);
3923 g_test_add_func("/cutils/qemu_strtou64/negative",
3924 test_qemu_strtou64_negative);
3925 g_test_add_func("/cutils/qemu_strtou64/negzero",
3926 test_qemu_strtou64_negzero);
3927 g_test_add_func("/cutils/qemu_strtou64_full/correct",
3928 test_qemu_strtou64_full_correct);
3929 g_test_add_func("/cutils/qemu_strtou64_full/null",
3930 test_qemu_strtou64_full_null);
3931 g_test_add_func("/cutils/qemu_strtou64_full/empty",
3932 test_qemu_strtou64_full_empty);
3933 g_test_add_func("/cutils/qemu_strtou64_full/negative",
3934 test_qemu_strtou64_full_negative);
3935 g_test_add_func("/cutils/qemu_strtou64_full/negzero",
3936 test_qemu_strtou64_full_negzero);
3937 g_test_add_func("/cutils/qemu_strtou64_full/trailing",
3938 test_qemu_strtou64_full_trailing);
3939 g_test_add_func("/cutils/qemu_strtou64_full/max",
3940 test_qemu_strtou64_full_max);
3941 g_test_add_func("/cutils/qemu_strtou64_full/erange_junk",
3942 test_qemu_strtou64_full_erange_junk);
3943
3944 /* qemu_strtod() tests */
3945 g_test_add_func("/cutils/qemu_strtod/simple",
3946 test_qemu_strtod_simple);
3947 g_test_add_func("/cutils/qemu_strtod/einval",
3948 test_qemu_strtod_einval);
3949 g_test_add_func("/cutils/qemu_strtod/erange",
3950 test_qemu_strtod_erange);
3951 g_test_add_func("/cutils/qemu_strtod/nonfinite",
3952 test_qemu_strtod_nonfinite);
3953 g_test_add_func("/cutils/qemu_strtod/trailing",
3954 test_qemu_strtod_trailing);
3955 g_test_add_func("/cutils/qemu_strtod/erange_junk",
3956 test_qemu_strtod_erange_junk);
3957
3958 /* qemu_strtod_finite() tests */
3959 g_test_add_func("/cutils/qemu_strtod_finite/simple",
3960 test_qemu_strtod_finite_simple);
3961 g_test_add_func("/cutils/qemu_strtod_finite/einval",
3962 test_qemu_strtod_finite_einval);
3963 g_test_add_func("/cutils/qemu_strtod_finite/erange",
3964 test_qemu_strtod_finite_erange);
3965 g_test_add_func("/cutils/qemu_strtod_finite/nonfinite",
3966 test_qemu_strtod_finite_nonfinite);
3967 g_test_add_func("/cutils/qemu_strtod_finite/trailing",
3968 test_qemu_strtod_finite_trailing);
3969 g_test_add_func("/cutils/qemu_strtod_finite/erange_junk",
3970 test_qemu_strtod_finite_erange_junk);
3971
3972 /* qemu_strtosz() tests */
3973 g_test_add_func("/cutils/strtosz/simple",
3974 test_qemu_strtosz_simple);
3975 g_test_add_func("/cutils/strtosz/hex",
3976 test_qemu_strtosz_hex);
3977 g_test_add_func("/cutils/strtosz/units",
3978 test_qemu_strtosz_units);
3979 g_test_add_func("/cutils/strtosz/float",
3980 test_qemu_strtosz_float);
3981 g_test_add_func("/cutils/strtosz/invalid",
3982 test_qemu_strtosz_invalid);
3983 g_test_add_func("/cutils/strtosz/trailing",
3984 test_qemu_strtosz_trailing);
3985 g_test_add_func("/cutils/strtosz/erange",
3986 test_qemu_strtosz_erange);
3987 g_test_add_func("/cutils/strtosz/metric",
3988 test_qemu_strtosz_metric);
3989
3990 g_test_add_func("/cutils/size_to_str",
3991 test_size_to_str);
3992 g_test_add_func("/cutils/freq_to_str",
3993 test_freq_to_str);
3994 g_test_add_func("/cutils/iec_binary_prefix",
3995 test_iec_binary_prefix);
3996 g_test_add_func("/cutils/si_prefix",
3997 test_si_prefix);
3998 return g_test_run();
3999 }
4000