Well, not only preprocessor has to be used - but it won't be seen to the end user.
When you want BASENAME()
to be used in some file - use this header file basename.h
:
// basename.h
#include <string.h>
static size_t basename_start_calc(const char* filename)
{
const char* base = strrchr(filename, '/');
return base ? (base - filename + 1) : 0;
}
static inline size_t basename_start(const char* filename)
{
static size_t retval = basename_start_calc(filename);
return retval;
}
#define STR_(t) #t
#define STR(t) STR_(t)
#define BASENAME() ((__FILE__ ":" STR(__LINE__)) + basename_start(__FILE__))
An ideone example here.
basename_start(__FILE__)
will be evaluated only once for the given source file. Unfortunately you can't use this solution in header files - only in source files. You can change it, so it can be used everywhere - but then start of baseline for the given filename will be calculated every time. Just use in BASENAME()
basename_start_calc(__FILE__)
instead of basename_start(__FILE__)
...
I believe this is best you can have automatically.
Of course you can define by hand in every file macro:
#define BASENAME() ("somefile.cpp:" STR(__LINE__))
but I am not sure this is what you wanted....