1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
#ifndef __a_ah__
#define __a_ah__
#include <stdio.h>
namespace coveragemonitor {
// data structure used to gather information about a joinpoint
struct Data {
unsigned _id;
};
// data structure used to link the joinpoint data elements
struct Chain {
static Chain *&_first () { static Chain *chain = 0; return chain; }
Data *_data;
Chain *_next;
Chain (Data *data) : _data (data) {
Chain *head = _first ();
_first () = this;
_next = head;
}
};
// data structure used to combine data and chain elements
template <unsigned ID>
struct Collector {
static Data _data;
static Chain _chain;
};
template <unsigned ID> Data Collector<ID>::_data = { ID };
template <unsigned ID> Chain Collector<ID>::_chain (&_data);
} // coveragemonitor
aspect IdChecker {
advice execution ("% ...::%(...)" && !("% IdChecker::%(...)" || "% coveragemonitor::...::%(...)") ) : after () {
using namespace coveragemonitor;
typedef Collector<JoinPoint::JPID> Collector;
// As the compiler recognizes the access to the elements of
// Collector<JoinPoint::JPID> it will create a template instance
// for all joinpoints - even for those that will never be
// visited.
// It is necessary to explicitly mention the _chain element
// here otherwise the compiler will not instantiate
// any Chain elements.
Collector::_chain._data->_id = JoinPoint::JPID;
}
advice execution ("% main(...)") : after() {
coveragemonitor::Chain *first = coveragemonitor::Chain::_first(); // remember starting point
unsigned count = 0;
for (coveragemonitor::Chain *i = first; i; i = i->_next) {
count++;
for (coveragemonitor::Chain *j = first; j; j = j->_next) {
if( (i != j) && (i->_data->_id == j->_data->_id) ) {
printf("Error: duplicate JPID found: %u\n", j->_data->_id);
}
}
}
if(count < 4) {
printf("Error: only %u disjoint JPID(s) found (min 4 required)\n", count);
}
}
};
#endif // __a_ah__
|