一个简单的用于嵌入式Linux开发的C调试日志打印接口

一个简单的用于嵌入式Linux开发的C调试日志打印接口


简介

这个C语言调试日志接口的目的是提供一种用于临时调试的手段, 要求使用方式类似于printf, 在不需要时可容易地去除相关的调试语句.
在必要的情况下可方便地扩展支持syslog接口.


这个接口仅提供了一个.h文件和一个.c文件, 只需向项目中加入这两个文件, 在使用时要包含头文件并在包含语句前作一个调试级别宏定义. 如果要去除相关的调试语句, 只需注释掉调试级别宏定义即可, 所有的调试语句将不会被生成.

注: dp是debug print的缩写.


-------------- 测试文件内容 --------------

/******************************************************************************
**
** FILENAME: main.c
**
** FILE DESCRIPTION:
**
** AUTHORS: Wang Shan
** CREATED:
**
** MODIFICATION HISTORY:
**
** DATE         NAME               DESCRIPTION
** --------------------------------------------------------------------------
**
**
**
*******************************************************************************/

/* If don't need debug print, comment this macro */
#define ENABLE_DPLOG_LEVEL (DPLOG_DEBUG)
#include "dplog.h"

/* interface definitiones */

int
main(int argc, char * argv[])
{
    /* emergency log will causes program abort */
        /* dpemerg("Test the emerge log./n"*/

        dpalert("Test the alert log./n");
        dpcrit("Test the crit log./n");
        dperr("Test the error log./n");
        dpng("Test the warning log./n");

    /* if condition is false, this log will causes assertion failure */
        /* dpassert(0, "Test the assert log./n"); */

        dpinfo("Test the info log./n");
        dpdbg("Test the debug log./n");

        return 0;
}


-------------- .h文件内容 --------------

/******************************************************************************
**
** FILENAME: dplog.h
**
** FILE DESCRIPTION:
**
** AUTHORS: Wang Shan
** CREATED:
**
** MODIFICATION HISTORY:
**
** DATE         NAME               DESCRIPTION
** --------------------------------------------------------------------------
**
**
**
*******************************************************************************/

#ifndef DPLOG_H
#define DPLOG_H

#include
#include

/*
 * levels of dplog are exactly the same as priorities of syslog
 */
#define DPLOG_EMERG   (0)         /* system is unusable */
#define DPLOG_ALERT   (1)         /* action must be taken immediately */
#define DPLOG_CRIT    (2)         /* critical conditions */
#define DPLOG_ERR     (3)         /* error conditions */
#define DPLOG_WARNING (4)         /* warning conditions */  
#define DPLOG_ASSERT  (5)         /* normal but significant condition */
#define DPLOG_INFO    (6)         /* informational */
#define DPLOG_DEBUG   (7)         /* debug-level messages */

#ifndef ENABLE_DPLOG_LEVEL
#define ENABLE_DPLOG_LEVEL (DPLOG_EMERG - 1)
#endif

#if ENABLE_DPLOG_LEVEL < DPLOG_ASSERT
#define NDEBUG
#else
#ifdef NDEBUG
#undef NDEBUG
#endif
#endif
#include

#define DPLOG_GET_LINE __LINE__

#define DPLOG_PATH_TOKEN  '/'
#define DPLOG_GET_FILE /
        ((strrchr(__FILE__, DPLOG_PATH_TOKEN) != NULL) ? (strrchr(__FILE__, DPLOG_PATH_TOKEN) + 1) : __FILE__)

#define DPLOG_GET_FUNC __func__

#if ENABLE_DPLOG_LEVEL < DPLOG_EMERG
#define dpemerg(...)
#else
#define dpemerg(...)                            /
        do {                                    /
                dplog_entry(DPLOG_EMERG,        /
                            DPLOG_GET_FILE,     /
                            DPLOG_GET_LINE,     /
                            DPLOG_GET_FUNC,     /
                            __VA_ARGS__);       /
                abort();                        /
        } while(0)
#endif

#if ENABLE_DPLOG_LEVEL < DPLOG_ALERT
#define dpalert(...)
#else
#define dpalert(...)                            /
        do {                                    /
                dplog_entry(DPLOG_ALERT,        /
                            DPLOG_GET_FILE,     /
                            DPLOG_GET_LINE,     /
                            DPLOG_GET_FUNC,     /
                            __VA_ARGS__);       /
        } while(0)
#endif

#if ENABLE_DPLOG_LEVEL < DPLOG_CRIT
#define dpcrit(...)
#else
#define dpcrit(...)                             /
        do {                                    /
                dplog_entry(DPLOG_CRIT,         /
                            DPLOG_GET_FILE,     /
                            DPLOG_GET_LINE,     /
                            DPLOG_GET_FUNC,     /
                            __VA_ARGS__);       /
        } while(0)
