Wednesday, March 11, 2009

Add code expiry for hacks in your projects

Sometimes we are under tight deadlines to finish things, and we are forced to put in some hacks and quick fixes int he code, hoping to fix them later and write them propertly. You can add \\todo comments, and other stuff to remind you, but there is nothing better than a compilation error after a certain date.

I found this bit of code online, and just modified it slightly. You can put a compilation timebomb in your code, and once a certain date passes, your code will no longer compile. You'll be reminded to fix what you wanted to fix.

An example is provided here:

#include <iostream>
#include <sstream>

void assert_fail(const char* expr, int line, char const* file, const char* function);
#ifdef WIN32
#define CUSTOM_ASSERT(x) do { if (x) {} else assert_fail(#x, __LINE__, __FILE__, __FUNCTION__); } while (false)
#else
#define CUSTOM_ASSERT(x) do { if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__); } while (false)
#endif //WIN32

/////////////////////////////
#define YEAR ((((__DATE__ [7] - '0') * 10 + (__DATE__ [8] - '0')) * 10 \
+ (__DATE__ [9] - '0')) * 10 + (__DATE__ [10] - '0'))

#define MONTH (__DATE__ [2] == 'n' ? (__DATE__ [1] == 'a' ? 1 : 6) \
: __DATE__ [2] == 'b' ? 2 \
: __DATE__ [2] == 'r' ? (__DATE__ [0] == 'M' ? 3 : 4) \
: __DATE__ [2] == 'y' ? 5 \
: __DATE__ [2] == 'l' ? 7 \
: __DATE__ [2] == 'g' ? 8 \
: __DATE__ [2] == 'p' ? 9 \
: __DATE__ [2] == 't' ? 10 \
: __DATE__ [2] == 'v' ? 11 : 12)

#define DAY ((__DATE__ [4] == ' ' ? 0 : __DATE__ [4] - '0') * 10 \
+ (__DATE__ [5] - '0'))

#define DATE_AS_INT (((YEAR - 2000) * 12 + MONTH) * 31 + DAY)YEAR - 2000) * 12 + MONTH) * 31 + DAY)

#define UNIQUE_NAME( Y,M,D ) ReviewBefore##_##Y##_##M##_##D##_##line
#define REVIEW_DATE( YYYY, MM, DD ) (((YYYY - 2000) * 12 + MM) * 31 + DD)
#define COMPILE_DATE (((YEAR - 2000) * 12 + MONTH) * 31 + DAY)

#define REVIEW_BEFORE( YYYY, MM, DD ) \
static const struct UNIQUE_NAME(YYYY,MM,DD)##__LINE__ { UNIQUE_NAME(YYYY,MM,DD)##__LINE__() { \
assert( COMPILE_DATE < REVIEW_DATE(YYYY, MM, DD) ); \
} } UNIQUE_NAME(YYYY,MM,DD)##__LINE__

#define EXPIRED "This code has expired"
#define REVIEW_BEFORE_STMT( YYYY, MM, DD ) \
CUSTOM_ASSERT(COMPILE_DATE < REVIEW_DATE(YYYY, MM, DD) )

void assert_fail(const char* expr, int line, char const* file, const char* function)
{
std::cerr << "Code obselete" << std::endl;
std::ostringstream str;
str << "Expresion: " << expr << "\n"
<< "line: " << line << "\n"
<< "file: " << file << "\n"
<< "function: " << function << "\n";

std::cerr << str.str() << std::endl;
}

int main()
{
REVIEW_BEFORE_STMT(2000,1,1);
std::cout << COMPILE_DATE << std::endl;

return 0;
}

0 comments: