diff --git a/include/libp7.h b/include/libp7.h index 5bd7067..ee43fac 100644 --- a/include/libp7.h +++ b/include/libp7.h @@ -129,7 +129,38 @@ p7_declare_func(p7_exit, void, p7_attrs_exit, /* List serial devices */ # define p7_attrs_comlist p7_attribute_nonnull(1) p7_declare_func(p7_comlist, int, p7_attrs_comlist, - p7_list_device_t *p7_arg_callback, void *p7_arg_cookie) + p7_liststr_t *p7_arg_callback, void *p7_arg_cookie) +/* ************************************************************************** */ +/* Interact with the login */ +/* ************************************************************************** */ +/* Log levels -- prefer the functions to these values, that can change! */ +typedef int p7_loglevel_t; /* uint_fast8_t? */ +# define p7_loglevel_info 0 +# define p7_loglevel_warn 10 +# define p7_loglevel_error 20 +# define p7_loglevel_fatal 30 +# define p7_loglevel_none 40 + +/* Get and set the log level at runtime */ +# define p7_attrs_setlog p7_attribute_THROW +p7_declare_func(p7_setlog, void, p7_attrs_setlog, + p7_loglevel_t p7_arg_level) +# define p7_attrs_getlog p7_attribute_THROW +p7_declare_func(p7_getlog, p7_loglevel_t, p7_attrs_getlog, void) + +/* Get, set and list log level strings */ +# define p7_attrs_loglevel_tostring p7_attribute_THROW +p7_declare_func(p7_loglevel_tostring, const char*, + p7_attrs_loglevel_tostring, + p7_loglevel_t p7_arg_level) +# define p7_attrs_loglevel_fromstring p7_attribute_THROW +p7_declare_func(p7_loglevel_fromstring, p7_loglevel_t, + p7_attrs_loglevel_fromstring, + const char *p7_arg_string) +# define p7_attrs_loglevel_list +p7_declare_func(p7_loglevel_list, void, + p7_attrs_loglevel_list, + p7_liststr_t *p7_arg_callback, void *p7_arg_cookie) /* ************************************************************************** */ /* MCS interaction */ /* ************************************************************************** */ diff --git a/include/libp7/internals.h b/include/libp7/internals.h index 47ad706..c8ea04d 100644 --- a/include/libp7/internals.h +++ b/include/libp7/internals.h @@ -121,7 +121,7 @@ extern int p7_seven_command_is_supported(unsigned int code, struct p7_handle_s { /* flags and protocol - see above */ unsigned int _flags; - unsigned int _protocol; + unsigned char _protocol; /* debug name, for multi-handle logging (e.g. `p7servtest` in p7utils) * a space/null, 8 chars max, and imposed null char */ diff --git a/include/libp7/internals/log.h b/include/libp7/internals/log.h index 2de5ac7..e5bee95 100644 --- a/include/libp7/internals/log.h +++ b/include/libp7/internals/log.h @@ -29,69 +29,55 @@ # define LIBP7_INTERNALS_LOG_H # include -/* ************************************************************************** */ -/* Log utility */ -/* ************************************************************************** */ -/* Log level */ -# define ll_info 0 -# define ll_warn 1 -# define ll_error 2 -# define ll_fatal 3 -# define ll_none 4 +/* Log levels */ +# define ll_info p7_loglevel_info +# define ll_warn p7_loglevel_warn +# define ll_error p7_loglevel_error +# define ll_fatal p7_loglevel_fatal +# define ll_none p7_loglevel_none -/* Check log level */ -# ifdef P7_DISABLED_FILE +/* check if we can log */ +# if defined(P7_DISABLED_FILE) # undef LOGLEVEL # define LOGLEVEL ll_none # endif +/* ************************************************************************** */ +/* Log utilities */ +/* ************************************************************************** */ +/* Main functions */ +extern void p7_log(const char *name, p7_loglevel_t loglevel, + const char *format, ...); +extern void p7_log_mem(const char *name, p7_loglevel_t loglevel, + const void *m, size_t n); /* Macros */ -# define logr(P, S, ...) fprintf(stderr, P "%s: " S "\n", \ - __FUNCTION__, ##__VA_ARGS__) -# define logrm(S, M, N) p7_log_mem(S, M, N) -# define log(P, S, ...) fprintf(stderr, P "%s: " S "\n", handle->_name, \ - __FUNCTION__, ##__VA_ARGS__) -# define logm(S, M, N) p7_log_mem(S, M, N, handle->_name) +# define p7_log_(LEVEL, ...) \ + p7_log(handle->_name, (LEVEL), __VA_ARGS__) +# define p7_logm_(LEVEL, M, N) \ + p7_log_mem(handle->_name, (LEVEL), (M), (N)) +# define p7_logr_(LEVEL, ...) \ + p7_log(NULL, (LEVEL), __VA_ARGS__) +# define p7_logrm_(LEVEL, M, N) \ + p7_log_mem(NULL, (LEVEL), (M), (N)) -# if LOGLEVEL <= ll_info -# define logr_info(S, ...) logr("[libp7 info] ", S, ##__VA_ARGS__) -# define logrm_info(M, N) logrm("[libp7 info] ", M, N) -# define log_info(S, ...) log("[libp7%s info] ", S, ##__VA_ARGS__) -# define logm_info(M, N) logm("[libp7%s info] ", M, N) -# else -# define logr_info(S, ...) -# define logrm_info(M, N) -# define log_info(S, ...) -# define logm_info(M, N) -# endif +/* Adapted for different log levels */ +# define log_info(...) p7_log_(ll_info, __VA_ARGS__) +# define logm_info(M, N) p7_logm_(ll_info, (M), (N)) +# define logr_info(...) p7_logr_(ll_info, __VA_ARGS__) +# define logrm_info(M, N) p7_logrm_(ll_info, (M), (N)) -# if LOGLEVEL <= ll_warn -# define logr_warn(S, ...) logr("[libp7 warn] ", S, ##__VA_ARGS__) -# define log_warn(S, ...) log("[libp7%s warn] ", S, ##__VA_ARGS__) -# define logm_warn(M, N) logm("[libp7%s warn] ", M, N) -# else -# define logr_warn(S, ...) -# define log_warn(S, ...) -# define logm_warn(M, N) -# endif +# define log_warn(...) p7_log_(ll_warn, __VA_ARGS__) +# define logm_warn(M, N) p7_logm_(ll_warn, (M), (N)) +# define logr_warn(...) p7_logr_(ll_warn, __VA_ARGS__) +# define logrm_warn(M, N) p7_logrm_(ll_warn, (M), (N)) -# if LOGLEVEL <= ll_error -# define logr_error(S, ...) logr("[libp7 error] ", S, ##__VA_ARGS__) -# define log_error(S, ...) log("[libp7%s error] ", S, ##__VA_ARGS__) -# else -# define logr_error(S, ...) -# define log_error(S, ...) -# endif - -# if LOGLEVEL <= ll_fatal -# define logr_fatal(S, ...) logr("[libp7 fatal] ", S, ##__VA_ARGS__) -# define log_fatal(S, ...) log("[libp7%s fatal] ", S, ##__VA_ARGS__) -# else -# define logr_fatal(S, ...) -# define log_fatal(S, ...) -# endif - -/* Functions prototypes */ -void p7_log_mem(const char *prefix, const void *m, size_t n, ...); +# define log_error(...) p7_log_(ll_error, __VA_ARGS__) +# define logm_error(M, N) p7_logm_(ll_error, (M), (N)) +# define logr_error(...) p7_logr_(ll_error, __VA_ARGS__) +# define logrm_error(M, N) p7_logrm_(ll_error, (M), (N)) +# define log_fatal(...) p7_log_(ll_fatal, __VA_ARGS__) +# define logm_fatal(M, N) p7_logm_(ll_fatal, (M), (N)) +# define logr_fatal(...) p7_logr_(ll_fatal, __VA_ARGS__) +# define logrm_fatal(M, N) p7_logrm_(ll_fatal, (M), (N)) #endif /* LIBP7_INTERNALS_LOG_H */ diff --git a/include/libp7/types.h b/include/libp7/types.h index 825c088..e09398f 100644 --- a/include/libp7/types.h +++ b/include/libp7/types.h @@ -87,11 +87,12 @@ extern const size_t p7_handle_size; /* ************************************************************************** */ /* Callbacks */ /* ************************************************************************** */ -/* p7_list_device_t: - * This callback is for serial devices listing; for each device found, the - * callback is found with its device. */ +/* p7_liststr_t: + * This callback is used as soon as a function needs to list strings. + * It's used for serial devices listing, or log level strings listing. */ -typedef void p7_list_device_t(void*, const char*); +typedef void p7_liststr_t(void*, const char*); +typedef p7_liststr_t p7_list_device_t; /* p7_screenfunc_t: * This callback is for `p7_getscreen`: when a screen is received, it is called diff --git a/src/core/log.c b/src/core/log.c index 590d4ac..daeff7c 100644 --- a/src/core/log.c +++ b/src/core/log.c @@ -17,12 +17,141 @@ * along with libp7; if not, see . * ************************************************************************** */ #include -#if LOGLEVEL < ll_none -# include -# include -# include -# include +#include +#include +#include +#include +#define should_log(LEVEL) (log_setting <= (LEVEL)) +/* ************************************************************************** */ +/* Interact with the log settings at runtime */ +/* ************************************************************************** */ +/* The log setting */ +static p7_loglevel_t log_setting = LOGLEVEL; + +/** + * p7_setlog: + * Set the log level at runtime. + * + * @arg level the level to set. + */ + +p7_define_func(p7_setlog, void, p7_attrs_setlog, + p7_loglevel_t level) +{ + log_setting = level; +} + +/** + * p7_getlog: + * Get the log level at runtime. + * + * @return the current level. + */ + +p7_define_func(p7_getlog, p7_loglevel_t, p7_attrs_getlog, void) +{ + return (log_setting); +} +/* ************************************************************************** */ +/* Make conversions between settings values and strings, list settings */ +/* ************************************************************************** */ +/** + * p7_loglevel_tostring: + * Make a string out of a log level. + * + * @arg level the log level. + * @return the string. + */ + +p7_define_func(p7_loglevel_tostring, const char*, + p7_attrs_loglevel_tostring, + p7_loglevel_t level) +{ + if (level >= 0 && level < 10) + return ("info"); + if (level >= 10 && level < 20) + return ("warn"); + if (level >= 20 && level < 30) + return ("error"); + if (level >= 30 && level < 40) + return ("fatal"); + return ("none"); +} + +/** + * p7_loglevel_fromstring: + * Make a log level out of a string. + * + * @arg string the string. + * @return the log level. + */ + +p7_define_func(p7_loglevel_fromstring, p7_loglevel_t, + p7_attrs_loglevel_fromstring, + const char *string) +{ + if (!strcmp(string, "info")) + return (p7_loglevel_info); + if (!strcmp(string, "warn")) + return (p7_loglevel_warn); + if (!strcmp(string, "error")) + return (p7_loglevel_error); + if (!strcmp(string, "fatal")) + return (p7_loglevel_fatal); + return (p7_loglevel_none); +} + +/** + * p7_loglevel_list: + * List log levels. + * + * @arg callback the callback. + * @arg cookie the callback cookie. + */ + +p7_define_func(p7_loglevel_list, void, + p7_attrs_loglevel_list, + p7_liststr_t *callback, void *cookie) +{ + (*callback)(cookie, "info"); + (*callback)(cookie, "warn"); + (*callback)(cookie, "error"); + (*callback)(cookie, "fatal"); +} +/* ************************************************************************** */ +/* Log simple messages */ +/* ************************************************************************** */ +/** + * p7_log: + * Log a simple message. + * + * @arg name the handle name. + * @arg loglevel the log level. + * @arg format the format. + * @arg ... the arguments. + */ + +void p7_log(const char *name, int loglevel, const char *format, ...) +{ + va_list args; + + /* put the prefix */ + name = name ? name : ""; + if (should_log(loglevel)) fprintf(stderr, "[libp7 %s%s] ", + name, p7_loglevel_tostring(loglevel)); + + /* put the main part */ + va_start(args, format); + if (should_log(loglevel)) { + vfprintf(stderr, format, args); + fputc('\n', stderr); + } + va_end(args); +} +/* ************************************************************************** */ +/* Log memory */ +/* ************************************************************************** */ /** * log_mem_hex: * Prints the octal interpretation of a max of two octets. @@ -75,42 +204,42 @@ static void log_mem_asc(char *s, const unsigned char *m, size_t n) * p7_log_mem: * Print memory zone. * - * @arg prefx the line prefix - * @arg m the memory zone to print - * @arg n the size of the memory zone + * @arg name the handle name. + * @arg loglevel the message log level. + * @arg m the memory zone to print. + * @arg n the size of the memory zone. */ -void p7_log_mem(const char *prefx, const void *m, size_t n, ...) +void p7_log_mem(const char *name, p7_loglevel_t loglevel, + const void *m, size_t n) { - /* make prefix buffer */ - char prefix[30]; - va_list ap; va_start(ap, n); - vsprintf(prefix, prefx, ap); - va_end(ap); + char linebuf[58]; + const unsigned char *p; + + /* check if the log level is good */ + if (!should_log(loglevel)) return ; /* if nothing, print it directly */ - if (!n) fprintf(stderr, "%s(nothing)\n", prefix); + name = name ? name : ""; + if (!n) { + fprintf(stderr, "[libp7 %s%s] (nothing)\n", + name, p7_loglevel_tostring(loglevel)); + return ; + } - /* prepare line buffer */ - unsigned int lineoff = strlen(prefix); - char linebuf[lineoff + 58]; - memcpy(linebuf, prefix, lineoff); - /* - for spaces - */ - memcpy(&linebuf[lineoff], "0000 0000 0000 0000 0000 0000 0000 0000 ", 40); - - /* then loop-loop-loop-loop-loop */ - const unsigned char *p = m; - while (n > 0) { + /* prepare line buffer, and loop-loop-loop-loop-loop */ + memcpy(linebuf, "0000 0000 0000 0000 0000 0000 0000 0000 ", 40); + for (p = m; n > 0;) { /* fill in ascii-hex part */ - log_mem_hex(&linebuf[lineoff], p, n); + log_mem_hex(&linebuf[0], p, n); /* fill in ascii part */ - log_mem_asc(&linebuf[lineoff + 40], p, n); + log_mem_asc(&linebuf[40], p, n); /* then print line */ + fprintf(stderr, "[libp7 %s%s] ", + name, p7_loglevel_tostring(loglevel)); fputs(linebuf, stderr); /* and increment pointer */ p += 16; n -= min(16, n); } } - -#endif diff --git a/src/usage/mcs/request.c b/src/usage/mcs/request.c index 4337022..1723d7b 100644 --- a/src/usage/mcs/request.c +++ b/src/usage/mcs/request.c @@ -31,7 +31,7 @@ p7_define_ufunc(p7_mcs_request, p7_attrs_mcs_request, p7_handle_t *handle, g1m_mcsfile_t **file, - g1m_mcshead_t *head, p7_disp_t *disp) + g1m_mcshead_t *reqhead, p7_disp_t *disp) { int err; /* make checks */