вторник, 4 февраля 2014 г.

Debug messages support for C, ver 2

This C module support debug/logging system with custom levels of messages. Suppressing of some level/levels are possible via DBG_LEVEL macro variable. Each custom level is created with DBG_LEVEL_ALIAS() macro. USer can define own print/dump implementations via DBG_PRN_IMPL/DBG_DUMP_IMPL.
#ifndef __DBG_H
#define __DBG_H

#include <stdint.h>
#include <inttypes.h>
#include <stdio.h>

#define DBG_LEVEL_ALIAS(L) (1<<(L))

#ifndef DBG_LEVEL
#define DBG_LEVEL 0
#endif

#ifndef DBG_LEVEL_FMT
#define DBG_LEVEL_FMT "%s: "
#endif

#define _DBG_PRN_IMPL_L(L, F, ...) printf(F, L, __VA_ARGS__)
#define _DBG_PRN_IMPL(F, ...) printf(F, __VA_ARGS__)
#define _DBG_DUMP_IMPL_L(L, p, sz) do { \
    int i; \
    for (i=0; i<(sz); i++) { \
        if (0 == i%16) { \
            DBG_PRN_IMPL("", "%s%s%08" PRIXPTR ": %02X "/*"%s%s%08lX: %02X "*/, i?"\n":"", \
                    16*i/16 + (uintptr_t)p, (uint8_t)(p)[i]); \
        } else if (0 == (i-7)%16) { \
            DBG_PRN_IMPL("", "%s%02X|", (uint8_t)(p)[i]); \
        } else { \
            DBG_PRN_IMPL("", "%s%02X ", (uint8_t)(p)[i]); \
        } \
    } \
    DBG_PRN_IMPL("", "%s%s", "\n"); \
} while (0)
#define _DBG_DUMP_IMPL(p, sz) do { \
    int i; \
    for (i=0; i<(sz); i++) { \
        if (0 == i%16) { \
            DBG_PRN_IMPL("%s%08" PRIXPTR ": %02X "/*"%s%08lX: %02X "*/, i?"\n":"", \
                    16*i/16 + (uintptr_t)p, (uint8_t)(p)[i]); \
        } else if (0 == (i-7)%16) { \
            DBG_PRN_IMPL("%02X|", (uint8_t)(p)[i]); \
        } else { \
            DBG_PRN_IMPL("%02X ", (uint8_t)(p)[i]); \
        } \
    } \
    DBG_PRN_IMPL("%s", "\n"); \
} while (0)

#ifdef DBG_LEVEL_IS_ARG

#ifndef DBG_PRN_IMPL
#define DBG_PRN_IMPL _DBG_PRN_IMPL_L
#endif
#ifndef DBG_DUMP_IMPL
#define DBG_DUMP_IMPL _DBG_DUMP_IMPL_L
#endif

#define DBG_PRN(L, F, ...) if ((DBG_LEVEL) & (L)) DBG_PRN_IMPL(#L, DBG_LEVEL_FMT F, __VA_ARGS__)
#define DBG_DUMP(L, ...) if ((DBG_LEVEL) & (L)) DBG_DUMP_IMPL(#L, __VA_ARGS__)

#else

#ifndef DBG_PRN_IMPL
#define DBG_PRN_IMPL _DBG_PRN_IMPL
#endif
#ifndef DBG_DUMP_IMPL
#define DBG_DUMP_IMPL _DBG_DUMP_IMPL
#endif

#define DBG_PRN(L, ...) if ((DBG_LEVEL) & (L)) DBG_PRN_IMPL(__VA_ARGS__)
#define DBG_DUMP(L, ...) if ((DBG_LEVEL) & (L)) DBG_DUMP_IMPL(__VA_ARGS__)

#endif

/// Print without level
#define DBG_PRN_UL(L, F, ...) if ((DBG_LEVEL) & (L)) DBG_PRN_IMPL("", "%s" F, __VA_ARGS__)

#endif /* EOF */
Usage:
#include <string.h>

// use level name as 1st argument of out DBG_PRN_IMPL
#define DBG_LEVEL_IS_ARG
#define DBG_LEVEL_FMT "[%s] "
#include "dbg.h"

// define levels
#define HARDWARE_LEVEL   DBG_LEVEL_ALIAS(1)
#define WRAPPER_LEVEL   DBG_LEVEL_ALIAS(2)
#define APP_LEVEL       DBG_LEVEL_ALIAS(3)

#undef DBG_LEVEL
#define DBG_LEVEL (HARDWARE_LEVEL|APP_LEVEL)

void main() {
    char dim[] = "0123456789Hello World!";
    DBG_PRN(HARDWARE_LEVEL, "There %d\n", 1);
    DBG_PRN(WRAPPER_LEVEL, "There %d\n", 2);
    DBG_PRN(APP_LEVEL, "There %d\n", 3);
    DBG_DUMP(APP_LEVEL, dim, strlen(dim));
    DBG_PRN_UL(APP_LEVEL, "%s\n", "Done.");
}
Output:
[HARDWARE_LEVEL] There 1
[APP_LEVEL] There 3
0022FEF5: 30 31 32 33 34 35 36 37 38|39 48 65 6C 6C 6F 20
0022FF05: 57 6F 72 6C 64 21
Done.

Комментариев нет:

Отправить комментарий

Thanks for your posting!