Rover Eye
Rover Eye

Reputation: 237

Getting file and function names wherever a function is called

I am using the macros __FILE__ and __func__ for retrieving the file and function location. My code is structured like this... (note i am using a game engine )

Test.h

class TestClass
{
...
void Log(int status);
...
};

Test.cpp

...
void TestClass::Log(int status)
{
printf("%s %s %i",__FILE__,__func__, status);
}
...

.

and i create a class object and use it to log whatever i want to.

example.cpp

#include "Test.h"
    ...
TestClass tt;
    ...
    tt.Log((int)1);
    ...

the problem is that the output pastes the file and function name of the Test.cpp, and note the filename and function of example.cpp.

Is there a way around this or do i have to directly use the printf statement again and again?

Thanks

Upvotes: 2

Views: 378

Answers (3)

Ivaylo Strandjev
Ivaylo Strandjev

Reputation: 71009

Create a macro expansion to call your Log function with extra parameters. Like this:

void Log(const char* filename, const char* funcname, int status)
{
  printf("%s %s %i",filename,funcname, status);
}

...
#define LOG(status) Log(__FILE__, __func__, status)
...


int foo() {
  LOG(3);
}

EDIT: more detailed explanation

This code does not show you how to use the method Log of your class it simply showcases the idea to use macro for what you want.

Also most of the logging implementations I have seen use a static method and therefor do not require an instance of the Logger class itself. That is why I did not propose a macro that also takes a class member.

Upvotes: 1

Luchian Grigore
Luchian Grigore

Reputation: 258638

You don't need to use printf wherever in the code, but you will need to call TestClass::Log with extra parameters __FILE__ and __func__.

Don't threat however, you can create a macro for that so you don't have to write down the extra parameters on each call:

#define TEST_CLASS_LOG(testClassInstance,status) \
              testClassInstance.Log((int)status, __FILE__, __func__);

and instead of calling

tt.Log((int)1);

you would call

TEST_CLASS_LOG(tt,1);

You'd need to change the Log signature to account for the extra parameters of course:

void Log(int status, const char* fileName, const char* functionName);

Also, I see Log isn't accessing any class members, so you can make it even easier and make it static:

class TestClass
{
   static void Log(int status);
};

void TestClass::Log(int status, const char* file, const char* func)
{
   printf("%s %s %i", file, func, status);
}

#define TEST_CLASS_LOG(status) \
                  TestClass::Log((int)status, __FILE__, __func__);

So, if you do it like this, you'd only need to call:

TEST_CLASS_LOG(1);

Unfortunately there's no way to do this automatically, without modifying your code, as macros expand at runtime. What your compiler sees now is:

void TestClass::Log(int status)
{
   printf("%s %s %i","Test.cpp","Log", status);
}

that is why you need the file name and function name passed as parameters.

Upvotes: 2

Lazer
Lazer

Reputation: 94960

You can make file name and function location parameters to the function TestClass::Log(). The call would look similar to below:

TestClass tt;
...
tt.Log(__FILE__,__func__,(int)1);
...

Upvotes: 0

Related Questions