#endif

#if ENABLE_DPLOG_LEVEL < DPLOG_ERR
#define dperr(...)
#else
#define dperr(...)                              /
        do {                                    /
                dplog_entry(DPLOG_ERR,          /
                            DPLOG_GET_FILE,     /
                            DPLOG_GET_LINE,     /
                            DPLOG_GET_FUNC,     /
                            __VA_ARGS__);       /
        } while(0)
#endif

#if ENABLE_DPLOG_LEVEL < DPLOG_WARNING
#define dpng(...)
#else
#define dpng(...)                               /
        do {                                    /
                dplog_entry(DPLOG_WARNING,      /
                            DPLOG_GET_FILE,     /
                            DPLOG_GET_LINE,     /
                            DPLOG_GET_FUNC,     /
                            __VA_ARGS__);       /
        } while(0)
#endif

#if ENABLE_DPLOG_LEVEL < DPLOG_ASSERT
#define dpassert(cond, ...)
#else
#define dpassert(cond, ...)                                     /
        do {                                                    /
                if (!(cond)) dplog_entry(DPLOG_ASSERT,          /
                                         DPLOG_GET_FILE,        /
                                         DPLOG_GET_LINE,        /
                                         DPLOG_GET_FUNC,        /
                                         __VA_ARGS__);          /
                assert(cond);                                   /
        } while(0)
#endif

#if ENABLE_DPLOG_LEVEL < DPLOG_INFO
#define dpinfo(...)
#else
#define dpinfo(...)                             /
        do {                                    /
                dplog_entry(DPLOG_INFO,         /
                            DPLOG_GET_FILE,     /
                            DPLOG_GET_LINE,     /
                            DPLOG_GET_FUNC,     /
                            __VA_ARGS__);       /
        } while(0)
#endif

#if ENABLE_DPLOG_LEVEL < DPLOG_DEBUG
#define dpdbg(...)
#else
#define dpdbg(...)                              /
        do {                                    /
                dplog_entry(DPLOG_DEBUG,        /
                            DPLOG_GET_FILE,     /
                            DPLOG_GET_LINE,     /
                            DPLOG_GET_FUNC,     /
                            __VA_ARGS__);       /
        } while(0)
#endif

void
dplog_entry(const int level,
            const char * file,
            const int line,
            const char * func,
            char * fmt, ...);

#endif /* *_H */
/* end of file */


-------------- .c文件内容 --------------

/******************************************************************************
**
** FILENAME: dplog.c
**
** FILE DESCRIPTION:
**
** AUTHORS: Wang Shan
** CREATED:
**
** MODIFICATION HISTORY:
**
** DATE         NAME               DESCRIPTION
** --------------------------------------------------------------------------
**
**
**
*******************************************************************************/

#include "dplog.h"

#include
#include
#include
#include
#include
#include
#include

/* static var declarations or definitiones */

static char * f_level_names[] =
        {
                "emerg",
                "alert",
                "crit",
                "error",
                "warning",
                "assert",
                "info",
                "debug"
        };

/* help function declarations */

static int
print_meta(const int level,
           const char * file,
           const int line,
           const char * func);

static int
print_log(const char * fmt, va_list ap);


/* interface definitiones */

void
dplog_entry(const int level,
            const char * file,
            const int line,
            const char * func,
            char * fmt, ...)
{
        va_list ap;

        fflush(stdout);

        /* print meta info of log */

        print_meta(level, file, line, func);

        /* print content of log */

        va_start(ap, fmt);
        if (NULL != fmt)
        {
                print_log(fmt, ap);
        }
        va_end(ap);

        fflush(stdout);
}

/* help function definitiones */

static int
print_meta(const int level,
           const char * file,
           const int line,
           const char * func)
{
        int n = 0;
       
        if (DPLOG_EMERG <= level && DPLOG_DEBUG >= level)
        {
                n += printf("%-8s ", f_level_names[level]);
        }
        else
        {
                n += printf("unknown ");
        }

        if (NULL != file)
        {
                n += printf("%s(%05d) ", file, line);
        }

        if (NULL != func)
        {
                n += printf("%s ", func);
        }

        n += printf("> ");

        return n;
}

static int
print_log(const char * fmt, va_list ap)
{
        if (NULL == fmt)
        {
                return 0;
        }

        /* print log to console */

        return vprintf(fmt, ap);
}

/* end of file */

你可能感兴趣的:(嵌入式Linux开发)