qemu/tests/unit/test-cutils.c
<<
>>
Prefs
   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
  34static 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
  47static 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
  61static 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
  76static 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
  91static 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
 105static 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
 119static 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
 133static 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
 147static 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
 163static 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
 179static 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
 211static 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
 235static 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
 249static 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
 261static 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
 273static 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
 286static 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
 298static 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
 313static 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
 327static 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
 342static 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
 357static 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
 372static 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
 387static 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
 410static 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
 434static 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
 467static 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
 483static 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
 531static 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
 547static 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
 603static 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
 627static 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
 642static 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
 654static 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
 668static 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
 680static 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
 692static 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
 704static 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
 716static 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
 729static 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
 742static 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
 757static 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
 771static 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
 786static 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
 801static 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
 816static 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
 831static 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
 854static 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
 878static 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
 911static 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
 927static 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
 943static 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
1007static 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
1055static 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
1070static 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
1085static 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
1097static 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
1108static 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
1120static 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
1131static 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
1142static 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
1154static 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
1167static 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
1180static 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
1195static 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
1209static 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
1224static 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
1239static 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
1254static 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
1269static 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
1292static 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
1316static 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
1349static 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
1365static 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
1408static 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
1424static 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
1467static 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
1482static 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
1497static 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
1509static 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
1523static 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
1535static 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
1547static 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
1559static 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
1571static 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
1584static 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
1597static 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
1612static 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
1626static 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
1641static 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
1656static 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
1671static 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
1686static 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
1709static 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
1733static 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
1766static 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
1783static 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
1799static 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
1842static 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
1885static 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
1900static 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
1915static 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
1927static 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
1938static 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
1950static 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
1961static 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
1972static 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
1984static 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
1997static 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
2010static 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
2025static 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
2039static 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
2054static 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
2069static 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
2084static 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
2099static 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
2122static 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
2146static 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
2179static 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
2195static 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
2227static 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
2243static 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
2275static 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
2290static 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
2305static 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
2317static 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
2328static 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
2340static 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
2352static 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
2364static 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
2376static 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
2390static 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
2403static 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
2418static 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
2432static 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
2447static 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
2462static 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
2477static 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
2492static 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
2515static 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
2539static 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
2572static 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
2587static 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
2603static 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
2635static 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
2667static 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
2682static 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
2697static 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
2709static 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
2720static 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
2732static 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
2744static 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
2756static 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
2768static 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
2781static 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
2794static 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
2848static 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
2886static 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
2922static 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
2958static 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
3011static 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
3038static 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
3092static 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
3130static 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
3168static 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
3205static 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
3261static 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
3288typedef int (*qemu_strtosz_fn)(const char *, const char **, uint64_t *);
3289static 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
3314static 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
3321static 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
3328static 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
3335static 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
3364static 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
3373static 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
3398static 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
3434static 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
3481static 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
3518static 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
3549static 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
3559static 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
3576static 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
3601static 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
3612static 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
3629int 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