Wrapper printf, которая фильтрует в соответствии с пользовательскими настройками
Моя программа пишет в логи и в стандартный вывод. Каждое сообщение, однако, имеет определенный приоритет, и пользователь указывает в настройках, какие приоритеты идут на какой поток (журнал или стандартный вывод).
unsigned short PRIO_HIGH = 0x0001;
unsigned short PRIO_NORMAL = 0x0002;
unsigned short PRIO_LOW = 0x0004;
Предпочтения обрабатываются некоторыми флагами:
unsigned short PRIO_LOG = (PRIO_HIGH | PRIO_NORMAL);
unsigned short PRIO_STD = (PRIO_HIGH);
Функция write_log
должна работать с теми же параметрами, что и функция printf, с добавленным параметром unsigned short priority
.
write_log((PRIO_NORMAL|PRIO_LOW), "HELLO %s, take %d", "World", 1);
(Даже если PRIO_NORMAL|PRIO_LOW
имеет мало смысла...)
Проверить флаги легко: if(priority & PRIO_LOG)
(Возвращает> 1, если какой-либо флаг установлен в обоих аргументах)
Однако я не могу выяснить, как мне передать строковый литерал и аргументы формата в функцию printf. Может кто-нибудь помочь или дать мне указатель (возможно, альтернативный метод, который достигает того же эффекта)? Это будет высоко ценится.
Ответы
Ответ 1
Вы хотите вызвать vprintf() вместо printf(), используя переменные аргументы " varargs " в C.
#include <stdarg.h>
int write_log(int priority, const char *format, ...)
{
va_list args;
va_start(args, format);
if(priority & PRIO_LOG)
vprintf(format, args);
va_end(args);
}
Для получения дополнительной информации, смотрите что-то вроде этого.
Ответ 2
Я думаю, что идея Джеффа - это путь, но вы также можете выполнить это с помощью макроса без использования vprintf. Для этого может потребоваться gcc:
#define write_log(priority,format,args...) \
if (priority & PRIO_LOG) { \
printf(format, ## args); \
}
Обратитесь здесь для получения информации о том, как это работает.
Ответ 3
Если вы хотите, чтобы определения PRIO_ * использовались как бит (используя | и &), вы должны указать каждому из них свой собственный бит:
unsigned short PRIO_HIGH = 0x0001;
unsigned short PRIO_NORMAL = 0x0002;
unsigned short PRIO_LOW = 0x0004;
Макрос можно улучшить, используя обозначение do {} while (0). Это делает вызовы write_log более похожим на инструкцию.
#define write_log(priority,format,args...) do { \
if (priority & PRIO_LOG) { \
printf(format, ## args); \
} while(0)