1 /* Test of [v]asnwprintf() with big results.
2 Copyright (C) 2024-2025 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Bruno Haible <bruno@clisp.org>, 2024. */
21 #include "vasnwprintf.h"
28 /* Get PTRDIFF_MAX. */
37 # include <sys/types.h>
38 # include <sys/time.h>
39 # include <sys/resource.h>
47 #if PTRDIFF_MAX == INT_MAX
48 fputs ("Skipping test: ptrdiff_t is not 64-bits wide\n", stderr
);
52 /* Disable core files that would be huge. */
53 # if HAVE_SETRLIMIT && defined RLIMIT_CORE
55 rl
.rlim_cur
= rl
.rlim_max
= 0;
56 setrlimit (RLIMIT_CORE
, &rl
);
58 /* The test below needs about 40 GiB of memory:
59 $ time /usr/bin/time -f "Max RSS: %M KiB" ./test-vasnwprintf-big
64 5 GiB for the inputs in the %s tests,
65 or 20 GiB for the inputs in the %ls tests,
66 and up to 20 GiB for temporary output buffers. */
67 double needed
= 40.0 * 1024 * 1024 * 1024;
68 double avail
= physmem_claimable (1.0);
69 printf ("memory needed = %g MiB, available = %g MiB\n",
70 needed
/ 1024 / 1024, avail
/ 1024 / 1024);
73 /* Note: The malloc() calls can fail, due to ulimit of RLIMIT_DATA.
74 For example, on OpenBSD 7.5, the soft limit is 1.0 GiB or 1.5 GiB,
75 and you need "ulimit -d 42991616". */
77 /* Verify that asnwprintf() can return a string of size > 4 GiB. */
79 size_t n1
= 3 * (INT_MAX
/ 4) + 10;
80 size_t n2
= 3 * (INT_MAX
/ 4) + 20;
84 s1
= (char *) malloc (n1
+ 1);
90 s2
= (char *) malloc (n2
+ 1);
97 wchar_t *s
= asnwprintf (NULL
, &len
, L
"x%sy%sz", s1
, s2
);
100 ASSERT (errno
== ENOMEM
);
105 ASSERT (wcslen (s
) == len
);
106 ASSERT (len
== n1
+ n2
+ 3);
108 for (i
= 0; i
<= len
; i
++)
109 s
[i
] = (i
== 0 ? 'x' :
112 i
<= n1
+ n2
+ 1 ? 'b' :
113 i
== n1
+ n2
+ 2 ? 'z' :
123 /* Verify that asnwprintf() can take a string of size > 2 GiB, < 4 GiB
126 size_t n1
= 3 * (size_t) (INT_MAX
/ 2) + 10;
129 s1
= (char *) malloc (n1
+ 1);
132 memset (s1
, 'a', n1
);
136 wchar_t *s
= asnwprintf (NULL
, &len
, L
"x%sy", s1
);
139 ASSERT (errno
== ENOMEM
);
144 ASSERT (wcslen (s
) == len
);
145 ASSERT (len
== n1
+ 2);
147 for (i
= 0; i
<= len
; i
++)
148 s
[i
] = (i
== 0 ? 'x' :
158 /* Verify that asnwprintf() can take a string of size > 4 GiB
161 size_t n1
= 5 * (size_t) (INT_MAX
/ 2) + 10;
162 if (n1
> (size_t) INT_MAX
)
166 s1
= (char *) malloc (n1
+ 1);
169 memset (s1
, 'a', n1
);
173 wchar_t *s
= asnwprintf (NULL
, &len
, L
"x%sy", s1
);
176 ASSERT (errno
== ENOMEM
);
181 ASSERT (wcslen (s
) == len
);
182 ASSERT (len
== n1
+ 2);
184 for (i
= 0; i
<= len
; i
++)
185 s
[i
] = (i
== 0 ? 'x' :
196 /* Verify that asnwprintf() can take a wide string with an element count
197 > 2^31, < 2^32 as argument. */
199 size_t n1
= 3 * (size_t) (INT_MAX
/ 2) + 10;
202 s1
= (wchar_t *) malloc ((n1
+ 1) * sizeof (wchar_t));
205 wmemset (s1
, L
'a', n1
);
209 wchar_t *s
= asnwprintf (NULL
, &len
, L
"x%lsy", s1
);
212 ASSERT (errno
== ENOMEM
);
217 ASSERT (wcslen (s
) == len
);
218 ASSERT (len
== n1
+ 2);
220 for (i
= 0; i
<= len
; i
++)
221 s
[i
] = (i
== 0 ? 'x' :
231 /* Verify that asnwprintf() can take a wide string with an element count
232 > 2^32 as argument. */
234 size_t n1
= 5 * (size_t) (INT_MAX
/ 2) + 10;
235 if (n1
> (size_t) INT_MAX
)
239 s1
= (wchar_t *) malloc ((n1
+ 1) * sizeof (wchar_t));
242 wmemset (s1
, L
'a', n1
);
246 wchar_t *s
= asnwprintf (NULL
, &len
, L
"x%lsy", s1
);
249 ASSERT (errno
== ENOMEM
);
254 ASSERT (wcslen (s
) == len
);
255 ASSERT (len
== n1
+ 2);
257 for (i
= 0; i
<= len
; i
++)
258 s
[i
] = (i
== 0 ? 'x' :
272 if (test_exit_status
!= EXIT_SUCCESS
)
273 return test_exit_status
;
276 fputs ("Skipping test: not enough memory available\n", stderr
);