通过宏修改printf()s以包含文件和行号信息

  • 本文关键字:文件 包含 信息 修改 printf
  • 更新时间 :
  • 英文 :


我只是想知道是否有一些宏hack我们可以使用,改变现有的printf()语句在一个项目。

/* file.c */
printf ("%s", strerror(errno));
/* After macro processing, this line would become */
printf ("%s %s %d", strerror(errno), __FILE__, __LINE__);

在我的评论中,您可以使用可变宏:

#define PRINTF_FL(format, ...) 
    printf(format " %s %d", __VA_ARGS__, __FILE__, __LINE__)

试试这个:

#define debug(fmt, ...) printf("%s:%d: " fmt, __FILE__, __LINE__, __VA_ARGS__);

我使用名称debug而不是printf,因为我认为您不应该覆盖标准函数。你可能会打碎东西。

使用如下:

debug("This is debug no %d", 5);

输出如下:

program.c:12: this is debug no 5

(file: program.c, line: 12).

这是我的"半便士"。

函数名&调试消息:

// debug mode, -DEBUG
#ifdef EBUG
    #define FNAME() fprintf(stderr, "n%s (%s, line %d)n", __func__, __FILE__, __LINE__)
    #define DBG(...) do{fprintf(stderr, "%s (%s, line %d): ", __func__, __FILE__, __LINE__); 
                    fprintf(stderr, __VA_ARGS__);           
                    fprintf(stderr, "n");} while(0)
#else
    #define FNAME()  do{}while(0)
    #define DBG(...) do{}while(0)
#endif //EBUG

使用宏FNAME()显示函数名称&文件/line, DBG(text)显示类似printf的调试信息,其中包含有关函数名&文件/行。

和一些可能是有用的彩色调试& &;错误/警告消息。

在头文件中:

extern int globErr;
#define ERR(...) do{globErr=errno; _WARN(__VA_ARGS__); exit(-1);}while(0)
#define WARN(...) do{globErr=errno; _WARN(__VA_ARGS__);}while(0)
#define WARNX(...) do{globErr=0; _WARN(__VA_ARGS__);}while(0)
// functions for color output in tty & no-color in pipes
EXTERN int (*red)(const char *fmt, ...);
EXTERN int (*_WARN)(const char *fmt, ...);
EXTERN int (*green)(const char *fmt, ...);

C文件:

int globErr = 0; // errno for WARN/ERR
// pointers to coloured output printf
int (*red)(const char *fmt, ...);
int (*green)(const char *fmt, ...);
int (*_WARN)(const char *fmt, ...);
/*
 * format red / green messages
 * name: r_pr_, g_pr_
 * @param fmt ... - printf-like format
 * @return number of printed symbols
 */
int r_pr_(const char *fmt, ...){
    va_list ar; int i;
    printf(RED);
    va_start(ar, fmt);
    i = vprintf(fmt, ar);
    va_end(ar);
    printf(OLDCOLOR);
    return i;
}
int g_pr_(const char *fmt, ...){
    va_list ar; int i;
    printf(GREEN);
    va_start(ar, fmt);
    i = vprintf(fmt, ar);
    va_end(ar);
    printf(OLDCOLOR);
    return i;
}
/*
 * print red error/warning messages (if output is a tty)
 * @param fmt ... - printf-like format
 * @return number of printed symbols
 */
int r_WARN(const char *fmt, ...){
    va_list ar; int i = 1;
    fprintf(stderr, RED);
    va_start(ar, fmt);
    if(globErr){
        errno = globErr;
        vwarn(fmt, ar);
        errno = 0;
        globErr = 0;
    }else
        i = vfprintf(stderr, fmt, ar);
    va_end(ar);
    i++;
    fprintf(stderr, OLDCOLOR "n");
    return i;
}
const char stars[] = "****************************************";
/*
 * notty variants of coloured printf
 * name: s_WARN, r_pr_notty
 * @param fmt ... - printf-like format
 * @return number of printed symbols
 */
int s_WARN(const char *fmt, ...){
    va_list ar; int i;
    i = fprintf(stderr, "n%sn", stars);
    va_start(ar, fmt);
    if(globErr){
        errno = globErr;
        vwarn(fmt, ar);
        errno = 0;
        globErr = 0;
    }else
        i = +vfprintf(stderr, fmt, ar);
    va_end(ar);
    i += fprintf(stderr, "n%sn", stars);
    i += fprintf(stderr, "n");
    return i;
}
int r_pr_notty(const char *fmt, ...){
    va_list ar; int i;
    i = printf("n%sn", stars);
    va_start(ar, fmt);
    i += vprintf(fmt, ar);
    va_end(ar);
    i += printf("n%sn", stars);
    return i;
}

在main ():

if(isatty(STDOUT_FILENO)){ // make color output in tty
    red = r_pr_; green = g_pr_;
}else{ // no colors in case of pipe
    red = r_pr_notty; green = printf;
}
if(isatty(STDERR_FILENO)) _WARN = r_WARN;
else _WARN = s_WARN;

之后,如果在终端中运行,则可以使用彩色输出,如果在管道中运行,则可以使用非彩色输出。函数redgreenprintf的彩色输出的类似物。功能_WARN用于宏中显示用户消息和errno的字符串:ERR用于错误情况(以exit结尾),WARN -模拟ERR但不包含exit, WARNX用于显示没有errno的消息。

要重新定义printf,不要使用undef,只需在头文件中定义以下printf

#define printf(MESSAGE,args...) { 
  const char *A[] = {MESSAGE}; 
  printf("%s %d",__FILE__,__LINE__); fflush(stdout);
  if(sizeof(A) > 0) {
    printf("::"); 
    printf(*A,##args); 
  } else {
    printf("n"); 
  }
}

你可以这样在你的代码中使用新的printf

printf(); // it will print only the file name and the line number

或以这种方式

printf("debug message any data %dn", 5);

定义下面的宏MYPRINT。包括文件名,行号,函数名和n

 #define MYPRINT(str,args...) printf("%s:%d %s() "str"n",__FILE__,__LINE__,__func__, ##args)

最新更新