#ifndef __AGNI_LOG_H
#define __AGNI_LOG_H
#include <unistd.h>
#include <stdio.h>
//bunch of macroses that will just disable log code and save some binary space
#define LOG_DEBUG_ENABLE
#define LOG_ERROR_ENABLE
#define LOG_WARNING_ENABLE
#define LOG_FATAL_ENABLE
#define LOG_INFO_ENABLE
#define SUB_MEM
#define SUB_CMDS
#define SUB_MSG
#define SUB_NET
//log level
#define LOG_LEVEL_NONE 0
#define LOG_LEVEL_FATAL 1
#define LOG_LEVEL_ERROR 2
#define LOG_LEVEL_WARNING 3
#define LOG_LEVEL_INFO 4
#define LOG_LEVEL_DEBUG 5
//logging subsystem
#define LOG_SUB_NONE 0
#define LOG_SUB_MEM 1
#define LOG_SUB_CMDS 2
#define LOG_SUB_MSG 3
#define LOG_SUB_NET 4
//loging location
#define LOG_LOC_STDIO 0
#define LOG_LOC_FILE 1
typedef struct logging_t
{
int disabled;
int sub;
int level;
int location;
FILE *fd;
char *fname;
} logging_t;
#define NUM_OF_LOG 5
logging_t __logs[NUM_OF_LOG]; //<-be carefull with this number woop woop
int log_init();
int log_register_sub(int sub, int level, int type, char *location);
#define LOG_PRINTF fprintf
#define LOG_COLORIZE
#define LOG_PRINT_LINENUM
#define LOG_PRINT_FILENAME
#define LOG_PRINT_DEBUG
//use color
#ifdef LOG_COLORIZE
#define LOG_D_COLOR "7;32m"
#define LOG_D_COLOR_S "\033[" LOG_D_COLOR
#define LOG_D_COLOR_E "\033[0m"
#define LOG_E_COLOR "0;31m"
#define LOG_E_COLOR_S "\033[" LOG_E_COLOR
#define LOG_E_COLOR_E "\033[0m"
#define LOG_W_COLOR "0;35m"
#define LOG_W_COLOR_S "\033[" LOG_W_COLOR
#define LOG_W_COLOR_E "\033[0m"
#define LOG_F_COLOR "5;31m"
#define LOG_F_COLOR_S "\033[" LOG_F_COLOR
#define LOG_F_COLOR_E "\033[0m"
#define LOG_I_COLOR "0;36m"
#define LOG_I_COLOR_S "\033[" LOG_I_COLOR
#define LOG_I_COLOR_E "\033[0m"
#else
#define LOG_D_COLOR
#define LOG_D_COLOR_S
#define LOG_D_COLOR_E
#define LOG_E_COLOR
#define LOG_E_COLOR_S
#define LOG_E_COLOR_E
#define LOG_W_COLOR
#define LOG_W_COLOR_S
#define LOG_W_COLOR_E
#define LOG_F_COLOR
#define LOG_F_COLOR_S
#define LOG_F_COLOR_E
#define LOG_I_COLOR
#define LOG_I_COLOR_S
#define LOG_I_COLOR_E
#endif
//print debug line
#ifdef LOG_PRINT_LINENUM
#define LOG_PRINT_LINE_F ":%d "
#define LOG_PRINT_LINE_D __LINE__
#else
#define LOG_PRINT_LINE_F "%s"
#define LOG_PRINT_LINE_D " "
#endif
//print
#ifdef LOG_PRINT_FILENAME
#define LOG_PRINT_FILE_F "%s"
#define LOG_PRINT_FILE_D __FILE__
#else
#define LOG_PRINT_FILE_F "%s"
#define LOG_PRINT_FILE_D " "
#endif
//print debug string
#ifdef LOG_PRINT_DEBUG
#define LOG_PRINT_DEBUG_F "DEBUG: "
#define LOG_PRINT_WARNING_F "WARN: "
#define LOG_PRINT_FATAL_F "FATAL: "
#define LOG_PRINT_INFO_F "INFO: "
#define LOG_PRINT_ERROR_F "ERROR: "
#else
#define LOG_PRINT_DEBUG_F ""
#define LOG_PRINT_WARNING_F ""
#define LOG_PRINT_FATAL_F ""
#define LOG_PRINT_ERROR_F ""
#define LOG_PRINT_INFO_F ""
#endif
#define LOG_INFO( fd, format, args ... ) LOG_PRINTF( fd, LOG_I_COLOR_S LOG_PRINT_INFO_F \
LOG_PRINT_FILE_F LOG_PRINT_LINE_F format LOG_I_COLOR_E, LOG_PRINT_FILE_D, \
LOG_PRINT_LINE_D, ##args);
#define LOG_DEBUG( fd, format, args ... ) LOG_PRINTF( fd, LOG_D_COLOR_S LOG_PRINT_DEBUG_F \
LOG_PRINT_FILE_F LOG_PRINT_LINE_F format LOG_D_COLOR_E, LOG_PRINT_FILE_D, \
LOG_PRINT_LINE_D, ##args);
#define LOG_ERROR( fd, format, args ... ) LOG_PRINTF( fd, LOG_E_COLOR_S LOG_PRINT_ERROR_F \
LOG_PRINT_FILE_F LOG_PRINT_LINE_F format LOG_E_COLOR_E, LOG_PRINT_FILE_D, \
LOG_PRINT_LINE_D, ##args);
#define LOG_WARNING( fd, format, args ... ) LOG_PRINTF( fd, LOG_W_COLOR_S LOG_PRINT_WARNING_F \
LOG_PRINT_FILE_F LOG_PRINT_LINE_F format LOG_W_COLOR_E, LOG_PRINT_FILE_D, \
LOG_PRINT_LINE_D, ##args);
#define LOG_FATAL( fd, format, args ... ) LOG_PRINTF( fd, LOG_F_COLOR_S LOG_PRINT_FATAL_F \
LOG_PRINT_FILE_F LOG_PRINT_LINE_F format LOG_F_COLOR_E, LOG_PRINT_FILE_D, \
LOG_PRINT_LINE_D, ##args);
//------------------------------------------------------------------------------
#ifdef LOG_INFO_ENABLE
#define LOG_NONE_I(format,args ... ) {\
if (0 == __logs[LOG_SUB_NONE].disabled){\
if (__logs[LOG_SUB_NONE].level >= LOG_LEVEL_INFO){\
if (__logs[LOG_SUB_NONE].location == LOG_LOC_STDIO){\
LOG_INFO(stdout, format, ##args );\
} else {\
LOG_INFO(__logs[LOG_SUB_NONE].fd, format, ##args );\
}}}\
}
#ifdef SUB_MEM
#define LOG_MEM_I(format,args ... ) {\
if (0 == __logs[LOG_SUB_MEM].disabled){\
if (__logs[LOG_SUB_MEM].level >= LOG_LEVEL_INFO){\
if (__logs[LOG_SUB_MEM].location == LOG_LOC_STDIO){\
LOG_INFO(stdout, "MEM-" );\
LOG_INFO(stdout, format, ##args );\
} else {\
LOG_INFO(stdout, "MEM-" );\
LOG_INFO(__logs[LOG_SUB_MEM].fd, format, ##args );\
}}}\
}
#else
#define LOG_MEM_I(format,args ...) {}
#endif
#else
LOG_NONE_I(format,args ...) {}
#endif
//------------------------------------------------------------------------------
#ifdef LOG_INFO_ENABLE
#define LOG_NONE_D(format,args ... ) {\
if (0 == __logs[LOG_SUB_NONE].disabled){\
if (__logs[LOG_SUB_NONE].level >= LOG_LEVEL_DEBUG){\
if (__logs[LOG_SUB_NONE].location == LOG_LOC_STDIO){\
LOG_DEBUG(stdout, format, ##args );\
} else {\
LOG_DEBUG(__logs[LOG_SUB_NONE].fd, format, ##args );\
}}}\
}
#ifdef SUB_MEM
#define LOG_MEM_D(format,args ... ) {\
if (0 == __logs[LOG_SUB_MEM].disabled){\
if (__logs[LOG_SUB_MEM].level >= LOG_LEVEL_DEBUG){\
if (__logs[LOG_SUB_MEM].location == LOG_LOC_STDIO){\
LOG_DEBUG(stdout, "MEM-" );\
LOG_DEBUG(stdout, format, ##args );\
} else {\
LOG_DEBUG(__logs[LOG_SUB_MEM].fd, "MEM-" );\
LOG_DEBUG(__logs[LOG_SUB_MEM].fd, format, ##args );\
}}}\
}
#else
#define LOG_MEM_D(format,args ...) {}
#endif
#else
LOG_NONE_D(format,args ...) {}
#endif
//------------------------------------------------------------------------------
#ifdef LOG_INFO_ENABLE
#define LOG_NONE_E(format,args ... ) {\
if (0 == __logs[LOG_SUB_NONE].disabled){\
if (__logs[LOG_SUB_NONE].level >= LOG_LEVEL_ERROR){\
if (__logs[LOG_SUB_NONE].location == LOG_LOC_STDIO){\
LOG_ERROR(stdout, format, ##args );\
} else {\
LOG_ERROR(__logs[LOG_SUB_NONE].fd, format, ##args );\
}}}\
}
#ifdef SUB_MEM
#define LOG_MEM_E(format,args ... ) {\
if (0 == __logs[LOG_SUB_MEM].disabled){\
if (__logs[LOG_SUB_MEM].level >= LOG_LEVEL_ERROR){\
if (__logs[LOG_SUB_MEM].location == LOG_LOC_STDIO){\
LOG_ERROR(stdout, "MEM-" );\
LOG_ERROR(stdout, format, ##args );\
} else {\
LOG_ERROR(__logs[LOG_SUB_MEM].fd, "MEM-" );\
LOG_ERROR(__logs[LOG_SUB_MEM].fd, format, ##args );\
}}}\
}
#else
#define LOG_MEM_E(format,args ...) {}
#endif
#else
LOG_NONE_E(format,args ...) {}
#endif
//------------------------------------------------------------------------------
#ifdef LOG_INFO_ENABLE
#define LOG_NONE_W(format,args ... ) {\
if (0 == __logs[LOG_SUB_NONE].disabled){\
if (__logs[LOG_SUB_NONE].level >= LOG_LEVEL_WARNING){\
if (__logs[LOG_SUB_NONE].location == LOG_LOC_STDIO){\
LOG_WARNING(stdout, format, ##args );\
} else {\
LOG_WARNING(__logs[LOG_SUB_NONE].fd, format, ##args );\
}}}\
}
#ifdef SUB_MEM
#define LOG_MEM_W(format,args ... ) {\
if (0 == __logs[LOG_SUB_MEM].disabled){\
if (__logs[LOG_SUB_MEM].level >= LOG_LEVEL_WARNING){\
if (__logs[LOG_SUB_MEM].location == LOG_LOC_STDIO){\
LOG_WARNING(stdout, "MEM-" );\
LOG_WARNING(stdout, format, ##args );\
} else {\
LOG_WARNING(__logs[LOG_SUB_MEM].fd, "MEM-" );\
LOG_WARNING(__logs[LOG_SUB_MEM].fd, format, ##args );\
}}}\
}
#else
#define LOG_MEM_W(format,args ...) {}
#endif
#else
LOG_NONE_W(format,args ...) {}
#endif
//------------------------------------------------------------------------------
#ifdef LOG_INFO_ENABLE
#define LOG_NONE_F(format,args ... ) {\
if (0 == __logs[LOG_SUB_NONE].disabled){\
if (__logs[LOG_SUB_NONE].level >= LOG_LEVEL_FATAL){\
if (__logs[LOG_SUB_NONE].location == LOG_LOC_STDIO){\
LOG_FATAL(stdout, format, ##args );\
} else {\
LOG_FATAL(__logs[LOG_SUB_NONE].fd, format, ##args );\
}}}\
}
#ifdef SUB_MEM
#define LOG_MEM_F(format,args ... ) {\
if (0 == __logs[LOG_SUB_MEM].disabled){\
if (__logs[LOG_SUB_MEM].level >= LOG_LEVEL_FATAL){\
if (__logs[LOG_SUB_MEM].location == LOG_LOC_STDIO){\
LOG_FATAL(stdout, "MEM-" );\
LOG_FATAL(stdout, format, ##args );\
} else {\
LOG_FATAL(__logs[LOG_SUB_MEM].fd, "MEM-" );\
LOG_FATAL(__logs[LOG_SUB_MEM].fd, format, ##args );\
}}}\
}
#else
#define LOG_MEM_F(format,args ...) {}
#endif
#else
LOG_NONE_f(format,args ...) {}
#endif
#endif