parent
7338ddc5cf
commit
5ac0645c20
7 changed files with 199 additions and 12 deletions
Binary file not shown.
@ -0,0 +1,132 @@ |
|||||||
|
/** @file
|
||||||
|
|
||||||
|
$Id: autofunctiontracelog4cxx.cpp,v 1.3 2005/04/14 19:12:18 marc Exp $ |
||||||
|
|
||||||
|
$Date: 2005/04/14 19:12:18 $ |
||||||
|
$Author: marc $ |
||||||
|
|
||||||
|
@copy © Marc Wäckerlin |
||||||
|
@license LGPL, see file <a href="license.html">COPYING</a> |
||||||
|
|
||||||
|
1 2 3 4 5 6 7 8 |
||||||
|
5678901234567890123456789012345678901234567890123456789012345678901234567890 |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __GNUG__ |
||||||
|
#error GNU C++ Compiler is required for automatical function trace |
||||||
|
#endif |
||||||
|
|
||||||
|
#include <mrw/string.hpp> |
||||||
|
#include <mrw/stacktrace.hpp> |
||||||
|
#include <iostream> |
||||||
|
#include <iomanip> |
||||||
|
|
||||||
|
#if (__GNUC__==3 && __GNUC_MINOR__<4 || __GNUC__<3) && _REENTRANT && !_MT |
||||||
|
#define _MT |
||||||
|
#endif |
||||||
|
|
||||||
|
// these are special built in functions of GNU Compiler Collection
|
||||||
|
extern "C" void __cyg_profile_func_enter (void *, void *) __attribute__((no_instrument_function)); |
||||||
|
extern "C" void __cyg_profile_func_exit (void *, void *) __attribute__((no_instrument_function)); |
||||||
|
|
||||||
|
namespace mrw { |
||||||
|
|
||||||
|
// workaround doxygen problem:
|
||||||
|
// - the C++ compiler compiles the following code
|
||||||
|
// - doxygen ignores it
|
||||||
|
#ifndef LET_DOXYGEN_IGNORE_THIS // no matching class member found for
|
||||||
|
// int mrw::ThreadInfo::level()
|
||||||
|
struct ThreadInfo { |
||||||
|
int level; |
||||||
|
bool recurse; |
||||||
|
}; |
||||||
|
#endif |
||||||
|
|
||||||
|
#ifdef _MT |
||||||
|
static __thread ThreadInfo info = {0, false}; |
||||||
|
#else |
||||||
|
static ThreadInfo info = {0, false}; |
||||||
|
#endif |
||||||
|
|
||||||
|
static bool mainPassed(false); |
||||||
|
|
||||||
|
class Lock { |
||||||
|
public: |
||||||
|
Lock() __attribute__((no_instrument_function)); |
||||||
|
~Lock() __attribute__((no_instrument_function)); |
||||||
|
}; |
||||||
|
// workaround doxygen problem:
|
||||||
|
// - the C++ compiler compiles the following code
|
||||||
|
// - doxygen ignores it
|
||||||
|
#ifndef LET_DOXYGEN_IGNORE_THIS // doxygen can't match with __attribute__ above
|
||||||
|
Lock::Lock() { |
||||||
|
info.recurse = true; |
||||||
|
} |
||||||
|
Lock::~Lock() { |
||||||
|
info.recurse = false; |
||||||
|
} |
||||||
|
#endif |
||||||
|
} |
||||||
|
|
||||||
|
extern "C" int main(int, char**); |
||||||
|
|
||||||
|
/** @addtogroup FunctionTrace */ |
||||||
|
//@{
|
||||||
|
|
||||||
|
/** @defgroup AutoFunctionTraceStdlog Automatic Function Trace to standard out for GNU g++
|
||||||
|
|
||||||
|
Same as @ref AutoFunctionTrace, but traces to @c stdlog. |
||||||
|
|
||||||
|
If you link to the library @c libmrwautofunctiontracestdlog using |
||||||
|
a linker option such as: @c -lmrwautofunctiontracestdlog and you |
||||||
|
must enable the GNU Compiler Collection specific function trace |
||||||
|
feature with compile and link option @c -finstrument-functions |
||||||
|
then you get an automatical function trace, that traces to @c |
||||||
|
stdlog. You don't need to change a single line in your code! |
||||||
|
|
||||||
|
*/ |
||||||
|
//@{
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
extern "C" void __cyg_profile_func_enter(void *this_fn, void*) { |
||||||
|
if (!mrw::mainPassed) |
||||||
|
if (this_fn == (void*)&::main) // not ANSI C++ conform...
|
||||||
|
mrw::mainPassed=true; |
||||||
|
else |
||||||
|
return; |
||||||
|
try { |
||||||
|
if (mrw::info.recurse) return; |
||||||
|
mrw::Lock lock; |
||||||
|
{ |
||||||
|
static bool init(mrw::StackTrace::createSymtable()); |
||||||
|
if (!init) return; |
||||||
|
mrw::StackTrace::CodePos pos(mrw::StackTrace::translate(this_fn)); |
||||||
|
std::clog<<std::setw(2+mrw::info.level++)<<std::setfill(' ') |
||||||
|
<<"\\ "<<pos.function<<" ("<<pos.file<<':'<<pos.line<<')' |
||||||
|
<<std::endl; |
||||||
|
} |
||||||
|
} catch (...) {} |
||||||
|
} |
||||||
|
|
||||||
|
extern "C" void __cyg_profile_func_exit(void *this_fn, void*) { |
||||||
|
if (!mrw::mainPassed) |
||||||
|
return; |
||||||
|
else |
||||||
|
if (this_fn == (void*)&::main) { // not ANSI C++ conform...
|
||||||
|
mrw::mainPassed=false; |
||||||
|
return; |
||||||
|
} |
||||||
|
try { |
||||||
|
if (mrw::info.recurse || mrw::info.level==0) return; |
||||||
|
mrw::Lock lock; |
||||||
|
{ |
||||||
|
mrw::StackTrace::CodePos pos(mrw::StackTrace::translate(this_fn)); |
||||||
|
std::clog<<std::setw(2+--mrw::info.level)<<std::setfill(' ') |
||||||
|
<<"/ "<<pos.function<<" ("<<pos.file<<':'<<pos.line<<')' |
||||||
|
<<std::endl; |
||||||
|
} |
||||||
|
} catch (...) {} |
||||||
|
} |
@ -0,0 +1,49 @@ |
|||||||
|
/** @file
|
||||||
|
|
||||||
|
$Id$ |
||||||
|
|
||||||
|
$Date$ |
||||||
|
$Author$ |
||||||
|
|
||||||
|
@copy © Marc Wäckerlin |
||||||
|
@license LGPL, see file <a href="license.html">COPYING</a> |
||||||
|
|
||||||
|
$Log$ |
||||||
|
|
||||||
|
1 2 3 4 5 6 7 8 |
||||||
|
5678901234567890123456789012345678901234567890123456789012345678901234567890 |
||||||
|
*/ |
||||||
|
#include <mrw/string.hpp> |
||||||
|
#include <mrw/list.hpp> |
||||||
|
#include <algorithm> |
||||||
|
|
||||||
|
#include <cppunit/TestFixture.h> |
||||||
|
#include <cppunit/ui/text/TestRunner.h> |
||||||
|
#include <cppunit/extensions/HelperMacros.h> |
||||||
|
#include <cppunit/extensions/TestFactoryRegistry.h> |
||||||
|
|
||||||
|
class StringTest: public CppUnit::TestFixture {
|
||||||
|
public: |
||||||
|
void Join() { |
||||||
|
std::list<std::string> l; |
||||||
|
l<<"Hello"<<"World"<<"here"<<"I"<<"am"; |
||||||
|
CPPUNIT_ASSERT(mrw::join(l)=="Hello World here I am"); |
||||||
|
} |
||||||
|
void Split() { |
||||||
|
std::string text("Hello World here I am"); |
||||||
|
std::list<std::string> a(mrw::split(text)), b; |
||||||
|
b<<"Hello"<<"World"<<"here"<<"I"<<"am"; |
||||||
|
CPPUNIT_ASSERT(equal(a.begin(), a.end(), b.begin())); |
||||||
|
} |
||||||
|
CPPUNIT_TEST_SUITE(StringTest); |
||||||
|
CPPUNIT_TEST(Join); |
||||||
|
CPPUNIT_TEST(Split); |
||||||
|
CPPUNIT_TEST_SUITE_END(); |
||||||
|
}; |
||||||
|
CPPUNIT_TEST_SUITE_REGISTRATION(StringTest); |
||||||
|
|
||||||
|
int main() { |
||||||
|
CppUnit::TextUi::TestRunner runner; |
||||||
|
runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest()); |
||||||
|
return runner.run() ? 0 : 1; |
||||||
|
} |
Loading…
Reference in new issue