1. 程式人生 > >Linux下列印除錯管理

Linux下列印除錯管理

#ifndef _DEBUG_MANAGE_H_
#define _DEBUG_MANAGE_H_

/* 資訊的除錯級別,數值起小級別越高 */
#define APP_EMERG   "<0>"   /* system is unusable */
#define APP_ALERT   "<1>"   /* action must be taken immediately */
#define APP_CRIT    "<2>"   /* critical conditions */
#define APP_ERR     "<3>"   /* error conditions */
#define APP_WARNING "<4>"   /* warning conditions */
#define APP_NOTICE  "<5>"   /* normal but significant condition */
#define APP_INFO    "<6>"   /* informational */
#define APP_DEBUG   "<7>"   /* debug-level messages */

/* 資訊的預設除錯級別 */
#define DEFAULT_DBGLEVEL  4

typedef struct debug_opt
{
  char *name;
  int is_can_use;
  int (*debug_init)(void); /* 除錯模組的初始化函式 */
  int (*debug_exit)(void); /* 退出函式 */
  int (*debug_print)(char *data); /* 輸出函式 */
  struct debug_opt *next;
} debug_opt_t, *debug_t;

int DebugRegister(debug_t node);
void DebugShow(void);
debug_t DebugGet(char *name);
int DebugSetLevel(char *buffer);
int DebugSetChannel(char *buffer);
int DebugInit(void);
int DebugPrint(const char *format, ...);
int DebugChannelInit(void);
int StdoutInit(void);

#endif /* _DEBUG_MANAGE_H_ */

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

static debug_t head;
static int debug_leval_limit = DEFAULT_DBGLEVEL;

int DebugRegister(debug_t node)
{
  debug_t point;

  if(!head)
  {
    head = node;
    head->next = NULL;
  }
  else
  {
    point = head;

    while(point->next)
    {
      point = point->next;
    }
    point->next = node;
    node->next = NULL;
  }

  return 1;
}


void DebugShow(void)
{
  int i = 0;
  debug_t point = head;

  while(point)
  {
    DebugPrint("%02d %s\n", i++, point->name);
    point = point->next;
  }
}

debug_t DebugGet(char * name)
{
  debug_t point = head;

  while(point)
  {
    if(strcmp(point->name, name) == 0)
    {
      return point;
    }
    point = point->next;
  }

  return NULL;
}

int DebugSetLevel(char * buffer)
{
  debug_leval_limit = buffer[9] - '0';
  printf("debug_leval_limit = %d\r\n", debug_leval_limit);

  return 0;
}

int DebugSetChannel(char * buffer)
{
  char *temp, name[100];
  debug_t point;

  temp = strchr(buffer, '=');

  if(!temp)
  {
    return -1;
  }
  else
  {
    strncpy(name, buffer, temp - buffer);
    name[temp - buffer] = '\0';
    point = DebugGet(name);

    if(!point)
    {
      return -1;
    }
    if(temp[1] == '0')
    {
      point->is_can_use = 0;
    }
    else
    {
      point->is_can_use = 1;
    }

    return 0;
  }
}

int DebugPrint(const char * format, ...)
{
  char buffer[1000];
  char *temp;
  va_list list;
  int num;
  debug_t point = head;
  int debug_level = DEFAULT_DBGLEVEL;

  /* 可變引數的處理, 抄自glibc的printf函式 */
  va_start (list, format);
  num = vsprintf (buffer, format, list);
  va_end (list);
  buffer[num] = '\0';

  temp = buffer;

  /* 根據列印級別決定是否列印 */
  if ((buffer[0] == '<') && (buffer[2] == '>'))
  {
    debug_level = buffer[1] - '0';
    if (debug_level >= 0 && debug_level <= 9)
    {
      temp = buffer + 3;
    }
    else
    {
      debug_level = DEFAULT_DBGLEVEL;
    }
  }

  if (debug_level >= debug_leval_limit)
  {
    return -1;
  }

  /* 呼叫連結串列中所有isCanUse為1的結構體的DebugPrint函式
   * 用來輸出除錯資訊
   */
  while (point)
  {
    if (point->is_can_use)
    {
      point->debug_print(temp);
    }
    point = point->next;
  }

  return 0;
}

int DebugChannelInit(void)
{
  debug_t point = head;

  while(point)
  {
    if(point->is_can_use && point->debug_init)
    {
      point->debug_init();
    }

    point = point->next;
  }

  return 0;
}

static int stdout_debug_print(char *data)
{
  printf("%s", data);

  return strlen(data);
}

static debug_opt_t debug_stdout =
{
  .name = "stdout",
  .is_can_use = 1,
  .debug_print = stdout_debug_print,
};


int StdoutInit(void)
{
  return DebugRegister(&debug_stdout);
}


int DebugInit(void)
{
  int error;

  error = StdoutInit();
// error |= NetPrintInit();

  return error;
}

int main(void)
{
  int error = DebugInit();

  printf("error: %d\n", error);
  DebugPrint("---------------\n");

  return 0;
}