/*
* File: test.cpp
* Author: Pete Goodliffe
* Version: 1.10
* Created: 7 June 2001
*
* Purpose: C++ debugging support library
*
* Copyright (c) Pete Goodliffe 2001-2002 (pete@cthree.org)
*
* This file is modifiable/redistributable under the terms of the GNU
* Lesser General Public License.
*
* You should have recieved a copy of the GNU General Public License along
* with this program; see the file COPYING. If not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 0211-1307, USA.
*/
#include "dbg.h"
#include <iostream>
#include <fstream>
#ifdef TEST_WITHOUT_ANY_LIBRARY_USAGE
#undef DO_DBG
#else
#define DO_DBG
#endif
// This is in dbg.cpp too. Sigh.
#ifdef _MSC_VER
#define STDCLK
#else
#define STDCLK std
#endif
/******************************************************************************
* Test harness
*****************************************************************************/
bool ret_true() { return true; }
bool ret_false() { return false; }
class post_test
{
public:
post_test() : a(10) {}
void do_test()
{
#ifdef DO_DBG
dbg::assertion(DBG_ASSERTION(invariant()));
dbg::post_mem_fun<post_test>
pmf(this, &post_test::invariant, DBG_HERE);
dbg::post b(&ret_false, DBG_HERE);
dbg::out(dbg::info) << dbg::prefix() << "hello\n";
#endif
a = 9;
}
private:
bool invariant()
{
return a == 10;
}
int a;
};
int main()
{
std::cout << "********************************************************\n";
std::cout << "dbg test rig\n";
std::cout << "Built with DBG_ENABLED ";
#ifdef DBG_ENABLED
std::cout << "on \n";
#else
std::cout << "off\n";
#endif
std::cout << "Built with API calling enabled: ";
#ifdef DO_DBG
std::cout << "yes";
#else
std::cout << "no ";
#endif
std::cout << "\n";
std::cout << "********************************************************\n";
//dbg::out(dbg::tracing) << DBG_HERE << "\n"; // doesn't work on MSCV 6.0
#ifdef DO_DBG
dbg::out(dbg::tracing) << DBG_HERE << "\n";
#endif
std::cout << "Switching assertions to non fatal\n";
#ifdef DO_DBG
dbg::enable(dbg::all, true);
dbg::attach_ostream(dbg::all, std::cerr);
dbg::attach_ostream(dbg::all, dbg::default_source, std::cerr);
dbg::set_assertion_behaviour(dbg::all, dbg::assertions_continue);
dbg::set_assertion_period(CLOCKS_PER_SEC*1);
dbg::enable_level_prefix(true);
dbg::enable_time_prefix(true);
#endif
std::cout << "--------------------------------------------------------\n";
#ifdef DO_DBG
dbg::out(dbg::tracing) << DBG_HERE << "\n";
#endif
std::cout << "Testing dbg::assertion\n";
#ifdef DO_DBG
dbg::assertion(dbg::info, DBG_ASSERTION(1 == 0));
#endif
std::cout << "--------------------------------------------------------\n";
#ifdef DO_DBG
dbg::out(dbg::tracing) << DBG_HERE << "\n";
#endif
std::cout << "Testing dbg::sentinel\n";
{
#ifdef DO_DBG
dbg::sentinel(dbg::info, DBG_HERE);
#endif
}
std::cout << "--------------------------------------------------------\n";
#ifdef DO_DBG
dbg::out(dbg::tracing) << DBG_HERE << "\n";
#endif
std::cout << "Testing dbg::unimplemented\n";
{
#ifdef DO_DBG
dbg::unimplemented(dbg::info, DBG_HERE);
#endif
}
std::cout << "--------------------------------------------------------\n";
#ifdef DO_DBG
dbg::out(dbg::tracing) << DBG_HERE << "\n";
#endif
std::cout << "Testing dbg::trace\n";
{
#ifdef DO_DBG
dbg::trace trace1("test function 1");
dbg::trace trace2("test function 2");
dbg::trace trace3(DBG_HERE);
dbg::out(dbg::tracing) << dbg::indent(dbg::tracing) << "hello\n";
#endif
}
std::cout << "--------------------------------------------------------\n";
#ifdef DO_DBG
dbg::out(dbg::tracing) << DBG_HERE << "\n";
#endif
std::cout << "Testing dbg::pre_post\n";
{
post_test test_obj;
test_obj.do_test();
}
std::cout << "--------------------------------------------------------\n";
#ifdef DO_DBG
dbg::out(dbg::tracing) << DBG_HERE << "\n";
#endif
std::cout << "Testing dbg::out\n";
{
#ifdef DO_DBG
dbg::out(dbg::info) << "Debug output is of more than " << 1
<< " standard type!\n";
#endif
}
std::cout << "--------------------------------------------------------\n";
#ifdef DO_DBG
dbg::out(dbg::tracing) << DBG_HERE << "\n";
#endif
std::cout << "Testing dbg::check_ptr\n";
{
int a_val = 1, b_val = 0;
int *a = &a_val, *b = &b_val;
#ifdef DO_DBG
dbg::check_ptr(dbg::info, a, DBG_HERE);
dbg::check_ptr(dbg::info, b, DBG_HERE);
#endif
std::cout << "Using some vars: " << *a << "," << *b << "\n";
}
std::cout << "--------------------------------------------------------\n";
#ifdef DO_DBG
dbg::out(dbg::tracing) << DBG_HERE << "\n";
#endif
std::cout << "Testing dbg::check_bounds\n";
{
int a[10];
int index = 9;
#ifdef DO_DBG
dbg::check_bounds(dbg::info, index, a, DBG_HERE);
dbg::check_bounds(dbg::info, 10, a, DBG_HERE);
#endif
a[index] = 4;
}
std::cout << "\n********************************************************\n";
#ifdef DO_DBG
dbg::out(dbg::tracing) << DBG_HERE << "\n";
#endif
std::cout << "Testing debug sources\n";
{
const char *SRC1 = "source type 1";
const char *SRC2 = "source type 2";
std::cout << "Using some vars: " << SRC1 << "," << SRC2 << "\n";
std::ofstream fout1("SRC1.out");
std::ofstream fout2("SRC2.out");
#ifdef DO_DBG
// Turn off all streams. Enable info by default. Attach
// std::cerr to all sources by default. The new streams, as
// they are added, should pick up these defaults. Note
// that just mentioning a source brings it into existance
// (if it doesn't already exist) as a copy of the default
// source.
dbg::enable_all(dbg::all, false);
dbg::enable(dbg::info, dbg::default_source, true);
dbg::attach_ostream(dbg::all, dbg::default_source, std::cerr);
// Disable output on info for SRC1. Should remain on for SRC2
dbg::enable(dbg::info, SRC1, false);
// Try attaching additional streams to the two sources.
dbg::attach_ostream(dbg::all, SRC1, fout1);
dbg::attach_ostream(dbg::all, SRC2, fout2);
// Modify the default source. Should have NO effect,
// since our two sources already exist.
dbg::enable(dbg::all, dbg::default_source, false);
// Do some output on the two sources now.
// Should not print
dbg::assertion(dbg::info, SRC1, DBG_ASSERTION(1 == 0));
// Modify the state of the sources
dbg::enable(dbg::info, SRC1, true);
dbg::enable(dbg::tracing, SRC1, true);
// Should print
dbg::assertion(dbg::info, SRC1, DBG_ASSERTION(1 == 0));
dbg::assertion(dbg::info, SRC2, DBG_ASSERTION(1 == 0));
// Should not print
dbg::assertion(dbg::warning, SRC2, DBG_ASSERTION(1 == 0));
// Should print for SRC1, not for SRC2
dbg::trace tr1(SRC1, DBG_HERE);
dbg::trace tr2(SRC1, "block 2");
dbg::trace tr3(SRC2, "block 3");
{
dbg::trace tr4(SRC1, "block 4");
// Disable tracing on SRC1 in mid-stream, to see what happens.
dbg::enable(dbg::tracing, SRC1, false);
}
// Re-enable tracing on SRC1, for kicks
dbg::enable(dbg::tracing, SRC1, true);
// Try a post object out. It won't print unless
// we turn the warning level on.
dbg::enable(dbg::warning, SRC1, true);
dbg::post b(SRC1, &ret_false, DBG_HERE);
#endif
}
dbg::enable(dbg::all, true);
std::cout << "\n********************************************************\n";
#ifdef DO_DBG
dbg::out(dbg::tracing) << DBG_HERE << "\n";
#endif
std::cout << "Testing dbg::set_assertion_period and looping\n";
{
for (STDCLK::clock_t now = STDCLK::clock();
STDCLK::clock() < now + (CLOCKS_PER_SEC*5);
/*nothing*/)
{
#ifdef DO_DBG
dbg::assertion(DBG_ASSERTION(1 == 0));
#endif
}
}
std::cout << "\n********************************************************\n";
#ifdef DO_DBG
dbg::out(dbg::tracing) << DBG_HERE << "\n";
#endif
std::cout << "Test rig completed succesffully.\n";
std::cout << " ... finishing off fatal for kicks ...\n";
#ifdef DO_DBG
dbg::assertion(dbg::fatal, DBG_ASSERTION(1 == 0));
#endif
return 0;
}