first commit

This commit is contained in:
Jose Caban
2025-06-07 11:34:38 -04:00
commit 0eb2d7c07d
4708 changed files with 1500614 additions and 0 deletions

View File

@@ -0,0 +1,181 @@
/************************************************************************
*
* 0.alloc.cpp - test exercising the rw_alloc() and rw_free() functions
*
* $Id: 0.alloc.cpp 590052 2007-10-30 12:44:14Z faridz $
*
************************************************************************
*
* 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.
*
**************************************************************************/
#include <setjmp.h> // for setjmp, longjmp
#include <signal.h> // for signal
#include <stddef.h> // for size_t
#include <rw_alloc.h> // for rw_alloc, rw_free
#include <rw_printf.h> // for rw_printf
#include <driver.h>
static jmp_buf mark;
extern "C" {
static void
sig_handler (int)
{
longjmp (mark, -1);
}
}
// on Cygwin use setjmp
#if !defined (__CYGWIN__) && defined (sigsetjmp)
#define SETJMP(env) sigsetjmp (env, 1)
#else
#define SETJMP(env) setjmp (env)
#endif
#define BEGIN_TEST_OVERRUN() \
(signal (SIGSEGV, sig_handler), \
(0 == SETJMP (mark)))
struct TestCase
{
size_t size_;
int index_;
int prot_;
const char* file_;
int line_;
};
void test (const TestCase& tcase)
{
if (void* buf = rw_alloc (tcase.size_, tcase.prot_)) {
char* str = _RWSTD_STATIC_CAST (char*, buf);
bool protbelow = 0 != (tcase.prot_ & RW_PROT_BELOW);
bool isguardpage = (protbelow && 0 > tcase.index_)
|| (!protbelow && tcase.index_ >= int (tcase.size_));
bool canread = (tcase.prot_ & RW_PROT_READ) && !isguardpage;
bool canwrite = (tcase.prot_ & RW_PROT_WRITE) && !isguardpage;
char c = 'a';
// check read access only if:
// tcase.prot_ & RW_PROT_READ != 0
// tcase.prot_ == RW_PROT_NONE
// tcase.prot_ & RW_PROT_WRITE != 0 and the
// accessed memory is placed in the guard page
if (tcase.prot_ & RW_PROT_READ || !canwrite) {
if (BEGIN_TEST_OVERRUN ()) {
c = str[tcase.index_];
rw_assert (canread, tcase.file_, tcase.line_,
"expected no read access, got read access");
} else
rw_assert (!canread, tcase.file_, tcase.line_,
"expected read access, got no read access");
}
if (BEGIN_TEST_OVERRUN ()) {
str[tcase.index_] = c;
rw_assert (canwrite, tcase.file_, tcase.line_,
"expected no write access, got write access");
} else
rw_assert (!canwrite, tcase.file_, tcase.line_,
"expected write access, got no write access");
rw_free (buf);
}
}
static int
run_test (int, char**)
{
const size_t BUF_SIZE = 10;
static const TestCase tcases[] = {
#ifdef TEST
#undef TEST
#endif
#define TEST(size, index, prot) \
{ size, index, prot, __FILE__, __LINE__ }
TEST(BUF_SIZE, -1, RW_PROT_NONE),
TEST(BUF_SIZE, -1, RW_PROT_READ),
TEST(BUF_SIZE, -1, RW_PROT_WRITE),
TEST(BUF_SIZE, -1, RW_PROT_RDWR),
TEST(BUF_SIZE, -1, RW_PROT_NONE | RW_PROT_BELOW),
TEST(BUF_SIZE, -1, RW_PROT_READ | RW_PROT_BELOW),
TEST(BUF_SIZE, -1, RW_PROT_WRITE | RW_PROT_BELOW),
TEST(BUF_SIZE, -1, RW_PROT_RDWR | RW_PROT_BELOW),
TEST(BUF_SIZE, 0, RW_PROT_NONE),
TEST(BUF_SIZE, 0, RW_PROT_READ),
TEST(BUF_SIZE, 0, RW_PROT_WRITE),
TEST(BUF_SIZE, 0, RW_PROT_RDWR),
TEST(BUF_SIZE, 0, RW_PROT_NONE | RW_PROT_BELOW),
TEST(BUF_SIZE, 0, RW_PROT_READ | RW_PROT_BELOW),
TEST(BUF_SIZE, 0, RW_PROT_WRITE | RW_PROT_BELOW),
TEST(BUF_SIZE, 0, RW_PROT_RDWR | RW_PROT_BELOW),
TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_NONE),
TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_READ),
TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_WRITE),
TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_RDWR),
TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_NONE | RW_PROT_BELOW),
TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_READ | RW_PROT_BELOW),
TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_WRITE | RW_PROT_BELOW),
TEST(BUF_SIZE, BUF_SIZE - 1, RW_PROT_RDWR | RW_PROT_BELOW),
TEST(BUF_SIZE, BUF_SIZE, RW_PROT_NONE),
TEST(BUF_SIZE, BUF_SIZE, RW_PROT_READ),
TEST(BUF_SIZE, BUF_SIZE, RW_PROT_WRITE),
TEST(BUF_SIZE, BUF_SIZE, RW_PROT_RDWR),
TEST(BUF_SIZE, BUF_SIZE, RW_PROT_NONE | RW_PROT_BELOW),
TEST(BUF_SIZE, BUF_SIZE, RW_PROT_READ | RW_PROT_BELOW),
TEST(BUF_SIZE, BUF_SIZE, RW_PROT_WRITE | RW_PROT_BELOW),
TEST(BUF_SIZE, BUF_SIZE, RW_PROT_RDWR | RW_PROT_BELOW)
};
for (size_t i = 0; i < sizeof (tcases) / sizeof (tcases[0]); ++i)
test (tcases [i]);
return 0;
}
/***********************************************************************/
int main (int argc, char *argv[])
{
return rw_test (argc, argv, __FILE__,
"",
0,
run_test,
"",
(void*)0 /* sentinel */);
}

View File

@@ -0,0 +1,364 @@
/************************************************************************
*
* 0.braceexp.cpp - tests exercising the rw_brace_expand()
* and rw_shell_expand() helper functions
*
* $Id: 0.braceexp.cpp 648752 2008-04-16 17:01:56Z faridz $
*
************************************************************************
*
* 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.
*
**************************************************************************/
#include <rw_braceexp.h>
#include <environ.h> // for rw_putenv()
#include <stdio.h> // for fprintf(), size_t, stderr
#include <stdlib.h> // for free()
#include <string.h> // for strcmp()
// the number of failed tests
static int nerrors;
static void
test (int line, const char* brace_expr, size_t n, const char* expect,
const char* fname,
char* (fn)(const char*, size_t, char*, size_t, char))
{
char buf [128];
char* result = fn (brace_expr, n, buf, sizeof (buf), ' ');
const bool equal = (expect && result)
? !strcmp (expect, result)
: expect == result;
if (!equal) {
++nerrors;
fprintf (stderr,
"%d. %s(\"%s\", ...) failed. "
"expected \"%s\" got \"%s\"\n",
line, fname, brace_expr,
expect ? expect : "(null)",
result ? result : "(null)");
}
if (result != buf)
free (result);
}
#define DO_TEST(s,e,f) test (__LINE__, s, strlen (s), e, #f, f)
#define TEST_COMMON(fn) run_tests (#fn, fn)
static void
run_tests (const char* fname,
char* (fn)(const char*, size_t, char*, size_t, char))
{
#undef TEST
#define TEST(s,e) test (__LINE__, s, strlen (s), e, fname, fn)
// run our tests
TEST ("", "");
// test plain and escaped whitespace
TEST ("\\ ", " ");
TEST ("\\ \\ ", " ");
TEST ("\\ \\\t\\ ", " \t ");
TEST ("a\\ b", "a b");
TEST ("a b", "a b");
TEST ("a", "a");
TEST ("a\\b", "ab");
TEST ("{", 0);
TEST ("}", "}");
TEST ("{}", "");
TEST ("}{", 0);
TEST ("}{}", "}");
TEST ("}{}{", 0);
TEST ("{{", 0);
TEST ("}}", "}}");
TEST ("{0}" , "0");
TEST ("\\{0}", "{0}");
TEST ("{\\0}", "0");
TEST ("{0\\}", 0);
TEST ("{\\{}", "{");
TEST ("{\\}}", "}");
TEST ("a{0}", "a0");
TEST ("a{0}b", "a0b");
TEST ("a\\{0\\}b", "a{0}b");
TEST ("a\\{0,123,4\\}b", "a{0,123,4}b");
// extension: bash sequence expansion
TEST ("{0..a}", "0..a");
TEST ("{a..0}", "a..0");
TEST ("{0..0}", "0");
TEST ("{0..5}", "0 1 2 3 4 5");
TEST ("{4..2}", "4 3 2");
TEST ("{+5..6}", "5 6");
TEST ("{6..+7}", "6 7");
TEST ("{+7..+8}", "7 8");
TEST ("{11..21}", "11 12 13 14 15 16 17 18 19 20 21");
TEST ("{0001..0002}", "1 2");
TEST ("{-0001..0002}", "-1 0 1 2");
TEST ("{-3..-1}", "-3 -2 -1");
TEST ("{+3..-2}", "3 2 1 0 -1 -2");
TEST ("{-3..+2}", "-3 -2 -1 0 1 2");
TEST ("{a..g}", "a b c d e f g");
TEST ("{g..c}", "g f e d c");
TEST ("{A..G}", "A B C D E F G");
TEST ("{G..C}", "G F E D C");
TEST ("{AB..CD}", "AB..CD");
TEST ("{0..1}", "0 1");
TEST ("\\{0..1}", "{0..1}");
TEST ("{\\0..1}", "0..1");
TEST ("{0\\..1}", "0..1");
TEST ("{0.\\.1}", "0..1");
TEST ("{0..\\1}", "0..1");
TEST ("{0..1\\}", 0);
// list expansion
TEST ("{,}", "");
TEST ("{,", 0);
TEST ("a{,}", "a a");
TEST ("b{,", 0);
TEST ("{c,}", "c");
TEST ("{d,", 0);
TEST ("{,e}", "e"); // for 100% compatibility this should be " e"
TEST ("{,f", 0);
TEST ("{,}g", "g g");
TEST ("a{,}b", "ab ab");
TEST ("{,,}", "");
TEST ("a{,,}", "a a a");
TEST ("{b,,}", "b");
TEST ("{,c,}", "c");
TEST ("{,,d}", "d");
TEST ("{,,}e", "e e e");
TEST ("a{,,}b", "ab ab ab");
TEST ("{abc,def}", "abc def");
TEST ("{ab\\c,d\\ef}", "abc def");
TEST ("abc{d,e,f}", "abcd abce abcf");
TEST ("z{c,a{d..f}a,c}z", "zcz zadaz zaeaz zafaz zcz");
TEST ("z{c,a{d,e,f}a,c}z", "zcz zadaz zaeaz zafaz zcz");
TEST ("{abc,{,d,e,f,}}", "abc d e f");
TEST ("{abc,{,d,e,f,}}{x,y}", "abcx abcy x y dx dy ex ey fx fy x y");
TEST ("{abc,{,d\\,e\\,f,}}", "abc d,e,f");
// list expansion with embedded whitespace
TEST ("a{b\\ ,c}", "ab ac");
TEST ("a{b\\ \\ ,c\\ }", "ab ac ");
// series of list and sequence expansions
TEST ("A{0..3}", "A0 A1 A2 A3");
TEST ("A{0..2}{6..7}", "A06 A07 A16 A17 A26 A27");
TEST ("A{A}{0..3}", "AA0 AA1 AA2 AA3");
TEST ("A{0..3}{A}", "A0A A1A A2A A3A");
TEST ("{A,a}{I,i}{X,x}", "AIX AIx AiX Aix aIX aIx aiX aix");
// list expansion with nested sequence expansions
TEST ("A{0,{4..7}{,}}", "A0 A4 A4 A5 A5 A6 A6 A7 A7");
TEST ("a{1,3,x{5..9}y}b", "a1b a3b ax5yb ax6yb ax7yb ax8yb ax9yb");
// make absolutely sure that we don't treat ${ as an open brace.
// we must expand its contents if appropriate.
TEST ("a${b}c", "a${b}c");
TEST ("a{${b},c,d}e", "a${b}e ace ade");
TEST ("a{b,${c},d}e", "abe a${c}e ade");
TEST ("a{b,${c{1,2}},d}e", "abe a${c1}e a${c2}e ade");
// csh specific behavior, lists with single items are valid and
// expanded
TEST ("{s}", "s");
TEST ("{{s}}", "s");
TEST ("{{{s}}", 0);
TEST ("{s,t}", "s t");
TEST ("{{s,t}}", "s t");
TEST ("{{{{s,t}}}}", "s t");
// extension: bash sequence expansion with csh behavior
TEST ("{{-10..10}}",
"-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10");
TEST ("{{{-10..10}}}",
"-10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10");
// escaping nested braces
TEST ("\\{{{-3..3}}", "{-3 {-2 {-1 {0 {1 {2 {3");
TEST ("{\\{{-3..3}}", "{-3 {-2 {-1 {0 {1 {2 {3");
TEST ("{{\\{-3..3}}", "{-3..3");
TEST ("{{{-3..3\\}}}}", "-3..3}");
TEST ("{{{-3..3}\\}}}", "-3} -2} -1} 0} 1} 2} 3}");
TEST ("{{{-3..3}}\\}}", "-3} -2} -1} 0} 1} 2} 3}");
TEST ("{{{-3..3}}}\\}", "-3} -2} -1} 0} 1} 2} 3}");
// lifted from the bash-3.2 testsuite and modified to be consistent
// with expectations of the csh shell and our extensions.
TEST ("ff{c,b,a}", "ffc ffb ffa");
TEST ("f{d,e,f}g", "fdg feg ffg");
TEST ("{l,n,m}xyz", "lxyz nxyz mxyz");
TEST ("{abc\\,def}", "abc,def");
TEST ("{abc}", "abc");
TEST ("\\{a,b,c,d,e}", "{a,b,c,d,e}");
TEST ("{x,y,\\{a,b,c}}", "x} y} {a} b} c}");
TEST ("{x\\,y,\\{abc\\},trie}", "x,y {abc} trie");
TEST ("/usr/{ucb/{ex,edit},lib/{ex,how_ex}}",
"/usr/ucb/ex /usr/ucb/edit /usr/lib/ex /usr/lib/how_ex");
TEST ("{}", "");
TEST ("}", "}");
TEST ("{", 0);
TEST ("abcd{efgh", 0);
TEST ("{1..10}", "1 2 3 4 5 6 7 8 9 10");
TEST ("{{0..10},braces}", "0 1 2 3 4 5 6 7 8 9 10 braces");
TEST ("x{{0..10},braces}y",
"x0y x1y x2y x3y x4y x5y x6y x7y x8y x9y x10y xbracesy");
TEST ("{3..3}", "3");
TEST ("x{3..3}y", "x3y");
TEST ("{10..1}", "10 9 8 7 6 5 4 3 2 1");
TEST ("{10..1}y", "10y 9y 8y 7y 6y 5y 4y 3y 2y 1y");
TEST ("x{10..1}y", "x10y x9y x8y x7y x6y x5y x4y x3y x2y x1y");
TEST ("{a..f}", "a b c d e f");
TEST ("{f..a}", "f e d c b a");
TEST ("{f..f}", "f");
// mixes are incorrectly-formed brace expansions
TEST ("{1..f}", "1..f");
TEST ("{f..1}", "f..1");
// do negative numbers work?
TEST ("{-1..-10}", "-1 -2 -3 -4 -5 -6 -7 -8 -9 -10");
TEST ("{-20..0}",
"-20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 "
"-9 -8 -7 -6 -5 -4 -3 -2 -1 0");
TEST ("a-{b{d,e}}-c", "a-bd-c a-be-c");
TEST ("a-{bdef-{g,i}-c", 0);
}
static void
run_brace_expand_tests ()
{
#undef TEST
#define TEST(s,e) DO_TEST (s,e,rw_brace_expand)
TEST_COMMON (rw_brace_expand);
// rw_brace_expand does not do whitespace collapse.
TEST ("a {1,2} b", "a 1 b a 2 b");
TEST ("a\t\t{1,2}\t\tb", "a\t\t1\t\tb a\t\t2\t\tb");
// test whitespace
TEST (" ", " ");
TEST (" ", " ");
TEST (" \t", " \t");
TEST ("a b", "a b");
TEST (" a b ", " a b ");
TEST (" a{b,c}", " ab ac");
TEST ("a {b,c}", "a b a c");
TEST ("a{ b,c}", "a b ac");
TEST ("a{b ,c}", "ab ac");
TEST ("a{b, c}", "ab a c");
TEST ("a{b,c }", "ab ac ");
TEST ("a{b,c} ", "ab ac ");
TEST ("{ }", " ");
TEST ("{{ }}", " ");
TEST ("{{ }", 0); // brace mismatch
}
static void
run_shell_expand_tests ()
{
#undef TEST
#define TEST(s,e) DO_TEST (s,e,rw_shell_expand)
TEST_COMMON (rw_shell_expand);
// rw_shell_expand does whitespace collapse
TEST ("a {1,2} b", "a 1 2 b");
TEST ("a\t\t{1,2}\t\tb", "a 1 2 b");
// test whitespace
TEST (" ", "");
TEST (" ", "");
TEST (" \t", "");
TEST ("a b", "a b");
TEST (" a b ", "a b");
TEST (" a{b,c}", "ab ac");
TEST ("a {b,c}", "a b c");
TEST ("a{ b,c}", 0);
TEST ("a{b ,c}", 0);
TEST ("a{b, c}", 0);
TEST ("a{b,c }", 0);
TEST ("a{b,c} ", "ab ac");
TEST ("{ }", 0); // brace mismatch
TEST ("{{ }}", 0); // brace mismatch
TEST ("{{ }", 0); // brace mismatch
#if 0 // not implemented yet
// set the three variables
rw_putenv ("var=baz:varx=vx:vary=vy");
TEST ("foo{bar,${var}.}", "foobar foobaz.");
TEST ("foo{bar,${var}}", "foobar foobaz");
TEST ("${var}\"{x,y}", "bazx bazy");
TEST ("$var{x,y}", "vx vy");
TEST ("${var}{x,y}", "bazx bazy");
// unset all three variables
rw_putenv ("var=:varx=:vary=");
#endif // 0
}
int main ()
{
run_brace_expand_tests ();
run_shell_expand_tests ();
// return 0 on success, 1 on failure
return !(0 == nerrors);
}

