0

I am implementing a logger in "C" and the core function is :

void log(Level tag, const char *message)

This function will be called in a client file which is different from my log.c file.

My question is :

How is it possible for this function to get the name of the caller file without passing it as a parameter (like adding another char *) argument and then passing it __FILE__ in the caller file ?

Thank you.

Smallware
  • 72
  • 6
  • You can't find the file name holding the calling function from within your `log` function. (Beware: `#include ` declares a function `log()` too — with a very different signature). You have to pass it as an argument. Use a macro to automate that: `#define LOG(tag, msg) debug_log(__FILE__, tag, msg)` or something similar. – Jonathan Leffler Jan 04 '16 at 06:55
  • 1
    You should look at [`#define` macro for debug printing](https://stackoverflow.com/questions/1644868/c-define-macro-for-debug-printing/) too. – Jonathan Leffler Jan 04 '16 at 06:59

3 Answers3

4

The first thing to do is rename log() to debug_log() or something so you can use #include <math.h> as well as the logging mechanism. Thanks, @JonathanLeffler.

Next thing you have to do is change debug_log so it accepts the file name as an argument.

void debug_log(Level tag, const char *message, char const* filename);

Then, add a macro to help with using the macro __FILE__ automatically.

#define LOG_MESSAGE(tag, message) debug_log((tag), (message), __FILE__)

Then, use the macro instead of the function in client code.

LOG_MESSAGE(my_tag, my_message);
R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

Make it a macro instead, which always passes __FILE__ to the function it calls.

That way the logger calls are cleaner-looking (you don't see the extra argument).

For example, to always add function name and line number, I use the following which also has variable arguments so you can call it like printf() with a format string and arguments. This requires GCC macro features.

#define DBG(x, args...) ({ \
    if (debug) { \
        fprintf(stderr, "%s:%d: " x "\n", __func__, __LINE__, ##args);  \
    } \
})
blueshift
  • 6,742
  • 2
  • 39
  • 63
0

If you are using GCC and you don't mind compiling with -rdynamic, you can use function backtrace() to get a backtrace, and then either dladdr() to find the name of the single function (the fist one in the list, returned by backtrace()), or backtrace_symbols to get symbols for all functions in stack, and use just a first one.

A bit more details here - https://stackoverflow.com/a/351980/28494

See man for details.

Community
  • 1
  • 1
qrdl
  • 34,062
  • 14
  • 56
  • 86