#define expression(p_condition) \
( \
{ \
static int exec_count = 0; \
bool condition = p_condition; \
std::cout \
<< "line(" << __LINE__ << ") " \
<< "exec_count(" << ++exec_count << ") " \
<< "condition_value(" << std::boolalpha << condition << std::noboolalpha << ") " \
<< "condition_code(" << #p_condition << ") " \
<< std::endl; \
condition; \
} \
)
#define if(p_condition) if(expression(p_condition))
#define while(p_condition) while(expression(p_condition))
... du code mono-thread (avec des if et des while) à inspecter ...
#undef if
#undef while
// Malheureusement, je n'ai pas de solution pour la boucle for ; hormis convertir les boucles for en boucle while...
// petit hack a 2 balles :
#define FOR( init, cond, inc ) \
for( (init) ; expression(cond) ;( inc ))
{
int i=0;
FOR( (i=0) , (i!=42) , (i++) ) {
std::cout<<i<<std::endl;
}
}
Le hack ci-dessus ne vaut rien car il demande trop de modif inutiles !
Celui-ci est meilleur :
soit une boucle for comme ceci : for(init; cond; incr)
il suffit de la changer en : for(init; expression(cond); incr)
- inspector.hpp
#ifndef INSPECTOR_HPP
#define INSPECTOR_HPP
#include <pthread.h>
#include <iostream>
class ScopedMutex
{
public:
ScopedMutex(pthread_mutex_t & p_mutex);
~ScopedMutex();
private:
ScopedMutex(const ScopedMutex &);
ScopedMutex & operator=(const ScopedMutex &);
pthread_mutex_t & m_mutex;
};
int register_exec_count_ts(const char * p_exec_count_location, int & p_exec_count);
void reset_exec_count_ts(const char * p_exec_count_location = 0);
pthread_mutex_t & get_mutex();
int register_exec_count(const char * p_exec_count_location, int & p_exec_count);
void reset_exec_count(const char * p_exec_count_location = 0);
std::ostream & print(std::ostream & p_ostream, const char * p_location, int p_exec_count, bool p_condition_value);
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define LOCATION __FILE__ ":" TOSTRING(__LINE__) ":"
#define PRINT(p_exec_count, p_condition_value) print(std::cout, LOCATION, (p_exec_count), (p_condition_value))
#define EXPRESSION(p_condition) \
( \
{ \
static int exec_count = 0; \
bool condition = (p_condition); \
{ \
ScopedMutex scoped_mutex(get_mutex()); \
{ \
static int tmp = register_exec_count(LOCATION, exec_count); \
tmp = tmp; \
} \
PRINT(++exec_count, condition) << #p_condition << std::endl; \
} \
condition; \
} \
)
#endif
- inspector.cpp
#include "inspector.hpp"
#include <map>
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER ;
static std::map<const char *, int *> exec_count_container ;
ScopedMutex::ScopedMutex
(
pthread_mutex_t & p_mutex
):
m_mutex(p_mutex)
{
pthread_mutex_lock(&m_mutex);
}
ScopedMutex::~ScopedMutex()
{
pthread_mutex_unlock(&m_mutex);
}
int register_exec_count_ts
(
const char * p_exec_count_location,
int & p_exec_count
)
{
ScopedMutex scoped_mutex(mutex);
return(register_exec_count(p_exec_count_location, p_exec_count));
}
void reset_exec_count_ts
(
const char * p_exec_count_location
)
{
ScopedMutex scoped_mutex(mutex);
reset_exec_count(p_exec_count_location);
}
pthread_mutex_t & get_mutex()
{
return(mutex);
}
int register_exec_count
(
const char * p_exec_count_location,
int & p_exec_count
)
{
exec_count_container.insert(std::pair<const char *, int *>(p_exec_count_location, &p_exec_count));
return(0);
}
void reset_exec_count
(
const char * p_exec_count_location
)
{
if (!p_exec_count_location)
{
for (std::map<const char *, int *>::const_iterator it = exec_count_container.begin();
it != exec_count_container.end();
++it)
{
*(it->second) = 0;
}
}
else
{
std::map<const char *, int *>::const_iterator it = exec_count_container.find(p_exec_count_location);
if (it != exec_count_container.end())
{
*(it->second) = 0;
}
}
}
std::ostream & print
(
std::ostream & p_ostream,
const char * p_location,
int p_exec_count,
bool p_condition_value
)
{
if (0 < p_exec_count)
{
p_ostream
<< p_location << "@"
<< p_exec_count << "@"
<< std::boolalpha << p_condition_value << std::noboolalpha << "@";
}
else
{
p_ostream
<< p_location << "@"
<< "N/A" << "@"
<< "N/A" << "@";
}
return(p_ostream);
}
#define if(p_condition) if(EXPRESSION(p_condition))
#define while(p_condition) while(EXPRESSION(p_condition))
void foo()
{
if (0 == 0) ;
EXPRESSION(1 != 1);
}
int main()
{
foo();
foo();
reset_exec_count_ts();
foo();
PRINT(0, false) << "end of program" << std::endl;
return(0);
}
#undef if
#undef while
./inspector | column -t -s @
inspector.cpp:109: 1 true 0 == 0
inspector.cpp:111: 1 false 1 != 1
inspector.cpp:109: 2 true 0 == 0
inspector.cpp:111: 2 false 1 != 1
inspector.cpp:109: 1 true 0 == 0
inspector.cpp:111: 1 false 1 != 1
inspector.cpp:123: N/A N/A end of program