Custom print function with _TIME_, _FILE_, _FUNCTION_, _LINE_

1.2k Views Asked by At

I have following code in debug.h:

#ifndef __DEBUG_H__
#define __DEBUG_H__

#ifdef DEBUG

int al_debug(const char *format,
        const char * time,
        const char * file,
        const char * function,
        int line,
        ...);
#define debug(fmt, args...) al_debug(fmt, __TIME__, __FILE__, __FUNCTION__, __LINE__, args...)
#else /* IF DEBUG NOT DEFINED*/
#define debug(fmt, ...) /* DO NOT PRINT ANYTHING IF DEBUG IS NOT PRESENT */
#endif /* END OF DEBUG */

#endif /* END OF __DEBUG_H__ */

In debug.c:

#include <stdarg.h>                                                     
#include <string.h>                                                     

#define __WRAP_FUNCTION__                                               
#include "debug.h"                                                      

#ifdef DEBUG   

int debug(const char *format,                                           
        const char * time,                                              
        const char * file,                                              
        const char * function,                                          
        int line,                                                       
        ...)                                                            
{                                                                       
    int done=0;                                                         
    va_list arg;                                                        
    va_start(arg, format);                                              
    done = vfprintf(stdout, "%s :%s:%s:%d", time, file, function, line);
    done += vfprintf(stdout, format, arg);                              
    va_end(arg);                                                        

    return done;                                                        
}           
#endif 

And after compiling it I am getting following errors:

gcc -g -Wall -DDEBUG -c debug.c -o d_debug.o
debug.c:16:1: error: expected declaration specifiers or ‘...’ before string constant
debug.c:16:1: error: expected declaration specifiers or ‘...’ before string constant
debug.c:11:5: error: expected declaration specifiers or ‘...’ before ‘__FUNCTION__’
debug.c:16:1: error: expected declaration specifiers or ‘...’ before numeric constant

How I can fix this problem? What is problem here? Thank you in advance.

2

There are 2 best solutions below

12
On BEST ANSWER

1) Change function name

// int debug(
int al_debug(

2) Use regular fprintf()

// done = vfprintf(stdout, "%s :%s:%s:%d", time, file, function, line);
done = fprintf(stdout, "%s :%s:%s:%d", time, file, function, line);

3) Start at line. Use parameter before ...

// va_start(arg, format);
va_start(arg, line);

4) Pedantic note: add done check for < 0 after each print.

done = fprintf(stdout, "%s :%s:%s:%d", time, file, function, line);
if (done >= 0) {
  int done_former = done
  done = vfprintf(stdout, format, arg);
  if (done >= 0) done += done_former;
  }
va_end(arg);
return done;

5) Change args...) to args) @leeduhem

[Edit] to work with no args after format.

int al_debug(const char * time, const char * file, const char * function,
        int line, const char *format, ...);
#define debug(...) al_debug(__TIME__, __FILE__, __func__, __LINE__, __VA_ARGS__)
// @leeduhem for __VA_ARGS__
#else /* IF DEBUG NOT DEFINED*/
#define debug(...) /* DO NOT PRINT ANYTHING IF DEBUG IS NOT PRESENT */
#endif /* END OF DEBUG */

int al_debug(const char * time, const char * file, const char * function,
        int line, const char *format, ...) {
  int done = 0;
  va_list arg;
  va_start(arg, format);  // change to `format`
  ...
6
On

Fixed version:

debug.h

#ifndef __DEBUG_H__
#define __DEBUG_H__

#ifdef DEBUG

int al_debug(const char *time, const char *file, const char *func, int line, const char * format, ...);
#define debug(...) al_debug(__TIME__, __FILE__, __func__, __LINE__, __VA_ARGS__)
#else /* IF DEBUG NOT DEFINED*/
#define debug(...) /* DO NOT PRINT ANYTHING IF DEBUG IS NOT PRESENT */
#endif /* END OF DEBUG */

#endif /* END OF __DEBUG_H__ */

debug.c

#include <stdio.h>
#include <stdarg.h>                                                     
#include <string.h>                                                     

#define __WRAP_FUNCTION__                                               
#include "debug.h"                                                      

#ifdef DEBUG   

int al_debug(const char *time, const char *file, const char *func, int line, const char *format, ...)
{                                                                       
    int done=0;                                                         
    va_list arg;                                                        
    va_start(arg, format);                                              
    done = fprintf(stdout, "%s :%s:%s:%d: ", time, file, func, line);
    done += vfprintf(stdout, format, arg);                              
    va_end(arg);                                                        

    return done;                                                        
}           
#endif

test.c

#include <stdio.h>
#include <stdlib.h>

#include "debug.h"

void foo(void)
{
    debug("debugg...\n");
    debug("%s and %d\n", "debug information", 42);
}

int
main(int argc, char *argv[])
{
    foo();

    exit(EXIT_SUCCESS);
}

Testing:

$ gcc -g -Wall -I. -DDEBUG  debug.c test.c 
test.c: In function ‘main’:
test.c:12:10: warning: unused parameter ‘argc’ [-Wunused-parameter]
test.c:12:22: warning: unused parameter ‘argv’ [-Wunused-parameter]
$ ./a.out 
10:46:40 :test.c:foo:8: debugg...
10:46:40 :test.c:foo:9: debug information and 42

$ gcc -g -Wall -I.   debug.c test.c 
test.c: In function ‘main’:
test.c:12:10: warning: unused parameter ‘argc’ [-Wunused-parameter]
test.c:12:22: warning: unused parameter ‘argv’ [-Wunused-parameter]
$ ./a.out 
$ 

A few links that may be helpful:

6.20 Macros with a Variable Number of Arguments
6.47 Function Names as Strings