デバッグ用Cマクロ

printf()でデバッグメッセージを出力するマクロ。以前から同じようなマクロはよく書いてきたが、最近やっと仕様が固まったのでコピペできるように日記に書いておく。

特徴としては

  • マクロが埋め込まれたソースファイル名とその行数を出力。
  • マルチスレッドなプログラムでも、出力がごっちゃにならない。
  • メッセージのON/OFFの切り替えは、実行時でも可能。

二つのマクロの使い分けは以下のとおり。

マクロ名 説明
HOGE_ERR   致命的なエラーメッセージ用
HOGE_DEBUG   デバッグ用の詳細なメッセージ用

挙動は次のようになる。

HOGE_ERR()のメッセージ HOGE_DEBUG()のメッセージ
DEBUGビルド (debug_level = 1) 出力される 出力される
DEBUGビルド (debug_level = 0) 出力される 出力されない
RELEASEビルド 出力されない 出力されない
#include <stdarg.h>
#include <stdio.h>

#ifdef DEBUG
#define HOGE_ERR(msg...) do { hoge_printf(0, stderr, __FILE__, __LINE__, msg ); } while(0)
#define HOGE_DEBUG(msg...) do { hoge_printf(1,stderr, __FILE__, __LINE__, msg ); } while(0)
#else
#define HOGE_ERR(msg...)    (void)0
#define HOGE_DEBUG(msg...)  (void)0
#endif
void hoge_printf(int level, FILE *fp, char *file, int line, char *fmt, ...);
extern int hoge_debug_level=0;
int hoge_set_debug_level(int level);
int hoge_debug_level=0;

int 
hoge_set_debug_level(int level)
{
    int old = hoge_debug_level;
    hoge_debug_level = level;
    return old;
}

void
hoge_printf(int level, FILE *fp, char *file, int line, char *fmt, ...)
{
    if (level <= hoge_debug_level) {
	va_list ap;
	va_start(ap, fmt);

	char buf[1024];
	char *p=buf;
	char *tail=p+sizeof(buf)-2;
	tail[1] = &#39;\0&#39;;
	p +=  snprintf(p, tail - p, "%s:%d: ", file, line);
	p += vsnprintf(p, tail - p, fmt, ap);
	p +=  snprintf(p, tail - p, "\n");

	fputs(buf, fp);
	va_end(ap);
    }
}