1249
extern/stdcxx/4.2.1/tests/self/0.char.cpp vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,689 @@
/************************************************************************
*
* 0.cmdopts.cpp - test exercising the rw_runopts() and rw_setopts()
* utility functions
*
* $Id: 0.cmdopts.cpp 590052 2007-10-30 12:44:14Z faridz $
*
************************************************************************
*
* 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-2006 Rogue Wave Software.
*
**************************************************************************/
#include <cmdopt.h>
#include <stdio.h>
#include <string.h>
// global buffer containing the names of all callbacks (along with
// their arguments) called in response to each invocation to rw_runopts()
static char argstr [4096];
// the maximum number of callbacks to be invoked by a single call
// to rw_runopts()
#define MAXCALLBACKS 32
// the values to be returned by each callback
static int retvals [MAXCALLBACKS];
// the cumulative number of callback invocations
static size_t ncalls;
// the exit status of the whole test
static int exit_status;
// the current line number
static int current_line;
/**************************************************************************/
// prints its arguments in a human-readable form to buf
static int
pargs (char *buf, const char *funcname, int argc, char *argv [])
{
_RWSTD_ASSERT (0 != buf);
char* next = buf + strlen (buf);
if ('\0' != *buf) {
next [0] = ';';
next [1] = '\0';
++next;
}
if (funcname)
next += sprintf (next, "%s(%d,{", funcname, argc);
else
next += sprintf (next, "%d,{", argc);
for (int i = 0; i < argc; ++i) {
if (argv [i])
next += sprintf (next, "\"%s\"", argv [i]);
else {
strcpy (next, "(null)");
next += strlen (next);
}
if (i + 1 < argc) {
next [0] = ',';
next [1] = '\0';
++next;
}
}
next [0] = '}';
next [1] = ')';
next [2] = '\0';
// verify that the number of calls hasn't exceeded the size
// of the array of return values
_RWSTD_ASSERT (ncalls < MAXCALLBACKS);
return retvals [ncalls];
}
/**************************************************************************/
static int
callback_imp (const char *cbname, int argc, char *argv[])
{
const int status = pargs (argstr, cbname, argc, argv);
++ncalls;
return status;
}
static int
foo (int argc, char *argv[])
{
return callback_imp ("foo", argc, argv);
}
static int
bar (int argc, char *argv[])
{
return callback_imp ("bar", argc, argv);
}
static int
err (int argc, char *argv[])
{
return callback_imp ("ERR", argc, argv);
}
/**************************************************************************/
typedef int (cbfun_t)(int, char*[]);
static int opt_counts [4];
// hackery to allow passing int* and cbfun_t* in the same argument
static const union {
int *pint;
cbfun_t *pfun;
int ival;
} cntptrs [] = {
{ opt_counts + 0 },
{ opt_counts + 1 },
{ opt_counts + 2 },
{ opt_counts + 3 }
};
/**************************************************************************/
static void
test_opts (const char *expect,
int get_exp,
char *argv [],
int set_exp,
const char *argspec,
cbfun_t *f0,
cbfun_t *f1 = 0,
cbfun_t *f2 = 0,
cbfun_t *f3 = 0)
{
argstr [0] = '\0';
// reset all previously set options
rw_setopts (0, 0);
// set new options
const int set_res = rw_setopts (argspec, f0, f1, f2, f3);
if (set_res != set_exp) {
// convert function pointers to void pointers
// to avoid compiler error and warnings
union {
cbfun_t *pfun;
void *pvoid;
} uptr[] = {
{ f0 }, { f1 }, { f2 }, { f3 }
};
fprintf (stderr,
"line %d: rw_setopts (\"%s\", %p, %p, %p, %p) == %d, got %d\n",
current_line, argspec,
uptr [0].pvoid, uptr [1].pvoid, uptr [2].pvoid, uptr [3].pvoid,
set_exp, set_res);
exit_status = 1;
}
argstr [0] = '\0';
// compute the value of argc from argv
int argc = 0;
for (; argv [argc]; ++argc);
// reset the number of callback invocations
ncalls = 0;
// reset the option counters
memset (opt_counts, 0, sizeof opt_counts);
const int get_res = rw_runopts (argc, argv);
if (get_res != get_exp) {
static char tmp [4096];
tmp [0] = '\0';
pargs (tmp, 0, argc, argv);
fprintf (stderr,
"line %d: rw_runopts (%s) == %d, got %d\n",
current_line, tmp, get_exp, get_res);
exit_status = 1;
}
if (strchr (expect, '#')) {
// when the expected result string contains the pound sign,
// treat the arguments as pointers to integers as opposed
// to pointers to callback functions and format the actual
// result as a sequence of integers at the given addresses
if (f0 == cntptrs [0].pfun) {
sprintf (argstr + strlen (argstr),
"%s%d", *argstr ? "; #" : "#", opt_counts [0]);
if (f1 == cntptrs [1].pfun) {
sprintf (argstr + strlen (argstr),
",%d", opt_counts [1]);
if (f2 == cntptrs [2].pfun) {
sprintf (argstr + strlen (argstr),
",%d", opt_counts [2]);
if (f3 == cntptrs [3].pfun) {
sprintf (argstr + strlen (argstr),
",%d", opt_counts [3]);
}
}
}
}
}
if (strcmp (argstr, expect)) {
fprintf (stderr,
"line %d: \"%s\" != \"%s\"\n",
current_line, argstr, expect);
exit_status = 1;
}
}
/**************************************************************************/
static char**
mkargv (const char *s0,
const char *s1 = 0,
const char *s2 = 0,
const char *s3 = 0,
const char *s4 = 0,
const char *s5 = 0,
const char *s6 = 0,
const char *s7 = 0,
const char *s8 = 0,
const char *s9 = 0)
{
static char argbuf [10][1024];
static char* argv [10];
argv [0] = s0 ? strcpy (argbuf [0], s0) : 0;
argv [1] = s1 ? strcpy (argbuf [1], s1) : 0;
argv [2] = s2 ? strcpy (argbuf [2], s2) : 0;
argv [3] = s3 ? strcpy (argbuf [3], s3) : 0;
argv [4] = s4 ? strcpy (argbuf [4], s4) : 0;
argv [5] = s5 ? strcpy (argbuf [5], s5) : 0;
argv [6] = s6 ? strcpy (argbuf [6], s6) : 0;
argv [7] = s7 ? strcpy (argbuf [7], s7) : 0;
argv [8] = s8 ? strcpy (argbuf [8], s8) : 0;
argv [9] = s9 ? strcpy (argbuf [9], s9) : 0;
return argv;
}
/**************************************************************************/
// convenience macros for brevity
#define A mkargv
#define B bar
#define F foo
#define E err
#define C0 cntptrs [0].pfun
#define C1 cntptrs [1].pfun
#define C2 cntptrs [2].pfun
#define C3 cntptrs [3].pfun
#define N(n) make_arg (n)
#define T (current_line = __LINE__), test_opts
/**************************************************************************/
static void
test_unknown_options ()
{
// +--------- expected result string (formatted by callbacks)
// | +----- expected value returned from rw_runopts()
// | | +-- second argument to rw_runopts() (argv)
// | | |
// | | | +---------- expected rw_setopts() result
// | | | | +------- rw_setopts() first argument
// | | | | | +-- rw_setopts() callbacks...
// | | | | | |
// V V V V V V
T ("", 0, A (""), 0, "", 0);
// exercise setting up the "unknown option" handler
T ("", 0, A (""), 1, "-", 0);
T ("", 0, A (""), 1, "-", E);
// exercise invoking the "unknown option" handler
T ("ERR(1,{\"-x\"})", 0, A ("-x"), 2, "- f", E, F);
T ("ERR(2,{\"-x\",\"-y\"});"
"foo(1,{\"-y\"})", 0, A ("-x","-y"), 2, "- y", E, F);
retvals [0] = 1;
T ("ERR(2,{\"-x\",\"-y\"})", 1, A ("-x","-y"), 2, "- y", E, F);
retvals [0] = 0;
retvals [1] = 2;
T ("foo(2,{\"-x\",\"-y\"});"
"ERR(1,{\"-y\"})", 2, A ("-x","-y"), 2, "- x", E, F);
T ("foo(3,{\"-x\",\"-y\",\"-x\"});"
"ERR(2,{\"-y\",\"-x\"})", 2, A ("-x","-y", "-x"), 2, "- x", E, F);
retvals [1] = 0;
}
/**************************************************************************/
static void
test_counted_options ()
{
// exercise options with a counter instead of a callback
T ("#1", 0, A ("-b"), 1, "b#", C0);
T ("#1", 0, A ("--cc"), 1, "|-cc#", C0);
T ("#2", 0, A ("-d", "-d"), 1, "d#", C0);
T ("#2", 0, A ("-e", "--ee"), 1, "e|-ee#", C0);
T ("#3", 0, A ("-e", "-e", "-e"), 1, "e#", C0);
T ("#1,2", 0, A ("-f", "-g", "-g"), 2, "f# g#", C0, C1);
// exercise counted options with a numerical argument
T ("#0", 0, A ("--n=0"), 1, "|-n#", C0);
T ("#1", 0, A ("--n=1"), 1, "|-n#", C0);
T ("#1", 0, A ("--n=+1"), 1, "|-n#", C0);
T ("#-1", 0, A ("--n=-1"), 1, "|-n#", C0);
T ("#2", 0, A ("--n=+2"), 1, "|-n#", C0);
T ("#-2", 0, A ("--n=-2"), 1, "|-n#", C0);
T ("#12345", 0, A ("--n=+12345"), 1, "|-n#", C0);
T ("#-12346", 0, A ("--n=-12346"), 1, "|-n#", C0);
// exercise counted options with a restricted numerical argument
T ("#0", 0, A ("--n=0"), 1, "|-n#0", C0);
T ("#1", 0, A ("--n=1"), 1, "|-n#0", C0);
T ("#1", 0, A ("--n=1"), 1, "|-n#1", C0);
T ("#2", 0, A ("--n=2"), 1, "|-n#1", C0);
T ("#1", 0, A ("--n=+1"), 1, "|-n#+1", C0);
T ("#-1", 0, A ("--n=-1"), 1, "|-n#-1", C0);
T ("#0", 0, A ("--n=0"), 1, "|-n#-1", C0);
T ("#1", 0, A ("--n=1"), 1, "|-n#-1", C0);
T ("#123", 0, A ("--n=+123"), 1, "|-n#+123", C0);
T ("#124", 0, A ("--n=+124"), 1, "|-n#+123", C0);
T ("#-125", 0, A ("--n=-125"), 1, "|-n#-125", C0);
T ("#-126", 0, A ("--n=-126"), 1, "|-n#-127", C0);
T ("#0", 0, A ("--n=0"), 1, "|-n#0-1", C0);
T ("#1", 0, A ("--n=1"), 1, "|-n#0-1", C0);
T ("#0", 0, A ("--n=0"), 1, "|-n#-1-0", C0);
// same as above but with an out of range argument
T ("", 1, A ("--n=1"), 1, "|-n#-1-0", C0);
T ("", 1, A ("--n=-1"), 1, "|-n#0", C0);
T ("", 1, A ("--n=0"), 1, "|-n#1", C0);
T ("", 1, A ("--n=1"), 1, "|-n#2", C0);
T ("", 1, A ("--n=+2"), 1, "|-n#+3", C0);
T ("", 1, A ("--n=-1"), 1, "|-n#0-1", C0);
T ("", 1, A ("--n=+2"), 1, "|-n#0-1", C0);
T ("", 1, A ("--n=-11"), 1, "|-n#-10--5", C0);
T ("", 1, A ("--n=-4"), 1, "|-n#-10--5", C0);
T ("", 1, A ("--n=-11"), 1, "|-n#-1-1", C0);
T ("", 1, A ("--n=-1"), 1, "|-n#0-32", C0);
T ("", 1, A ("--n=33"), 1, "|-n#0-32", C0);
}
/**************************************************************************/
static void
test_tristate ()
{
// +-- expected result string
// | +-- expected return value from rw_getopts()
// | | +-- command line arguments
// | | | +-- number of directives
// | | | | +-- cmdopt specification
// | | | | | +-- counter
// | | | | | |
// V V V V V V
T ("#1", 0, A ("--enable-foo"), 1, "|-foo~", C0);
T ("#1", 0, A ("--use-foo"), 1, "|-foo~", C0);
T ("#1", 0, A ("--with-foo"), 1, "|-foo~", C0);
T ("#-1", 0, A ("--disable-foo"), 1, "|-foo~", C0);
T ("#-1", 0, A ("--no-foo"), 1, "|-foo~", C0);
T ("#-1", 0, A ("--without-foo"), 1, "|-foo~", C0);
// the same tristate can be repeated any number of times
T ("#1", 0, A ("--enable-foo", "--use-foo"), 1, "|-foo~", C0);
T ("#-1", 0, A ("--no-foo", "--without-foo"), 1, "|-foo~", C0);
// the last tristate wins
T ("#-1", 0, A ("--use-foo", "--no-foo"), 1, "|-foo~", C0);
T ("#1", 0, A ("--no-foo", "--use-foo"), 1, "|-foo~", C0);
//////////////////////////////////////////////////////////////////
// set bits using a bitmap
T ("#1", 0, A ("--enable-foo"), 1, "|-foo~:0", C0);
T ("#1", 0, A ("--enable-foo"), 1, "|-foo~:1", C0);
T ("#2", 0, A ("--enable-foo"), 1, "|-foo~:2", C0);
T ("#3", 0, A ("--enable-foo"), 1, "|-foo~:3", C0);
T ("#4", 0, A ("--enable-foo"), 1, "|-foo~:4", C0);
// unset bits using a bitmap
T ("#-2", 0, A ("--disable-foo"), 1, "|-foo~:1", C0);
T ("#-3", 0, A ("--disable-foo"), 1, "|-foo~:2", C0);
T ("#-4", 0, A ("--disable-foo"), 1, "|-foo~:3", C0);
T ("#-5", 0, A ("--disable-foo"), 1, "|-foo~:4", C0);
// set bits in word 2
T ("#0,1", 0, A ("--enable-bar"), 1, "|-bar~32:0", C0, C1);
T ("#0,1", 0, A ("--enable-bar"), 1, "|-bar~32:1", C0, C1);
T ("#0,2", 0, A ("--enable-bar"), 1, "|-bar~32:2", C0, C1);
T ("#0,3", 0, A ("--enable-bar"), 1, "|-bar~32:3", C0, C1);
T ("#0,4", 0, A ("--enable-bar"), 1, "|-bar~32:4", C0, C1);
// enable bits 0 through 4 in C0 one at a time
T ("#1", 0, A ("--with-0"), 4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
T ("#2", 0, A ("--with-1"), 4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
T ("#4", 0, A ("--with-2"), 4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
T ("#8", 0, A ("--with-3"), 4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
// enable multiple bits 0 through 4 in C0 simultaneously
T ("#3", 0, A ("--with-0", "--with-1"),
4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
T ("#7", 0, A ("--with-0", "--with-1", "--with-2"),
4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
T ("#15", 0, A ("--with-0", "--with-1", "--with-2", "--with-3"),
4, "|-0~0 |-1~1 |-2~2 |-3~3", C0, C0, C0, C0);
// specify bit value
T ("#1", 0, A ("--with-0"),
4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
T ("#2", 0, A ("--with-1"),
4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
T ("#4", 0, A ("--with-2"),
4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
T ("#8", 0, A ("--with-3"),
4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
T ("#3", 0, A ("--with-0", "--with-1"),
4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
T ("#7", 0, A ("--with-0", "--with-1", "--with-2"),
4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
T ("#15", 0, A ("--with-0", "--with-1", "--with-2", "--with-3"),
4, "|-0~0:1 |-1~1:1 |-2~2:1 |-3~3:1", C0, C0, C0, C0);
T ("#-1073741824",
0, A ("--enable-f30"),
3, "|-f30~30:3 |-f28~28:2 |-f26~26:2", C0, C0, C0);
T ("#-2147483648",
0, A ("--enable-f30"),
3, "|-f30~30:2 |-f28~28:2 |-f26~26:2", C0, C0, C0);
T ("#-1610612736",
0, A ("--enable-f30","--enable-f28"),
3, "|-f30~30:2 |-f28~28:2 |-f26~26:2", C0, C0, C0);
T ("#-1476395008",
0, A ("--enable-f30","--enable-f28","--enable-f26"),
3, "|-f30~30:2 |-f28~28:2 |-f26~26:2", C0, C0, C0);
}
/**************************************************************************/
static void
test_optional_argument ()
{
// exercise an option with an optional argument
T ("foo(1,{\"-a\"})", 0, A ("-a"), 1, "a:", F);
T ("foo(1,{\"-a\"})", 0, A ("-a"), 1, "a:", F);
T ("foo(2,{\"-a\",\"x\"})", 0, A ("-a", "x"), 1, "a:", F);
T ("foo(1,{\"-ay\"})", 0, A ("-ay"), 1, "a:", F);
T ("foo(1,{\"-axyz\"})", 0, A ("-axyz"), 1, "a:", F);
T ("foo(1,{\"--a\"})", 0, A ("--a"), 1, "|-a:", F);
T ("ERR(1,{\"--ab\"})", 0, A ("--ab"), 2, "- |-a:", E, F);
// exercise the processing of two optional command line options
T ("foo(2,{\"-a\",\"-b\"});"
"bar(1,{\"-b\"})",
0, A ("-a", "-b"), 2, "a: b", F, B);
T ("foo(3,{\"-a\",\"x\",\"-b\"});"
"bar(1,{\"-b\"})",
0, A ("-a", "x", "-b"), 2, "a: b", F, B);
// exercise optional restricted numeric argument
T ("foo(2,{\"-n\",\"0\"})", 0, A ("-n", "0"), 1, "n:0", F);
T ("foo(2,{\"-n\",\"+1\"})", 0, A ("-n", "+1"), 1, "n:1", F);
T ("foo(2,{\"-n\",\"+2\"})", 0, A ("-n", "+2"), 1, "n:+2", F);
T ("foo(2,{\"-n\",\"\\-2\"})", 0, A ("-n", "\\-2"), 1, "n:-3", F);
T ("foo(2,{\"-n\",\"\\-0\"})", 0, A ("-n", "\\-0"), 1, "n:-3-0", F);
}
/**************************************************************************/
static void
test_required_argument ()
{
// exercise the processing of an option with a required argument
// the equals sign missing
T ("ERR(1,{\"--a\"})", 0, A ("--a"), 2, "- |-a=", E, F);
// required argument empty
T ("foo(1,{\"--a=\"})", 0, A ("--a="), 1, "|-a=", F);
// required argument contains funky characters
T ("foo(1,{\"--a=1\"})", 0, A ("--a=1"), 1, "|-a=", F);
T ("foo(1,{\"--b=1-\"})", 0, A ("--b=1-"), 1, "|-b=", F);
T ("foo(1,{\"--c=-2\"})", 0, A ("--c=-2"), 1, "|-c=", F);
T ("foo(1,{\"--d=1-2\"})", 0, A ("--d=1-2"), 1, "|-d=", F);
T ("foo(1,{\"--e=-1=2\"})", 0, A ("--e=-1=2"), 1, "|-e=", F);
T ("foo(1,{\"--f=-1=-2\"})", 0, A ("--f=-1=-2"), 1, "|-f=", F);
T ("foo(1,{\"--g=2,3\"})", 0, A ("--g=2,3"), 1, "|-g=", F);
T ("foo(1,{\"--h=3:4\"})", 0, A ("--h=3:4"), 1, "|-h=", F);
T ("foo(1,{\"--i=\"j\"\"})", 0, A ("--i=\"j\""), 1, "|-i=", F);
// exercise restricted numeric argument
T ("foo(1,{\"--a=1\"})", 0, A ("--a=1"), 1, "|-a=0", F);
T ("foo(1,{\"--a=1\"})", 0, A ("--a=1"), 1, "|-a=1", F);
T ("foo(1,{\"--a=2\"})", 0, A ("--a=2"), 1, "|-a=2", F);
T ("foo(1,{\"--a=3\"})", 0, A ("--a=3"), 1, "|-a=3-4", F);
T ("foo(1,{\"--a=5\"})", 0, A ("--a=5"), 1, "|-a=4-5", F);
T ("", 1, A ("--a=1"), 1, "|-a=2", F);
T ("", 1, A ("--a=2"), 1, "|-a=0-1", F);
T ("", 1, A ("--a=-1"), 1, "|-a=1-2", F);
T ("", 1, A ("--a=+123"), 1, "|-a=+2-3", F);
}
/**************************************************************************/
static void
test_repeated_options ()
{
// exercise repeated options
// only the first occurrence of each command line option
// causes an invocation of the callback, all subsequent
// ones will be ignored by default
T ("foo(2,{\"-a\",\"-a\"})", 0, A ("-a", "-a"), 1, "a", F);
// unlimited number of invocations
T ("foo(2,{\"-a\",\"-a\"});"
"foo(1,{\"-a\"})",
0, A ("-a", "-a"), 1, "a@*", F);
// no invocation (option is disabled)
T ("", 0, A ("-a"), 1, "a@0", F);
T ("", 0, A ("-a", "-a"), 1, "a@0", F);
T ("bar(1,{\"-b\"})", 0, A ("-a", "-a", "-b"), 2, "a@0 b", F, B);
T ("bar(2,{\"-b\",\"-a\"})", 0, A ("-a", "-b", "-a"), 2, "a@0 b", F, B);
T ("bar(3,{\"-b\",\"-a\",\"-b\"})",
0, A ("-b", "-a", "-b"), 2, "b a@0", B, F);
T ("bar(4,{\"-b\",\"-a\",\"-b\",\"-a\"})",
0, A ("-b", "-a", "-b", "-a"), 2, "b a@0", B, F);
// at most one invocation (default)
T ("foo(2,{\"-a\",\"-a\"})", 0, A ("-a", "-a"), 1, "a@1", F);
T ("foo(2,{\"-a\",\"-a\"})", 0, A ("-a", "-a"), 1, "a@1", F);
// at most two invocations
T ("foo(2,{\"-a\",\"-a\"});"
"foo(1,{\"-a\"})",
0, A ("-a", "-a"), 1, "a@2", F);
T ("foo(3,{\"-a\",\"-a\",\"-a\"});"
"foo(2,{\"-a\",\"-a\"})",
0, A ("-a", "-a", "-a"), 1, "a@2", F);
// inverted option (callback invoked iff option is not specified)
T ("", 0, A ("-i"), 1, "i!", F);
T ("foo(0,{})", 0, A (""), 1, "i!", F);
T ("", 0, A ("--j"), 1, "i|-j!", F);
T ("foo(1,{\"-k\"});"
"foo(0,{})", 0, A ("-k"), 2, "k l!", F, F);
}
/**************************************************************************/
int main ()
{
// +--------- expected result string (formatted by callbacks)
// | +----- expected value returned from rw_runopts()
// | | +-- second argument to rw_runopts() (argv)
// | | |
// | | | +---------- expected rw_setopts() result
// | | | | +------- rw_setopts() first argument
// | | | | | +-- rw_setopts() callbacks...
// | | | | | |
// V V V V V V
T ("", 0, A (""), 0, "", 0);
T ("", 0, A ("a"), 0, "", 0);
T ("", 0, A ("a", "b"), 0, "", 0);
T ("", 0, A ("a", "b"), 0, "", 0);
T ("", 0, A (""), 1, "f", F);
T ("", 0, A ("a"), 1, "f", F);
T ("", 0, A ("a", "b"), 1, "f", F);
T ("", 0, A ("a", "b"), 1, "f", F);
T ("", 0, A ("a", "f"), 1, "f", F);
T ("", 0, A ("f", "f"), 1, "f", F);
// exercise short and/or long options
T ("foo(1,{\"-a\"})", 0, A ("-a"), 1, "a", F);
T ("foo(1,{\"--a\"})", 0, A ("--a"), 1, "|-a", F);
T ("foo(1,{\"-a\"})", 0, A ("-a"), 1, "a|-a", F);
T ("foo(1,{\"--a\"})", 0, A ("--a"), 1, "a|-a", F);
// exercise the handling of unknown options
test_unknown_options ();
// exercise the handling of options with a counter
// instead of a callback handler
test_counted_options ();
// exercise the handling of options with an optional argument
test_optional_argument ();
// exercise the handling of tristate options
test_tristate ();
// exercise the handling of options with a required argument
test_required_argument ();
// exercise the handling of repeated occurrences of the same option
test_repeated_options ();
// exercise callback errors
retvals [0] = 1;
T ("foo(2,{\"-a\",\"-b\"})",
retvals [0], A ("-a", "-b"), 2, "a b", F, B);
retvals [0] = 0;
retvals [1] = 2;
T ("foo(3,{\"-a\",\"-b\",\"-c\"});"
"bar(2,{\"-b\",\"-c\"})",
retvals [1], A ("-a", "-b", "-c"), 3, "a b c", F, B, E);
retvals [1] = 0;
return exit_status;
}

View File

@@ -0,0 +1,497 @@
/************************************************************************
*
* 0.ctype.cpp - test exercising the UserCtype helper class template
*
* $Id: 0.ctype.cpp 590052 2007-10-30 12:44:14Z faridz $
*
************************************************************************
*
* 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 2006 Rogue Wave Software.
*
**************************************************************************/
#include <rw_char.h> // for UserChar
#include <rw_ctype.h> // for UserCtype
#include <rw_printf.h> // for rw_printf
#include <driver.h>
#include <stdlib.h> // for free()
#include <string.h> // for memset(), size_t, strlen()
/***********************************************************************/
extern const char
cntrl[] = {
#if 'A' == 0x41 // ASCII
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f"
#elif 'A' == 0xc1 // EBCDIC
""
#endif
};
extern const std::size_t
n_cntrl = sizeof cntrl - 1;
extern const char
digits[] = "0123456789";
extern const std::size_t
n_digits = sizeof digits - 1;
extern const char
graph[] = "!\"#$%&\\()*+,-./0123456789:;<=>?@[]^_`{|}~";
extern const std::size_t
n_graph = sizeof graph - 1;
extern const char
lower[] = "abcdefghijklmnopqrstuvwxyz";
extern const std::size_t
n_lower = sizeof lower - 1;
extern const char
punct[] = "!#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~";
extern const std::size_t
n_punct = sizeof punct - 1;
extern const char
print[] = {
"!\"#$%&\\()*+,-./0123456789:;<=>?@[]^_`{|}~"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
};
extern const std::size_t
n_print = sizeof print - 1;
extern const char
spaces[] = " \t\v\f\r\n";
extern const std::size_t
n_spaces = sizeof spaces - 1;
extern const char
upper[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
extern const std::size_t
n_upper = sizeof upper - 1;
extern const char
xdigits[] = "0123456789ABCDEFabcdef";
extern const std::size_t
n_xdigits = sizeof xdigits - 1;
/***********************************************************************/
template <class charT>
void
test_id (charT*, const char *cname)
{
rw_info (0, 0, __LINE__, "UserCtype<%s>::id", cname);
std::locale::id* const pid_b = &std::ctype<charT>::id;
std::locale::id* const pid_d = &UserCtype<charT>::id;
rw_assert (pid_b == pid_d, 0, __LINE__,
"&ctype<%s>::id == &UserCtype<%1$s>::id "
"(%#p == %2$#p, got %#p)",
cname, pid_b, pid_d);
}
/***********************************************************************/
template <class charT>
void
test_is (charT*, const char *cname,
std::ctype_base::mask m,
const char *chars, std::size_t n_chars)
{
UserCtype<charT> ctp;
std::size_t n_calls = ctp.n_calls_ [ctp.mf_is];
std::size_t n_throws = ctp.n_throws_ [ctp.mf_is];
std::size_t expect_calls = 0;
std::size_t expect_throws = 0;
for (std::size_t i = 0; i != n_chars; ++i) {
const charT ch = make_char (chars [i], (charT*)0);
int result = -1;
#ifndef _RWSTD_NO_EXCEPTIONS
// let the first call call succeed and trigger an exception
// on the second call to UserCtype::is()
ctp.throw_at_calls_ [ctp.mf_is] =
ctp.n_calls_ [ctp.mf_is] + 2;
for (int j = 0; j != 2; ++j) {
if (1 < sizeof (charT)) {
// can only count UserCtype<charT>::is() calls when
// charT != char since there is no virtual do_is()
// in the char explicit specialization
++expect_calls;
}
else if (j) {
// cannot induce an exception out of UserCtype<char>::is()
// since there is no virtual do_is() in the specialization
break;
}
if (j)
++expect_throws;
int threw = 0;
try {
result = ctp.is (m, ch);
}
catch (...) {
threw = 1;
}
rw_assert (j == threw, 0, __LINE__,
"UserCtype<%s>::is(%{LC}, %{#c}) "
"%{?}unexpectedly threw%{:}failed to throw%{;}",
cname, m, ch, j == threw);
}
#else // if defined (_RWSTD_NO_EXCEPTIONS)
++expect_calls;
result = ctp.is (m, ch);
#endif // _RWSTD_NO_EXCEPTIONS
rw_assert (result, 0, __LINE__,
"UserCtype<%s>::is(%{LC}, %{#c}) == true",
cname, m, chars [i]);
}
n_calls = ctp.n_calls_ [ctp.mf_is] - n_calls;
rw_assert (expect_calls == n_calls, 0, __LINE__,
"expected %zu calls to UserCtype<%s>::is(%{LC}, char_type), "
"got %zu", expect_calls, cname, m, n_calls);
n_throws = ctp.n_throws_ [ctp.mf_is] - n_throws;
rw_assert (expect_throws == n_throws, 0, __LINE__,
"expected %zu exceptions thrown by UserCtype<%s>::is(%{LC}, "
"char_type), got %zu", expect_throws, cname, m, n_throws);
}
template <class charT>
void
test_is (charT*, const char *cname)
{
rw_info (0, 0, __LINE__, "UserCtype<%s>::is"
"(mask, char_type) const", cname);
//////////////////////////////////////////////////////////////////
// exercise default behavior
test_is ((charT*)0, cname, std::ctype_base::alnum, lower, n_lower);
test_is ((charT*)0, cname, std::ctype_base::alnum, upper, n_upper);
test_is ((charT*)0, cname, std::ctype_base::alnum, digits, n_digits);
test_is ((charT*)0, cname, std::ctype_base::alnum, xdigits, n_xdigits);
test_is ((charT*)0, cname, std::ctype_base::alpha, lower, n_lower);
test_is ((charT*)0, cname, std::ctype_base::alpha, upper, n_upper);
test_is ((charT*)0, cname, std::ctype_base::cntrl, cntrl, n_cntrl);
test_is ((charT*)0, cname, std::ctype_base::digit, digits, n_digits);
test_is ((charT*)0, cname, std::ctype_base::graph, graph, n_graph);
test_is ((charT*)0, cname, std::ctype_base::lower, lower, n_lower);
test_is ((charT*)0, cname, std::ctype_base::print, print, n_print);
test_is ((charT*)0, cname, std::ctype_base::punct, punct, n_punct);
test_is ((charT*)0, cname, std::ctype_base::space, spaces, n_spaces);
test_is ((charT*)0, cname, std::ctype_base::xdigit, xdigits, n_xdigits);
//////////////////////////////////////////////////////////////////
// exercise custom behavior
static const int chars[] = {
'0', '1', '2', '3', 'a', 'b', 'c',
0x100, 0x7fff, 0x8000, 0xffff,
#if 2 < _RWSTD_INT_SIZE
0x10000, 0x7fffffff, 0x80000000, 0xffffffff,
#else
0x1ff, 0x700, 0x8fff, 0xf000,
#endif
-1 // end of chars
};
static const int masks[] = {
/* '0' */ std::ctype_base::alpha,
/* '1' */ std::ctype_base::cntrl,
/* '2' */ std::ctype_base::digit,
/* '3' */ std::ctype_base::lower,
/* 'a' */ std::ctype_base::print,
/* 'b' */ std::ctype_base::punct,
/* 'c' */ std::ctype_base::space,
/* 0x100 */ std::ctype_base::upper,
/* 0x7fff */ std::ctype_base::xdigit,
/* 0x8000 */ std::ctype_base::alpha | std::ctype_base::cntrl,
/* 0xffff */ std::ctype_base::cntrl | std::ctype_base::digit,
/* 0x10000 */ std::ctype_base::digit | std::ctype_base::lower,
/* 0x7fffffff */ std::ctype_base::lower | std::ctype_base::print,
/* 0x80000000 */ std::ctype_base::print | std::ctype_base::punct,
/* 0xffffffff */ std::ctype_base::punct | std::ctype_base::space,
-1 // end of masks
};
static const int mask_all =
std::ctype_base::alpha
| std::ctype_base::cntrl
| std::ctype_base::digit
| std::ctype_base::lower
| std::ctype_base::print
| std::ctype_base::punct
| std::ctype_base::space
| std::ctype_base::upper
| std::ctype_base::xdigit;
const UserCtype<charT> cust (chars, masks);
for (std::size_t i = 0; 0 <= chars [i]; ++i) {
// FIXME: enable tests of characters greater than CHAR_MAX
if ( _RWSTD_UCHAR_MAX < std::size_t (chars [i])
/* && sizeof (char) == sizeof (charT) */) {
// when charT == char break out when the character
// value is greater than CHAR_MAX
break;
}
const charT ch = make_char (chars [i], (charT*)0);
const std::ctype_base::mask m_is =
std::ctype_base::mask (masks [i]);
rw_assert (cust.is (m_is, ch),
0, __LINE__,
"UserCtype<%s>::is(%{LC}, %{#lc}) == true",
cname, m_is, chars [i]);
const std::ctype_base::mask m_not =
std::ctype_base::mask (~m_is & mask_all);
rw_assert (!cust.is (m_not, ch), 0, __LINE__,
"UserCtype<%s>::is(%{LC}, %{#lc}) == false",
cname, m_not, chars [i]);
}
}
/***********************************************************************/
template <class charT>
void
test_scan_is (charT*, const char *cname)
{
rw_info (0, 0, __LINE__, "UserCtype<%s>::scan_is"
"(mask, const char_type*, const char_type*) const", cname);
rw_warn (0, 0, __LINE__, "UserCtype<%s>::scan_is"
"(mask, const char_type*, const char_type*) const"
" not exercised", cname);
}
/***********************************************************************/
template <class charT>
void
test_scan_not (charT*, const char *cname)
{
rw_info (0, 0, __LINE__, "UserCtype<%s>::scan_not"
"(mask, const char_type*, const char_type*) const", cname);
rw_warn (0, 0, __LINE__, "UserCtype<%s>::scan_not"
"(mask, const char_type*, const char_type*) const "
"not exercised", cname);
}
/***********************************************************************/
template <class charT>
void
test_toupper (charT*, const char *cname)
{
rw_info (0, 0, __LINE__, "UserCtype<%s>::toupper"
"(char_type) const", cname);
rw_warn (0, 0, __LINE__, "UserCtype<%s>::toupper"
"(char_type) const not exercised", cname);
rw_info (0, 0, __LINE__, "UserCtype<%s>::toupper"
"(char_type*, const char_type) const", cname);
rw_warn (0, 0, __LINE__, "UserCtype<%s>::toupper"
"(char_type*, const char_type) const not exercised", cname);
}
/***********************************************************************/
template <class charT>
void
test_tolower (charT*, const char *cname)
{
rw_info (0, 0, __LINE__, "UserCtype<%s>::tolower"
"(char_type) const", cname);
rw_warn (0, 0, __LINE__, "UserCtype<%s>::tolower"
"(char_type) const not exercised", cname);
rw_info (0, 0, __LINE__, "UserCtype<%s>::tolower"
"(char_type*, const char_type) const", cname);
rw_warn (0, 0, __LINE__, "UserCtype<%s>::tolower"
"(char_type*, const char_type) const not exercised", cname);
}
/***********************************************************************/
template <class charT>
void
test_widen (charT*, const char *cname)
{
rw_info (0, 0, __LINE__, "UserCtype<%s>::widen"
"(char) const", cname);
rw_warn (0, 0, __LINE__, "UserCtype<%s>::widen"
"(char) const not exercised", cname);
rw_info (0, 0, __LINE__, "UserCtype<%s>::widen"
"(const char*, const char*, char_type*) const", cname);
rw_warn (0, 0, __LINE__, "UserCtype<%s>::widen"
"(const char*, const char*, char_type*) const not exercised",
cname);
}
/***********************************************************************/
template <class charT>
void
test_narrow (charT*, const char *cname)
{
rw_info (0, 0, __LINE__, "UserCtype<%s>::narrow"
"(char_type, char) const", cname);
rw_warn (0, 0, __LINE__, "UserCtype<%s>::narrow"
"(char_type, char) const not exercised", cname);
rw_info (0, 0, __LINE__, "UserCtype<%s>::narrow"
"(const char_type*, const char_type*, char, char*) const",
cname);
rw_warn (0, 0, __LINE__, "UserCtype<%s>::narrow"
"(const char_type*, const char_type*, char, char*) const"
" not exercised",
cname);
}
/***********************************************************************/
/* extern */ int opt_id;
/* extern */ int opt_is;
/* extern */ int opt_scan_is;
/* extern */ int opt_scan_not;
/* extern */ int opt_toupper;
/* extern */ int opt_tolower;
/* extern */ int opt_widen;
/* extern */ int opt_narrow;
template <class charT>
void
test (charT*, const char *cname)
{
#define TEST(func) \
if (0 <= opt_ ## func) \
test_ ## func ((charT*)0, cname); \
else \
rw_note (0, 0, __LINE__, \
"UserCtype<%s>::%s() tests disabled", \
cname, # func)
TEST (id);
TEST (is);
TEST (scan_is);
TEST (scan_not);
TEST (toupper);
TEST (tolower);
TEST (widen);
TEST (narrow);
}
/***********************************************************************/
static int
run_test (int, char**)
{
test ((char*)0, "char");
#ifndef _RWSTD_NO_WCHAR_T
test ((wchar_t*)0, "wchar_t");
#endif // _RWSTD_NO_WCHAR_T
test ((UserChar*)0, "UserChar");
return 0;
}
/***********************************************************************/
int main (int argc, char *argv[])
{
return rw_test (argc, argv, __FILE__,
"",
0,
run_test,
"|-id~ "
"|-is~ "
"|-scan_is~ "
"|-scan_not~ "
"|-toupper~ "
"|-tolower~ "
"|-widen~ "
"|-narrow~ ",
&opt_id,
&opt_is,
&opt_scan_is,
&opt_scan_not,
&opt_toupper,
&opt_tolower,
&opt_widen,
&opt_narrow,
(void*)0 /* sentinel */);
}

View File

@@ -0,0 +1,453 @@
/************************************************************************
*
* 0.fnmatch.cpp - tests exercising the rw_fnmatch() helper function
*
* $Id: 0.fnmatch.cpp 648752 2008-04-16 17:01:56Z faridz $
*
************************************************************************
*
* 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.
*
**************************************************************************/
#include <rw_fnmatch.h> // for rw_fnmatch()
#include <stdio.h> // for fprintf(), stderr
#ifdef _RWSTD_OS_LINUX
# include <fnmatch.h> // for fnmatch()
# define FNMATCH(pat, str, arg) fnmatch (pat, str, arg)
#endif // _RWSTD_OS_LINUX
// the number of failed tests
static int nerrors;
static void
test (int line, int exp, const char *pat, const char *str)
{
const int result = rw_fnmatch (pat, str, 0);
#ifdef FNMATCH
const int native = FNMATCH (pat, str, 0);
#else // if !defined (FNMATCH)
const int native = exp;
#endif // FNMATCH
if (result != native || -1 < exp && result != exp) {
++nerrors;
fprintf (stderr,
"%d. rw_fnmatch(\"%s\", \"%s\", 0) ==> %d, "
"expected (native:own) %d:%d\n",
line, pat, str, result, native, exp);
}
}
int main ()
{
#define TEST(exp, pat, str) test (__LINE__, exp, pat, str)
TEST (0, "", "");
TEST (1, "", "a");
TEST (1, "a", "");
TEST (0, "a", "a");
TEST (1, "a", "b");
TEST (0, "ab", "ab");
TEST (1, "ab", "ac");
TEST (0, "abc", "abc");
TEST (1, "xbc", "abc");
TEST (1, "ayc", "abc");
TEST (1, "abz", "abc");
// exercise escaped characters
TEST (1, "\\a", "");
TEST (0, "\\a", "a");
TEST (1, "\\a", "\\a");
TEST (1, "\\\\", "");
TEST (0, "\\\\", "\\");
TEST (1, "\\?", "\\a");
TEST (0, "\\?", "?");
TEST (1, "\\?", "\\?");
TEST (0, "\\[", "[");
TEST (1, "\\[", "\\[");
TEST (0, "\\[a", "[a");
TEST (0, "\\[a]", "[a]");
TEST (0, "\\[a\\]", "[a]");
TEST (0, "\\[\\a\\]", "[a]");
// exercise the question mark pattern
TEST (1, "?", "");
TEST (0, "?", "a");
TEST (1, "?", "ab");
TEST (1, "\\?", "");
TEST (1, "\\?", "a");
TEST (0, "\\?", "?");
TEST (0, "a?", "ad");
TEST (0, "?b", "ab");
TEST (1, "?b", "ac");
TEST (0, "??", "ae");
TEST (1, "??", "aef");
TEST (0, "?bc", "abc");
TEST (0, "a?c", "abc");
TEST (0, "ab?", "abc");
TEST (0, "??c", "abc");
TEST (0, "a??", "abc");
TEST (0, "?b?", "abc");
TEST (1, "??c", "abz");
TEST (1, "a??", "xbc");
TEST (1, "?b?", "ayc");
TEST (0, "???", "abc");
TEST (1, "???", "ab");
TEST (1, "???", "abcd");
// exercise the asterisk pattern
TEST (0, "*", "");
TEST (0, "*", "a");
TEST (0, "*", "ab");
TEST (0, "*", "abc");
TEST (1, "\\*", "");
TEST (1, "\\*", "a");
TEST (0, "\\*", "*");
TEST (1, "\\*", "ab");
TEST (1, "\\*", "abc");
TEST (0, "**", "");
TEST (0, "**", "a");
TEST (0, "**", "ab");
TEST (0, "**", "abc");
TEST (1, "*\\*", "");
TEST (1, "*\\*", "a");
TEST (0, "*\\*", "a*");
TEST (0, "*\\*", "ab*");
TEST (1, "a*", "");
TEST (0, "a*", "a");
TEST (0, "a*", "ab");
TEST (0, "a*", "abc");
TEST (1, "a**", "");
TEST (0, "a**", "a");
TEST (0, "a**", "ab");
TEST (0, "a**", "abc");
TEST (1, "**c", "");
TEST (1, "**c", "a");
TEST (1, "**c", "ab");
TEST (0, "**c", "abc");
TEST (1, "**c", "abcd");
TEST (1, "a*z", "");
TEST (1, "a*z", "a");
TEST (1, "a*z", "ab");
TEST (1, "a*z", "abc");
TEST (0, "a*z", "abcz");
TEST (0, "a*z", "abcdz");
TEST (0, "a*z", "abcdez");
TEST (1, "ab*z", "");
TEST (1, "ab*z", "a");
TEST (1, "ab*z", "ab");
TEST (1, "ab*z", "abc");
TEST (0, "ab*z", "abcz");
TEST (0, "ab*z", "abcdz");
TEST (0, "ab*z", "abcdez");
TEST (1, "a*yz", "");
TEST (1, "a*yz", "a");
TEST (1, "a*yz", "ab");
TEST (1, "a*yz", "abc");
TEST (1, "a*yz", "abcz");
TEST (0, "a*yz", "abcyz");
TEST (0, "a*yz", "abcdyz");
TEST (1, "ab*yz", "");
TEST (1, "ab*yz", "a");
TEST (1, "ab*yz", "ab");
TEST (1, "ab*yz", "abc");
TEST (1, "ab*yz", "abcz");
TEST (0, "ab*yz", "abcyz");
TEST (0, "ab*yz", "abcdyz");
TEST (0, "ab*yz", "abcdeyz");
TEST (1, "ab*x*z", "");
TEST (1, "ab*x*z", "a");
TEST (1, "ab*x*z", "ab");
TEST (1, "ab*x*z", "abc");
TEST (1, "ab*x*z", "abcz");
TEST (1, "ab*x*z", "abcyz");
TEST (0, "ab*x*z", "abcxyz");
TEST (0, "ab*x*z", "abcxxyz");
TEST (0, "ab*x*z", "abcxyyz");
TEST (1, "*b*x*z", "");
TEST (1, "*b*x*z", "a");
TEST (1, "*b*x*z", "ab");
TEST (1, "*b*x*z", "abc");
TEST (1, "*b*x*z", "abcz");
TEST (1, "*b*x*z", "abcyz");
TEST (0, "*b*x*z", "bcxyz");
TEST (0, "*b*x*z", "abcxyz");
TEST (0, "*b*x*z", "aabcxyz");
TEST (0, "*b*x*z", "abcxxyz");
TEST (0, "*b*x*z", "abcxyyz");
TEST (1, "abc*klm*xyz", "");
TEST (1, "abc*klm*xyz", "a");
TEST (1, "abc*klm*xyz", "ak");
TEST (1, "abc*klm*xyz", "akx");
TEST (1, "abc*klm*xyz", "abkx");
TEST (1, "abc*klm*xyz", "abklx");
TEST (1, "abc*klm*xyz", "abklxy");
TEST (1, "abc*klm*xyz", "abcklxy");
TEST (1, "abc*klm*xyz", "abcklmxy");
TEST (0, "abc*klm*xyz", "abcklmxyz");
TEST (0, "abc*klm*xyz", "abcdklmxyz");
TEST (0, "abc*klm*xyz", "abcdklmnxyz");
// exercise simple bracket expressions
TEST (1, "[a]", "");
TEST (0, "[a]", "a");
TEST (1, "[a]", "b");
TEST (1, "[?]", "c");
TEST (0, "[?]", "?");
TEST (1, "[-]", "d");
TEST (0, "[-]", "-");
TEST (1, "[]]", "e");
TEST (0, "[]]", "]");
TEST (1, "[\\]]", "f");
TEST (1, "[\\]]", "\\");
TEST (0, "[\\]]", "]");
TEST (1, "[\\!a]", "");
TEST (0, "[\\!a]", "a");
TEST (1, "[\\!a]", "b");
TEST (0, "[\\!?]", "!");
TEST (0, "[\\!?]", "?");
TEST (0, "[\\!-]", "-");
TEST (0, "[\\!!]", "!");
TEST (0, "[\\\\!]", "\\");
TEST (1, "[ab]", "");
TEST (0, "[ab]", "a");
TEST (0, "[ab]", "b");
TEST (1, "[ab]", "c");
TEST (1, "[a]b", "");
TEST (1, "[a]b", "a");
TEST (0, "[a]b", "ab");
TEST (1, "[a]b", "b");
TEST (1, "a[b]", "");
TEST (1, "a[b]", "a");
TEST (0, "a[b]", "ab");
TEST (1, "a[b]", "b");
TEST (1, "a[bc]", "");
TEST (1, "a[bc]", "a");
TEST (0, "a[bc]", "ab");
TEST (0, "a[bc]", "ac");
TEST (1, "a[bc]", "abc");
TEST (1, "a[\\]]", "ab");
TEST (0, "a[\\]]", "a]");
TEST (1, "[abc]", "");
TEST (0, "[abc]", "a");
TEST (0, "[abc]", "b");
TEST (0, "[abc]", "c");
TEST (1, "[abc]", "ab");
TEST (1, "[abc]", "ac");
TEST (1, "[abc]", "abc");
// exercise negated bracket expressions
TEST (1, "[!a]", "");
TEST (1, "[!a]", "a");
TEST (0, "[!a]", "b");
TEST (1, "[!?]", "?");
TEST (0, "[!?]", "c");
TEST (1, "[!-]", "-");
TEST (0, "[!-]", "d");
TEST (1, "[!!]", "!");
TEST (0, "[!!]", "e");
TEST (1, "[!ab]", "");
TEST (1, "[!ab]", "a");
TEST (1, "[!ab]", "b");
TEST (0, "[!ab]", "c");
TEST (1, "[!a]b", "");
TEST (1, "[!a]b", "a");
TEST (1, "[!a]b", "ab");
TEST (1, "[!a]b", "b");
TEST (0, "[!a]b", "bb");
TEST (1, "a[!b]", "");
TEST (1, "a[!b]", "a");
TEST (1, "a[!b]", "ab");
TEST (1, "a[!b]", "b");
TEST (0, "a[!b]", "ac");
TEST (1, "a[!bc]", "");
TEST (1, "a[!bc]", "a");
TEST (1, "a[!bc]", "ab");
TEST (1, "a[!bc]", "ac");
TEST (0, "a[!bc]", "ad");
TEST (0, "a[!!?]", "ae");
TEST (0, "a[!?!]", "af");
TEST (0, "a[!?-]", "ag");
TEST (0, "a[!-?]", "ah");
TEST (1, "a[!bc]", "aae");
TEST (1, "a[!bc]", "abe");
TEST (1, "a[!bc]", "ace");
TEST (1, "[!abc]", "");
TEST (1, "[!abc]", "a");
TEST (1, "[!abc]", "b");
TEST (1, "[!abc]", "c");
TEST (0, "[!abc]", "d");
TEST (1, "[!abc]", "ab");
TEST (1, "[!abc]", "ac");
TEST (1, "[!abc]", "ad");
TEST (1, "[!abc]", "abc");
TEST (1, "[!abc]", "abcd");
TEST (1, "[!abc]d", "");
TEST (1, "[!abc]d", "a");
TEST (1, "[!abc]d", "b");
TEST (1, "[!abc]d", "c");
TEST (1, "[!abc]d", "d");
TEST (0, "[!abc]d", "dd");
TEST (1, "[!abc]d", "ab");
TEST (1, "[!abc]d", "ac");
TEST (1, "[!abc]d", "ad");
TEST (1, "[!abc]d", "abc");
TEST (1, "[!abc]d", "abcd");
// exercise bracket expressions with ranges
TEST (1, "[a-a]", "");
TEST (0, "[a-a]", "a");
TEST (1, "[a-a]", "b");
TEST (1, "[a-a]", "ab");
TEST (1, "[a-a]", "ba");
TEST (1, "[a-b]", "");
TEST (0, "[a-b]", "a");
TEST (0, "[a-b]", "b");
TEST (1, "[a-b]", "c");
TEST (1, "[a-c]", "");
TEST (0, "[a-c]", "a");
TEST (0, "[a-c]", "b");
TEST (0, "[a-c]", "c");
TEST (1, "[a-c]", "d");
TEST (1, "[a-ce]", "");
TEST (0, "[a-ce]", "a");
TEST (0, "[a-ce]", "b");
TEST (0, "[a-ce]", "c");
TEST (1, "[a-ce]", "d");
TEST (0, "[a-ce]", "e");
TEST (1, "[a-ce]", "f");
TEST (1, "[ac-e]", "");
TEST (0, "[ac-e]", "a");
TEST (1, "[ac-e]", "b");
TEST (0, "[ac-e]", "c");
TEST (0, "[ac-e]", "d");
TEST (0, "[ac-e]", "e");
TEST (1, "[ac-e]", "f");
TEST (1, "[ac-eg]", "");
TEST (0, "[ac-eg]", "a");
TEST (1, "[ac-eg]", "b");
TEST (0, "[ac-eg]", "c");
TEST (0, "[ac-eg]", "d");
TEST (0, "[ac-eg]", "e");
TEST (1, "[ac-eg]", "f");
TEST (0, "[ac-eg]", "g");
TEST (1, "[ac-egk-m]", "");
TEST (0, "[ac-egk-m]", "a");
TEST (1, "[ac-egk-m]", "b");
TEST (0, "[ac-egk-m]", "c");
TEST (0, "[ac-egk-m]", "d");
TEST (0, "[ac-egk-m]", "e");
TEST (1, "[ac-egk-m]", "f");
TEST (0, "[ac-egk-m]", "g");
TEST (1, "[ac-egk-m]", "h");
TEST (1, "[ac-egk-m]", "i");
TEST (1, "[ac-egk-m]", "j");
TEST (0, "[ac-egk-m]", "k");
TEST (0, "[ac-egk-m]", "l");
TEST (0, "[ac-egk-m]", "m");
TEST (1, "[ac-egk-m]", "n");
TEST (1, "[1-9][0-9]", "");
TEST (1, "[1-9][0-9]", "0");
TEST (1, "[1-9][0-9]", "1");
TEST (1, "[1-9][0-9]", "2");
TEST (1, "[1-9][0-9]", "00");
TEST (1, "[1-9][0-9]", "01");
TEST (0, "[1-9][0-9]", "10");
TEST (0, "[1-9][0-9]", "11");
TEST (0, "[1-9][0-9]", "12");
TEST (0, "[1-9][0-9]", "90");
TEST (0, "[1-9][0-9]", "99");
TEST (1, "[1-9][0-9]", "999");
TEST (1, "[1-9].[0-9]", "0.1");
TEST (0, "[1-9].[0-9]", "1.0");
TEST (1, "[1-9].[0-9]", "1.0.0");
// exercise mixed patterns
TEST (1, "[1-9].[0-9]*", "1.");
TEST (0, "[1-9].[0-9]*", "1.2");
TEST (0, "[1-9].[0-9]*", "1.23");
TEST (0, "[1-9].[0-9]*", "1.2x");
TEST (0, "[1-9]?[0-9]*", "1-2y");
TEST (1, "*-aix[1-9].[0-9]-xlc7.0.0.[0-9]", "ppc-aix4.3-xlc6.0");
TEST (1, "*-aix[1-9].[0-9]-xlc7.0.0.[0-9]", "ppc-aix5.2-xlc6.0");
TEST (0, "*-aix[1-9].[0-9]-xlc7.0.0.[0-9]", "ppc-aix4.3-xlc7.0.0.0");
// exercise incomplete patterns
TEST (1, "\\", "");
TEST (1, "\\", "a");
TEST (1, "\\", "\\");
TEST (1, "[", "");
TEST (1, "[", "a");
TEST (1, "[", "[");
TEST (1, "[a", "");
TEST (1, "[a", "[a");
// return 0 on success, 1 on failure
return !(0 == nerrors);
}

View File

@@ -0,0 +1,369 @@
/************************************************************************
*
* 0.inputiter.cpp - test exercising the InputIter class template
*
* $Id: 0.inputiter.cpp 550991 2007-06-26 23:58:07Z sebor $
*
************************************************************************
*
* 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 1994-2005 Rogue Wave Software.
*
**************************************************************************/
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#ifdef _MSC_VER
#include <crtdbg.h> // for _CrtSetReportMode()
#endif
#include <alg_test.h> // for InputIter
#include <rw_value.h> // for UserClass
#include <driver.h> // for rw_test(), ...
/***********************************************************************/
int exit_status /* = 0 */;
extern "C" {
int line;
int fail;
jmp_buf env;
void handle_ABRT (int)
{
fail = 0;
longjmp (env, 1);
}
}
#define FAIL(code) \
fail = line = __LINE__; \
signal (SIGABRT, handle_ABRT); \
if (0 == setjmp (env)) { \
code; \
exit_status = 1; \
rw_assert (0, 0, line, "expected assertion"); \
} \
else \
(void)0
#define PASS(code) \
fail = -1; line = __LINE__; \
signal (SIGABRT, handle_ABRT); \
if (0 == setjmp (env)) \
code; \
else if (fail != line) { \
exit_status = 1; \
rw_assert (0, 0, line, "unexpected assertion"); \
} (void)0
typedef InputIter<UserClass> Iterator;
// FIXME: implement an easy way to print out an array of UserClass
#define X2STR(ign1, ign2) "***NOT IMPLEMENTED ***"
/***********************************************************************/
static void
test_0 ()
{
UserClass *x = UserClass::from_char ("abc");
Iterator end0 = make_iter (x + 3, x + 0, x + 3, end0);
Iterator end1 = make_iter (x + 3, x + 0, x + 3, end1);
bool equal;
// end iterator must compare equal to itself
PASS (equal = end0 == end0);
rw_assert (equal, 0, __LINE__,
"InputIter<UserClass> end iterator unexpectedly "
"not equal to self: %p == %p", end0.cur_, end0.cur_);
PASS (equal = end0 != end0);
rw_assert (!equal, 0, __LINE__,
"InputIter<UserClass> end iterator unexpectedly "
"not equal to self: %p == %p", end0.cur_, end0.cur_);
// end iterator must compare equal to another
PASS (equal = end0 == end1);
rw_assert (equal, 0, __LINE__,
"InputIter<UserClass> end iterator unexpectedly "
"not equal to another: %p == %p", end0.cur_, end1.cur_);
PASS (equal = end0 != end1);
rw_assert (!equal, 0, __LINE__,
"InputIter<UserClass> end iterator unexpectedly "
"not equal to another: %p == %p", end0.cur_, end1.cur_);
// cannot increment the end iterator
FAIL (++end0);
FAIL (end0++);
FAIL (++end1);
FAIL (end1++);
// cannot dereference the end iterator
FAIL (x [0] = *end0);
FAIL (x [0] = *end1);
FAIL (equal = int ('a') == end0->data_.val_);
FAIL (equal = int ('a') == end1->data_.val_);
delete[] x;
}
/***********************************************************************/
static void
test_1 ()
{
UserClass *x = UserClass::from_char ("abcdef");
UserClass *y = UserClass::from_char ("ABCDEF");
const Iterator end = make_iter (x + 6, x + 0, x + 6, end);
Iterator it = make_iter (x + 0, x + 0, x + 6, it);
bool equal;
// non-end iterator must compare unequal to the end iterator
PASS (equal = it == end);
rw_assert (!equal, 0, __LINE__,
"InputIter<UserClass> unexpectedly equal to end: "
"%p == %p", it.cur_, end.cur_);
PASS (y [0] = *it);
PASS (++it);
PASS (equal = it == end);
rw_assert (!equal, 0, __LINE__,
"InputIter<UserClass> unexpectedly equal to end: "
"%p == %p", it.cur_, end.cur_);
PASS (y [1] = *it);
PASS (++it);
PASS (equal = it == it);
rw_assert (equal, 0, __LINE__,
"InputIter<UserClass> unexpectedly equal to self: "
"%p == %p", it.cur_, it.cur_);
PASS (y [2] = *it);
PASS (++it);
PASS (y [3] = *it);
PASS (++it);
PASS (y [4] = *it);
PASS (++it);
PASS (y [5] = *it);
PASS (++it);
PASS (equal = it == end);
rw_assert (equal, 0, __LINE__,
"InputIter<UserClass> unexpectedly not qual to end: "
"%p != %p (diff = %d)",
it.cur_, end.cur_, end.cur_ - it.cur_);
rw_assert (0 == UserClass::compare (x, y, 6), 0, __LINE__,
"InputIter<UserClass> data mismatch: %s != %s",
X2STR (x, 6), X2STR (y, 6));
delete[] x;
delete[] y;
}
/***********************************************************************/
static void
test_2 ()
{
UserClass *x = UserClass::from_char ("abcdef");
UserClass *y = UserClass::from_char ("ABCDEF");
const Iterator end = make_iter (x + 6, x + 0, x + 6, end);
Iterator it = make_iter (x + 0, x + 0, x + 6, it);
PASS (y [0] = *it);
PASS (y [1] = *++it);
PASS (y [2] = *it++); // it++ is the same as ++it
PASS (y [3] = *it++);
PASS (++it);
PASS (y [4] = *it);
PASS (y [5] = *it++);
bool equal;
PASS (equal = it == end);
rw_assert (!equal, 0, __LINE__,
"InputIter<UserClass> unexpectedly equal to end: "
"%p != %p (diff = %d)",
it.cur_, end.cur_, end.cur_ - it.cur_);
PASS (++it);
PASS (equal = it == end);
rw_assert (equal, 0, __LINE__,
"InputIter<UserClass> unexpectedly not equal to end: "
"%p != %p (diff = %d)",
it.cur_, end.cur_, end.cur_ - it.cur_);
rw_assert (0 == UserClass::compare (x, y, 6), 0, __LINE__,
"InputIter<UserClass> data mismatch: %s != %s",
X2STR (x, 6), X2STR (y, 6));
delete[] x;
delete[] y;
}
/***********************************************************************/
static void
test_3 ()
{
UserClass *x = UserClass::from_char ("abcdef");
UserClass *y = UserClass::from_char ("ABCDEF");
const Iterator end = make_iter (x + 6, x + 6, x + 6, end);
Iterator it0 = make_iter (x + 0, x + 0, x + 6, it0);
Iterator it1 = it0;
bool equal;
PASS (equal = it0 == it1);
rw_assert (equal, 0, __LINE__,
"InputIter<UserClass> unexpectedly not equal: "
"%p != %p (diff = %d)",
it0.cur_, it1.cur_, it0.cur_ - it1.cur_);
PASS (equal = it0 == end);
rw_assert (!equal, 0, __LINE__,
"InputIter<UserClass> unexpectedly equal to end: "
"%p == %p", it1.cur_, end.cur_);
PASS (y [0] = *it0);
PASS (y [1] = *it1);
rw_assert (y [0].data_.val_ == y [1].data_.val_, 0, __LINE__,
"two copies of InputIter<UserClass> unexpectedly yield "
"different values: %d != %d",
y [0].data_.val_, y [1].data_.val_);
PASS (it0++);
FAIL (it1++); // can't pass through the same iterator twice
FAIL (it0 == it1); // it1 not in the domain of operator==()
PASS (equal = it0 == end);
rw_assert (!equal, 0, __LINE__,
"InputIter<UserClass> unexpectedly equal to end: "
"%p == %p", it1.cur_, end.cur_);
PASS (it1 = it0);
PASS (equal = it0 == it1);
rw_assert (equal, 0, __LINE__,
"InputIter<UserClass> unexpectedly not equal: "
"%p == %p", it0.cur_, it1.cur_);
PASS (y [0] = *it0);
PASS (y [1] = *it1);
rw_assert (y [0].data_.val_ == y [1].data_.val_, 0, __LINE__,
"two copies of InputIter<UserClass> unexpectedly yield "
"different values: %d != %d",
y [0].data_.val_, y [1].data_.val_);
rw_assert (y [0].data_.val_ == 'b', 0, __LINE__,
"InputIter<UserClass>::operator*() == %d, got %d",
y [0].data_.val_, 'b');
PASS (it1++);
FAIL (it0++); // can't pass through the same iterator twice
FAIL (it0 == it1); // it0 not in the domain of operator==()
PASS (equal = it1 == end);
rw_assert (!equal, 0, __LINE__,
"InputIter<UserClass> unexpectedly equal to end: "
"%p == %p", it1.cur_, end.cur_);
FAIL (x [0] = *it0); // cannot dereference
delete[] x;
delete[] y;
}
/***********************************************************************/
static int
run_test (int, char*[])
{
#ifndef NDEBUG
// silence stderr output from invocations of the RW_ASSERT() macro
// that are expected to fail by design (i.e., that's what this test
// exercises)
fclose (stderr);
test_0 ();
test_1 ();
test_2 ();
test_3 ();
#else // if defined (NDEBUG)
rw_assert (0, 0, __LINE__, "macro NDEBUG #defined, cannot test");
#endif // NDEBUG
return exit_status;
}
/***********************************************************************/
int main (int argc, char *argv[])
{
#ifdef _MSC_VER
// disable GUI window from abort()
_CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_DEBUG);
#endif
return rw_test (argc, argv, __FILE__,
0 /* no clause */,
0 /* no comment */, run_test,
0 /* co command line options */);
}

524
extern/stdcxx/4.2.1/tests/self/0.new.cpp vendored Normal file
View File

@@ -0,0 +1,524 @@
/***************************************************************************
*
* 0.new.cpp - test exercising replacement operator new and delete
*
* $Id: 0.new.cpp 641117 2008-03-26 02:32:31Z sebor $
*
***************************************************************************
*
* 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 1994-2008 Rogue Wave Software, Inc.
*
**************************************************************************/
#include <new> // for bad_alloc
#include <cstddef> // for size_t
#include <setjmp.h> // for longjmp(), setjmp()
#include <signal.h> // for SIGABRT, signal()
#include <rw_new.h>
#include <driver.h>
/**************************************************************************/
// program exit status
int exit_status /* = 0 */;
extern "C" {
volatile int line; // currently executed line
volatile int fail; // non-zero when line failed
jmp_buf env;
static void
handle_ABRT (int)
{
fail = 0;
longjmp (env, 1);
}
}
#define FAIL(code) \
fail = line = __LINE__; \
signal (SIGABRT, handle_ABRT); \
if (0 == setjmp (env)) { \
code; \
exit_status = 1; \
rw_assert (0, __FILE__, line, "expected assertion"); \
} \
else \
(void)0
#define PASS(code) \
fail = -1; line = __LINE__; \
signal (SIGABRT, handle_ABRT); \
if (0 == setjmp (env)) { \
code; \
} \
else if (fail != line) { \
exit_status = 1; \
rw_assert (0, __FILE__, line, "unexpected assertion"); \
} (void)0
/**************************************************************************/
void test_new_delete ()
{
rw_info (0, __FILE__, __LINE__,
"exercising successful allocation and deallocation");
{
void *p = 0;
PASS (p = operator new (0));
rw_assert (p != 0, __FILE__, __LINE__, "operator new(0) != 0");
operator delete (p);
}
{
void *p = 0;
PASS (p = operator new (1));
rw_assert (p != 0, __FILE__, __LINE__, "operator new(1) != 0");
operator delete (p);
}
{
void *p = 0;
PASS (p = operator new (2));
rw_assert (p != 0, __FILE__, __LINE__, "operator new(2) != 0");
operator delete (p);
}
{
void *p = 0;
PASS (p = operator new (1024));
rw_assert (p != 0, __FILE__, __LINE__, "operator new(1024) != 0");
operator delete (p);
}
}
/**************************************************************************/
#define CATCH(code) \
try { code; fail = 1; } \
catch (_RWSTD_BAD_ALLOC) { fail = 0; } \
catch (...) { fail = 2; } \
rw_assert (!fail, __FILE__, __LINE__, \
"%s", 1 == fail ? "failed to throw" : \
"threw an unknown exception")
#define NOTHROW(code) \
try { fail = 0; code; } \
catch (...) { fail = 1; } \
rw_assert (!fail, __FILE__, __LINE__, \
"unexpected exception")
void test_bad_alloc ()
{
rw_info (0, __FILE__, __LINE__,
"exercising the ability of ordinary "
"operator new to throw std::bad_alloc");
rwt_free_store* const pst = rwt_get_free_store (0);
*pst->throw_at_blocks_ [0] = pst->blocks_ [0];
CATCH (operator new (0));
CATCH (operator new (1));
CATCH (operator new (2));
CATCH (operator new (1024));
{
void *p = 0;
NOTHROW (p = operator new[](0));
operator delete[](p);
}
{
void *p = 0;
NOTHROW (p = operator new[](1));
operator delete[](p);
}
{
void *p = 0;
NOTHROW (p = operator new[](2));
operator delete[](p);
}
{
void *p = 0;
NOTHROW (p = operator new[](1024));
operator delete[](p);
}
rw_info (0, __FILE__, __LINE__,
"exercising the ability of the array form "
"of operator new to throw std::bad_alloc");
*pst->throw_at_blocks_ [0] = std::size_t (-1);
*pst->throw_at_blocks_ [1] = pst->blocks_ [1];
CATCH (operator new[](0));
CATCH (operator new[](1));
CATCH (operator new[](2));
CATCH (operator new[](1024));
{
void *p = 0;
NOTHROW (p = operator new (0));
rw_assert (p != 0, __FILE__, __LINE__, "operator new[](0) != 0");
operator delete (p);
}
{
void *p = 0;
NOTHROW (p = operator new (1));
rw_assert (p != 0, __FILE__, __LINE__, "operator new[](1) != 0");
operator delete (p);
}
{
void *p = 0;
NOTHROW (p = operator new (32));
rw_assert (p != 0, __FILE__, __LINE__, "operator new[](32) != 0");
operator delete (p);
}
{
void *p = 0;
NOTHROW (p = operator new (4096));
rw_assert (p != 0, __FILE__, __LINE__, "operator new[](4096) != 0");
operator delete (p);
}
*pst->throw_at_blocks_ [1] = std::size_t (-1);
}
/**************************************************************************/
void test_mismatch ()
{
rw_info (0, __FILE__, __LINE__,
"exercising the ability to detect "
"allocation/deallocation mismatches");
{
// detect allocations by operator new() deallocated
// using (the array form of) operator delete[]
void *p = 0;
PASS (p = operator new (0));
FAIL (operator delete[](p));
PASS (operator delete (p));
}
{
void *p = 0;
PASS (p = operator new (1));
FAIL (operator delete[](p));
PASS (operator delete (p));
}
{
void *p = 0;
PASS (p = operator new[](33));
FAIL (operator delete (p));
PASS (operator delete[] (p));
}
}
/**************************************************************************/
void test_bad_delete ()
{
rw_info (0, __FILE__, __LINE__,
"exercising the ability to detect "
"deletion of unallocated storage");
{
char *p = 0;
PASS (p = new char);
FAIL (delete (p - 1));
FAIL (delete (p + 1));
PASS (delete (p));
}
{
char *p = 0;
PASS (p = new char [4]);
FAIL (delete (p - 1));
FAIL (delete (p + 1));
FAIL (delete (p + 2));
FAIL (delete (p + 3));
FAIL (delete (p + 4));
FAIL (delete[] (p - 1));
FAIL (delete[] (p + 1));
FAIL (delete[] (p + 2));
FAIL (delete[] (p + 3));
FAIL (delete[] (p + 4));
PASS (delete[] p);
}
}
/**************************************************************************/
void test_double_delete ()
{
rw_info (0, __FILE__, __LINE__,
"exercising the ability to detect double deletion");
{
char *p = 0;
PASS (p = new char);
PASS (delete (p));
FAIL (delete (p));
}
{
char *p = 0;
PASS (p = new char [32]);
PASS (delete[] p);
FAIL (delete[] p);
FAIL (delete p);
}
}
/**************************************************************************/
void test_corruption ()
{
rw_info (0, __FILE__, __LINE__,
"exercising the ability to detect memory corruption");
// corrupt (and restore) memory past the end of the allocated block
for (std::size_t i = 1; i != 8; ++i) {
char *p = 0;
PASS (p = new char);
// save the value of the byte past the end of the block
// and temporarily overwrite it with another value
const char save = p [i];
p [i] = ~p [i];
// expect operator delete to diagnose the corruption
// and call abort() without actually freeing the block
FAIL (delete p);
// restore the corrupted byte to its original value
p [i] = save;
// expect operator delete not to complain
PASS (delete p);
}
}
/**************************************************************************/
#define LEAK(code, bytes, blks) \
do { \
/* establish a checkpoint for memory leaks */ \
rwt_check_leaks (0, 0); \
\
code; \
\
/* find memory leaks since the last checkpoint */ \
std::size_t nbytes; \
const std::size_t nblocks = rwt_check_leaks (&nbytes, 0); \
\
rw_assert (blks == nblocks && bytes == nbytes, \
__FILE__, __LINE__, \
"failed to detect a leak of %d bytes in " \
"%d blocks: got %zu bytes in %zu blocks", \
bytes, blks, nbytes, nblocks); \
} while (0)
void test_leaks ()
{
rw_info (0, __FILE__, __LINE__,
"exercising the ability to detect memory leaks");
{
void *p = 0;
LEAK (p = operator new (0), 0, 1);
PASS (operator delete (p));
}
{
void *p = 0;
LEAK (p = operator new (1), 1, 1);
PASS (operator delete (p));
}
{
void *p = 0;
LEAK (p = operator new (1234), 1234, 1);
PASS (operator delete (p));
}
{
void *p0 = 0;
void *p1 = 0;
LEAK (p0 = operator new (32);
p1 = operator new (64), 96, 2);
PASS (operator delete (p0));
PASS (operator delete (p1));
}
{
void *p = 0;
LEAK (p = operator new[] (12345), 12345, 1);
PASS (operator delete[] (p));
}
}
/**************************************************************************/
void test_stress ()
{
rw_info (0, __FILE__, __LINE__,
"stress-testing replacement operators new and delete");
rwt_free_store* const pst = rwt_get_free_store (0);
std::size_t nblocks = pst->blocks_ [0] + pst->blocks_ [1];
std::size_t nbytes = pst->bytes_ [0] + pst->bytes_ [1];
void* ptrs [1000];
const std::size_t N = sizeof ptrs / sizeof *ptrs;
for (std::size_t i = 0; i != N; ++i) {
if (i % 2) {
PASS (ptrs [i] = operator new[](i));
}
else {
PASS (ptrs [i] = operator new (i));
}
}
for (std::size_t i = 0; i < N; ++i) {
const std::size_t j = (i * (i + 17)) % N;
if (j % 2) {
PASS (operator delete[](ptrs [j]));
}
else {
PASS (operator delete (ptrs [j]));
}
ptrs [j] = 0;
}
for (std::size_t i = 0; i < N; ++i) {
if (i % 2) {
PASS (operator delete[](ptrs [i]));
}
else {
PASS (operator delete (ptrs [i]));
}
}
nblocks = pst->blocks_ [0] + pst->blocks_ [1] - nblocks;
nbytes = pst->bytes_ [0] + pst->bytes_ [1] - nbytes;
rw_assert (0 == nblocks && 0 == nbytes, __FILE__, __LINE__,
"false leaks detected: %zu bytes in %zu blocks",
nbytes, nblocks);
}
/**************************************************************************/
static int rw_opt_no_new_delete; // for --no-new-delete
static int rw_opt_no_bad_alloc; // for --no-bad_alloc
static int rw_opt_no_mismatch; // for --no-mismatch
static int rw_opt_no_bad_delete; // for --no-bad-delete
static int rw_opt_no_double_delete; // for --no-double-delete
static int rw_opt_no_corruption; // for --no-corruption
static int rw_opt_no_leaks; // for --no-leaks
static int rw_opt_no_stress; // for --no-stress
int run_test (int, char**)
{
#ifndef _RWSTD_NO_REPLACEABLE_NEW_DELETE
// disable diagnostics issued by the replacement operator new
// and delete defined by the test driver in response to deliberate
// errors caused by this test
rw_enable (rw_error, false);
# define TEST(name) \
if (rw_opt_no_ ## name) \
rw_note (0, 0, __LINE__, "%s test disabled", #name); \
else \
test_ ## name ()
TEST (bad_alloc);
TEST (mismatch);
TEST (double_delete);
TEST (bad_delete);
TEST (corruption);
TEST (leaks);
TEST (stress);
#else // _RWSTD_NO_REPLACEABLE_NEW_DELETE
rw_note (0, 0, __LINE__, "Test disabled");
#endif // _RWSTD_NO_REPLACEABLE_NEW_DELETE
return 0;
}
/**************************************************************************/
int main (int argc, char** argv)
{
return rw_test (argc, argv, __FILE__,
0 /* no clause */,
0 /* no comment */,
run_test,
"|-no-new-delete# "
"|-no-bad_alloc# "
"|-no-mismatch# "
"|-no-bad-delete# "
"|-no-double-delete# "
"|-no-corruption# "
"|-no-leaks# "
"|-no-stress-test#",
&rw_opt_no_new_delete,
&rw_opt_no_bad_alloc,
&rw_opt_no_mismatch,
&rw_opt_no_bad_delete,
&rw_opt_no_double_delete,
&rw_opt_no_corruption,
&rw_opt_no_leaks,
&rw_opt_no_stress);
}

View File

@@ -0,0 +1,342 @@
/************************************************************************
*
* 0.outputiter.cpp - test exercising the OutputIter class template
*
* $Id: 0.outputiter.cpp 550991 2007-06-26 23:58:07Z sebor $
*
************************************************************************
*
* 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 1994-2005 Rogue Wave Software.
*
**************************************************************************/
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#ifdef _MSC_VER
#include <crtdbg.h> // for _CrtSetReportMode()
#endif
#include <alg_test.h> // for OutputIter
#include <rw_value.h> // for UserClass
#include <driver.h> // for rw_test(), ...
/***********************************************************************/
int exit_status /* = 0 */;
extern "C" {
int line;
int fail;
jmp_buf env;
void handle_ABRT (int)
{
fail = 0;
longjmp (env, 1);
}
}
#define FAIL(code) \
fail = line = __LINE__; \
signal (SIGABRT, handle_ABRT); \
if (0 == setjmp (env)) { \
code; \
exit_status = 1; \
rw_assert (0, 0, line, "expected assertion"); \
} \
else \
(void)0
#define PASS(code) \
fail = -1; line = __LINE__; \
signal (SIGABRT, handle_ABRT); \
if (0 == setjmp (env)) \
code; \
else if (fail != line) { \
exit_status = 1; \
rw_assert (0, 0, line, "unexpected assertion"); \
} (void)0
/***********************************************************************/
static void
test_1 ()
{
UserClass *x = UserClass::from_char ("abcdef");
UserClass *y = UserClass::from_char ("ABCDEF");
// use `out' as the last argument to make_iter() (as opposed
// to, say, OutputIter<UserClass>()) since Output Iterators
// are not required to be copy-constructible
OutputIter<UserClass> out = make_iter (x + 0, x + 0, x + 6, out);
PASS (*out++ = y [0]);
PASS (*out++ = y [1]);
PASS (*out++ = y [2]);
PASS (*out++ = y [3]);
PASS (*out++ = y [4]);
PASS (*out++ = y [5]);
delete[] x;
delete[] y;
}
/***********************************************************************/
static void
test_2 ()
{
UserClass *x = UserClass::from_char ("abcdef");
UserClass *y = UserClass::from_char ("ABCDEF");
OutputIter<UserClass> out = make_iter (x + 0, x + 0, x + 6, out);
PASS (*out = y [0]);
PASS (++out);
PASS (out = y [1]);
PASS (++out);
PASS (*out = y [2]);
PASS (++out);
PASS (out = y [3]);
PASS (++out);
PASS (*out = y [4]);
PASS (++out);
PASS (out = y [5]);
PASS (++out);
delete[] x;
delete[] y;
}
/***********************************************************************/
static void
test_3 ()
{
UserClass *x = UserClass::from_char ("abcdef");
UserClass *y = UserClass::from_char ("ABCDEF");
OutputIter<UserClass> out = make_iter (x + 0, x + 0, x + 6, out);
PASS (*out = y [0]);
PASS (out++);
PASS (out = y [1]);
PASS (out++);
PASS (*out = y [2]);
PASS (out++);
PASS (out = y [3]);
PASS (out++);
PASS (*out = y [4]);
PASS (out++);
PASS (out = y [5]);
PASS (out++);
delete[] x;
delete[] y;
}
/***********************************************************************/
static void
test_4 ()
{
UserClass *x = UserClass::from_char ("abcdef");
UserClass *y = UserClass::from_char ("ABCDEF");
OutputIter<UserClass> out = make_iter (x + 0, x + 0, x + 6, out);
PASS (*out++ = y [0]);
PASS (*out = y [1]);
PASS (out++);
PASS (out++ = y [2]);
PASS (out = y [3]);
PASS (out++);
PASS (*out++ = y [4]);
PASS (*out = y [5]);
PASS (out++);
delete[] x;
delete[] y;
}
/***********************************************************************/
static void
test_5 ()
{
UserClass *x = UserClass::from_char ("abcdef");
UserClass *y = UserClass::from_char ("ABCDEF");
OutputIter<UserClass> out = make_iter (x + 0, x + 0, x + 6, out);
PASS (*out = y [0]);
PASS (++out);
PASS (*out++ = y [1]);
PASS (out = y [2]);
PASS (++out);
PASS (out++ = y [3]);
PASS (*out = y [4]);
PASS (++out);
PASS (*out++ = y [5]);
delete[] x;
delete[] y;
}
/***********************************************************************/
static void
test_6 ()
{
UserClass *x = UserClass::from_char ("abcdef");
UserClass *y = UserClass::from_char ("ABCDEF");
OutputIter<UserClass> out = make_iter (x + 0, x + 0, x + 6, out);
PASS (*out = y [0]);
PASS (*++out = y [1]);
PASS (++out = y [2]);
PASS (*++out = y [3]);
PASS (++out = y [4]);
PASS (*++out = y [5]);
PASS (out++);
delete[] x;
delete[] y;
}
/***********************************************************************/
static void
test_7 ()
{
UserClass x;
OutputIter<UserClass> out = make_iter (&x, &x, &x, out);
FAIL (++out);
FAIL (out++);
FAIL (*out);
FAIL (*out++);
FAIL (*out = x);
FAIL (*out++ = x);
FAIL (*++out = x);
FAIL (out = x);
FAIL (out++ = x);
FAIL (++out = x);
out = make_iter (&x, &x, &x + 1, out);
}
/***********************************************************************/
static void
test_8 ()
{
UserClass *x = UserClass::from_char ("abcdef");
UserClass *y = UserClass::from_char ("ABCDEF");
OutputIter<UserClass> out = make_iter (x + 0, x + 0, x + 6, out);
PASS (*out++ = y [0]);
PASS (*out++ = y [1]);
PASS (*out++ = y [2]);
PASS (*out++ = y [3]);
PASS (*out++ = y [4]);
PASS (*out++ = y [5]);
FAIL (out++);
delete[] x;
delete[] y;
}
/***********************************************************************/
static void
test_9 ()
{
UserClass *x = UserClass::from_char ("abcdef");
UserClass *y = UserClass::from_char ("ABCDEF");
OutputIter<UserClass> out = make_iter (x + 0, x + 0, x + 6, out);
PASS (*out++ = y [0]);
PASS (out++);
FAIL (*out++ = y [1]);
delete[] x;
delete[] y;
}
/***********************************************************************/
static int
run_test (int, char*[])
{
#ifndef NDEBUG
// silence stderr output from invocations of the RW_ASSERT() macro
// that are expected to fail by design (i.e., that's what this test
// exercises)
fclose (stderr);
test_1 ();
test_2 ();
test_3 ();
test_4 ();
test_5 ();
test_6 ();
test_7 ();
test_8 ();
test_9 ();
#else // if defined (NDEBUG)
rw_assert (0, 0, __LINE__, "macro NDEBUG #defined, cannot test");
#endif // NDEBUG
return exit_status;
}
/***********************************************************************/
int main (int argc, char *argv[])
{
#ifdef _MSC_VER
// disable GUI window from abort()
_CrtSetReportMode (_CRT_ERROR, _CRTDBG_MODE_DEBUG);
#endif
return rw_test (argc, argv, __FILE__,
0 /* no clause */,
0 /* no comment */, run_test,
0 /* co command line options */);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,307 @@
/************************************************************************
*
* 0.process.cpp - test exercising the rw_process_create(),
* rw_process_kill() and rw_waitpid() functions
*
* $Id: 0.process.cpp 580483 2007-09-28 20:55:52Z sebor $
*
************************************************************************
*
* 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.
*
**************************************************************************/
// tell Compaq C++ we need POSIX errno constants that are otherwise
// guarded (not defined) in the compiler's pure C++ libc headers
#undef __PURE_CNAME
#include <errno.h> // for ENOENT, ECHILD, ESRCH, errno
#include <string.h> // for strcmp()
#include <rw_process.h> // for rw_process_create(), rw_waitpid()
#include <driver.h> // for rw_test()
static int _rw_child = 0;
static int _rw_timeout = 5;
static char arg1[] = "--child=1";
static char arg2[] = "--no-stdout";
static char* args [] = { 0, arg1, arg2, 0 };
static const int nargs = sizeof (args) / sizeof (*args) - 1;
static rw_pid_t _rw_pid = -1;
static int join_test (rw_pid_t pid, bool should_hang)
{
int result = 0;
const rw_pid_t ret = rw_waitpid (pid, &result, _rw_timeout);
rw_assert (-1 != ret, __FILE__, __LINE__,
"rw_waitpid() failed, errno = %{#m}");
if (-1 == ret)
return 1;
if (0 == ret) {
// set to ignore rw_error diagnostic
rw_enable (rw_error, false);
// time_out elapsed, kill the process
if (1 == rw_process_kill (pid)) {
// the process not yet terminated
// wait for process termination and remove the zombie process
rw_waitpid (pid, 0);
}
// enable rw_error diagnostic
rw_enable (rw_error);
rw_assert (should_hang, __FILE__, __LINE__,
"The child process unexpectedly deadlocked");
return should_hang ? 0 : 1;
}
rw_assert (!should_hang, __FILE__, __LINE__,
"Expected the deadlocked process, but process exited "
"with code: %d",
result);
if (!should_hang)
rw_assert (0 == result, __FILE__, __LINE__,
"Process exit code: expected 0, got %d", result);
return result;
}
static int test_process_create1 ()
{
rw_info (0, 0, 0,
"Exercising the rw_process_create "
"(const char*, char* const []) overload");
const rw_pid_t pid = rw_process_create (args [0], args);
rw_assert (-1 != pid, __FILE__, __LINE__,
"rw_process_create() failed, errno = %{#m}");
if (-1 == pid)
return 1;
// save the pid for test exercising rw_waitpid() fail
if (-1 == _rw_pid)
_rw_pid = pid;
return join_test (pid, false);
}
static int test_process_create2 ()
{
rw_info (0, 0, 0,
"Exercising the rw_process_create (const char*, ...) overload");
const rw_pid_t pid = rw_process_create ("\"%s\" %s %s",
args[0], args[1], args[2]);
rw_assert (-1 != pid, __FILE__, __LINE__,
"rw_process_create() failed, errno = %{#m}");
if (-1 == pid)
return 1;
// save the pid for test exercising rw_waitpid() fail
if (-1 == _rw_pid)
_rw_pid = pid;
return join_test (pid, false);
}
static int test_process_deadlocked ()
{
rw_info (0, 0, 0,
"Exercising the rw_waitpid() with timeout and deadlocked process");
const rw_pid_t pid = rw_process_create ("\"%s\" --child=2 %s",
args[0], args[2]);
rw_assert (-1 != pid, __FILE__, __LINE__,
"rw_process_create() failed, errno = %{#m}");
return -1 == pid ? 1 : join_test (pid, true);
}
static int test_process_create_fail ()
{
rw_info (0, 0, 0,
"Exercising the rw_process_create() behavior "
"when invalid path specified");
// set to ignore rw_error diagnostic
rw_enable (rw_error, false);
const rw_pid_t pid = rw_process_create ("/\\/\\/\\", args);
// enable rw_error diagnostic
rw_enable (rw_error);
rw_assert (-1 == pid, __FILE__, __LINE__,
"rw_process_create returns %ld, expected -1",
long (pid));
if (-1 != pid) {
rw_waitpid (pid, 0);
return 1;
}
rw_assert (ENOENT == errno, __FILE__, __LINE__,
"errno: expected ENOENT, got %{#m}");
return ENOENT == errno ? 0 : 1;
}
static int test_waitpid_fail ()
{
if (-1 == _rw_pid) {
rw_info (0, 0, 0,
"The test, exercising the rw_waitpid() behavior "
"when invalid pid specified is disabled");
return 0;
}
rw_info (0, 0, 0,
"Exercising the rw_waitpid() behavior "
"when invalid pid specified");
// set to ignore rw_error diagnostic
rw_enable (rw_error, false);
const rw_pid_t pid = rw_waitpid (_rw_pid, 0);
// enable rw_error diagnostic
rw_enable (rw_error);
rw_assert (-1 == pid, __FILE__, __LINE__,
"rw_waitpid returns %ld, expected -1",
long (pid));
if (-1 != pid)
return 1;
rw_assert (ECHILD == errno, __FILE__, __LINE__,
"errno: expected ECHILD, got %{#m}");
return ECHILD == errno ? 0 : 1;
}
static int test_process_kill_fail ()
{
if (-1 == _rw_pid) {
rw_info (0, 0, 0,
"The test, exercising the rw_process_kill() behavior "
"when invalid pid specified is disabled");
return 0;
}
rw_info (0, 0, 0,
"Exercising the rw_process_kill() behavior "
"when invalid pid specified");
// set to ignore rw_error diagnostic
rw_enable (rw_error, false);
const int res = rw_process_kill (_rw_pid);
// enable rw_error diagnostic
rw_enable (rw_error);
rw_assert (-1 == res, __FILE__, __LINE__,
"rw_process_kill returns %ld, expected -1",
long (res));
if (-1 != res)
return 1;
rw_assert (ESRCH == errno, __FILE__, __LINE__,
"errno: expected ESRCH, got %{#m}");
return ESRCH == errno ? 0 : 1;
}
static int
run_test (int argc, char** argv)
{
if (_rw_child) {
rw_info (0, 0, 0,
"The child process: _rw_child = %i", _rw_child);
if (2 == _rw_child) {
// simulate the deadlock
while (true) ;
}
// compare number of parameters with expected
if (nargs != argc)
return nargs;
// compare the parameters with expected
for (int i = 1; i < argc; ++i) {
if (0 != strcmp (argv [i], args [i]))
return i;
}
return 0;
}
args [0] = argv [0];
int fails = 0;
if (test_process_create1 ())
++fails;
if (test_process_create2 ())
++fails;
if (test_process_deadlocked ())
++fails;
if (test_process_create_fail ())
++fails;
if (test_waitpid_fail ())
++fails;
if (test_process_kill_fail ())
++fails;
return fails;
}
int main (int argc, char *argv[])
{
return rw_test (argc, argv, __FILE__,
"0.process",
"", run_test,
"|-child#0 "
"|-timeout#",
&_rw_child,
&_rw_timeout,
0 /*sentinel*/);
}

View File

@@ -0,0 +1,190 @@
/************************************************************************
*
* 0.strcmp.cpp - test exercising the rw_strcmp() utility functions
*
* $Id: 0.strncmp.cpp 430542 2006-08-10 21:33:38Z sebor $
*
************************************************************************
*
* 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 2004-2006 Rogue Wave Software.
*
**************************************************************************/
#include <valcmp.h> // for rw_strncmp()
#include <stdio.h> // for fprintf()
/***********************************************************************/
static int
run_test (int, char*[])
{
int exit_status = 0;
// rw_strncmp():
//
// compares up to a maximum number of characters from the two strings
// posisbly including any embedded NULs (when the CMP_NULTERM bit is
// clear) and returns -1, 0, or +1 if the first string compares less,
// equal, or greater, respectively, than the second string, or the
// offset of the first mismatched character (when the CMP_RETOFF bit
// is set) or an out of bounds value such as -1 when no such character
// exists
//
// rw_strncmp(s1, s2) is equivalent to a call to strcmp(s1, s2) when
// the type of s1 and s2 is char*, wcscmp(s1, s2) when the type is
// wchar_t*
//
// when (N != SIZE_MAX) is true,
// rw_strncmp(s1, s2, N, CMP_NULTERM) is equivalent to a call to
// strncmp(s1, s2, N) or wcsncmp(s1, s2, N), respectively
//
// rw_strncmp(s1, s2, N) is equivalent to a call to memcmp(s1, s2, N)
// or wmemcmp(s1, s2, n), respectively
#undef TEST
#define TEST(expect, s1, s2, nc, fl) \
do { \
const int result = (fl) < 0 ? \
rw_strncmp (s1, s2, nc) : rw_strncmp (s1, s2, nc, fl); \
if (expect != result) { \
exit_status = 2; \
fprintf (stderr, "line %d: rw_strncmp(%p, %p, %u, %d) == %d, " \
"got %d\n", __LINE__, (const void*)s1, \
(const void*)s2, unsigned (nc), fl, expect, \
result); \
} \
} while (0)
//////////////////////////////////////////////////////////////////
printf ("rw_strncmp(const char*, const char*, size_t, int)\n");
// +------------------ expected result
// | +--------------- first string
// | | +----------- second string
// | | | +------ value of N
// | | | | +-- value of flags, or none when -1
// | | | | |
// v v v v v
TEST ( 0, "", "", _RWSTD_SIZE_MAX, -1);
TEST (+1, "a", "", _RWSTD_SIZE_MAX, -1);
TEST (-1, "", "a", _RWSTD_SIZE_MAX, -1);
TEST ( 0, "a", "b", 0, -1);
TEST ( 0, "a\0b", "a\0b", 3, -1);
TEST ( 0, "a\0c", "a\0b", 3, -1);
TEST ( 0, "a\0b", "a\0c", 3, -1);
TEST ( 0, "a\0b", "a\0b", 3, CMP_NULTERM);
TEST (+1, "a\0c", "a\0b", 3, 0);
TEST (-1, "a\0b", "a\0c", 3, 0);
TEST (-1, "a\0b", "a\0b", 3, CMP_NULTERM | CMP_RETOFF);
TEST (-1, "a\0c", "a\0b", 3, CMP_NULTERM | CMP_RETOFF);
TEST (-1, "a\0b", "a\0c", 3, CMP_NULTERM | CMP_RETOFF);
TEST (-1, "a\0b", "a\0b", 3, CMP_RETOFF);
TEST ( 2, "a\0c", "a\0b", 3, CMP_RETOFF);
TEST ( 2, "a\0b", "a\0c", 3, CMP_RETOFF);
#ifndef _RWSTD_NO_WCHAR_T
//////////////////////////////////////////////////////////////////
printf ("rw_strncmp(const wchar_t*, const wchar_t*, size_t, int)\n");
TEST ( 0, L"", L"", ~0, -1);
TEST (+1, L"a", L"", ~0, -1);
TEST (-1, L"", L"a", ~0, -1);
TEST ( 0, L"a", L"b", 0, -1);
TEST ( 0, L"a\0b", L"a\0b", 3, -1);
TEST ( 0, L"a\0c", L"a\0b", 3, -1);
TEST ( 0, L"a\0b", L"a\0c", 3, -1);
TEST ( 0, L"a\0b", L"a\0b", 3, 0);
TEST (+1, L"a\0c", L"a\0b", 3, 0);
TEST (-1, L"a\0b", L"a\0c", 3, 0);
TEST (-1, L"a\0b", L"a\0b", 3, CMP_RETOFF);
TEST (+2, L"a\0c", L"a\0b", 3, CMP_RETOFF);
TEST (+2, L"a\0b", L"a\0c", 3, CMP_RETOFF);
TEST (-1, L"a\0b", L"a\0b", 3, CMP_NULTERM | CMP_RETOFF);
TEST (-1, L"a\0c", L"a\0b", 3, CMP_NULTERM | CMP_RETOFF);
TEST (-1, L"a\0b", L"a\0c", 3, CMP_NULTERM | CMP_RETOFF);
//////////////////////////////////////////////////////////////////
printf ("rw_strncmp(const wchar_t*, const char*, size_t, int)\n");
TEST ( 0, L"", "", ~0, -1);
TEST (+1, L"a", "", ~0, -1);
TEST (-1, L"", "a", ~0, -1);
TEST ( 0, L"a", "b", 0, -1);
TEST ( 0, L"a\0b", "a\0b", 3, -1);
TEST ( 0, L"a\0c", "a\0b", 3, -1);
TEST ( 0, L"a\0b", "a\0c", 3, -1);
TEST ( 0, L"a\0b", "a\0b", 3, CMP_NULTERM);
TEST ( 0, L"a\0c", "a\0b", 3, CMP_NULTERM);
TEST ( 0, L"a\0b", "a\0c", 3, CMP_NULTERM);
TEST (-1, L"a\0b", "a\0b", 3, CMP_RETOFF);
TEST ( 2, L"a\0c", "a\0b", 3, CMP_RETOFF);
TEST ( 2, L"a\0b", "a\0c", 3, CMP_RETOFF);
TEST (-1, L"a\0b", "a\0b", 3, CMP_NULTERM | CMP_RETOFF);
TEST (-1, L"a\0c", "a\0b", 3, CMP_NULTERM | CMP_RETOFF);
TEST (-1, L"a\0b", "a\0c", 3, CMP_NULTERM | CMP_RETOFF);
//////////////////////////////////////////////////////////////////
printf ("rw_strncmp(const char*, const wchar_t*, size_t, int)\n");
TEST ( 0, "", L"", ~0, -1);
TEST (+1, "a", L"", ~0, -1);
TEST (-1, "", L"a", ~0, -1);
TEST ( 0, "a", L"b", 0, -1);
TEST ( 0, "a\0b", L"a\0b", 3, -1);
TEST ( 0, "a\0c", L"a\0b", 3, -1);
TEST ( 0, "a\0b", L"a\0c", 3, -1);
TEST ( 0, "a\0b", L"a\0b", 3, CMP_NULTERM);
TEST ( 0, "a\0c", L"a\0b", 3, CMP_NULTERM);
TEST ( 0, "a\0b", L"a\0c", 3, CMP_NULTERM);
TEST (-1, "a\0b", L"a\0b", 3, CMP_RETOFF);
TEST ( 2, "a\0c", L"a\0b", 3, CMP_RETOFF);
TEST ( 2, "a\0b", L"a\0c", 3, CMP_RETOFF);
TEST (-1, "a\0b", L"a\0b", 3, CMP_NULTERM | CMP_RETOFF);
TEST (-1, "a\0c", L"a\0b", 3, CMP_NULTERM | CMP_RETOFF);
TEST (-1, "a\0b", L"a\0c", 3, CMP_NULTERM | CMP_RETOFF);
#endif // _RWSTD_NO_WCHAR_T
return exit_status;
}
/***********************************************************************/
int main (int argc, char *argv[])
{
return run_test (argc, argv);
}

View File

@@ -0,0 +1,307 @@
/************************************************************************
*
* valcmp.cpp - test exercising the rw_valcmp() family
* of utility functions
*
* $Id: 0.valcmp.cpp 475989 2006-11-16 23:48:45Z sebor $
*
************************************************************************
*
* 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-2006 Rogue Wave Software.
*
**************************************************************************/
#include <valcmp.h>
#include <stdio.h> // for fprintf, size_t
// the exit status of the whole test
static int exit_status;
template <class T, class U>
void
test_case (const T* /* dummy */, const U* /* dummy */,
const char *tname, const char *uname,
int line, int expect,
const char *str1, const char *str2, size_t nelems, int flags)
{
T buf1 [256] = { T () };
U buf2 [256] = { U () };
typedef unsigned char UChar;
for (size_t i = 0; i != nelems; ++i) {
buf1 [i] = T (_RWSTD_STATIC_CAST (UChar, str1 [i]));
buf2 [i] = U (_RWSTD_STATIC_CAST (UChar, str2 [i]));
}
const int result = rw_valcmp (buf1, buf2, nelems, flags);
if (result != expect) {
fprintf (stderr,
"line %d: %d == rw_valcmp(const %s* = %p, const %s* = %p, "
"%u, %d), got %d\n",
line, expect, tname, (void*)buf1, uname, (void*)buf2,
unsigned (nelems), flags, result);
exit_status = 1;
}
}
struct Case {
int line;
int expect;
const char *str1;
const char *str2;
size_t nelems;
int flags;
};
extern const Case cases [] = {
#define CASE(expect, str1, str2, nelems, flags) \
{ __LINE__, expect, str1, str2, nelems, flags }
CASE ( 0, 0, 0, 0, 0),
CASE ( 0, "", "", 0, 0),
CASE ( 0, "", "", 1, 0),
CASE ( 0, "a", "\0", 0, 0),
CASE (+1, "a", "\0", 1, 0),
CASE (+1, "a", "\0", 2, 0),
CASE ( 0, "\0", "a", 0, 0),
CASE (-1, "\0", "a", 1, 0),
CASE (-1, "\0", "a", 2, 0),
CASE ( 0, "ab", "\0\0", 0, 0),
CASE (+1, "ab", "\0\0", 1, 0),
CASE (+1, "ab", "\0\0", 2, 0),
CASE (+1, "ab", "\0\0", 3, 0),
CASE ( 0, "\0\0", "ab", 0, 0),
CASE (-1, "\0\0", "ab", 1, 0),
CASE (-1, "\0\0", "ab", 2, 0),
CASE (-1, "\0\0", "ab", 3, 0),
CASE ( 0, "ab", "a\0", 0, 0),
CASE ( 0, "ab", "a\0", 1, 0),
CASE (+1, "ab", "a\0", 2, 0),
CASE (+1, "ab", "a\0", 3, 0),
CASE ( 0, "a\0", "ab", 0, 0),
CASE ( 0, "a\0", "ab", 1, 0),
CASE (-1, "a\0", "ab", 2, 0),
CASE (-1, "a\0", "ab", 3, 0),
CASE ( 0, "\0ab", "\0a\0", 0, 0),
CASE ( 0, "\0ab", "\0a\0", 1, 0),
CASE ( 0, "\0ab", "\0a\0", 2, 0),
CASE (+1, "\0ab", "\0a\0", 3, 0),
CASE (+1, "\0ab", "\0a\0", 4, 0),
CASE ( 0, "\0a\0", "\0ab", 0, 0),
CASE ( 0, "\0a\0", "\0ab", 1, 0),
CASE ( 0, "\0a\0", "\0ab", 2, 0),
CASE (-1, "\0a\0", "\0ab", 3, 0),
CASE (-1, "\0a\0", "\0ab", 4, 0),
CASE ( 0, "abc", "aB\0", 0, 0),
CASE ( 0, "abc", "aB\0", 1, 0),
CASE (+1, "abc", "aB\0", 2, 0),
CASE (+1, "abc", "aB\0", 3, 0),
CASE (+1, "abc", "aB\0", 4, 0),
CASE ( 0, "aB\0", "abc", 0, 0),
CASE ( 0, "aB\0", "abc", 1, 0),
CASE (-1, "aB\0", "abc", 2, 0),
CASE (-1, "aB\0", "abc", 3, 0),
CASE (-1, "aB\0", "abc", 4, 0),
CASE ( 0, "a\0b\0c\0d", "a\0b\0c\0R", 0, 0),
CASE ( 0, "a\0b\0c\0e", "a\0b\0c\0S", 1, 0),
CASE ( 0, "a\0b\0c\0f", "a\0b\0c\0T", 2, 0),
CASE ( 0, "a\0b\0c\0g", "a\0b\0c\0U", 3, 0),
CASE ( 0, "a\0b\0c\0h", "a\0b\0c\0V", 4, 0),
CASE ( 0, "a\0b\0c\0i", "a\0b\0c\0W", 5, 0),
CASE ( 0, "a\0b\0c\0j", "a\0b\0c\0X", 6, 0),
CASE (+1, "a\0b\0c\0k", "a\0b\0c\0Y", 7, 0),
CASE (+1, "a\0b\0c\0l", "a\0b\0c\0Z", 8, 0),
CASE ( 0, "a\0b\0c\0R", "a\0b\0c\0d", 0, 0),
CASE ( 0, "a\0b\0c\0S", "a\0b\0c\0d", 1, 0),
CASE ( 0, "a\0b\0c\0T", "a\0b\0c\0d", 2, 0),
CASE ( 0, "a\0b\0c\0U", "a\0b\0c\0d", 3, 0),
CASE ( 0, "a\0b\0c\0V", "a\0b\0c\0d", 4, 0),
CASE ( 0, "a\0b\0c\0W", "a\0b\0c\0d", 5, 0),
CASE ( 0, "a\0b\0c\0X", "a\0b\0c\0d", 6, 0),
CASE (-1, "a\0b\0c\0Y", "a\0b\0c\0d", 7, 0),
CASE (-1, "a\0b\0c\0Z", "a\0b\0c\0d", 8, 0),
CASE ( 0, "a\0b\0c\0R", "a\0b\0c\0d", 0, CMP_NOCASE),
CASE ( 0, "a\0b\0c\0S", "a\0b\0c\0e", 1, CMP_NOCASE),
CASE ( 0, "a\0b\0c\0T", "a\0b\0c\0f", 2, CMP_NOCASE),
CASE ( 0, "a\0b\0c\0U", "a\0b\0c\0g", 3, CMP_NOCASE),
CASE ( 0, "a\0b\0c\0V", "a\0b\0c\0h", 4, CMP_NOCASE),
CASE ( 0, "a\0b\0c\0W", "a\0b\0c\0i", 5, CMP_NOCASE),
CASE ( 0, "a\0b\0c\0X", "a\0b\0c\0j", 6, CMP_NOCASE),
CASE (+1, "a\0b\0c\0Y", "a\0b\0c\0k", 7, CMP_NOCASE),
CASE (+1, "a\0b\0c\0Z", "a\0b\0c\0l", 8, CMP_NOCASE),
CASE ( 0, "A\0b\0c\0d", "a\0B\0c\0R", 0, CMP_NOCASE),
CASE ( 0, "A\0b\0c\0e", "a\0B\0c\0S", 1, CMP_NOCASE),
CASE ( 0, "A\0b\0c\0f", "a\0B\0c\0T", 2, CMP_NOCASE),
CASE ( 0, "A\0b\0c\0g", "a\0B\0c\0U", 3, CMP_NOCASE),
CASE ( 0, "A\0b\0c\0h", "a\0B\0c\0V", 4, CMP_NOCASE),
CASE ( 0, "A\0b\0c\0i", "a\0B\0c\0W", 5, CMP_NOCASE),
CASE ( 0, "A\0b\0c\0j", "a\0B\0c\0X", 6, CMP_NOCASE),
CASE (-1, "A\0b\0c\0k", "a\0B\0c\0Y", 7, CMP_NOCASE),
CASE (-1, "A\0b\0c\0l", "a\0B\0c\0Z", 8, CMP_NOCASE),
CASE ( 0, "Abc", "aB\0", 0, CMP_NOCASE),
CASE ( 0, "Abc", "aB\0", 1, CMP_NOCASE),
CASE ( 0, "Abc", "aB\0", 2, CMP_NOCASE),
CASE (+1, "Abc", "aB\0", 3, CMP_NOCASE),
CASE (+1, "Abc", "aB\0", 4, CMP_NOCASE),
CASE ( 0, "aB\0", "Abc", 0, CMP_NOCASE),
CASE ( 0, "aB\0", "Abc", 1, CMP_NOCASE),
CASE ( 0, "aB\0", "Abc", 2, CMP_NOCASE),
CASE (-1, "aB\0", "Abc", 3, CMP_NOCASE),
CASE (-1, "aB\0", "Abc", 4, CMP_NOCASE),
CASE ( 0, "abcd", "abc\0", 0, CMP_NULTERM),
CASE ( 0, "abcd", "abc\0", 1, CMP_NULTERM),
CASE ( 0, "abcd", "abc\0", 2, CMP_NULTERM),
CASE ( 0, "abcd", "abc\0", 3, CMP_NULTERM),
CASE (+1, "abcd", "abc\0", 4, CMP_NULTERM),
CASE (+1, "abcd", "abc\0", 5, CMP_NULTERM),
CASE ( 0, "abc\0", "abcd", 0, CMP_NULTERM),
CASE ( 0, "abc\0", "abcd", 1, CMP_NULTERM),
CASE ( 0, "abc\0", "abcd", 2, CMP_NULTERM),
CASE ( 0, "abc\0", "abcd", 3, CMP_NULTERM),
CASE (-1, "abc\0", "abcd", 4, CMP_NULTERM),
CASE (-1, "abc\0", "abcd", 5, CMP_NULTERM)
};
template <class T, class U>
void
test_all_cases (const T* /* dummy */, const U* /* dummy */,
const char *tname, const char *uname)
{
// print out the name of the specialization being tested
static const int one_time_per_specialization =
printf ("rw_valcmp(const %s*, const %s*, size_t, int)\n",
tname, uname);
_RWSTD_UNUSED (one_time_per_specialization);
for (size_t i = 0; i != sizeof cases / sizeof cases; ++i) {
test_case ((T*)0, (U*)0,
tname, uname,
cases [i].line,
cases [i].expect,
cases [i].str1,
cases [i].str2,
cases [i].nelems,
cases [i].flags);
}
}
#define STR(x) #x
template <class T>
void
run_test (const T* /* dummy */, const char *tname)
{
#define TEST_ALL_CASES(U) test_all_cases ((T*)0, (U*)0, tname, STR (U))
// run all test cases for all integral types except bool
TEST_ALL_CASES (char);
TEST_ALL_CASES (signed char);
TEST_ALL_CASES (unsigned char);
TEST_ALL_CASES (short);
TEST_ALL_CASES (unsigned short);
TEST_ALL_CASES (int);
TEST_ALL_CASES (unsigned int);
TEST_ALL_CASES (long);
TEST_ALL_CASES (unsigned long);
#ifdef _RWSTD_LONG_LONG
TEST_ALL_CASES (_RWSTD_LONG_LONG);
TEST_ALL_CASES (unsigned _RWSTD_LONG_LONG);
#endif // _RWSTD_LONG_LONG
#ifndef _RWSTD_NO_WCHAR_T
TEST_ALL_CASES (wchar_t);
#endif // _RWSTD_NO_WCHAR_T
}
int main ()
{
#define RUN_TEST(T) run_test ((T*)0, STR (T))
// run the for all integral types except bool
RUN_TEST (char);
RUN_TEST (signed char);
RUN_TEST (unsigned char);
RUN_TEST (short);
RUN_TEST (unsigned short);
RUN_TEST (int);
RUN_TEST (unsigned int);
RUN_TEST (long);
RUN_TEST (unsigned long);
#ifdef _RWSTD_LONG_LONG
RUN_TEST (_RWSTD_LONG_LONG);
RUN_TEST (unsigned _RWSTD_LONG_LONG);
#endif // _RWSTD_LONG_LONG
#ifndef _RWSTD_NO_WCHAR_T
RUN_TEST (wchar_t);
#endif // _RWSTD_NO_WCHAR_T
return exit_status;
}