2021-03-06 16:45:44 +00:00
|
|
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
|
|
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
|
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
|
|
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
|
|
|
│ │
|
|
|
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
|
|
|
│ any purpose with or without fee is hereby granted, provided that the │
|
|
|
|
│ above copyright notice and this permission notice appear in all copies. │
|
|
|
|
│ │
|
|
|
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
|
|
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
|
|
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
|
|
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
|
|
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
|
|
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
|
|
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
|
|
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
|
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
|
|
#include "libc/fmt/fmt.h"
|
2023-03-29 07:10:53 +00:00
|
|
|
|
2021-03-06 22:26:36 +00:00
|
|
|
#include "libc/limits.h"
|
2021-10-14 00:27:13 +00:00
|
|
|
#include "libc/log/log.h"
|
2021-03-06 16:45:44 +00:00
|
|
|
#include "libc/math.h"
|
2022-09-13 06:10:38 +00:00
|
|
|
#include "libc/mem/gc.h"
|
2021-03-06 16:45:44 +00:00
|
|
|
#include "libc/str/str.h"
|
|
|
|
#include "libc/testlib/testlib.h"
|
2022-09-13 06:10:38 +00:00
|
|
|
#include "libc/x/xasprintf.h"
|
2021-03-06 16:45:44 +00:00
|
|
|
|
2021-03-06 22:26:36 +00:00
|
|
|
TEST(fmt, d) {
|
2022-09-13 06:10:38 +00:00
|
|
|
EXPECT_STREQ("-123", _gc(xasprintf("%d", -123)));
|
|
|
|
EXPECT_STREQ("-1", _gc(xasprintf("%d", -1)));
|
|
|
|
EXPECT_STREQ("1", _gc(xasprintf("%d", 1)));
|
|
|
|
EXPECT_STREQ("16", _gc(xasprintf("%d", 16)));
|
|
|
|
EXPECT_STREQ("2147483647", _gc(xasprintf("%d", INT_MAX)));
|
|
|
|
EXPECT_STREQ("-2147483648", _gc(xasprintf("%d", INT_MIN)));
|
|
|
|
EXPECT_STREQ(" -123", _gc(xasprintf("%10d", -123)));
|
|
|
|
EXPECT_STREQ(" -1", _gc(xasprintf("%10d", -1)));
|
|
|
|
EXPECT_STREQ(" 1", _gc(xasprintf("%10d", 1)));
|
|
|
|
EXPECT_STREQ(" 16", _gc(xasprintf("%10d", 16)));
|
|
|
|
EXPECT_STREQ("2147483647", _gc(xasprintf("%10d", INT_MAX)));
|
|
|
|
EXPECT_STREQ("-2147483648", _gc(xasprintf("%10d", INT_MIN)));
|
|
|
|
EXPECT_STREQ("-000000123", _gc(xasprintf("%010d", -123)));
|
|
|
|
EXPECT_STREQ("-000000001", _gc(xasprintf("%010d", -1)));
|
|
|
|
EXPECT_STREQ("0000000001", _gc(xasprintf("%010d", 1)));
|
|
|
|
EXPECT_STREQ("0000000016", _gc(xasprintf("%010d", 16)));
|
|
|
|
EXPECT_STREQ("2147483647", _gc(xasprintf("%010d", INT_MAX)));
|
|
|
|
EXPECT_STREQ("-2147483648", _gc(xasprintf("%010d", INT_MIN)));
|
|
|
|
EXPECT_STREQ("-123 ", _gc(xasprintf("%-10d", -123)));
|
|
|
|
EXPECT_STREQ("-1 ", _gc(xasprintf("%-10d", -1)));
|
|
|
|
EXPECT_STREQ("1 ", _gc(xasprintf("%-10d", 1)));
|
|
|
|
EXPECT_STREQ("16 ", _gc(xasprintf("%-10d", 16)));
|
|
|
|
EXPECT_STREQ("2147483647", _gc(xasprintf("%-10d", INT_MAX)));
|
|
|
|
EXPECT_STREQ("-2147483648", _gc(xasprintf("%-10d", INT_MIN)));
|
|
|
|
EXPECT_STREQ(" -123", _gc(xasprintf("%+10d", -123)));
|
|
|
|
EXPECT_STREQ(" -1", _gc(xasprintf("%+10d", -1)));
|
|
|
|
EXPECT_STREQ(" +1", _gc(xasprintf("%+10d", 1)));
|
|
|
|
EXPECT_STREQ(" +16", _gc(xasprintf("%+10d", 16)));
|
|
|
|
EXPECT_STREQ("+2147483647", _gc(xasprintf("%+10d", INT_MAX)));
|
|
|
|
EXPECT_STREQ("-2147483648", _gc(xasprintf("%+10d", INT_MIN)));
|
|
|
|
EXPECT_STREQ("-123", _gc(xasprintf("% d", -123)));
|
|
|
|
EXPECT_STREQ("-1", _gc(xasprintf("% d", -1)));
|
|
|
|
EXPECT_STREQ(" 1", _gc(xasprintf("% d", 1)));
|
|
|
|
EXPECT_STREQ(" 16", _gc(xasprintf("% d", 16)));
|
|
|
|
EXPECT_STREQ(" 2147483647", _gc(xasprintf("% d", INT_MAX)));
|
|
|
|
EXPECT_STREQ("-2147483648", _gc(xasprintf("% d", INT_MIN)));
|
Fix padding+minus flag on numbers for printf-family functions (#787)
The C standard states, for conversions using the d, i, b, B, o, u, x or X conversion specifiers:
> The precision specifies the minimum number of digits to appear; if
> the value being converted can be represented in fewer digits, it is
> expanded with leading zeros.
- C standard, 7.23.6.1. The fprintf function
However, cosmopolitan currently suppresses the addition of leading
zeros when the minus flag is set. This is not reflected by anything
within the C standard, meaning that behavior is incorrect.
This patch fixes this.
2023-03-25 18:39:25 +00:00
|
|
|
EXPECT_STREQ("042 ", _gc(xasprintf("%-4.3d", 42)));
|
|
|
|
EXPECT_STREQ("-00054", _gc(xasprintf("%-1.5lld", -54ll)));
|
|
|
|
EXPECT_STREQ("00109", _gc(xasprintf("%-.5lld", 109ll)));
|
|
|
|
EXPECT_STREQ("-00116", _gc(xasprintf("%-.5lld", -116ll)));
|
|
|
|
EXPECT_STREQ("00108 ", _gc(xasprintf("%-8.5lld", 108ll)));
|
|
|
|
EXPECT_STREQ("-00054 ", _gc(xasprintf("%-8.5lld", -54ll)));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(fmt, u) {
|
|
|
|
EXPECT_STREQ("042 ", _gc(xasprintf("%-4.3u", 42)));
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(fmt, x) {
|
|
|
|
EXPECT_STREQ("0x01 ", _gc(xasprintf("%#-07.2x", 1)));
|
|
|
|
EXPECT_STREQ("0x00136d ", _gc(xasprintf("%#-010.6x", 4973)));
|
2023-03-29 07:10:53 +00:00
|
|
|
EXPECT_STREQ("0X1", _gc(xasprintf("%#X", 1)));
|
|
|
|
EXPECT_STREQ("0XA", _gc(xasprintf("%#X", 10)));
|
|
|
|
EXPECT_STREQ("0XFFFF", _gc(xasprintf("%#X", 65535)));
|
|
|
|
EXPECT_STREQ("0XABCDEF", _gc(xasprintf("%#X", 0xABCDEF)));
|
|
|
|
EXPECT_STREQ("0X1", _gc(xasprintf("%#hX", (short)1)));
|
|
|
|
EXPECT_STREQ("0XA", _gc(xasprintf("%#hX", (short)10)));
|
|
|
|
EXPECT_STREQ("0XFFFF", _gc(xasprintf("%#hX", (short)65535)));
|
|
|
|
EXPECT_STREQ("0XABCD", _gc(xasprintf("%#hX", (short)0xABCD)));
|
|
|
|
EXPECT_STREQ(" 0X308C6705", _gc(xasprintf("%#20X", 814507781)));
|
|
|
|
EXPECT_STREQ("0X0000000000308C6705", _gc(xasprintf("%#020X", 814507781)));
|
|
|
|
EXPECT_STREQ(" 0X6705",
|
|
|
|
_gc(xasprintf("%#20hX", (short)814507781)));
|
|
|
|
EXPECT_STREQ("0X000000000000006705",
|
|
|
|
_gc(xasprintf("%#020hX", (short)814507781)));
|
|
|
|
EXPECT_STREQ(" 0XABCDEF", _gc(xasprintf("%#20X", 0xABCDEF)));
|
|
|
|
EXPECT_STREQ("0X000000000000ABCDEF", _gc(xasprintf("%#020X", 0xABCDEF)));
|
|
|
|
EXPECT_STREQ(" 0XCDEF",
|
|
|
|
_gc(xasprintf("%#20hX", (short)0xABCDEF)));
|
|
|
|
EXPECT_STREQ("0X00000000000000CDEF",
|
|
|
|
_gc(xasprintf("%#020hX", (short)0xABCDEF)));
|
Fix padding+minus flag on numbers for printf-family functions (#787)
The C standard states, for conversions using the d, i, b, B, o, u, x or X conversion specifiers:
> The precision specifies the minimum number of digits to appear; if
> the value being converted can be represented in fewer digits, it is
> expanded with leading zeros.
- C standard, 7.23.6.1. The fprintf function
However, cosmopolitan currently suppresses the addition of leading
zeros when the minus flag is set. This is not reflected by anything
within the C standard, meaning that behavior is incorrect.
This patch fixes this.
2023-03-25 18:39:25 +00:00
|
|
|
}
|
|
|
|
|
Fix issues 774, 782 and 789 (printf precision bugs) (#790)
The C standard states that, within the context of a printf-family
function, when specifying the precision of a conversion specification:
> A negative precision argument is taken as if the precision were
> omitted.
- Quoth the C Standard, 7.23.6.1. The fprintf function
Cosmopolitan instead treated negative precision arguments as
though they had a value of 0, which was non-conforming. This
change fixes that. Another issue we found relates to:
> For o conversion, it increases the precision, if and only if
> necessary, to force the first digit of the result to be a zero (if
> the value and precision are both 0, a single 0 is printed).
- Quoth the C standard, 7.23.6.1.6. The fprintf function
When printing numbers in their alternative form, with a precision and
with a conversion specifier of o (octal), Cosmopolitan wasn't following
the standard in two ways:
1. When printing a value with a precision that results in 0-padding,
cosmopolitan would still add an extra 0 even though this should be
done "if and only if necessary"
2. When printing a value of 0 with a precision of 0, nothing is
printed, even though the standard specifically states that a single
0 is printed in this case
This change fixes those issues too. Furthermore, regression tests have
been introduced to ensure Cosmopolitan continues to be conformant
going forward.
Fixes #774
Fixes #782
Fixes #789
2023-03-29 08:11:48 +00:00
|
|
|
TEST(fmt, o) {
|
|
|
|
EXPECT_STREQ("0000000000000037777777634", _gc(xasprintf("%#.25o", -100)));
|
|
|
|
EXPECT_STREQ("0001777777777777777777634", _gc(xasprintf("%#.25lo", -100L)));
|
|
|
|
EXPECT_STREQ("0001777777777777777777634", _gc(xasprintf("%#.25llo", -100LL)));
|
|
|
|
EXPECT_STREQ("0", _gc(xasprintf("%#.o", 0)));
|
Fix printf precision/field width being limited by internal buffer size (#799)
The C standard, when defining field width and precision, never gives
any limit on the values used for them (except, I believe, that they
fit within an int). In other words, if the user gives a field width of
32145 and a precision of 9218, the implementation has to handle these
values correctly. However, when such kinds of high numbers are used
with integer conversions, cosmopolitan is limited by an internal
buffer size of 144, which means precisions and field widths have to
fit within this, which violates the standard.
This means that for example, the following program:
#include <stdio.h>
#include <string.h>
int main()
{
char buf2[512] = {};
int i = snprintf(buf2, sizeof(buf2), "%.9999u", 10);
printf("%d %zu\n", i, strlen(buf2));
}
would, instead of printing "9999 511" (the correct output), instead
print "144 144" under cosmopolitan.
This patch fixes this.
2023-04-04 18:16:34 +00:00
|
|
|
EXPECT_STREQ(" 056520", _gc(xasprintf("%#8.6o", 23888)));
|
|
|
|
EXPECT_STREQ("00144 ", _gc(xasprintf("%#-8.5llo", 100ll)));
|
|
|
|
EXPECT_STREQ("0 ", _gc(xasprintf("%-#02lo", 0l)));
|
|
|
|
EXPECT_STREQ("0", _gc(xasprintf("%#01lo", 0l)));
|
|
|
|
EXPECT_STREQ("00", _gc(xasprintf("%#02lo", 0l)));
|
Fix issues 774, 782 and 789 (printf precision bugs) (#790)
The C standard states that, within the context of a printf-family
function, when specifying the precision of a conversion specification:
> A negative precision argument is taken as if the precision were
> omitted.
- Quoth the C Standard, 7.23.6.1. The fprintf function
Cosmopolitan instead treated negative precision arguments as
though they had a value of 0, which was non-conforming. This
change fixes that. Another issue we found relates to:
> For o conversion, it increases the precision, if and only if
> necessary, to force the first digit of the result to be a zero (if
> the value and precision are both 0, a single 0 is printed).
- Quoth the C standard, 7.23.6.1.6. The fprintf function
When printing numbers in their alternative form, with a precision and
with a conversion specifier of o (octal), Cosmopolitan wasn't following
the standard in two ways:
1. When printing a value with a precision that results in 0-padding,
cosmopolitan would still add an extra 0 even though this should be
done "if and only if necessary"
2. When printing a value of 0 with a precision of 0, nothing is
printed, even though the standard specifically states that a single
0 is printed in this case
This change fixes those issues too. Furthermore, regression tests have
been introduced to ensure Cosmopolitan continues to be conformant
going forward.
Fixes #774
Fixes #782
Fixes #789
2023-03-29 08:11:48 +00:00
|
|
|
}
|
|
|
|
|
Fix padding+minus flag on numbers for printf-family functions (#787)
The C standard states, for conversions using the d, i, b, B, o, u, x or X conversion specifiers:
> The precision specifies the minimum number of digits to appear; if
> the value being converted can be represented in fewer digits, it is
> expanded with leading zeros.
- C standard, 7.23.6.1. The fprintf function
However, cosmopolitan currently suppresses the addition of leading
zeros when the minus flag is set. This is not reflected by anything
within the C standard, meaning that behavior is incorrect.
This patch fixes this.
2023-03-25 18:39:25 +00:00
|
|
|
TEST(fmt, b) {
|
|
|
|
EXPECT_STREQ("000010100 ", _gc(xasprintf("%-14.9b", 20)));
|
Fix printf precision/field width being limited by internal buffer size (#799)
The C standard, when defining field width and precision, never gives
any limit on the values used for them (except, I believe, that they
fit within an int). In other words, if the user gives a field width of
32145 and a precision of 9218, the implementation has to handle these
values correctly. However, when such kinds of high numbers are used
with integer conversions, cosmopolitan is limited by an internal
buffer size of 144, which means precisions and field widths have to
fit within this, which violates the standard.
This means that for example, the following program:
#include <stdio.h>
#include <string.h>
int main()
{
char buf2[512] = {};
int i = snprintf(buf2, sizeof(buf2), "%.9999u", 10);
printf("%d %zu\n", i, strlen(buf2));
}
would, instead of printing "9999 511" (the correct output), instead
print "144 144" under cosmopolitan.
This patch fixes this.
2023-04-04 18:16:34 +00:00
|
|
|
EXPECT_STREQ("0b110", _gc(xasprintf("%#b", 6)));
|
2021-03-06 22:26:36 +00:00
|
|
|
}
|
|
|
|
|
2023-03-25 18:38:21 +00:00
|
|
|
TEST(fmt, s) {
|
Fix issues 774, 782 and 789 (printf precision bugs) (#790)
The C standard states that, within the context of a printf-family
function, when specifying the precision of a conversion specification:
> A negative precision argument is taken as if the precision were
> omitted.
- Quoth the C Standard, 7.23.6.1. The fprintf function
Cosmopolitan instead treated negative precision arguments as
though they had a value of 0, which was non-conforming. This
change fixes that. Another issue we found relates to:
> For o conversion, it increases the precision, if and only if
> necessary, to force the first digit of the result to be a zero (if
> the value and precision are both 0, a single 0 is printed).
- Quoth the C standard, 7.23.6.1.6. The fprintf function
When printing numbers in their alternative form, with a precision and
with a conversion specifier of o (octal), Cosmopolitan wasn't following
the standard in two ways:
1. When printing a value with a precision that results in 0-padding,
cosmopolitan would still add an extra 0 even though this should be
done "if and only if necessary"
2. When printing a value of 0 with a precision of 0, nothing is
printed, even though the standard specifically states that a single
0 is printed in this case
This change fixes those issues too. Furthermore, regression tests have
been introduced to ensure Cosmopolitan continues to be conformant
going forward.
Fixes #774
Fixes #782
Fixes #789
2023-03-29 08:11:48 +00:00
|
|
|
EXPECT_STREQ("123456", _gc(xasprintf("%4.*s", -5, "123456")));
|
|
|
|
EXPECT_STREQ("123456789", _gc(xasprintf("%4.*s", -5, "123456789")));
|
|
|
|
EXPECT_STREQ("12345678901234567890",
|
|
|
|
_gc(xasprintf("%4.*s", -5, "12345678901234567890")));
|
|
|
|
EXPECT_STREQ("123456789012345678901234567890",
|
|
|
|
_gc(xasprintf("%4.*s", -5, "123456789012345678901234567890")));
|
|
|
|
EXPECT_STREQ(
|
|
|
|
"1234567890123456789012345678901234567890",
|
|
|
|
_gc(xasprintf("%4.*s", -5, "1234567890123456789012345678901234567890")));
|
|
|
|
EXPECT_STREQ(
|
|
|
|
"12345678901234567890123456789012345678901234567890",
|
|
|
|
_gc(xasprintf("%4.*s", -5,
|
|
|
|
"12345678901234567890123456789012345678901234567890")));
|
|
|
|
EXPECT_STREQ(
|
|
|
|
"123456789012345678901234567890123456789012345678901234567890",
|
|
|
|
_gc(xasprintf(
|
|
|
|
"%4.*s", -5,
|
|
|
|
"123456789012345678901234567890123456789012345678901234567890")));
|
2023-03-25 18:38:21 +00:00
|
|
|
EXPECT_STREQ("Wide character output test",
|
|
|
|
_gc(xasprintf("%S", L"Wide character output test")));
|
|
|
|
}
|
|
|
|
|
2021-03-06 22:26:36 +00:00
|
|
|
TEST(fmt, g) {
|
2022-09-13 06:10:38 +00:00
|
|
|
EXPECT_STREQ("1", _gc(xasprintf("%g", 1.)));
|
|
|
|
EXPECT_STREQ(" 1", _gc(xasprintf("% g", 1.)));
|
|
|
|
EXPECT_STREQ("+1", _gc(xasprintf("%+g", 1.)));
|
|
|
|
EXPECT_STREQ("-1", _gc(xasprintf("%g", -1.)));
|
|
|
|
EXPECT_STREQ("10", _gc(xasprintf("%g", 10.)));
|
|
|
|
EXPECT_STREQ("-10", _gc(xasprintf("%g", -10.)));
|
|
|
|
EXPECT_STREQ("1e+01", _gc(xasprintf("%.0g", 10.)));
|
|
|
|
EXPECT_STREQ("-1e+01", _gc(xasprintf("%.0g", -10.)));
|
|
|
|
EXPECT_STREQ("1", _gc(xasprintf("%.0g", 1.0)));
|
|
|
|
EXPECT_STREQ("1e-05", _gc(xasprintf("%.0g", 0.00001)));
|
|
|
|
EXPECT_STREQ("0.0001", _gc(xasprintf("%.0g", 0.0001)));
|
|
|
|
EXPECT_STREQ("1e+01", _gc(xasprintf("%.1g", 10.)));
|
|
|
|
EXPECT_STREQ("-1e+01", _gc(xasprintf("%.1g", -10.)));
|
|
|
|
EXPECT_STREQ("1", _gc(xasprintf("%.1g", 1.0)));
|
|
|
|
EXPECT_STREQ("1e-05", _gc(xasprintf("%.1g", 0.00001)));
|
|
|
|
EXPECT_STREQ("0.0001", _gc(xasprintf("%.1g", 0.0001)));
|
|
|
|
EXPECT_STREQ("0.007812", _gc(xasprintf("%.4g", 0.0078125)));
|
|
|
|
EXPECT_STREQ("0.023438", _gc(xasprintf("%.5g", 0.0234375)));
|
|
|
|
EXPECT_STREQ("1e+100", _gc(xasprintf("%g", 1e100)));
|
|
|
|
EXPECT_STREQ("1e-100", _gc(xasprintf("%g", 1e-100)));
|
|
|
|
EXPECT_STREQ("-1e-100", _gc(xasprintf("%g", -1e-100)));
|
|
|
|
EXPECT_STREQ("0.123456", _gc(xasprintf("%g", 0.1234564)));
|
|
|
|
EXPECT_STREQ("0.123457", _gc(xasprintf("%g", 0.1234566)));
|
|
|
|
EXPECT_STREQ("3.14159", _gc(xasprintf("%g", 0x1.921fb54442d1846ap+1)));
|
|
|
|
EXPECT_STREQ("0", _gc(xasprintf("%g", 0.)));
|
|
|
|
EXPECT_STREQ("-0", _gc(xasprintf("%g", -0.)));
|
|
|
|
EXPECT_STREQ("nan", _gc(xasprintf("%g", NAN)));
|
|
|
|
EXPECT_STREQ("-nan", _gc(xasprintf("%g", -NAN)));
|
|
|
|
EXPECT_STREQ("inf", _gc(xasprintf("%g", INFINITY)));
|
|
|
|
EXPECT_STREQ("-inf", _gc(xasprintf("%g", -INFINITY)));
|
|
|
|
EXPECT_STREQ("2.22507e-308", _gc(xasprintf("%g", __DBL_MIN__)));
|
|
|
|
EXPECT_STREQ("1.79769e+308", _gc(xasprintf("%g", __DBL_MAX__)));
|
|
|
|
EXPECT_STREQ("0", _gc(xasprintf("%G", 0.)));
|
|
|
|
EXPECT_STREQ("-0", _gc(xasprintf("%G", -0.)));
|
|
|
|
EXPECT_STREQ("NAN", _gc(xasprintf("%G", NAN)));
|
|
|
|
EXPECT_STREQ("-NAN", _gc(xasprintf("%G", -NAN)));
|
|
|
|
EXPECT_STREQ("INF", _gc(xasprintf("%G", INFINITY)));
|
|
|
|
EXPECT_STREQ("-INF", _gc(xasprintf("%G", -INFINITY)));
|
|
|
|
EXPECT_STREQ("2.22507E-308", _gc(xasprintf("%G", __DBL_MIN__)));
|
|
|
|
EXPECT_STREQ("1.79769E+308", _gc(xasprintf("%G", __DBL_MAX__)));
|
|
|
|
EXPECT_STREQ(" 0", _gc(xasprintf("%13g", 0.)));
|
|
|
|
EXPECT_STREQ(" -0", _gc(xasprintf("%13g", -0.)));
|
|
|
|
EXPECT_STREQ(" nan", _gc(xasprintf("%13g", NAN)));
|
|
|
|
EXPECT_STREQ(" -nan", _gc(xasprintf("%13g", -NAN)));
|
|
|
|
EXPECT_STREQ(" inf", _gc(xasprintf("%13g", INFINITY)));
|
|
|
|
EXPECT_STREQ(" -inf", _gc(xasprintf("%13g", -INFINITY)));
|
|
|
|
EXPECT_STREQ(" 2.22507e-308", _gc(xasprintf("%13g", __DBL_MIN__)));
|
|
|
|
EXPECT_STREQ(" 1.79769e+308", _gc(xasprintf("%13g", __DBL_MAX__)));
|
|
|
|
EXPECT_STREQ(" 0", _gc(xasprintf("%13G", 0.)));
|
|
|
|
EXPECT_STREQ(" -0", _gc(xasprintf("%13G", -0.)));
|
|
|
|
EXPECT_STREQ(" NAN", _gc(xasprintf("%13G", NAN)));
|
|
|
|
EXPECT_STREQ(" -NAN", _gc(xasprintf("%13G", -NAN)));
|
|
|
|
EXPECT_STREQ(" INF", _gc(xasprintf("%13G", INFINITY)));
|
|
|
|
EXPECT_STREQ(" -INF", _gc(xasprintf("%13G", -INFINITY)));
|
|
|
|
EXPECT_STREQ(" 2.22507E-308", _gc(xasprintf("%13G", __DBL_MIN__)));
|
|
|
|
EXPECT_STREQ(" 1.79769E+308", _gc(xasprintf("%13G", __DBL_MAX__)));
|
2021-03-06 16:45:44 +00:00
|
|
|
}
|
|
|
|
|
2021-03-06 22:26:36 +00:00
|
|
|
TEST(fmt, f) {
|
2022-09-13 06:10:38 +00:00
|
|
|
EXPECT_STREQ("3.141593", _gc(xasprintf("%f", 0x1.921fb54442d1846ap+1)));
|
2021-03-06 16:45:44 +00:00
|
|
|
EXPECT_STREQ("3.1415926535897931",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%.16f", 0x1.921fb54442d1846ap+1)));
|
2021-03-06 16:45:44 +00:00
|
|
|
EXPECT_STREQ("100000000000000001590289110975991804683608085639452813"
|
|
|
|
"89781327557747838772170381060813469985856815104.000000",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%f", 1e100)));
|
|
|
|
EXPECT_STREQ("0.000000", _gc(xasprintf("%f", 0.)));
|
|
|
|
EXPECT_STREQ("-0.000000", _gc(xasprintf("%f", -0.)));
|
|
|
|
EXPECT_STREQ("nan", _gc(xasprintf("%f", NAN)));
|
|
|
|
EXPECT_STREQ("-nan", _gc(xasprintf("%f", -NAN)));
|
|
|
|
EXPECT_STREQ("inf", _gc(xasprintf("%f", INFINITY)));
|
|
|
|
EXPECT_STREQ("-inf", _gc(xasprintf("%f", -INFINITY)));
|
|
|
|
EXPECT_STREQ("0.000000", _gc(xasprintf("%f", __DBL_MIN__)));
|
2021-03-06 16:45:44 +00:00
|
|
|
EXPECT_STREQ(
|
|
|
|
"179769313486231570814527423731704356798070567525844996598917476803157260"
|
|
|
|
"780028538760589558632766878171540458953514382464234321326889464182768467"
|
|
|
|
"546703537516986049910576551282076245490090389328944075868508455133942304"
|
|
|
|
"583236903222948165808559332123348274797826204144723168738177180919299881"
|
|
|
|
"250404026184124858368.000000",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%f", __DBL_MAX__)));
|
|
|
|
EXPECT_STREQ("0.000000", _gc(xasprintf("%F", 0.)));
|
|
|
|
EXPECT_STREQ("-0.000000", _gc(xasprintf("%F", -0.)));
|
|
|
|
EXPECT_STREQ("NAN", _gc(xasprintf("%F", NAN)));
|
|
|
|
EXPECT_STREQ("-NAN", _gc(xasprintf("%F", -NAN)));
|
|
|
|
EXPECT_STREQ("INF", _gc(xasprintf("%F", INFINITY)));
|
|
|
|
EXPECT_STREQ("-INF", _gc(xasprintf("%F", -INFINITY)));
|
|
|
|
EXPECT_STREQ("0.000000", _gc(xasprintf("%F", __DBL_MIN__)));
|
2021-03-06 16:45:44 +00:00
|
|
|
EXPECT_STREQ(
|
|
|
|
"179769313486231570814527423731704356798070567525844996598917476803157260"
|
|
|
|
"780028538760589558632766878171540458953514382464234321326889464182768467"
|
|
|
|
"546703537516986049910576551282076245490090389328944075868508455133942304"
|
|
|
|
"583236903222948165808559332123348274797826204144723168738177180919299881"
|
|
|
|
"250404026184124858368.000000",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%F", __DBL_MAX__)));
|
|
|
|
EXPECT_STREQ(" 0.000000", _gc(xasprintf("%10f", 0.)));
|
|
|
|
EXPECT_STREQ(" -0.000000", _gc(xasprintf("%10f", -0.)));
|
|
|
|
EXPECT_STREQ(" nan", _gc(xasprintf("%10f", NAN)));
|
|
|
|
EXPECT_STREQ(" -nan", _gc(xasprintf("%10f", -NAN)));
|
|
|
|
EXPECT_STREQ(" inf", _gc(xasprintf("%10f", INFINITY)));
|
|
|
|
EXPECT_STREQ(" -inf", _gc(xasprintf("%10f", -INFINITY)));
|
|
|
|
EXPECT_STREQ(" 0.000000", _gc(xasprintf("%10f", __DBL_MIN__)));
|
2021-03-06 16:45:44 +00:00
|
|
|
EXPECT_STREQ(
|
|
|
|
"179769313486231570814527423731704356798070567525844996598917476803157260"
|
|
|
|
"780028538760589558632766878171540458953514382464234321326889464182768467"
|
|
|
|
"546703537516986049910576551282076245490090389328944075868508455133942304"
|
|
|
|
"583236903222948165808559332123348274797826204144723168738177180919299881"
|
|
|
|
"250404026184124858368.000000",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%10f", __DBL_MAX__)));
|
|
|
|
EXPECT_STREQ(" 0.000000", _gc(xasprintf("%10F", 0.)));
|
|
|
|
EXPECT_STREQ(" -0.000000", _gc(xasprintf("%10F", -0.)));
|
|
|
|
EXPECT_STREQ(" NAN", _gc(xasprintf("%10F", NAN)));
|
|
|
|
EXPECT_STREQ(" -NAN", _gc(xasprintf("%10F", -NAN)));
|
|
|
|
EXPECT_STREQ(" INF", _gc(xasprintf("%10F", INFINITY)));
|
|
|
|
EXPECT_STREQ(" -INF", _gc(xasprintf("%10F", -INFINITY)));
|
|
|
|
EXPECT_STREQ(" 0.000000", _gc(xasprintf("%10F", __DBL_MIN__)));
|
2021-03-06 16:45:44 +00:00
|
|
|
EXPECT_STREQ(
|
|
|
|
"179769313486231570814527423731704356798070567525844996598917476803157260"
|
|
|
|
"780028538760589558632766878171540458953514382464234321326889464182768467"
|
|
|
|
"546703537516986049910576551282076245490090389328944075868508455133942304"
|
|
|
|
"583236903222948165808559332123348274797826204144723168738177180919299881"
|
|
|
|
"250404026184124858368.000000",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%10F", __DBL_MAX__)));
|
2021-03-06 16:45:44 +00:00
|
|
|
}
|
|
|
|
|
2021-03-06 22:26:36 +00:00
|
|
|
TEST(fmt, e) {
|
2022-09-13 06:10:38 +00:00
|
|
|
EXPECT_STREQ("3.14159", _gc(xasprintf("%g", 0x1.921fb54442d1846ap+1)));
|
2021-03-06 16:45:44 +00:00
|
|
|
EXPECT_STREQ("3.141592653589793",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%.16g", 0x1.921fb54442d1846ap+1)));
|
|
|
|
EXPECT_STREQ("1.000000e+100", _gc(xasprintf("%e", 1e100)));
|
|
|
|
EXPECT_STREQ("1.000000E+100", _gc(xasprintf("%E", 1e100)));
|
|
|
|
EXPECT_STREQ(" 0.000000e+00", _gc(xasprintf("%24e", 0.)));
|
|
|
|
EXPECT_STREQ(" -0.000000e+00", _gc(xasprintf("%24e", -0.)));
|
|
|
|
EXPECT_STREQ(" nan", _gc(xasprintf("%24e", NAN)));
|
|
|
|
EXPECT_STREQ(" -nan", _gc(xasprintf("%24e", -NAN)));
|
|
|
|
EXPECT_STREQ(" inf", _gc(xasprintf("%24e", INFINITY)));
|
|
|
|
EXPECT_STREQ(" -inf", _gc(xasprintf("%24e", -INFINITY)));
|
|
|
|
EXPECT_STREQ(" 2.225074e-308", _gc(xasprintf("%24e", __DBL_MIN__)));
|
|
|
|
EXPECT_STREQ(" 1.797693e+308", _gc(xasprintf("%24e", __DBL_MAX__)));
|
|
|
|
EXPECT_STREQ(" 0.000000E+00", _gc(xasprintf("%24E", 0.)));
|
|
|
|
EXPECT_STREQ(" -0.000000E+00", _gc(xasprintf("%24E", -0.)));
|
|
|
|
EXPECT_STREQ(" NAN", _gc(xasprintf("%24E", NAN)));
|
|
|
|
EXPECT_STREQ(" -NAN", _gc(xasprintf("%24E", -NAN)));
|
|
|
|
EXPECT_STREQ(" INF", _gc(xasprintf("%24E", INFINITY)));
|
|
|
|
EXPECT_STREQ(" -INF", _gc(xasprintf("%24E", -INFINITY)));
|
|
|
|
EXPECT_STREQ(" 2.225074E-308", _gc(xasprintf("%24E", __DBL_MIN__)));
|
|
|
|
EXPECT_STREQ(" 1.797693E+308", _gc(xasprintf("%24E", __DBL_MAX__)));
|
|
|
|
EXPECT_STREQ(" +0.000000e+00", _gc(xasprintf("%+24e", 0.)));
|
|
|
|
EXPECT_STREQ(" -0.000000e+00", _gc(xasprintf("%+24e", -0.)));
|
|
|
|
EXPECT_STREQ(" +nan", _gc(xasprintf("%+24e", NAN)));
|
|
|
|
EXPECT_STREQ(" -nan", _gc(xasprintf("%+24e", -NAN)));
|
|
|
|
EXPECT_STREQ(" +inf", _gc(xasprintf("%+24e", INFINITY)));
|
|
|
|
EXPECT_STREQ(" -inf", _gc(xasprintf("%+24e", -INFINITY)));
|
|
|
|
EXPECT_STREQ(" +2.225074e-308",
|
|
|
|
_gc(xasprintf("%+24e", __DBL_MIN__)));
|
|
|
|
EXPECT_STREQ(" +1.797693e+308",
|
|
|
|
_gc(xasprintf("%+24e", __DBL_MAX__)));
|
|
|
|
EXPECT_STREQ(" +0.000000E+00", _gc(xasprintf("%+24E", 0.)));
|
|
|
|
EXPECT_STREQ(" -0.000000E+00", _gc(xasprintf("%+24E", -0.)));
|
|
|
|
EXPECT_STREQ(" +NAN", _gc(xasprintf("%+24E", NAN)));
|
|
|
|
EXPECT_STREQ(" -NAN", _gc(xasprintf("%+24E", -NAN)));
|
|
|
|
EXPECT_STREQ(" +INF", _gc(xasprintf("%+24E", INFINITY)));
|
|
|
|
EXPECT_STREQ(" -INF", _gc(xasprintf("%+24E", -INFINITY)));
|
|
|
|
EXPECT_STREQ(" +2.225074E-308",
|
|
|
|
_gc(xasprintf("%+24E", __DBL_MIN__)));
|
|
|
|
EXPECT_STREQ(" +1.797693E+308",
|
|
|
|
_gc(xasprintf("%+24E", __DBL_MAX__)));
|
2021-03-06 16:45:44 +00:00
|
|
|
}
|
|
|
|
|
2021-03-06 22:26:36 +00:00
|
|
|
TEST(fmt, a) {
|
2021-03-06 16:45:44 +00:00
|
|
|
EXPECT_STREQ("0x1.921fb54442d18p+1",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%a", 0x1.921fb54442d1846ap+1)));
|
2021-03-06 16:45:44 +00:00
|
|
|
EXPECT_STREQ("0X1.921FB54442D18P+1",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%A", 0x1.921fb54442d1846ap+1)));
|
|
|
|
EXPECT_STREQ(" 0x0p+0", _gc(xasprintf("%24a", 0.)));
|
|
|
|
EXPECT_STREQ(" -0x0p+0", _gc(xasprintf("%24a", -0.)));
|
|
|
|
EXPECT_STREQ(" nan", _gc(xasprintf("%24a", NAN)));
|
|
|
|
EXPECT_STREQ(" -nan", _gc(xasprintf("%24a", -NAN)));
|
|
|
|
EXPECT_STREQ(" inf", _gc(xasprintf("%24a", INFINITY)));
|
|
|
|
EXPECT_STREQ(" -inf", _gc(xasprintf("%24a", -INFINITY)));
|
|
|
|
EXPECT_STREQ(" 0x1p-1022", _gc(xasprintf("%24a", __DBL_MIN__)));
|
|
|
|
EXPECT_STREQ(" 0x1.fffffffffffffp+1023", _gc(xasprintf("%24a", __DBL_MAX__)));
|
|
|
|
EXPECT_STREQ(" 0X0P+0", _gc(xasprintf("%24A", 0.)));
|
|
|
|
EXPECT_STREQ(" -0X0P+0", _gc(xasprintf("%24A", -0.)));
|
|
|
|
EXPECT_STREQ(" NAN", _gc(xasprintf("%24A", NAN)));
|
|
|
|
EXPECT_STREQ(" -NAN", _gc(xasprintf("%24A", -NAN)));
|
|
|
|
EXPECT_STREQ(" INF", _gc(xasprintf("%24A", INFINITY)));
|
|
|
|
EXPECT_STREQ(" -INF", _gc(xasprintf("%24A", -INFINITY)));
|
|
|
|
EXPECT_STREQ(" 0X1P-1022", _gc(xasprintf("%24A", __DBL_MIN__)));
|
|
|
|
EXPECT_STREQ(" 0X1.FFFFFFFFFFFFFP+1023", _gc(xasprintf("%24A", __DBL_MAX__)));
|
|
|
|
EXPECT_STREQ(" 0X1.E9A488E8A71DEP+14", _gc(xasprintf("%24A", 31337.1337)));
|
|
|
|
EXPECT_STREQ(" -0X1.E9A488E8A71DEP+14", _gc(xasprintf("%24A", -31337.1337)));
|
2021-03-06 16:45:44 +00:00
|
|
|
}
|
2021-03-06 22:26:36 +00:00
|
|
|
|
|
|
|
TEST(fmt, p) {
|
2022-09-13 06:10:38 +00:00
|
|
|
EXPECT_STREQ("0x1", _gc(xasprintf("%p", 1)));
|
|
|
|
EXPECT_STREQ("0x10", _gc(xasprintf("%p", 16)));
|
|
|
|
EXPECT_STREQ("0x31337", _gc(xasprintf("%p", 0x31337)));
|
|
|
|
EXPECT_STREQ("0xffffffff", _gc(xasprintf("%p", 0xffffffff)));
|
|
|
|
EXPECT_STREQ("0xffff800000031337", _gc(xasprintf("%p", 0xffff800000031337)));
|
|
|
|
EXPECT_STREQ(" 0x1", _gc(xasprintf("%10p", 1)));
|
|
|
|
EXPECT_STREQ(" 0x10", _gc(xasprintf("%10p", 16)));
|
|
|
|
EXPECT_STREQ(" 0x31337", _gc(xasprintf("%10p", 0x31337)));
|
|
|
|
EXPECT_STREQ("0xffffffff", _gc(xasprintf("%10p", 0xffffffff)));
|
2021-03-06 22:26:36 +00:00
|
|
|
EXPECT_STREQ("0xffff800000031337",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%10p", 0xffff800000031337)));
|
|
|
|
EXPECT_STREQ("0x00000001", _gc(xasprintf("%010p", 1)));
|
|
|
|
EXPECT_STREQ("0x00000010", _gc(xasprintf("%010p", 16)));
|
|
|
|
EXPECT_STREQ("0x00031337", _gc(xasprintf("%010p", 0x31337)));
|
|
|
|
EXPECT_STREQ("0xffffffff", _gc(xasprintf("%010p", 0xffffffff)));
|
2021-03-06 22:26:36 +00:00
|
|
|
EXPECT_STREQ("0xffff800000031337",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%010p", 0xffff800000031337)));
|
|
|
|
EXPECT_STREQ("0x1 ", _gc(xasprintf("%-10p", 1)));
|
|
|
|
EXPECT_STREQ("0x10 ", _gc(xasprintf("%-10p", 16)));
|
|
|
|
EXPECT_STREQ("0x31337 ", _gc(xasprintf("%-10p", 0x31337)));
|
|
|
|
EXPECT_STREQ("0xffffffff", _gc(xasprintf("%-10p", 0xffffffff)));
|
2021-03-06 22:26:36 +00:00
|
|
|
EXPECT_STREQ("0xffff800000031337",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%-10p", 0xffff800000031337)));
|
|
|
|
EXPECT_STREQ(" 0x1", _gc(xasprintf("%+10p", 1)));
|
|
|
|
EXPECT_STREQ(" 0x10", _gc(xasprintf("%+10p", 16)));
|
|
|
|
EXPECT_STREQ(" 0x31337", _gc(xasprintf("%+10p", 0x31337)));
|
|
|
|
EXPECT_STREQ("0xffffffff", _gc(xasprintf("%+10p", 0xffffffff)));
|
2021-03-06 22:26:36 +00:00
|
|
|
EXPECT_STREQ("0xffff800000031337",
|
2022-09-13 06:10:38 +00:00
|
|
|
_gc(xasprintf("%+10p", 0xffff800000031337)));
|
|
|
|
EXPECT_STREQ(" 0x1", _gc(xasprintf("% 10p", 1)));
|
|
|
|
EXPECT_STREQ(" 0x10", _gc(xasprintf("% 10p", 16)));
|
|
|
|
EXPECT_STREQ(" 0x31337", _gc(xasprintf("% 10p", 0x31337)));
|
|
|
|
EXPECT_STREQ("0xffffffff", _gc(xasprintf("% 10p", 0xffffffff)));
|
|
|
|
EXPECT_STREQ("0xffff800000031337",
|
|
|
|
_gc(xasprintf("% 10p", 0xffff800000031337)));
|
2021-03-06 22:26:36 +00:00
|
|
|
}
|
2021-05-14 12:36:58 +00:00
|
|
|
|
2022-05-25 18:31:08 +00:00
|
|
|
TEST(fmt, quoted) {
|
2022-09-13 06:10:38 +00:00
|
|
|
ASSERT_STREQ(" \"hello\"", _gc(xasprintf("%`*.*s", 10, 5, "hello")));
|
|
|
|
ASSERT_STREQ("\"hello\" ", _gc(xasprintf("%-`*.*s", 10, 5, "hello")));
|
2022-05-25 18:31:08 +00:00
|
|
|
}
|
|
|
|
|
2022-06-13 05:25:42 +00:00
|
|
|
TEST(fmt, nulCharacter) {
|
|
|
|
char b[3] = {1, 1, 1};
|
|
|
|
ASSERT_EQ(1, snprintf(0, 0, "%c", 0));
|
|
|
|
ASSERT_EQ(1, snprintf(b, 3, "%c", 0));
|
|
|
|
ASSERT_EQ(0, b[0]);
|
|
|
|
ASSERT_EQ(0, b[1]);
|
|
|
|
ASSERT_EQ(1, b[2]);
|
|
|
|
}
|
|
|
|
|
2021-07-09 04:54:21 +00:00
|
|
|
TEST(fmt, regress) {
|
|
|
|
char buf[512];
|
|
|
|
const char *meth = "GET";
|
|
|
|
const char *path = "/";
|
|
|
|
const char *host = "10.10.10.124";
|
|
|
|
const char *port = "8080";
|
|
|
|
const char *agent = "hurl/1.o (https://github.com/jart/cosmopolitan)";
|
|
|
|
ASSERT_EQ(
|
|
|
|
strlen("GET / HTTP/1.1\r\n"
|
|
|
|
"Host: 10.10.10.124:8080\r\n"
|
|
|
|
"Connection: close\r\n"
|
|
|
|
"User-Agent: hurl/1.o (https://github.com/jart/cosmopolitan)\r\n"),
|
|
|
|
sprintf(buf,
|
|
|
|
"%s %s HTTP/1.1\r\n"
|
|
|
|
"Host: %s:%s\r\n"
|
|
|
|
"Connection: close\r\n"
|
|
|
|
"User-Agent: %s\r\n",
|
|
|
|
meth, path, host, port, agent));
|
|
|
|
ASSERT_STREQ(
|
|
|
|
"GET / HTTP/1.1\r\n"
|
|
|
|
"Host: 10.10.10.124:8080\r\n"
|
|
|
|
"Connection: close\r\n"
|
|
|
|
"User-Agent: hurl/1.o (https://github.com/jart/cosmopolitan)\r\n",
|
|
|
|
buf);
|
|
|
|
}
|