Я сделал макрос __FILENAME__
, который избегает каждый раз обрезать полный путь.Проблема заключается в том, чтобы хранить полученное имя файла в локальной переменной cpp.
Это легко сделать, определив статическую глобальную переменную в файле .h .Это определение дает отдельные и независимые переменные в каждом файле .cpp , который включает .h .Чтобы обеспечить многопоточность, необходимо, чтобы переменная (и) также была локальной (TLS).
Одна переменная хранит имя файла (сокращенное).Другой содержит необрезанное значение, которое дал __FILE__
.Файл h:
static __declspec( thread ) const char* fileAndThreadLocal_strFilePath = NULL;
static __declspec( thread ) const char* fileAndThreadLocal_strFileName = NULL;
Сам макрос вызывает метод со всей логикой:
#define __FILENAME__ \
GetSourceFileName(__FILE__, fileAndThreadLocal_strFilePath, fileAndThreadLocal_strFileName)
И функция реализована следующим образом:
const char* GetSourceFileName(const char* strFilePath,
const char*& rstrFilePathHolder,
const char*& rstrFileNameHolder)
{
if(strFilePath != rstrFilePathHolder)
{
//
// This if works in 2 cases:
// - when first time called in the cpp (ordinary case) or
// - when the macro __FILENAME__ is used in both h and cpp files
// and so the method is consequentially called
// once with strFilePath == "UserPath/HeaderFileThatUsesMyMACRO.h" and
// once with strFilePath == "UserPath/CPPFileThatUsesMyMACRO.cpp"
//
rstrFileNameHolder = removePath(strFilePath);
rstrFilePathHolder = strFilePath;
}
return rstrFileNameHolder;
}
RemovePath () может быть реализован по-разному, но быстрый и простой, кажется, с strrchr:
const char* removePath(const char* path)
{
const char* pDelimeter = strrchr (path, '\\');
if (pDelimeter)
path = pDelimeter+1;
pDelimeter = strrchr (path, '/');
if (pDelimeter)
path = pDelimeter+1;
return path;
}