blob: 3d922d66ef83b41ae2be924669a558b2dac5d3a3 [file] [log] [blame]
/************************************************************************
*
* 0.printf.cpp - test exercising the rw_snprinfa() utility functions
*
* $Id$
*
************************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Copyright 2005-2008 Rogue Wave Software, Inc.
*
**************************************************************************/
// tell Compaq C++ we need ENOMEM (defined by POSIX
// but not in the compiler's pure C++ libc headers)
#undef __PURE_CNAME
#include <rw_environ.h> // for rw_putenv()
#include <rw_printf.h>
#include <rw_process.h> // for rw_pid_t
#include <rw_value.h> // for UserClass
#include <bitset> // for bitset
#include <ios> // for ios::iostate, ios::openmode, ios::seekdir
#include <string> // for string
#include <locale> // for locale::all, ...
#include <assert.h> // for assert()
#include <ctype.h> // for isdigit()
#include <errno.h> // for EXXX, errno
#include <limits.h> // for INT_MAX, ...
#include <locale.h> // for LC_ALL, ...
#include <signal.h> // for SIGABRT, ...
#include <stdio.h> // for printf(), ...
#include <stdlib.h> // for free(), size_t
#include <string.h> // for strcpy()
#include <stdarg.h> // for va_arg, ...
#include <time.h> // for struct tm
#include <wchar.h> // for WEOF
// disable tests for function name in "%{lF}"
#define _RWSTD_NO_SPRINTFA_FUNNAME
/***********************************************************************/
int ntests; // number of tests performed
int nfailures; // number of failures
static void
do_test (int line, // line number of the test case
const char *fmt, // format string
const char *expect, // expected output or 0 on error
char *result) // actual result (0 on error)
{
static char nullstr[] = "null";
++ntests;
const char* q_fmt = "\"\"";
if (0 == fmt) {
fmt = nullstr;
q_fmt = "()";
}
if (result && expect) {
const int cmp = memcmp (expect, result, strlen (expect) + 1);
if (cmp) {
++nfailures;
fprintf (stderr,
"# Assertion failed on line %d: "
"rw_sprintf(%c%s%c, ...) == \"%s\", got \"%s\"\n",
line, q_fmt [0], fmt, q_fmt [1], expect, result);
}
}
else if (result || expect) {
++nfailures;
const char* q_expect = "\"\"";
const char* q_result = "\"\"";
if (0 == expect) {
expect = nullstr;
q_expect = "()";
}
if (0 == result) {
result = nullstr;
q_result = "()";
}
fprintf (stderr, "# Assertion failed on line %d: "
"rw_printf(%c%s%c, ...) == %c%s%c got %c%s%c\n",
line, q_fmt [0], fmt, q_fmt [1],
q_expect [0], expect, q_expect [1],
q_result [0], result, q_result [1]);
}
else /* if (!result && !expect) */ {
_RWSTD_ASSERT (!result && !expect);
}
if (result && result != nullstr)
free (result);
}
#undef TEST
#define TEST(fmt, a1, a2, a3, expect) \
do_test (__LINE__, fmt, expect, rw_sprintfa (fmt, a1, a2, a3))
#undef TEST_SPEC
#define TEST_SPEC(pfx, a1, a2, a3, expect) \
{ \
++ntests; \
char fmt [64]; \
sprintf (fmt, "%s%c", pfx, spec); \
char* const s0 = rw_sprintfa (fmt, a1, a2, a3); \
char buf [256]; \
/* non-const variable below avoids warnings about */ \
/* controlling expression being constant */ \
const char* /* const */ expect_var = (expect); \
if (expect_var) \
strcpy (buf, expect_var ? expect_var : ""); \
else \
sprintf (buf, fmt, a1, a2, a3); \
const int result = memcmp (buf, s0, strlen (buf) + 1); \
if (result) { \
++nfailures; \
fprintf (stderr, \
"# Assertion failed on line %d: " \
"rw_printf(\"%s\", %ld, %ld, %ld) " \
"== \"%s\", got \"%s\"\n", \
__LINE__, fmt, \
(long)a1, (long)a2, (long)a3, buf, s0); \
} \
free (s0); \
} (void)0 /* require semicolon after macro invocation */
/***********************************************************************/
// returns an invalid or misaligned address (when 1 < size)
const void* bad_address (size_t size)
{
const char *addr;
if (1 < size) {
static const char buf [] = "0123456789abcdef";
addr = buf;
while (0 == ((size_t)addr & (size - 1)))
++addr;
}
else {
#ifndef _RWSTD_OS_HP_UX
// the first page is usually unmapped
addr = (char*)32;
#else
// the first page on HP-UX is readable, this should give
// an invalid (inaccessible) address both on IPF and PA
addr = (char*)(0 - size_t (32));
#endif // _RWSTD_OS_HP_UX
}
return addr;
}
// returns the expected string corresponding to an invalid
// or misaligned address
const char* format_bad_address (const void *ptr, bool valid)
{
static char buf [80];
#if 4 == _RWSTD_PTR_SIZE
sprintf (buf, "(%s address %#010" _RWSTD_PRIz "x)",
valid ? "misaligned" : "invalid", (size_t)ptr);
#elif 8 == _RWSTD_PTR_SIZE
sprintf (buf, "(%s address %#018" _RWSTD_PRIz "x)",
valid ? "misaligned" : "invalid", (size_t)ptr);
#else
sprintf (buf, "(%s address %#0" _RWSTD_PRIz "x)",
valid ? "misaligned" : "invalid", (size_t)ptr);
#endif
return buf;
}
/***********************************************************************/
static void
test_percent ()
{
//////////////////////////////////////////////////////////////////
printf ("%s\n", "\"%\": percent sign");
TEST ("%", 0, 0, 0, "%");
TEST ("%%", 0, 0, 0, "%");
TEST ("%% ", 0, 0, 0, "% ");
TEST (" %% ", 0, 0, 0, " % ");
TEST ("%%%", 0, 0, 0, "%%");
TEST ("%% %", 0, 0, 0, "% %");
TEST (" %", 0, 0, 0, " %");
TEST (" %", 0, 0, 0, " %");
TEST ("%%%%", 0, 0, 0, "%%");
TEST ("%% %%", 0, 0, 0, "% %");
TEST ("%% %% %", 0, 0, 0, "% % %");
TEST ("%% %% ", 0, 0, 0, "% % ");
TEST (" %%%% ", 0, 0, 0, " %% ");
TEST ("%%%%%%%%", 0, 0, 0, "%%%%");
}
/***********************************************************************/
static void
test_character ()
{
//////////////////////////////////////////////////////////////////
printf ("%s\n", "\"%c\": character formatting");
const char spec = 'c';
TEST_SPEC ("%", '\0', 0, 0, "\0");
TEST_SPEC ("%", '\a', 0, 0, "\a");
TEST_SPEC ("%", '\n', 0, 0, "\n");
TEST_SPEC ("%", '\r', 0, 0, "\r");
TEST_SPEC ("%", '\t', 0, 0, "\t");
TEST_SPEC ("%", '0', 0, 0, "0");
TEST_SPEC ("%", '1', 0, 0, "1");
TEST_SPEC ("%", 'A', 0, 0, "A");
TEST_SPEC ("%", 'Z', 0, 0, "Z");
TEST_SPEC ("%", '\xff', 0, 0, "\xff");
// exercise right justification
TEST_SPEC ("%0", 'v', 0, 0, "v");
TEST_SPEC ("%1", 'w', 0, 0, "w");
TEST_SPEC ("%2", 'x', 0, 0, " x");
TEST_SPEC ("%3", 'y', 0, 0, " y");
TEST_SPEC ("%4", 'z', 0, 0, " z");
TEST_SPEC ("%*", 0, '0', 0, "0");
TEST_SPEC ("%*", 1, '1', 0, "1");
TEST_SPEC ("%*", 2, '2', 0, " 2");
TEST_SPEC ("%*", 3, '3', 0, " 3");
TEST_SPEC ("%*", 4, '4', 0, " 4");
// exercise left justification
TEST_SPEC ("%-0", 'V', 0, 0, "V");
TEST_SPEC ("%-1", 'W', 0, 0, "W");
TEST_SPEC ("%-2", 'X', 0, 0, "X ");
TEST_SPEC ("%-3", 'Y', 0, 0, "Y ");
TEST_SPEC ("%-4", 'Z', 0, 0, "Z ");
TEST_SPEC ("%-*", 0, '0', 0, "0");
TEST_SPEC ("%-*", 1, '1', 0, "1");
TEST_SPEC ("%-*", 2, '2', 0, "2 ");
TEST_SPEC ("%-*", 3, '3', 0, "3 ");
TEST_SPEC ("%-*", 4, '4', 0, "4 ");
// 7.19.6.1, p5 of ISO/IEC 9899:1999:
// A negative field width argument is taken as a - flag
// followed by a positive field width.
TEST_SPEC ("%*", -1, '1', 0, "1");
TEST_SPEC ("%*", -2, '2', 0, "2 ");
TEST_SPEC ("%*", -3, '3', 0, "3 ");
TEST_SPEC ("%*", -4, '4', 0, "4 ");
TEST_SPEC ("%-*", -5, '5', 0, "5 ");
TEST_SPEC ("%#", 'a', 0, 0, "'a'");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{c}\": escaped character");
TEST ("%{c}", '\0', 0, 0, "\\0");
TEST ("%{c}", '\2', 0, 0, "\\x02");
TEST ("%{c}", '\a', 0, 0, "\\a");
TEST ("%{c}", '\n', 0, 0, "\\n");
TEST ("%{c}", '\r', 0, 0, "\\r");
TEST ("%{c}", '\t', 0, 0, "\\t");
TEST ("%{c}", '0', 0, 0, "0");
TEST ("%{c}", '2', 0, 0, "2");
TEST ("%{c}", 'A', 0, 0, "A");
TEST ("%{c}", 'Z', 0, 0, "Z");
TEST ("%{c}", '\xff', 0, 0, "\\xff");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{#c}\": quoted escaped character");
TEST ("%{#c}", '\0', 0, 0, "'\\0'");
TEST ("%{#c}", '\3', 0, 0, "'\\x03'");
TEST ("%{#c}", '\a', 0, 0, "'\\a'");
TEST ("%{#c}", '\n', 0, 0, "'\\n'");
TEST ("%{#c}", '\r', 0, 0, "'\\r'");
TEST ("%{#c}", '\t', 0, 0, "'\\t'");
TEST ("%{#c}", '0', 0, 0, "'0'");
TEST ("%{#c}", '3', 0, 0, "'3'");
TEST ("%{#c}", 'A', 0, 0, "'A'");
TEST ("%{#c}", 'Z', 0, 0, "'Z'");
TEST ("%{#c}", '\xff', 0, 0, "'\\xff'");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "\"%lc\": wide character");
TEST_SPEC ("%", L'\0', 0, 0, "\0");
TEST_SPEC ("%", L'\a', 0, 0, "\a");
TEST_SPEC ("%", L'\n', 0, 0, "\n");
TEST_SPEC ("%", L'\r', 0, 0, "\r");
TEST_SPEC ("%", L'\t', 0, 0, "\t");
TEST_SPEC ("%", L'0', 0, 0, "0");
TEST_SPEC ("%", L'1', 0, 0, "1");
TEST_SPEC ("%", L'A', 0, 0, "A");
TEST_SPEC ("%", L'Z', 0, 0, "Z");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{lc}\": escaped wide character");
TEST ("%{lc}", L'\0', 0, 0, "\\0");
TEST ("%{lc}", L'\4', 0, 0, "\\x04");
TEST ("%{lc}", L'\a', 0, 0, "\\a");
TEST ("%{lc}", L'\n', 0, 0, "\\n");
TEST ("%{lc}", L'\r', 0, 0, "\\r");
TEST ("%{lc}", L'\t', 0, 0, "\\t");
TEST ("%{lc}", L'0', 0, 0, "0");
TEST ("%{lc}", L'1', 0, 0, "1");
TEST ("%{lc}", L'A', 0, 0, "A");
TEST ("%{lc}", L'Z', 0, 0, "Z");
TEST ("%{lc}", L'\xff', 0, 0, "\\xff");
TEST ("%{lc}", WEOF, 0, 0, "EOF");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{#lc}\": quoted escaped wide character");
TEST ("%{#lc}", L'\0', 0, 0, "'\\0'");
TEST ("%{#lc}", L'\5', 0, 0, "'\\x05'");
TEST ("%{#lc}", L'\a', 0, 0, "'\\a'");
TEST ("%{#lc}", L'\n', 0, 0, "'\\n'");
TEST ("%{#lc}", L'\r', 0, 0, "'\\r'");
TEST ("%{#lc}", L'\t', 0, 0, "'\\t'");
TEST ("%{#lc}", L'0', 0, 0, "'0'");
TEST ("%{#lc}", L'1', 0, 0, "'1'");
TEST ("%{#lc}", L'A', 0, 0, "'A'");
TEST ("%{#lc}", L'Z', 0, 0, "'Z'");
TEST ("%{#lc}", L'\xff', 0, 0, "'\\xff'");
TEST ("%{#lc}", WEOF, 0, 0, "EOF");
}
/***********************************************************************/
static void
test_string ()
{
//////////////////////////////////////////////////////////////////
printf ("%s\n", "\"%s\": character string");
TEST ("", "", 0, 0, "");
TEST ("%s", "", 0, 0, "");
TEST ("%s", "a", 0, 0, "a");
TEST ("%s", "ab", 0, 0, "ab");
TEST ("%s", "abc", 0, 0, "abc");
TEST ("%s", "abcd", 0, 0, "abcd");
TEST ("%s", "abcde", 0, 0, "abcde");
TEST ("%s", "abcdef", 0, 0, "abcdef");
TEST ("|%1s|", "xyz", 0, 0, "|xyz|");
TEST ("|%2s|", "xyz", 0, 0, "|xyz|");
TEST ("|%3s|", "xyz", 0, 0, "|xyz|");
TEST ("|%4s|", "xyz", 0, 0, "| xyz|");
TEST ("|%5s|", "xyz", 0, 0, "| xyz|");
TEST ("|%6s|", "xyz", 0, 0, "| xyz|");
TEST ("|%-1s|", "xyz", 0, 0, "|xyz|");
TEST ("|%-2s|", "xyz", 0, 0, "|xyz|");
TEST ("|%-3s|", "xyz", 0, 0, "|xyz|");
TEST ("|%-4s|", "xyz", 0, 0, "|xyz |");
TEST ("|%-5s|", "xyz", 0, 0, "|xyz |");
TEST ("|%-6s|", "xyz", 0, 0, "|xyz |");
TEST ("|%+1s|", "xyz", 0, 0, "|xyz|");
TEST ("|%+2s|", "xyz", 0, 0, "|xyz|");
TEST ("|%+3s|", "xyz", 0, 0, "|xyz|");
TEST ("|%+4s|", "xyz", 0, 0, "| xyz|");
TEST ("|%+5s|", "xyz", 0, 0, "| xyz|");
TEST ("|%+6s|", "xyz", 0, 0, "| xyz|");
TEST ("|%1.0s|", "xyz", 0, 0, "| |");
TEST ("|%2.1s|", "xyz", 0, 0, "| x|");
TEST ("|%3.2s|", "xyz", 0, 0, "| xy|");
TEST ("|%4.3s|", "xyz", 0, 0, "| xyz|");
TEST ("|%5.4s|", "xyz", 0, 0, "| xyz|");
TEST ("|%6.5s|", "xyz", 0, 0, "| xyz|");
TEST ("|%*.*s|", 7, 2, "xyz", "| xy|");
TEST ("|%*.*s|", -8, 1, "xyz", "|x |");
TEST ("%s%s", "A", "BC", 0, "ABC");
TEST ("1%s2%s3", "A", "BC", 0, "1A2BC3");
TEST ("%s%s%s", "A", "BC", "DEF", "ABCDEF");
TEST ("1%s2%s3%s4", "A", "BC", "DEF", "1A2BC3DEF4");
TEST ("%s", 0, 0, 0, "(null)");
const void* addr = bad_address (0);
TEST ("%s", addr, 0, 0, format_bad_address (addr, false));
#ifndef _RWSTD_NO_WCHAR_T
//////////////////////////////////////////////////////////////////
printf ("%s\n", "\"%ls\": wide character string");
TEST ("%ls", 0, 0, 0, "(null)");
addr = bad_address (0);
TEST ("%ls", addr, 0, 0, format_bad_address (addr, false));
addr = bad_address (sizeof (wchar_t));
TEST ("%ls", addr, 0, 0, format_bad_address (addr, true));
fprintf (stderr, "Warning: %s\n", "\"%ls\" not exercised");
#endif // _RWSTD_NO_WCHAR_T
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{#s}\": quoted character string");
TEST ("%{#s}", "", 0, 0, "\"\"");
TEST ("%{#s}", "\0", 0, 0, "\"\"");
TEST ("%{#s}", "\1", 0, 0, "\"\\x01\"");
TEST ("%{#s}", "\a", 0, 0, "\"\\a\"");
TEST ("%{#s}", "\n", 0, 0, "\"\\n\"");
TEST ("%{#s}", "\r", 0, 0, "\"\\r\"");
TEST ("%{#s}", "\t", 0, 0, "\"\\t\"");
TEST ("%{#s}", "\v", 0, 0, "\"\\v\"");
TEST ("%{#s}", "a", 0, 0, "\"a\"");
TEST ("%{#s}", "ab", 0, 0, "\"ab\"");
TEST ("%{#s}", "abc", 0, 0, "\"abc\"");
TEST ("%{#s}", "a\ac", 0, 0, "\"a\\ac\"");
TEST ("%{#s}", "a\"c", 0, 0, "\"a\\\"c\"");
// embedded NULs
TEST ("%{#1s}", "\0", 0, 0, "\"\\0\"");
TEST ("%{#2s}", "\0", 0, 0, "\"\\0\\0\"");
TEST ("%{#2s}", "a\0", 0, 0, "\"a\\0\"");
TEST ("%{#2s}", "\0a", 0, 0, "\"\\0a\"");
TEST ("%{#3s}", "\0\0\0", 0, 0, "\"\\0\\0\\0\"");
TEST ("%{#3s}", "\0a\0", 0, 0, "\"\\0a\\0\"");
TEST ("%{#3s}", "\0\0a", 0, 0, "\"\\0\\0a\"");
TEST ("%{#*s}", 0, "\0\0\0v", 0, "\"\"");
TEST ("%{#*s}", 1, "\0\0\0w", 0, "\"\\0\"");
TEST ("%{#*s}", 2, "\0\0\0x", 0, "\"\\0\\0\"");
TEST ("%{#*s}", 3, "\0\0\0y", 0, "\"\\0\\0\\0\"");
TEST ("%{#*s}", 4, "\0\0\0z", 0, "\"\\0\\0\\0z\"");
TEST ("%{#*s}", 5, "\0\0\0z", 0, "\"\\0\\0\\0z\\0\"");
#ifndef _RWSTD_NO_WCHAR_T
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{#ls}\": quoted wide character string");
TEST ("%{#ls}", L"", 0, 0, "\"\"");
TEST ("%{#ls}", L"\1", 0, 0, "\"\\x01\"");
TEST ("%{#ls}", L"\a", 0, 0, "\"\\a\"");
TEST ("%{#ls}", L"\n", 0, 0, "\"\\n\"");
TEST ("%{#ls}", L"\r", 0, 0, "\"\\r\"");
TEST ("%{#ls}", L"\t", 0, 0, "\"\\t\"");
TEST ("%{#ls}", L"\v", 0, 0, "\"\\v\"");
TEST ("%{#ls}", L"a", 0, 0, "\"a\"");
TEST ("%{#ls}", L"ab", 0, 0, "\"ab\"");
TEST ("%{#ls}", L"abc", 0, 0, "\"abc\"");
TEST ("%{#ls}", L"a\ac", 0, 0, "\"a\\ac\"");
TEST ("%{#ls}", L"a\"c", 0, 0, "\"a\\\"c\"");
TEST ("%{#ls}", L"\x100", 0, 0, "\"\\x100\"");
// embedded NULs
TEST ("%{#1ls}", L"\0", 0, 0, "\"\\0\"");
TEST ("%{#2ls}", L"\0", 0, 0, "\"\\0\\0\"");
TEST ("%{#2ls}", L"a\0", 0, 0, "\"a\\0\"");
TEST ("%{#2ls}", L"\0a", 0, 0, "\"\\0a\"");
TEST ("%{#3ls}", L"\0\0\0", 0, 0, "\"\\0\\0\\0\"");
TEST ("%{#3ls}", L"\0a\0", 0, 0, "\"\\0a\\0\"");
TEST ("%{#3ls}", L"\0\0a", 0, 0, "\"\\0\\0a\"");
TEST ("%{#*ls}", 0, L"\0\0\0v", 0, "\"\"");
TEST ("%{#*ls}", 1, L"\0\0\0w", 0, "\"\\0\"");
TEST ("%{#*ls}", 2, L"\0\0\0x", 0, "\"\\0\\0\"");
TEST ("%{#*ls}", 3, L"\0\0\0y", 0, "\"\\0\\0\\0\"");
TEST ("%{#*ls}", 4, L"\0\0\0z", 0, "\"\\0\\0\\0z\"");
TEST ("%{#*ls}", 5, L"\0\0\0z", 0, "\"\\0\\0\\0z\\0\"");
addr = bad_address (0);
TEST ("%{#ls}", addr, 0, 0, format_bad_address (addr, false));
addr = bad_address (sizeof (wchar_t));
TEST ("%{#ls}", addr, 0, 0, format_bad_address (addr, true));
#endif // _RWSTD_NO_WCHAR_T
}
/***********************************************************************/
static void
test_chararray ()
{
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{Ac}\": quoted character array");
// exercise the formatting of arrays of characters of arbitrary width
// (i.e., single-byte narrow, 2-byte, 4-byte (usually wchar_t's), and
// 8-byte characters
TEST ("%{Ac}", 0, 0, 0, "(null)");
TEST ("%{Ac}", "", 0, 0, "\"\"");
TEST ("%{Ac}", "a", 0, 0, "\"a\"");
TEST ("%{Ac}", "ab", 0, 0, "\"ab\"");
TEST ("%{Ac}", "abc", 0, 0, "\"abc\"");
TEST ("%{1Ac}", 0, 0, 0, "(null)");
TEST ("%{1Ac}", "", 0, 0, "\"\"");
TEST ("%{1Ac}", "a", 0, 0, "\"a\"");
TEST ("%{1Ac}", "ab", 0, 0, "\"ab\"");
TEST ("%{1Ac}", "abc", 0, 0, "\"abc\"");
// +---- width: character width in bytes
// | +-- precision: number of elements in array
// | |
// v v
TEST ("%{1.0Ac}", 0, 0, 0, "(null)");
TEST ("%{1.0Ac}", "", 0, 0, "\"\"");
TEST ("%{1.1Ac}", "", 0, 0, "\"\\0\"");
TEST ("%{1.0Ac}", "a", 0, 0, "\"\"");
TEST ("%{1.1Ac}", "a", 0, 0, "\"a\"");
TEST ("%{1.2Ac}", "a", 0, 0, "\"a\\0\"");
TEST ("%{1.0Ac}", "ab", 0, 0, "\"\"");
TEST ("%{1.1Ac}", "ab", 0, 0, "\"a\"");
TEST ("%{1.2Ac}", "ab", 0, 0, "\"ab\"");
TEST ("%{1.3Ac}", "ab", 0, 0, "\"ab\\0\"");
TEST ("%{1.*Ac}", 7, "ab\0cdef", 0, "\"ab\\0cdef\"");
TEST ("%{*.7Ac}", 1, "abc\0def", 0, "\"abc\\0def\"");
TEST ("%{*.*Ac}", 1, 7, "abcd\0ef", "\"abcd\\0ef\"");
#ifndef _RWSTD_NO_WCHAR_T
const unsigned wchar_size = sizeof (wchar_t);
#else // if defined (_RWSTD_NO_WCHAR_T)
const unsigned wchar_size = 0;
#endif // _RWSTD_NO_WCHAR_T
if (2 == wchar_size) {
TEST ("%{2Ac}", 0, 0, 0, "(null)");
TEST ("%{2Ac}", L"", 0, 0, "L\"\"");
TEST ("%{2Ac}", L"a", 0, 0, "L\"a\"");
TEST ("%{2Ac}", L"ab", 0, 0, "L\"ab\"");
TEST ("%{2Ac}", L"abc", 0, 0, "L\"abc\"");
TEST ("%{2.0Ac}", L"", 0, 0, "L\"\"");
TEST ("%{2.1Ac}", L"", 0, 0, "L\"\\0\"");
TEST ("%{2.0Ac}", L"a", 0, 0, "L\"\"");
TEST ("%{2.1Ac}", L"a", 0, 0, "L\"a\"");
TEST ("%{2.2Ac}", L"a", 0, 0, "L\"a\\0\"");
TEST ("%{2.0Ac}", L"ab", 0, 0, "L\"\"");
TEST ("%{2.1Ac}", L"ab", 0, 0, "L\"a\"");
TEST ("%{2.2Ac}", L"ab", 0, 0, "L\"ab\"");
TEST ("%{2.3Ac}", L"ab", 0, 0, "L\"ab\\0\"");
TEST ("%{2.0Ac}", L"abc", 0, 0, "L\"\"");
TEST ("%{2.1Ac}", L"abc", 0, 0, "L\"a\"");
TEST ("%{2.2Ac}", L"abc", 0, 0, "L\"ab\"");
TEST ("%{2.3Ac}", L"abc", 0, 0, "L\"abc\"");
TEST ("%{2.4Ac}", L"abc", 0, 0, "L\"abc\\0\"");
TEST ("%{2.*Ac}", 7, L"ab\0cdef", 0, "L\"ab\\0cdef\"");
TEST ("%{*.7Ac}", 2, L"abc\0def", 0, "L\"abc\\0def\"");
TEST ("%{*.*Ac}", 2, 7, L"abcd\0ef", "L\"abcd\\0ef\"");
}
if (sizeof (short) != wchar_size) {
const short s_ [] = { '\0' };
const short s_a [] = { 'a', '\0' };
const short s_ab [] = { 'a', 'b', '\0' };
const short s_abc [] = { 'a', 'b', 'c', '\0' };
TEST ("%{2Ac}", 0, 0, 0, "(null)");
TEST ("%{2Ac}", s_, 0, 0, "\"\"");
TEST ("%{2Ac}", s_a, 0, 0, "\"a\"");
TEST ("%{2Ac}", s_ab, 0, 0, "\"ab\"");
TEST ("%{2Ac}", s_abc, 0, 0, "\"abc\"");
}
if (4 == wchar_size) {
TEST ("%{4Ac}", 0, 0, 0, "(null)");
TEST ("%{4Ac}", L"", 0, 0, "L\"\"");
TEST ("%{4Ac}", L"a", 0, 0, "L\"a\"");
TEST ("%{4Ac}", L"ab", 0, 0, "L\"ab\"");
TEST ("%{4Ac}", L"abc", 0, 0, "L\"abc\"");
TEST ("%{4.0Ac}", L"", 0, 0, "L\"\"");
TEST ("%{4.1Ac}", L"", 0, 0, "L\"\\0\"");
TEST ("%{4.0Ac}", L"a", 0, 0, "L\"\"");
TEST ("%{4.1Ac}", L"a", 0, 0, "L\"a\"");
TEST ("%{4.2Ac}", L"a", 0, 0, "L\"a\\0\"");
TEST ("%{4.0Ac}", L"ab", 0, 0, "L\"\"");
TEST ("%{4.1Ac}", L"ab", 0, 0, "L\"a\"");
TEST ("%{4.2Ac}", L"ab", 0, 0, "L\"ab\"");
TEST ("%{4.3Ac}", L"ab", 0, 0, "L\"ab\\0\"");
TEST ("%{4.0Ac}", L"abc", 0, 0, "L\"\"");
TEST ("%{4.1Ac}", L"abc", 0, 0, "L\"a\"");
TEST ("%{4.2Ac}", L"abc", 0, 0, "L\"ab\"");
TEST ("%{4.3Ac}", L"abc", 0, 0, "L\"abc\"");
TEST ("%{4.4Ac}", L"abc", 0, 0, "L\"abc\\0\"");
TEST ("%{4.*Ac}", 7, L"ab\0cdef", 0, "L\"ab\\0cdef\"");
TEST ("%{*.7Ac}", 4, L"abc\0def", 0, "L\"abc\\0def\"");
TEST ("%{*.*Ac}", 4, 7, L"abcd\0ef", "L\"abcd\\0ef\"");
}
}
/***********************************************************************/
static const char**
mkargv (const char *arg0 = 0,
const char *arg1 = 0,
const char *arg2 = 0,
const char *arg3 = 0,
const char *arg4 = 0,
const char *arg5 = 0,
const char *arg6 = 0,
const char *arg7 = 0,
const char *arg8 = 0,
const char *arg9 = 0)
{
static const char* argv [10];
argv [0] = arg0;
argv [1] = arg1;
argv [2] = arg2;
argv [3] = arg3;
argv [4] = arg4;
argv [5] = arg5;
argv [6] = arg6;
argv [7] = arg7;
argv [8] = arg8;
argv [9] = arg9;
return argv;
}
static void
test_stringarray ()
{
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{As}\": array of character strings");
#undef ARG
#define ARG mkargv
TEST ("%{As}", 0, 0, 0, "(null)");
TEST ("%{As}", ARG ("a"), 0, 0, "a");
TEST ("%{As}", ARG ("a", "bc"), 0, 0, "a,bc");
TEST ("%{As}", ARG ("a", "bc", "def"), 0, 0, "a,bc,def");
TEST ("%{As}", ARG ("a", "bc", "def", "ghij"), 0, 0, "a,bc,def,ghij");
TEST ("%{#As}", 0, 0, 0, "(null)");
TEST ("%{#As}", ARG ("abcd"), 0, 0, "\"abcd\"");
TEST ("%{#As}", ARG ("abcd", "efg"), 0, 0, "\"abcd\",\"efg\"");
TEST ("%{#As}", ARG ("abcd", "efg", "hi"), 0, 0, "\"abcd\",\"efg\",\"hi\"");
TEST ("%{ As}", 0, 0, 0, "(null)");
TEST ("%{ As}", ARG ("a"), 0, 0, "a");
TEST ("%{ As}", ARG ("a", "bc"), 0, 0, "a bc");
TEST ("%{ As}", ARG ("a", "bc", "def"), 0, 0, "a bc def");
TEST ("%{ As}", ARG ("a", "bc", "def", "ghij"), 0, 0, "a bc def ghij");
TEST ("%{ #As}", 0, 0, 0, "(null)");
TEST ("%{ #As}", ARG ("abc"), 0, 0, "\"abc\"");
TEST ("%{ #As}", ARG ("abc", "efg"), 0, 0, "\"abc\" \"efg\"");
TEST ("%{ #As}", ARG ("abc", "efg", "hi"), 0, 0, "\"abc\" \"efg\" \"hi\"");
}
/***********************************************************************/
static void
test_basic_string ()
{
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{S}\": std::string");
std::string str;
#undef S
#define S(s) &(str = std::string (s, sizeof s - 1))
TEST ("%{S}", 0, 0, 0, "(null)");
TEST ("%{S}", S (""), 0, 0, "");
TEST ("%{S}", S ("a"), 0, 0, "a");
TEST ("%{S}", S ("ab"), 0, 0, "ab");
TEST ("%{S}", S ("abc"), 0, 0, "abc");
TEST ("%{#S}", S ("\a\n\r\t\v"), 0, 0, "\"\\a\\n\\r\\t\\v\"");
TEST ("%{#S}", S ("\0bc"), 0, 0, "\"\\0bc\"");
TEST ("%{#S}", S ("a\0c"), 0, 0, "\"a\\0c\"");
TEST ("%{#S}", S ("ab\0"), 0, 0, "\"ab\\0\"");
TEST ("%{#S}", S ("a\0\0"), 0, 0, "\"a\\0\\0\"");
TEST ("%{#S}", S ("\0\0\0"), 0, 0, "\"\\0\\0\\0\"");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{lS}\": std::wstring");
#ifndef _RWSTD_NO_WCHAR_T
std::wstring wstr;
# undef WS
# define WS(ws) \
&(wstr = std::wstring (L ## ws, sizeof L ## ws / sizeof (wchar_t) - 1))
TEST ("%{lS}", 0, 0, 0, "(null)");
TEST ("%{lS}", WS (""), 0, 0, "");
TEST ("%{lS}", WS ("a"), 0, 0, "a");
TEST ("%{lS}", WS ("ab"), 0, 0, "ab");
TEST ("%{lS}", WS ("abc"), 0, 0, "abc");
TEST ("%{#lS}", WS ("\a\n\r\t\v"), 0, 0, "\"\\a\\n\\r\\t\\v\"");
TEST ("%{#lS}", WS ("\0bc"), 0, 0, "\"\\0bc\"");
TEST ("%{#lS}", WS ("a\0c"), 0, 0, "\"a\\0c\"");
TEST ("%{#lS}", WS ("ab\0"), 0, 0, "\"ab\\0\"");
TEST ("%{#lS}", WS ("a\0\0"), 0, 0, "\"a\\0\\0\"");
TEST ("%{#lS}", WS ("\0\0\0"), 0, 0, "\"\\0\\0\\0\"");
#else // if defined (_RWSTD_NO_WCHAR_T)
fprintf (stderr, "Warning: %s\n", "\"%{lS}\" not exercised: "
"_RWSTD_NO_WCHAR_T #defined");
#endif // _RWSTD_NO_WCHAR_T
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{#*S}\": std::basic_string<charT> with "
"sizeof (charT)");
TEST ("%{#1S}", 0, 0, 0, "(null)");
TEST ("%{#1S}", S ("\0bc"), 0, 0, "\"\\0bc\"");
TEST ("%{#1S}", S ("a\0c"), 0, 0, "\"a\\0c\"");
TEST ("%{#1S}", S ("ab\0"), 0, 0, "\"ab\\0\"");
TEST ("%{#1S}", S ("a\0\0"), 0, 0, "\"a\\0\\0\"");
TEST ("%{#1S}", S ("\0\0\0"), 0, 0, "\"\\0\\0\\0\"");
#if 2 == _RWSTD_WCHAR_SIZE
TEST ("%{#2S}", 0, 0, 0, "(null)");
TEST ("%{#2S}", WS (""), 0, 0, "L\"\"");
TEST ("%{#2S}", WS ("a"), 0, 0, "L\"a\"");
TEST ("%{#2S}", WS ("ab"), 0, 0, "L\"ab\"");
TEST ("%{#2S}", WS ("abc"), 0, 0, "L\"abc\"");
TEST ("%{#2S}", WS ("\0bc"), 0, 0, "L\"\\0bc\"");
TEST ("%{#2S}", WS ("a\0c"), 0, 0, "L\"a\\0c\"");
TEST ("%{#2S}", WS ("ab\0"), 0, 0, "L\"ab\\0\"");
TEST ("%{#2S}", WS ("a\0\0"), 0, 0, "L\"a\\0\\0\"");
TEST ("%{#2S}", WS ("\0\0\0"), 0, 0, "L\"\\0\\0\\0\"");
#elif 4 == _RWSTD_WCHAR_SIZE
TEST ("%{#4S}", 0, 0, 0, "(null)");
TEST ("%{#4S}", WS (""), 0, 0, "L\"\"");
TEST ("%{#4S}", WS ("a"), 0, 0, "L\"a\"");
TEST ("%{#4S}", WS ("ab"), 0, 0, "L\"ab\"");
TEST ("%{#4S}", WS ("abc"), 0, 0, "L\"abc\"");
TEST ("%{#4S}", WS ("\0bc"), 0, 0, "L\"\\0bc\"");
TEST ("%{#4S}", WS ("a\0c"), 0, 0, "L\"a\\0c\"");
TEST ("%{#4S}", WS ("ab\0"), 0, 0, "L\"ab\\0\"");
TEST ("%{#4S}", WS ("a\0\0"), 0, 0, "L\"a\\0\\0\"");
TEST ("%{#4S}", WS ("\0\0\0"), 0, 0, "L\"\\0\\0\\0\"");
#endif // _RWSTD_WCHAR_SIZE
}
/***********************************************************************/
static void
test_ios_bitmasks ()
{
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{Is}\": std::ios_base::iostate");
const int bad = std::ios_base::badbit;
const int eof = std::ios_base::eofbit;
const int fail = std::ios_base::failbit;
TEST ("[%{Is}]", 0, 0, 0, "[goodbit]");
TEST ("[%{Is}]", bad, 0, 0, "[badbit]");
TEST ("[%{Is}]", eof, 0, 0, "[eofbit]");
TEST ("[%{Is}]", fail, 0, 0, "[failbit]");
TEST ("[%{#Is}]", 0, 0, 0, "[std::ios::goodbit]");
TEST ("[%{#Is}]", bad, 0, 0, "[std::ios::badbit]");
TEST ("[%{#Is}]", eof, 0, 0, "[std::ios::eofbit]");
TEST ("[%{#Is}]", fail, 0, 0, "[std::ios::failbit]");
TEST ("[%{Is}]", bad | eof, 0, 0, "[badbit | eofbit]");
TEST ("[%{Is}]", bad | fail, 0, 0, "[badbit | failbit]");
TEST ("[%{Is}]", eof | fail, 0, 0, "[eofbit | failbit]");
TEST ("[%{Is}]", bad | eof | fail, 0, 0, "[badbit | eofbit | failbit]");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{Io}\": std::ios_base::opemode");
const int in = std::ios_base::in;
const int out = std::ios_base::out;
const int ate = std::ios_base::ate;
TEST ("[%{Io}]", 0, 0, 0, "[openmode(0)]");
TEST ("[%{Io}]", in, 0, 0, "[in]");
TEST ("[%{Io}]", out, 0, 0, "[out]");
TEST ("[%{Io}]", ate, 0, 0, "[ate]");
TEST ("[%{Io}]", in | out, 0, 0, "[in | out]");
TEST ("[%{Io}]", in | ate, 0, 0, "[in | ate]");
TEST ("[%{Io}]", in | out | ate, 0, 0, "[in | out | ate]");
TEST ("[%{Io}]", out | ate, 0, 0, "[out | ate]");
TEST ("[%{#Io}]", 0, 0, 0, "[std::ios::openmode(0)]");
TEST ("[%{#Io}]", in, 0, 0, "[std::ios::in]");
TEST ("[%{#Io}]", out, 0, 0, "[std::ios::out]");
TEST ("[%{#Io}]", ate, 0, 0, "[std::ios::ate]");
TEST ("[%{#Io}]", in | out, 0, 0, "[std::ios::in | std::ios::out]");
TEST ("[%{#Io}]", in | ate, 0, 0, "[std::ios::in | std::ios::ate]");
TEST ("[%{#Io}]", in | out | ate, 0, 0,
"[std::ios::in | std::ios::out | std::ios::ate]");
TEST ("[%{#Io}]", out | ate, 0, 0, "[std::ios::out | std::ios::ate]");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{Iw}\": std::ios_base::seekdir");
TEST ("[%{Iw}]", std::ios::beg, 0, 0, "[beg]");
TEST ("[%{Iw}]", std::ios::cur, 0, 0, "[cur]");
TEST ("[%{Iw}]", std::ios::end, 0, 0, "[end]");
TEST ("[%{#Iw}]", std::ios::beg, 0, 0, "[std::ios::beg]");
TEST ("[%{#Iw}]", std::ios::cur, 0, 0, "[std::ios::cur]");
TEST ("[%{#Iw}]", std::ios::end, 0, 0, "[std::ios::end]");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{If}\": std::ios_base::fmtflags");
#define BASE(n) ((n) << _RWSTD_IOS_BASEOFF)
TEST ("[%{If}]", 0, 0, 0, "[fmtflags(0)]");
TEST ("[%{If}]", std::ios::adjustfield, 0, 0, "[adjustfield]");
TEST ("[%{If}]", std::ios::basefield, 0, 0, "[basefield]");
TEST ("[%{If}]", std::ios::boolalpha, 0, 0, "[boolalpha]");
TEST ("[%{If}]", std::ios::dec, 0, 0, "[dec]");
TEST ("[%{If}]", std::ios::fixed, 0, 0, "[fixed]");
TEST ("[%{If}]", std::ios::hex, 0, 0, "[hex]");
TEST ("[%{If}]", std::ios::internal, 0, 0, "[internal]");
TEST ("[%{If}]", std::ios::left, 0, 0, "[left]");
TEST ("[%{If}]", std::ios::oct, 0, 0, "[oct]");
TEST ("[%{If}]", std::ios::right, 0, 0, "[right]");
TEST ("[%{If}]", std::ios::scientific, 0, 0, "[scientific]");
TEST ("[%{If}]", std::ios::showbase, 0, 0, "[showbase]");
TEST ("[%{If}]", std::ios::showpoint, 0, 0, "[showpoint]");
TEST ("[%{If}]", std::ios::showpos, 0, 0, "[showpos]");
TEST ("[%{If}]", std::ios::skipws, 0, 0, "[skipws]");
TEST ("[%{If}]", std::ios::unitbuf, 0, 0, "[unitbuf]");
TEST ("[%{If}]", std::ios::uppercase, 0, 0, "[uppercase]");
#ifndef _RWSTD_NO_EXT_BIN_IO
TEST ("[%{If}]", std::ios::bin, 0, 0, "[bin]");
#endif // _RWSTD_NO_EXT_BIN_IO
#ifndef _RWSTD_NO_EXT_REENTRANT_IO
TEST ("[%{If}]", std::ios::nolock, 0, 0, "[nolock]");
TEST ("[%{If}]", std::ios::nolockbuf, 0, 0, "[nolockbuf]");
#endif // _RWSTD_NO_EXT_REENTRANT_IO
TEST ("[%{If}]", BASE (1), 0, 0, "[fmtflags(0) | base(1)]");
TEST ("[%{If}]", BASE (2), 0, 0, "[fmtflags(0) | base(2)]");
TEST ("[%{If}]", BASE (3), 0, 0, "[fmtflags(0) | base(3)]");
TEST ("[%{If}]", BASE (4), 0, 0, "[fmtflags(0) | base(4)]");
TEST ("[%{If}]", BASE (5), 0, 0, "[fmtflags(0) | base(5)]");
TEST ("[%{If}]", BASE (6), 0, 0, "[fmtflags(0) | base(6)]");
TEST ("[%{If}]", BASE (7), 0, 0, "[fmtflags(0) | base(7)]");
TEST ("[%{If}]", BASE (8), 0, 0, "[fmtflags(0)]");
TEST ("[%{If}]", BASE (9), 0, 0, "[fmtflags(0) | base(9)]");
TEST ("[%{If}]", BASE (10), 0, 0, "[fmtflags(0)]");
TEST ("[%{If}]", BASE (11), 0, 0, "[fmtflags(0) | base(11)]");
TEST ("[%{If}]", BASE (12), 0, 0, "[fmtflags(0) | base(12)]");
TEST ("[%{If}]", BASE (13), 0, 0, "[fmtflags(0) | base(13)]");
TEST ("[%{If}]", BASE (14), 0, 0, "[fmtflags(0) | base(14)]");
TEST ("[%{If}]", BASE (15), 0, 0, "[fmtflags(0) | base(15)]");
TEST ("[%{If}]", BASE (16), 0, 0, "[fmtflags(0)]");
TEST ("[%{If}]", BASE (17), 0, 0, "[fmtflags(0) | base(17)]");
TEST ("[%{If}]", BASE (18), 0, 0, "[fmtflags(0) | base(18)]");
TEST ("[%{If}]", BASE (19), 0, 0, "[fmtflags(0) | base(19)]");
TEST ("[%{If}]", BASE (20), 0, 0, "[fmtflags(0) | base(20)]");
TEST ("[%{If}]", BASE (21), 0, 0, "[fmtflags(0) | base(21)]");
TEST ("[%{If}]", BASE (22), 0, 0, "[fmtflags(0) | base(22)]");
TEST ("[%{If}]", BASE (23), 0, 0, "[fmtflags(0) | base(23)]");
TEST ("[%{If}]", BASE (24), 0, 0, "[fmtflags(0) | base(24)]");
TEST ("[%{If}]", BASE (25), 0, 0, "[fmtflags(0) | base(25)]");
TEST ("[%{If}]", BASE (26), 0, 0, "[fmtflags(0) | base(26)]");
TEST ("[%{If}]", BASE (27), 0, 0, "[fmtflags(0) | base(27)]");
TEST ("[%{If}]", BASE (28), 0, 0, "[fmtflags(0) | base(28)]");
TEST ("[%{If}]", BASE (29), 0, 0, "[fmtflags(0) | base(29)]");
TEST ("[%{If}]", BASE (30), 0, 0, "[fmtflags(0) | base(30)]");
TEST ("[%{If}]", BASE (31), 0, 0, "[fmtflags(0) | base(31)]");
TEST ("[%{If}]", BASE (32), 0, 0, "[fmtflags(0) | base(32)]");
TEST ("[%{If}]", BASE (33), 0, 0, "[fmtflags(0) | base(33)]");
TEST ("[%{If}]", BASE (34), 0, 0, "[fmtflags(0) | base(34)]");
TEST ("[%{If}]", BASE (35), 0, 0, "[fmtflags(0) | base(35)]");
TEST ("[%{If}]", BASE (36), 0, 0, "[fmtflags(0) | base(36)]");
TEST ("[%{#If}]", 0, 0, 0, "[std::ios::fmtflags(0)]");
TEST ("[%{#If}]", std::ios::adjustfield, 0, 0, "[std::ios::adjustfield]");
TEST ("[%{#If}]", std::ios::basefield, 0, 0, "[std::ios::basefield]");
TEST ("[%{#If}]", std::ios::boolalpha, 0, 0, "[std::ios::boolalpha]");
TEST ("[%{#If}]", std::ios::dec, 0, 0, "[std::ios::dec]");
TEST ("[%{#If}]", std::ios::fixed, 0, 0, "[std::ios::fixed]");
TEST ("[%{#If}]", std::ios::hex, 0, 0, "[std::ios::hex]");
TEST ("[%{#If}]", std::ios::internal, 0, 0, "[std::ios::internal]");
TEST ("[%{#If}]", std::ios::left, 0, 0, "[std::ios::left]");
TEST ("[%{#If}]", std::ios::oct, 0, 0, "[std::ios::oct]");
TEST ("[%{#If}]", std::ios::right, 0, 0, "[std::ios::right]");
TEST ("[%{#If}]", std::ios::scientific, 0, 0, "[std::ios::scientific]");
TEST ("[%{#If}]", std::ios::showbase, 0, 0, "[std::ios::showbase]");
TEST ("[%{#If}]", std::ios::showpoint, 0, 0, "[std::ios::showpoint]");
TEST ("[%{#If}]", std::ios::showpos, 0, 0, "[std::ios::showpos]");
TEST ("[%{#If}]", std::ios::skipws, 0, 0, "[std::ios::skipws]");
TEST ("[%{#If}]", std::ios::unitbuf, 0, 0, "[std::ios::unitbuf]");
TEST ("[%{#If}]", std::ios::uppercase, 0, 0, "[std::ios::uppercase]");
#ifndef _RWSTD_NO_EXT_BIN_IO
TEST ("[%{#If}]", std::ios::bin, 0, 0, "[std::ios::bin]");
#endif // _RWSTD_NO_EXT_BIN_IO
#ifndef _RWSTD_NO_EXT_REENTRANT_IO
TEST ("[%{#If}]", std::ios::nolock, 0, 0, "[std::ios::nolock]");
TEST ("[%{#If}]", std::ios::nolockbuf, 0, 0, "[std::ios::nolockbuf]");
#endif // _RWSTD_NO_EXT_REENTRANT_IO
TEST ("[%{#If}]", BASE (1), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(1)]");
TEST ("[%{#If}]", BASE (2), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(2)]");
TEST ("[%{#If}]", BASE (3), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(3)]");
TEST ("[%{#If}]", BASE (4), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(4)]");
TEST ("[%{#If}]", BASE (5), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(5)]");
TEST ("[%{#If}]", BASE (6), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(6)]");
TEST ("[%{#If}]", BASE (7), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(7)]");
TEST ("[%{#If}]", BASE (8), 0, 0,
"[std::ios::fmtflags(0)]");
TEST ("[%{#If}]", BASE (9), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(9)]");
TEST ("[%{#If}]", BASE (10), 0, 0,
"[std::ios::fmtflags(0)]");
TEST ("[%{#If}]", BASE (11), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(11)]");
TEST ("[%{#If}]", BASE (12), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(12)]");
TEST ("[%{#If}]", BASE (13), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(13)]");
TEST ("[%{#If}]", BASE (14), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(14)]");
TEST ("[%{#If}]", BASE (15), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(15)]");
TEST ("[%{#If}]", BASE (16), 0, 0,
"[std::ios::fmtflags(0)]");
TEST ("[%{#If}]", BASE (17), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(17)]");
TEST ("[%{#If}]", BASE (18), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(18)]");
TEST ("[%{#If}]", BASE (19), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(19)]");
TEST ("[%{#If}]", BASE (20), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(20)]");
TEST ("[%{#If}]", BASE (21), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(21)]");
TEST ("[%{#If}]", BASE (22), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(22)]");
TEST ("[%{#If}]", BASE (23), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(23)]");
TEST ("[%{#If}]", BASE (24), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(24)]");
TEST ("[%{#If}]", BASE (25), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(25)]");
TEST ("[%{#If}]", BASE (26), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(26)]");
TEST ("[%{#If}]", BASE (27), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(27)]");
TEST ("[%{#If}]", BASE (28), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(28)]");
TEST ("[%{#If}]", BASE (29), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(29)]");
TEST ("[%{#If}]", BASE (30), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(30)]");
TEST ("[%{#If}]", BASE (31), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(31)]");
TEST ("[%{#If}]", BASE (32), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(32)]");
TEST ("[%{#If}]", BASE (33), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(33)]");
TEST ("[%{#If}]", BASE (34), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(34)]");
TEST ("[%{#If}]", BASE (35), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(35)]");
TEST ("[%{#If}]", BASE (36), 0, 0,
"[std::ios::fmtflags(0) | std::ios::base(36)]");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{Ie}\": std::ios_base::event");
TEST ("[%{Ie}]", std::ios::erase_event, 0, 0, "[erase_event]");
TEST ("[%{Ie}]", std::ios::imbue_event, 0, 0, "[imbue_event]");
TEST ("[%{Ie}]", std::ios::copyfmt_event, 0, 0, "[copyfmt_event]");
TEST ("[%{Ie}]", 3, 0, 0, "[event(3)]");
TEST ("[%{Ie}]", 10, 0, 0, "[event(10)]");
TEST ("[%{#Ie}]", std::ios::erase_event, 0, 0,
"[std::ios::erase_event]");
TEST ("[%{#Ie}]", std::ios::imbue_event, 0, 0,
"[std::ios::imbue_event]");
TEST ("[%{#Ie}]", std::ios::copyfmt_event, 0, 0,
"[std::ios::copyfmt_event]");
TEST ("[%{#Ie}]", 3, 0, 0,
"[std::ios::event(3)]");
TEST ("[%{#Ie}]", 10, 0, 0,
"[std::ios::event(10)]");
}
/***********************************************************************/
static void
test_locale_category ()
{
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{Lc}\": locale category");
TEST ("[%{Lc}]", LC_ALL, 0, 0, "[LC_ALL]");
TEST ("[%{Lc}]", LC_COLLATE, 0, 0, "[LC_COLLATE]");
TEST ("[%{Lc}]", LC_CTYPE, 0, 0, "[LC_CTYPE]");
TEST ("[%{Lc}]", LC_MONETARY, 0, 0, "[LC_MONETARY]");
TEST ("[%{Lc}]", LC_NUMERIC, 0, 0, "[LC_NUMERIC]");
TEST ("[%{Lc}]", LC_TIME, 0, 0, "[LC_TIME]");
#ifdef LC_MESSAGES
TEST ("[%{Lc}]", LC_MESSAGES, 0, 0, "[LC_MESSAGES]");
#endif // LC_MESSAGES
TEST ("[%{Lc}]", std::locale::all, 0, 0, "[all]");
TEST ("[%{Lc}]", std::locale::none, 0, 0, "[none]");
TEST ("[%{Lc}]", std::locale::collate, 0, 0, "[collate]");
TEST ("[%{Lc}]", std::locale::ctype, 0, 0, "[ctype]");
TEST ("[%{Lc}]", std::locale::monetary, 0, 0, "[monetary]");
TEST ("[%{Lc}]", std::locale::numeric, 0, 0, "[numeric]");
TEST ("[%{Lc}]", std::locale::messages, 0, 0, "[messages]");
TEST ("[%{Lc}]", std::locale::time, 0, 0, "[time]");
TEST ("[%{#Lc}]", LC_ALL, 0, 0, "[LC_ALL]");
TEST ("[%{#Lc}]", LC_COLLATE, 0, 0, "[LC_COLLATE]");
TEST ("[%{#Lc}]", LC_CTYPE, 0, 0, "[LC_CTYPE]");
TEST ("[%{#Lc}]", LC_MONETARY, 0, 0, "[LC_MONETARY]");
TEST ("[%{#Lc}]", LC_NUMERIC, 0, 0, "[LC_NUMERIC]");
TEST ("[%{#Lc}]", LC_TIME, 0, 0, "[LC_TIME]");
#ifdef LC_MESSAGES
TEST ("[%{#Lc}]", LC_MESSAGES, 0, 0, "[LC_MESSAGES]");
#endif // LC_MESSAGES
TEST ("[%{#Lc}]", std::locale::all, 0, 0, "[std::locale::all]");
TEST ("[%{#Lc}]", std::locale::none, 0, 0, "[std::locale::none]");
TEST ("[%{#Lc}]", std::locale::collate, 0, 0, "[std::locale::collate]");
TEST ("[%{#Lc}]", std::locale::ctype, 0, 0, "[std::locale::ctype]");
TEST ("[%{#Lc}]", std::locale::monetary, 0, 0, "[std::locale::monetary]");
TEST ("[%{#Lc}]", std::locale::numeric, 0, 0, "[std::locale::numeric]");
TEST ("[%{#Lc}]", std::locale::messages, 0, 0, "[std::locale::messages]");
TEST ("[%{#Lc}]", std::locale::time, 0, 0, "[std::locale::time]");
}
/***********************************************************************/
static void
test_ctype_mask ()
{
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{LC}\": std::ctype_base::mask");
const int Alpha = std::ctype_base::alpha;
const int Alnum = std::ctype_base::alnum;
const int Cntrl = std::ctype_base::cntrl;
const int Digit = std::ctype_base::digit;
const int Graph = std::ctype_base::graph;
const int Lower = std::ctype_base::lower;
const int Print = std::ctype_base::print;
const int Punct = std::ctype_base::punct;
const int Space = std::ctype_base::space;
const int Xdigit = std::ctype_base::xdigit;
TEST ("[%{LC}]", Alpha, 0, 0, "[alpha]");
TEST ("[%{LC}]", Alnum, 0, 0, "[alnum]");
TEST ("[%{LC}]", Cntrl, 0, 0, "[cntrl]");
TEST ("[%{LC}]", Digit, 0, 0, "[digit]");
TEST ("[%{LC}]", Graph, 0, 0, "[graph]");
TEST ("[%{LC}]", Lower, 0, 0, "[lower]");
TEST ("[%{LC}]", Print, 0, 0, "[print]");
TEST ("[%{LC}]", Punct, 0, 0, "[punct]");
TEST ("[%{LC}]", Space, 0, 0, "[space]");
TEST ("[%{LC}]", Xdigit, 0, 0, "[xdigit]");
TEST ("[%{#LC}]", Alpha, 0, 0, "[std::ctype_base::alpha]");
TEST ("[%{#LC}]", Alnum, 0, 0, "[std::ctype_base::alnum]");
TEST ("[%{#LC}]", Cntrl, 0, 0, "[std::ctype_base::cntrl]");
TEST ("[%{#LC}]", Digit, 0, 0, "[std::ctype_base::digit]");
TEST ("[%{#LC}]", Graph, 0, 0, "[std::ctype_base::graph]");
TEST ("[%{#LC}]", Lower, 0, 0, "[std::ctype_base::lower]");
TEST ("[%{#LC}]", Print, 0, 0, "[std::ctype_base::print]");
TEST ("[%{#LC}]", Punct, 0, 0, "[std::ctype_base::punct]");
TEST ("[%{#LC}]", Space, 0, 0, "[std::ctype_base::space]");
TEST ("[%{#LC}]", Xdigit, 0, 0, "[std::ctype_base::xdigit]");
TEST ("[%{LC}]", Alpha | Cntrl, 0, 0, "[alpha | cntrl]");
TEST ("[%{LC}]", Cntrl | Digit, 0, 0, "[cntrl | digit]");
TEST ("[%{LC}]", Digit | Graph, 0, 0, "[digit | graph]");
TEST ("[%{LC}]", Graph | Lower, 0, 0, "[graph | lower]");
TEST ("[%{LC}]", Lower | Print, 0, 0, "[lower | print]");
TEST ("[%{LC}]", Print | Punct, 0, 0, "[print | punct]");
TEST ("[%{LC}]", Punct | Space, 0, 0, "[punct | space]");
}
/***********************************************************************/
static const char*
mkbitset (const char *str)
{
static char bitset [32];
memset (bitset, 0, sizeof bitset);
char *pbyte = bitset;
for (const char *pc = str; *pc; ++pc) {
const size_t bitno = size_t (pc - str);
if ((bitno & 15) == 8)
++pbyte;
const size_t binx = bitno & 7;
if ('0' == *pc)
*pbyte &= ~(1 << binx);
else if ('1' == *pc)
*pbyte |= 1 << binx;
else
RW_ASSERT (!"logic error: bit must be '0' or '1'");
RW_ASSERT (size_t (pbyte - bitset) < sizeof bitset);
}
return bitset;
}
static void
test_bitset ()
{
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{b}\": bitset");
#define BS(str) mkbitset (str)
TEST ("%{b}", 0, 0, 0, "(null)");
TEST ("%{.1b}", BS ("1"), 0, 0, "1");
TEST ("%{.2b}", BS ("1"), 0, 0, "10");
TEST ("%{.3b}", BS ("1"), 0, 0, "100");
TEST ("%{.3b}", BS ("101"), 0, 0, "101");
TEST ("%{.8b}", BS ("11111111"), 0, 0, "11111111");
TEST ("%{.16b}", BS ("0000000000000000"), 0, 0, "0000000000000000");
TEST ("%{.16b}", BS ("0000000000000001"), 0, 0, "0000000000000001");
TEST ("%{.16b}", BS ("0000000000000010"), 0, 0, "0000000000000010");
TEST ("%{.16b}", BS ("0000000000000100"), 0, 0, "0000000000000100");
TEST ("%{.16b}", BS ("0000000000001000"), 0, 0, "0000000000001000");
TEST ("%{.16b}", BS ("0000000000010000"), 0, 0, "0000000000010000");
TEST ("%{.16b}", BS ("0000000000100000"), 0, 0, "0000000000100000");
TEST ("%{.16b}", BS ("0000000001000000"), 0, 0, "0000000001000000");
TEST ("%{.16b}", BS ("0000000010000000"), 0, 0, "0000000010000000");
TEST ("%{.16b}", BS ("0000000100000000"), 0, 0, "0000000100000000");
TEST ("%{.16b}", BS ("0000001000000000"), 0, 0, "0000001000000000");
TEST ("%{.16b}", BS ("0000010000000000"), 0, 0, "0000010000000000");
TEST ("%{.16b}", BS ("0000100000000000"), 0, 0, "0000100000000000");
TEST ("%{.16b}", BS ("0001000000000000"), 0, 0, "0001000000000000");
TEST ("%{.16b}", BS ("0010000000000000"), 0, 0, "0010000000000000");
TEST ("%{.16b}", BS ("0100000000000000"), 0, 0, "0100000000000000");
TEST ("%{.16b}", BS ("1000000000000000"), 0, 0, "1000000000000000");
}
/***********************************************************************/
static void
test_dec (char spec)
{
const bool sgn = 'u' != spec;
// "%d", "%i" ////////////////////////////////////////////////////
printf ("\"%%%c\": %ssigned integer\n", spec, sgn ? "" : "un");
TEST_SPEC ("%", 0, 0, 0, "0");
TEST_SPEC ("%", 1, 0, 0, "1");
TEST_SPEC ("%", 2, 0, 0, "2");
TEST_SPEC ("%", 3, 0, 0, "3");
TEST_SPEC ("%", -1, 0, 0, sgn ? "-1" : "4294967295");
TEST_SPEC ("%", -2, 0, 0, sgn ? "-2" : "4294967294");
TEST_SPEC ("%", -3, 0, 0, sgn ? "-3" : "4294967293");
TEST_SPEC ("%+", 4, 0, 0, sgn ? "+4" : "4");
TEST_SPEC ("%+", 5, 0, 0, sgn ? "+5" : "5");
TEST_SPEC ("%+", 6, 0, 0, sgn ? "+6" : "6");
TEST_SPEC ("%+", -4, 0, 0, sgn ? "-4" : "4294967292");
TEST_SPEC ("%+", -5, 0, 0, sgn ? "-5" : "4294967291");
TEST_SPEC ("%+", -6, 0, 0, sgn ? "-6" : "4294967290");
TEST_SPEC ("%", 123, 0, 0, "123");
TEST_SPEC ("%", 2345, 0, 0, "2345");
TEST_SPEC ("%", 34567, 0, 0, "34567");
TEST_SPEC ("%", -124, 0, 0, sgn ? "-124" : "4294967172");
TEST_SPEC ("%", -2346, 0, 0, sgn ? "-2346" : "4294964950");
TEST_SPEC ("%", -34568, 0, 0, sgn ? "-34568" : "4294932728");
TEST_SPEC ("%", INT_MIN, 0, 0, 0);
TEST_SPEC ("%", INT_MAX, 0, 0, 0);
// exercise right justification
TEST_SPEC ("%0", 3140, 0, 0, "3140");
TEST_SPEC ("%1", 3141, 0, 0, "3141");
TEST_SPEC ("%2", 3142, 0, 0, "3142");
TEST_SPEC ("%3", 3143, 0, 0, "3143");
TEST_SPEC ("%4", 3144, 0, 0, "3144");
TEST_SPEC ("%5", 3145, 0, 0, " 3145");
TEST_SPEC ("%6", 3146, 0, 0, " 3146");
TEST_SPEC ("%7", 3147, 0, 0, " 3147");
TEST_SPEC ("%+8", 3148, 0, 0, sgn ? " +3148" : " 3148");
TEST_SPEC ("%9", -3149, 0, 0, sgn ? " -3149" : "4294964147");
// exercise left justification
TEST_SPEC ("%-0", 4140, 0, 0, "4140");
TEST_SPEC ("%-1", 4141, 0, 0, "4141");
TEST_SPEC ("%-2", 4142, 0, 0, "4142");
TEST_SPEC ("%-3", 4143, 0, 0, "4143");
TEST_SPEC ("%-4", 4144, 0, 0, "4144");
TEST_SPEC ("%-5", 4145, 0, 0, "4145 ");
TEST_SPEC ("%-6", 4146, 0, 0, "4146 ");
TEST_SPEC ("%-7", 4147, 0, 0, "4147 ");
TEST_SPEC ("%-8", -4148, 0, 0, sgn ? "-4148 " : "4294963148");
TEST_SPEC ("%+-9", 4149, 0, 0, sgn ? "+4149 " : "4149 ");
// exercise precision
TEST_SPEC ("%.0", 5670, 0, 0, "5670");
TEST_SPEC ("%.1", 5671, 0, 0, "5671");
TEST_SPEC ("%.2", 5672, 0, 0, "5672");
TEST_SPEC ("%.3", 5673, 0, 0, "5673");
TEST_SPEC ("%.4", 5674, 0, 0, "5674");
TEST_SPEC ("%.5", 5675, 0, 0, "05675");
TEST_SPEC ("%.6", 5676, 0, 0, "005676");
TEST_SPEC ("%.7", 5677, 0, 0, "0005677");
TEST_SPEC ("%.8", -5678, 0, 0, sgn ? "-00005678" : "4294961618");
TEST_SPEC ("%+.9", 5679, 0, 0, sgn ? "+000005679" : "000005679");
// exercise justification with precision
TEST_SPEC ("%3.0", 30, 0, 0, " 30");
TEST_SPEC ("%3.1", 31, 0, 0, " 31");
TEST_SPEC ("%3.2", 32, 0, 0, " 32");
TEST_SPEC ("%3.3", 33, 0, 0, "033");
TEST_SPEC ("%3.4", 34, 0, 0, "0034");
TEST_SPEC ("%3.5", 35, 0, 0, "00035");
TEST_SPEC ("%4.5", 45, 0, 0, "00045");
TEST_SPEC ("%5.5", 55, 0, 0, "00055");
TEST_SPEC ("%6.5", 65, 0, 0, " 00065");
TEST_SPEC ("%7.5", 75, 0, 0, " 00075");
TEST_SPEC ("%8.5", 85, 0, 0, " 00085");
TEST_SPEC ("%9.5", 95, 0, 0, " 00095");
TEST_SPEC ("%9.6", -96, 0, 0, sgn ? " -000096" : "4294967200");
TEST_SPEC ("%+9.7", 97, 0, 0, sgn ? " +0000097" : " 0000097");
TEST_SPEC ("%+-9.8", 98, 0, 0, sgn ? "+00000098" : "00000098 ");
TEST_SPEC ("%-+9.9", 99, 0, 0, sgn ? "+000000099" : "000000099");
// exercise edge cases
// 7.19.6.1 of ISO/IEC 9899:1999:
// The result of converting a zero value with a precision
// of zero is no characters.
TEST_SPEC ("%.0", 0, 0, 0, "");
TEST_SPEC ("%1.0", 0, 0, 0, " ");
TEST_SPEC ("%2.0", 0, 0, 0, " ");
TEST_SPEC ("%+3.0", 0, 0, 0, " ");
TEST_SPEC ("%-4.0", 0, 0, 0, " ");
// 7.19.6.1, p5 of ISO/IEC 9899:1999:
// A negative field width argument is taken as
// a - flag followed by a positive field width.
// A negative precision argument is taken as
// if the precision were omitted.
TEST_SPEC ("%*", 0, 0, 0, "0");
TEST_SPEC ("%*", 1, 1, 0, "1");
TEST_SPEC ("%*", 2, 2, 0, " 2");
TEST_SPEC ("%*", 3, 3, 0, " 3");
TEST_SPEC ("%*", -4, -4, 0, sgn ? "-4 " : "4294967292");
TEST_SPEC ("%-*", 5, 5, 0, "5 ");
TEST_SPEC ("%-*", -6, -6, 0, sgn ? "-6 " : "4294967290");
TEST_SPEC ("%*.*", 0, 0, 0, "");
TEST_SPEC ("%*.*", 1, 0, 0, " ");
TEST_SPEC ("%*.*", 2, 0, 0, " ");
TEST_SPEC ("%*.*", 2, 0, 1, " 1");
TEST_SPEC ("%*.*", 2, 1, 2, " 2");
TEST_SPEC ("%*.*", 2, 2, 2, "02");
TEST_SPEC ("%*.*", -3, 2, 3, "03 ");
TEST_SPEC ("%-*.*", -4, 2, -4, sgn ? "-04 " : "4294967292");
TEST_SPEC ("%-*.*", -4, -2, -4, sgn ? "-4 " : "4294967292");
// "%hhd", "%hhi", ///////////////////////////////////////////////
printf ("\"%%hh%c\": %ssigned char\n", spec, sgn ? "" : "un");
TEST_SPEC ("%hh", '\0', 0, 0, "0");
TEST_SPEC ("%hh", '\1', 0, 0, "1");
TEST_SPEC ("%hh", '\2', 0, 0, "2");
TEST_SPEC ("%hh", '\x7f', 0, 0, "127");
TEST_SPEC ("%hh", '\x80', 0, 0, sgn ? "-128" : "128");
TEST_SPEC ("%hh", '\xff', 0, 0, sgn ? "-1" : "255");
// "%hd", "%hi" //////////////////////////////////////////////////
printf ("\"%%h%c\": %ssigned short\n", spec, sgn ? "" : "un");
TEST_SPEC ("%h", short (0), 0, 0, "0");
TEST_SPEC ("%h", short (1), 0, 0, "1");
TEST_SPEC ("%h", short (2), 0, 0, "2");
TEST_SPEC ("%h", SHRT_MIN, 0, 0, 0);
TEST_SPEC ("%h", SHRT_MAX, 0, 0, 0);
// "%ld", "%li" //////////////////////////////////////////////////
printf ("\"%%l%c\": signed long\n", spec);
TEST_SPEC ("%l", 0L, 0, 0, "0");
TEST_SPEC ("%l", 1L, 0, 0, "1");
TEST_SPEC ("%l", 2L, 0, 0, "2");
TEST_SPEC ("%l", LONG_MAX, 0, 0, 0);
TEST_SPEC ("%l", -1L, 0, 0, 0);
TEST_SPEC ("%l", -2L, 0, 0, 0);
TEST_SPEC ("%l", LONG_MIN, 0, 0, 0);
#ifndef _RWSTD_NO_LONG_LONG
// "%lld", "%lli" ////////////////////////////////////////////////
printf ("\"%%ll%c\": signed long long\n", spec);
const _RWSTD_LONG_LONG llong_min = _RWSTD_LLONG_MIN;
const _RWSTD_LONG_LONG llong_max = _RWSTD_LLONG_MAX;
TEST_SPEC ("%ll", 0LL, 0, 0, "0");
TEST_SPEC ("%ll", 1LL, 0, 0, "1");
TEST_SPEC ("%ll", 12LL, 0, 0, "12");
TEST_SPEC ("%ll", 123LL, 0, 0, "123");
TEST_SPEC ("%ll", 1234LL, 0, 0, "1234");
TEST_SPEC ("%ll", 12345LL, 0, 0, "12345");
TEST_SPEC ("%ll", 123456LL, 0, 0, "123456");
TEST_SPEC ("%ll", 1234567LL, 0, 0, "1234567");
TEST_SPEC ("%ll", 12345678LL, 0, 0, "12345678");
TEST_SPEC ("%ll", 123456789LL, 0, 0, "123456789");
# if 4 == _RWSTD_LLONG_SIZE
// FIXME: exercise 32-bit negative long long
fprintf (stderr, "Warning: %s\n", "\"%lld\" not exercised "
"with negative values for %u-bit long long",
sizeof (RWSTD_LONG_LONG) * CHAR_BIT);
# elif 8 == _RWSTD_LLONG_SIZE
TEST_SPEC ("%ll", -1LL, 0, 0, sgn ? "-1" : "18446744073709551615");
TEST_SPEC ("%ll", -2LL, 0, 0, sgn ? "-2" : "18446744073709551614");
TEST_SPEC ("%ll", -3LL, 0, 0, sgn ? "-3" : "18446744073709551613");
TEST_SPEC ("%ll", llong_min, 0, 0,
sgn ? "-9223372036854775808" : "9223372036854775808");
TEST_SPEC ("%ll", llong_min + 1, 0, 0,
sgn ? "-9223372036854775807" : "9223372036854775809");
TEST_SPEC ("%ll", llong_min + 2, 0, 0,
sgn ? "-9223372036854775806" : "9223372036854775810");
TEST_SPEC ("%ll", llong_max, 0, 0, "9223372036854775807");
TEST_SPEC ("%ll", llong_max - 1, 0, 0, "9223372036854775806");
# endif
#else // if defined (_RWSTD_NO_LONG_LONG)
fprintf (stderr, "Warning: %s\n", "\"%lld\" not exercised");
#endif // _RWSTD_NO_LONG_LONG
}
/***********************************************************************/
static void
test_oct ()
{
printf ("%s\n", "\"%o\": octal integer");
TEST ("%o", 0, 0, 0, "0");
TEST ("%o", 1, 0, 0, "1");
TEST ("%o", 2, 0, 0, "2");
TEST ("%o", 3, 0, 0, "3");
TEST ("%o", 4, 0, 0, "4");
TEST ("%o", 5, 0, 0, "5");
TEST ("%o", 6, 0, 0, "6");
TEST ("%o", 7, 0, 0, "7");
TEST ("%o", 8, 0, 0, "10");
TEST ("%o", 9, 0, 0, "11");
TEST ("%o", 10, 0, 0, "12");
TEST ("%#o", 11, 0, 0, "013");
}
/***********************************************************************/
static void
test_hex (char spec)
{
printf ("\"%%%c\": hexadecimal integer\n", spec);
// exercise by comparing against libc sprintf()
TEST_SPEC ("%", 0, 0, 0, 0);
TEST_SPEC ("%", 1, 0, 0, 0);
TEST_SPEC ("%", 2, 0, 0, 0);
TEST_SPEC ("%", 3, 0, 0, 0);
TEST_SPEC ("%", 9, 0, 0, 0);
TEST_SPEC ("%", 10, 0, 0, 0);
TEST_SPEC ("%", 11, 0, 0, 0);
TEST_SPEC ("%", 12, 0, 0, 0);
TEST_SPEC ("%", 13, 0, 0, 0);
TEST_SPEC ("%", 14, 0, 0, 0);
TEST_SPEC ("%", 15, 0, 0, 0);
TEST_SPEC ("%", 123, 0, 0, 0);
TEST_SPEC ("%", 234, 0, 0, 0);
TEST_SPEC ("%", 345, 0, 0, 0);
TEST_SPEC ("%", -1, 0, 0, 0);
TEST_SPEC ("%", -2, 0, 0, 0);
TEST_SPEC ("%", -3, 0, 0, 0);
TEST_SPEC ("%", -4, 0, 0, 0);
TEST_SPEC ("%+", 0, 0, 0, 0);
TEST_SPEC ("%+", 1, 0, 0, 0);
TEST_SPEC ("%+", 2, 0, 0, 0);
TEST_SPEC ("%+", 3, 0, 0, 0);
TEST_SPEC ("%+", 4, 0, 0, 0);
TEST_SPEC ("%+", 5, 0, 0, 0);
TEST_SPEC ("%+", 6, 0, 0, 0);
TEST_SPEC ("%+", 15, 0, 0, 0);
TEST_SPEC ("%+", 16, 0, 0, 0);
TEST_SPEC ("%+", -1, 0, 0, 0);
TEST_SPEC ("%+", -2, 0, 0, 0);
TEST_SPEC ("%+", -3, 0, 0, 0);
TEST_SPEC ("%+", -4, 0, 0, 0);
TEST_SPEC ("%+", -5, 0, 0, 0);
TEST_SPEC ("%+", -6, 0, 0, 0);
TEST_SPEC ("%+", -15, 0, 0, 0);
TEST_SPEC ("%+", -16, 0, 0, 0);
TEST_SPEC ("%#", 0, 0, 0, "0");
TEST_SPEC ("%#", 1, 0, 0, 0);
TEST_SPEC ("%#", 20, 0, 0, 0);
TEST_SPEC ("%#", -30, 0, 0, 0);
TEST_SPEC ("%0", 0, 0, 0, "0");
TEST_SPEC ("%0", 2, 0, 0, 0);
TEST_SPEC ("%0", 21, 0, 0, 0);
TEST_SPEC ("%0", -32, 0, 0, 0);
// exercise right justification
TEST_SPEC ("%0", 1000, 0, 0, 0);
TEST_SPEC ("%1", 1001, 0, 0, 0);
TEST_SPEC ("%2", 1002, 0, 0, 0);
TEST_SPEC ("%3", 1003, 0, 0, 0);
TEST_SPEC ("%4", 1004, 0, 0, 0);
TEST_SPEC ("%5", 1005, 0, 0, 0);
TEST_SPEC ("%6", 1006, 0, 0, 0);
TEST_SPEC ("%7", 1007, 0, 0, 0);
TEST_SPEC ("%8", 1008, 0, 0, 0);
TEST_SPEC ("%9", 1009, 0, 0, 0);
TEST_SPEC ("%10", 1010, 0, 0, 0);
TEST_SPEC ("%11", -1011, 0, 0, 0);
TEST_SPEC ("%12", -1012, 0, 0, 0);
TEST_SPEC ("%13", -1013, 0, 0, 0);
TEST_SPEC ("%14", -1014, 0, 0, 0);
TEST_SPEC ("%15", -1015, 0, 0, 0);
TEST_SPEC ("%16", -1016, 0, 0, 0);
TEST_SPEC ("%17", -1017, 0, 0, 0);
TEST_SPEC ("%18", -1018, 0, 0, 0);
TEST_SPEC ("%19", -1019, 0, 0, 0);
TEST_SPEC ("%20", -1020, 0, 0, 0);
// exercise left justification
TEST_SPEC ("%-0", 2000, 0, 0, 0);
TEST_SPEC ("%-1", 2001, 0, 0, 0);
TEST_SPEC ("%-2", 2002, 0, 0, 0);
TEST_SPEC ("%-3", 2003, 0, 0, 0);
TEST_SPEC ("%-4", 2004, 0, 0, 0);
TEST_SPEC ("%-5", 2005, 0, 0, 0);
TEST_SPEC ("%-6", 2006, 0, 0, 0);
TEST_SPEC ("%-7", 2007, 0, 0, 0);
TEST_SPEC ("%-8", 2008, 0, 0, 0);
TEST_SPEC ("%-9", 2009, 0, 0, 0);
TEST_SPEC ("%-10", 2010, 0, 0, 0);
TEST_SPEC ("%-11", -2011, 0, 0, 0);
TEST_SPEC ("%-12", -2012, 0, 0, 0);
TEST_SPEC ("%-13", -2013, 0, 0, 0);
TEST_SPEC ("%-14", -2014, 0, 0, 0);
TEST_SPEC ("%-15", -2015, 0, 0, 0);
TEST_SPEC ("%-16", -2016, 0, 0, 0);
TEST_SPEC ("%-17", -2017, 0, 0, 0);
TEST_SPEC ("%-18", -2018, 0, 0, 0);
TEST_SPEC ("%-19", -2019, 0, 0, 0);
TEST_SPEC ("%-20", -2020, 0, 0, 0);
// exercise precision
TEST_SPEC ("%.0", 3000, 0, 0, 0);
TEST_SPEC ("%.1", 3001, 0, 0, 0);
TEST_SPEC ("%.2", 3002, 0, 0, 0);
TEST_SPEC ("%.3", 3003, 0, 0, 0);
TEST_SPEC ("%.4", 3004, 0, 0, 0);
TEST_SPEC ("%.5", 3005, 0, 0, 0);
TEST_SPEC ("%.6", 3006, 0, 0, 0);
TEST_SPEC ("%.7", 3007, 0, 0, 0);
TEST_SPEC ("%.8", 3008, 0, 0, 0);
TEST_SPEC ("%.9", 3009, 0, 0, 0);
TEST_SPEC ("%.10", 3010, 0, 0, 0);
TEST_SPEC ("%+.0", 4000, 0, 0, 0);
TEST_SPEC ("%+.1", 4001, 0, 0, 0);
TEST_SPEC ("%+.2", 4002, 0, 0, 0);
TEST_SPEC ("%+.3", 4003, 0, 0, 0);
TEST_SPEC ("%+.4", 4004, 0, 0, 0);
TEST_SPEC ("%+.5", 4005, 0, 0, 0);
TEST_SPEC ("%+.6", 4006, 0, 0, 0);
TEST_SPEC ("%+.7", 4007, 0, 0, 0);
TEST_SPEC ("%+.8", 4008, 0, 0, 0);
TEST_SPEC ("%+.9", 4009, 0, 0, 0);
TEST_SPEC ("%+.10", 4010, 0, 0, 0);
// exercise justification with precision
TEST_SPEC ("%+-.0", 5000, 0, 0, 0);
TEST_SPEC ("%+-.1", 5001, 0, 0, 0);
TEST_SPEC ("%+-.2", 5002, 0, 0, 0);
TEST_SPEC ("%+-.3", 5003, 0, 0, 0);
TEST_SPEC ("%+-.4", 5004, 0, 0, 0);
TEST_SPEC ("%+-.5", 5005, 0, 0, 0);
TEST_SPEC ("%+-.6", 5006, 0, 0, 0);
TEST_SPEC ("%+-.7", 5007, 0, 0, 0);
TEST_SPEC ("%+-.8", 5008, 0, 0, 0);
TEST_SPEC ("%+-.9", 5009, 0, 0, 0);
TEST_SPEC ("%+-.10", 5010, 0, 0, 0);
TEST_SPEC ("%-+.0", 5020, 0, 0, 0);
TEST_SPEC ("%-+.1", 5021, 0, 0, 0);
TEST_SPEC ("%-+.2", 5022, 0, 0, 0);
TEST_SPEC ("%-+.3", 5023, 0, 0, 0);
TEST_SPEC ("%-+.4", 5024, 0, 0, 0);
TEST_SPEC ("%-+.5", 5025, 0, 0, 0);
TEST_SPEC ("%-+.6", 5026, 0, 0, 0);
TEST_SPEC ("%-+.7", 5027, 0, 0, 0);
TEST_SPEC ("%-+.8", 5028, 0, 0, 0);
TEST_SPEC ("%-+.9", 5029, 0, 0, 0);
TEST_SPEC ("%-+.10", 5020, 0, 0, 0);
// exercise edge cases
// 7.19.6.1 of ISO/IEC 9899:1999:
// The result of converting a zero value with a precision
// of zero is no characters.
TEST_SPEC ("%.0", 0, 0, 0, "");
TEST_SPEC ("%1.0", 0, 0, 0, " ");
TEST_SPEC ("%2.0", 0, 0, 0, " ");
TEST_SPEC ("%+3.0", 0, 0, 0, " ");
TEST_SPEC ("%-4.0", 0, 0, 0, " ");
// 7.19.6.1, p5 of ISO/IEC 9899:1999:
// A negative field width argument is taken as
// a - flag followed by a positive field width.
// A negative precision argument is taken as
// if the precision were omitted.
TEST_SPEC ("%*", 0, 0, 0, 0);
TEST_SPEC ("%*", 1, 1, 0, 0);
TEST_SPEC ("%*", 2, 2, 0, 0);
TEST_SPEC ("%*", 3, 3, 0, 0);
TEST_SPEC ("%*", -4, -4, 0, 0);
TEST_SPEC ("%-*", 5, 5, 0, 0);
TEST_SPEC ("%-*", -6, -6, 0, 0);
TEST_SPEC ("%*.*", 0, 0, 0, 0);
TEST_SPEC ("%*.*", 1, 0, 0, 0);
TEST_SPEC ("%*.*", 2, 0, 0, 0);
TEST_SPEC ("%*.*", 2, 0, 1, 0);
TEST_SPEC ("%*.*", 2, 1, 2, 0);
TEST_SPEC ("%*.*", 2, 2, 2, 0);
TEST_SPEC ("%*.*", -3, 2, 3, 0);
TEST_SPEC ("%-*.*", -4, 2, -4, 0);
TEST_SPEC ("%-*.*", -4, -2, -4, 0);
// "%hhx", "%hhx", ///////////////////////////////////////////////
printf ("\"%%hh%c\": hexadecimal char\n", spec);
TEST_SPEC ("%hh", '\0', 0, 0, "0");
TEST_SPEC ("%hh", '\1', 0, 0, "1");
TEST_SPEC ("%hh", '\2', 0, 0, "2");
TEST_SPEC ("%hh", '\x7f', 0, 0, ('x' == spec ? "7f" : "7F"));
TEST_SPEC ("%hh", '\x80', 0, 0, "80");
TEST_SPEC ("%hh", '\xff', 0, 0, ('x' == spec ? "ff" : "FF"));
TEST_SPEC ("%#hh", '\0', 0, 0, "0");
TEST_SPEC ("%#hh", '\1', 0, 0, ('x' == spec ? "0x1" : "0X1"));
TEST_SPEC ("%#hh", '\2', 0, 0, ('x' == spec ? "0x2" : "0X2"));
TEST_SPEC ("%#hh", '\x7f', 0, 0, ('x' == spec ? "0x7f" : "0X7F"));
TEST_SPEC ("%#hh", '\x80', 0, 0, ('x' == spec ? "0x80" : "0X80"));
TEST_SPEC ("%#hh", '\xff', 0, 0, ('x' == spec ? "0xff" : "0XFF"));
// "%hx", "%hhX" /////////////////////////////////////////////////
printf ("\"%%h%c\": hexadecimal short\n", spec);
TEST_SPEC ("%h", short (0), 0, 0, "0");
TEST_SPEC ("%h", short (1), 0, 0, "1");
TEST_SPEC ("%h", short (2), 0, 0, "2");
TEST_SPEC ("%h", SHRT_MIN, 0, 0, 0);
TEST_SPEC ("%h", SHRT_MAX, 0, 0, 0);
}
/***********************************************************************/
static void
test_bool ()
{
printf ("%s\n", "extension: \"%b\": bool");
TEST ("%b", false, 0, 0, "false");
TEST ("%b", true, 0, 0, "true");
TEST ("%b", '\0', 0, 0, "false");
TEST ("%b", '\x01', 0, 0, "true");
TEST ("%b", '\x80', 0, 0, "true");
TEST ("%b", '\xff', 0, 0, "true");
TEST ("%b", 0, 0, 0, "false");
TEST ("%b", -1, 0, 0, "true");
TEST ("%b", +1, 0, 0, "true");
TEST ("%b", -2, 0, 0, "true");
TEST ("%b", +2, 0, 0, "true");
}
/***********************************************************************/
static void
test_integer ()
{
test_dec ('d');
test_dec ('i');
test_dec ('u');
test_oct ();
test_hex ('x');
test_hex ('X');
test_bool ();
}
/***********************************************************************/
void* make_array (int width, // element width in bytes
int a0 = 0, int a1 = 0, int a2 = 0, int a3 = 0,
int a4 = 0, int a5 = 0, int a6 = 0, int a7 = 0,
int a8 = 0, int a9 = 0, int a10 = 0, int a11 = 0,
int a12 = 0, int a13 = 0, int a14 = 0, int a15 = 0)
{
RW_ASSERT (8 == width || 4 == width || 2 == width || 1 == width);
#ifdef _RWSTD_INT64_T
typedef _RWSTD_UINT64_T ui64_t;
typedef _RWSTD_INT64_T i64_t;
#else
typedef _RWSTD_UINT32_T ui64_t;
typedef _RWSTD_INT32_T i64_t;
#endif
typedef _RWSTD_UINT32_T ui32_t;
typedef _RWSTD_INT32_T i32_t;
typedef _RWSTD_INT16_T ui16_t;
typedef _RWSTD_INT16_T i16_t;
typedef _RWSTD_INT8_T ui8_t;
typedef _RWSTD_INT8_T i8_t;
static union {
i64_t i64;
i32_t i32;
i16_t i16;
i8_t i8;
} array [17];
union {
i64_t* pi64;
i32_t* pi32;
i16_t* pi16;
i8_t* pi8;
} ptr = { &array [0].i64 };
#define ADD_ELEMENT(n) \
switch (width) { \
case 8 /* bytes */: *ptr.pi64++ = i64_t (a##n); break; \
case 4 /* bytes */: *ptr.pi32++ = i32_t (a##n); break; \
case 2 /* bytes */: *ptr.pi16++ = i16_t (a##n); break; \
case 1 /* byte */: *ptr.pi8++ = i8_t (a##n); break; \
} (void)0
ADD_ELEMENT ( 0); ADD_ELEMENT ( 1); ADD_ELEMENT ( 2); ADD_ELEMENT ( 3);
ADD_ELEMENT ( 4); ADD_ELEMENT ( 5); ADD_ELEMENT ( 6); ADD_ELEMENT ( 7);
ADD_ELEMENT ( 8); ADD_ELEMENT ( 9); ADD_ELEMENT (10); ADD_ELEMENT (11);
ADD_ELEMENT (12); ADD_ELEMENT (13); ADD_ELEMENT (14); ADD_ELEMENT (15);
// zero-terminate
const int a16 = 0;
ADD_ELEMENT (16);
return array;
}
static void
test_intarray ()
{
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{Ao}\": array of octal integers");
#define AR make_array
// null 1, 2, 4, and 8-byte integer arrays
TEST ("%{1Ao}", 0, 0, 0, "(null)");
TEST ("%{2Ao}", 0, 0, 0, "(null)");
TEST ("%{4Ao}", 0, 0, 0, "(null)");
#ifdef _RWSTD_INT64_T
TEST ("%{8Ao}", 0, 0, 0, "(null)");
#endif // _RWSTD_INT64_T
// 2-byte integer arrays
TEST ("%{2Ao}", AR (2, 0), 0, 0, "");
TEST ("%{2Ao}", AR (2, 1, 2), 0, 0, "1,2");
TEST ("%{2Ao}", AR (2, 2, 3, 4), 0, 0, "2,3,4");
TEST ("%{2Ao}", AR (2, 3, 4, 5, 6), 0, 0, "3,4,5,6");
TEST ("%{2Ao}", AR (2, 4, 5, 6, 7, 8), 0, 0, "4,5,6,7,10");
TEST ("%{*Ao}", 2, AR (2, 4, 5, 6, 7, 8), 0, "4,5,6,7,10");
TEST ("%{*.*Ao}", 2, 2, AR (2, 4, 0, 6, 0, 8), "4,0");
TEST ("%{*.*Ao}", 2, 3, AR (2, 4, 0, 6, 0, 8), "4,0,6");
TEST ("%{*.*Ao}", 2, 4, AR (2, 4, 0, 6, 0, 8), "4,0,6,0");
TEST ("%{*.*Ao}", 2, 5, AR (2, 4, 0, 6, 0, 8), "4,0,6,0,10");
// the pound flag alone has no affect on the '0' prefix
TEST ("%{#2Ao}", AR (2, 5, 6, 7, 8, 9), 0, 0, "5,6,7,10,11");
// zero and pound flags add the '0' prefix
TEST ("%{0#2Ao}", AR (2, 6, 7, 8, 9, 10), 0, 0, "06,07,010,011,012");
_RWSTD_INT8_T array8 [] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 /* terminate */
};
_RWSTD_INT16_T array16 [] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 /* terminate */
};
_RWSTD_INT32_T array32 [] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 /* terminate */
};
#ifdef _RWSTD_INT64_T
_RWSTD_INT64_T array64 [] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 /* terminate */
};
// set array element at index inx to value val
# define SET_ELEM(inx, val) \
RW_ASSERT (unsigned (inx) < array_size); \
array8 [inx] = val; array16 [inx] = val; \
array32 [inx] = val; array64 [inx] = val; \
array_str [inx * 2] = '0' + val
#else // if !defined (_RWSTD_INT64_T)
// set array element at index inx to value val
# define SET_ELEM(inx, val) \
RW_ASSERT (unsigned (inx) < array_size); \
array8 [inx] = val; array16 [inx] = val; \
array32 [inx] = val; \
array_str [inx * 2] = '0' + val
#endif // _RWSTD_INT64_T
const unsigned array_size = sizeof array16 / sizeof *array16;
char array_str [2 * array_size] = {
"1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,"
"1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1"
};
TEST ("%{1Ao}", array8, 0, 0, array_str);
TEST ("%{#1Ao}", array8, 0, 0, "{ 1 <repeats 32 times> }");
TEST ("%{2Ao}", array16, 0, 0, array_str);
TEST ("%{#2Ao}", array16, 0, 0, "{ 1 <repeats 32 times> }");
TEST ("%{4Ao}", array32, 0, 0, array_str);
TEST ("%{#4Ao}", array32, 0, 0, "{ 1 <repeats 32 times> }");
SET_ELEM (1, 2);
TEST ("%{2Ao}", array16, 0, 0, array_str);
TEST ("%{#2Ao}", array16, 0, 0, "{ 1,2,1 <repeats 30 times> }");
SET_ELEM ( 1, 1);
SET_ELEM (30, 2);
TEST ("%{2Ao}", array16, 0, 0, array_str);
TEST ("%{#2Ao}", array16, 0, 0, "{ 1 <repeats 30 times>,2,1 }");
SET_ELEM (30, 1);
SET_ELEM (31, 2);
TEST ("%{2Ao}", array16, 0, 0, array_str);
TEST ("%{#2Ao}", array16, 0, 0, "{ 1 <repeats 31 times>,2 }");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{Ad}\": array of decimal integers");
TEST ("%{4Ad}", AR (4, 0), 0, 0, "");
TEST ("%{4Ad}", AR (4, 20, 31), 0, 0, "20,31");
TEST ("%{4Ad}", AR (4, 21, 32, 43), 0, 0, "21,32,43");
TEST ("%{4Ad}", AR (4, 22, 33, 44, 55), 0, 0, "22,33,44,55");
TEST ("%{4Ad}", AR (4, 23, 34, 45, 56, 67), 0, 0, "23,34,45,56,67");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "extension: \"%{Ax}\": array of hexadecimal integers");
TEST ("%{4Ax}", AR (4, 0), 0, 0, "");
TEST ("%{4Ax}", AR (4, 0xa, 0xb), 0, 0, "a,b");
TEST ("%{4Ax}", AR (4, 0xb, 0xc, 0xd), 0, 0, "b,c,d");
TEST ("%{4Ax}", AR (4, 0xc, 0xd, 0xe, 0xf), 0, 0, "c,d,e,f");
TEST ("%{4Ax}", AR (4, 0xc9, 0xda, 0xeb, 0xfc), 0, 0, "c9,da,eb,fc");
TEST ("%{#4Ax}", AR (4, 0xd, 0xe, 0xa, 0xd), 0, 0, "d,e,a,d");
TEST ("%{0#4Ax}", AR (4, 0xb, 0xe, 0xe, 0xf), 0, 0, "0xb,0xe,0xe,0xf");
}
/***********************************************************************/
static void
test_floating ()
{
//////////////////////////////////////////////////////////////////
printf ("%s\n", "\"%e\": scientific floating point notation");
// double formatting
TEST ("%e", 0.0, 0, 0, "0.000000e+00");
TEST ("%e", 1.0, 0, 0, "1.000000e+00");
TEST ("%e", -1.0, 0, 0, "-1.000000e+00");
TEST ("%e", 10.0, 0, 0, "1.000000e+01");
TEST ("%e", -10.0, 0, 0, "-1.000000e+01");
TEST ("%e", 10.1, 0, 0, "1.010000e+01");
TEST ("%e", -10.1, 0, 0, "-1.010000e+01");
// long double formatting
TEST ("%Le", 0.0L, 0, 0, "0.000000e+00");
TEST ("%Le", 1.0L, 0, 0, "1.000000e+00");
TEST ("%Le", -1.0L, 0, 0, "-1.000000e+00");
TEST ("%Le", 10.0L, 0, 0, "1.000000e+01");
TEST ("%Le", -10.0L, 0, 0, "-1.000000e+01");
TEST ("%Le", 10.1L, 0, 0, "1.010000e+01");
TEST ("%Le", -10.1L, 0, 0, "-1.010000e+01");
TEST ("%Le", 1.1e+01L, 0, 0, "1.100000e+01");
TEST ("%Le", 1.2e+10L, 0, 0, "1.200000e+10");
TEST ("%Le", 1.3e+12L, 0, 0, "1.300000e+12");
#if 100 < _RWSTD_LDBL_MAX_10_EXP
// especially exercise the correct number of zeros in the exponent
// to verify that the function corrects MSVC's screwed up formatting
// without messing it up even more than it is (see PR #27946)
TEST ("%Le", 1.4e+100L, 0, 0, "1.400000e+100");
TEST ("%Le", 1.5e+120L, 0, 0, "1.500000e+120");
TEST ("%Le", 1.6e+123L, 0, 0, "1.600000e+123");
#endif
#if 1000 < _RWSTD_LDBL_MAX_10_EXP
TEST ("%Le", 1.7e+1000L, 0, 0, "1.700000e+1000");
TEST ("%Le", 1.8e+1200L, 0, 0, "1.800000e+1200");
TEST ("%Le", 1.9e+1230L, 0, 0, "1.900000e+1230");
TEST ("%Le", 2.0e+1234L, 0, 0, "2.000000e+1234");
#endif
//////////////////////////////////////////////////////////////////
printf ("%s\n", "\"%E\": scientific floating point notation");
fprintf (stderr, "Warning: %s\n", "\"%E\" not exercised");
//////////////////////////////////////////////////////////////////
printf ("%s\n", "\"%f\": fixed floating point notation");
fprintf (stderr, "Warning: %s\n", "\"%f\" not exercised"