| /************************************************************************ |
| * |
| * 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_printf.h> |
| #include <rw_process.h> // for rw_pid_t |
| #include <environ.h> // for rw_putenv() |
| |
| #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 <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 <locale.h> // for LC_ALL, ... |
| |
| |
| // 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}", -1, 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}", -1, 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; |
| const int good = std::ios_base::goodbit; |
| |
| 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"); |
|