1 /** \file gphoto2-port-log.h 2 * 3 * Copyright 2001 Lutz Mueller <lutz@users.sf.net> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Lesser General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, write to the 17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301 USA 19 */ 20 21 #ifndef __GPHOTO2_PORT_LOG_H__ 22 #define __GPHOTO2_PORT_LOG_H__ 23 24 #include <stdarg.h> 25 26 /** 27 * \brief Logging level 28 * Specifies the logging severity level. 29 */ 30 typedef enum { 31 GP_LOG_ERROR = 0, /**< \brief Log message is an error information. */ 32 GP_LOG_VERBOSE = 1, /**< \brief Log message is an verbose debug information. */ 33 GP_LOG_DEBUG = 2, /**< \brief Log message is an debug information. */ 34 GP_LOG_DATA = 3 /**< \brief Log message is a data hex dump. */ 35 } GPLogLevel; 36 37 /** 38 * GP_LOG_ALL: 39 * 40 * Used by frontends if they want to be sure their 41 * callback function receives all messages. Defined 42 * as the highest debug level. Can make frontend code 43 * more understandable and extension of log levels 44 * easier. 45 **/ 46 #define GP_LOG_ALL GP_LOG_DATA 47 48 /** 49 * \brief Logging function hook 50 * 51 * This is the function frontends can use to receive logging information 52 * from the libgphoto2 framework. It is set using gp_log_add_func() and 53 * removed using gp_log_remove_func() and will then receive the logging 54 * messages of the level specified. 55 * 56 * \param level the log level of the passed message, as set by the camera driver or libgphoto2 57 * \param domain the logging domain as set by the camera driver, or libgphoto2 function 58 * \param str the logmessage, without linefeed 59 * \param data the caller private data that was passed to gp_log_add_func() 60 */ 61 typedef void (* GPLogFunc) (GPLogLevel level, const char *domain, const char *str, void *data); 62 63 #ifndef DISABLE_DEBUGGING 64 65 int gp_log_add_func (GPLogLevel level, GPLogFunc func, void *data); 66 int gp_log_remove_func (int id); 67 68 /* Logging */ 69 void gp_log (GPLogLevel level, const char *domain, 70 const char *format, ...) 71 #ifdef __GNUC__ 72 __attribute__((__format__(printf,3,4))) 73 #endif 74 ; 75 void gp_log_with_source_location( 76 GPLogLevel level, const char *file, int line, const char *func, 77 const char *format, ...) 78 #ifdef __GNUC__ 79 __attribute__((__format__(printf,5,6))) 80 #endif 81 ; 82 void gp_logv (GPLogLevel level, const char *domain, const char *format, 83 va_list args) 84 #ifdef __GNUC__ 85 __attribute__((__format__(printf,3,0))) 86 #endif 87 ; 88 void gp_log_data (const char *domain, const char *data, unsigned int size, 89 const char *format, ...) 90 #ifdef __GNUC__ 91 __attribute__((__format__(printf,4,5))) 92 #endif 93 ; 94 95 /* 96 * GP_DEBUG: 97 * msg: message to log 98 * params: params to message 99 * 100 * Logs message at log level #GP_LOG_DEBUG by calling #gp_log() with 101 * an automatically generated domain 102 * You have to define GP_MODULE as "mymod" for your module 103 * mymod before using #GP_DEBUG(). 104 */ 105 106 #ifdef _GPHOTO2_INTERNAL_CODE 107 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 108 #define GP_DEBUG(...) \ 109 gp_log(GP_LOG_DEBUG, GP_MODULE "/" __FILE__, __VA_ARGS__) 110 111 /* 112 * GP_LOG_D/E: 113 * simple helper macros for convenient and consistent logging of error 114 * and debug messages including information about the source location. 115 */ 116 #define GP_LOG_D(...) gp_log(GP_LOG_DEBUG, __func__, __VA_ARGS__) 117 #define GP_LOG_E(...) gp_log_with_source_location(GP_LOG_ERROR, __FILE__, __LINE__, __func__, __VA_ARGS__) 118 #define GP_LOG_DATA(DATA, SIZE, MSG, ...) gp_log_data(__func__, DATA, SIZE, MSG, ##__VA_ARGS__) 119 120 #elif defined(__GNUC__) && __GNUC__ >= 2 121 #define GP_DEBUG(msg, params...) \ 122 gp_log(GP_LOG_DEBUG, GP_MODULE "/" __FILE__, msg, ##params) 123 /* 124 * GP_LOG_D/E: 125 * simple helper macros for convenient and consistent logging of error 126 * and debug messages including information about the source location. 127 */ 128 #define GP_LOG_D(...) gp_log(GP_LOG_DEBUG, __func__, __VA_ARGS__) 129 #define GP_LOG_E(...) gp_log_with_source_location(GP_LOG_ERROR, __FILE__, __LINE__, __func__, __VA_ARGS__) 130 #define GP_LOG_DATA(DATA, SIZE, MSG, ...) gp_log_data(__func__, DATA, SIZE, MSG, ##__VA_ARGS__) 131 132 #else 133 # ifdef __GNUC__ 134 # warning Disabling GP_DEBUG because variadic macros are not allowed 135 # endif 136 #define GP_DEBUG (void) 137 #define GP_LOG_D(...) /* no-op */ 138 #define GP_LOG_E(...) /* no-op */ 139 #define GP_LOG_DATA(DATA, SIZE, ...) /* no-op */ 140 #endif 141 #endif /* _GPHOTO2_INTERNAL_CODE */ 142 143 #else /* DISABLE_DEBUGGING */ 144 145 /* Stub these functions out if debugging is disabled */ 146 #define gp_log_add_func(level, func, data) (0) 147 #define gp_log_remove_func(id) (0) 148 #define gp_log(level, domain, format, args...) /**/ 149 #define gp_log_with_source_location(level, file, line, func, format, ...) 150 #define gp_logv(level, domain, format, args) /**/ 151 #define gp_log_data(domain, data, size) /**/ 152 153 #ifdef _GPHOTO2_INTERNAL_CODE 154 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 155 #define GP_DEBUG(...) /* no-op */ 156 #define GP_LOG_D(...) /* no-op */ 157 #define GP_LOG_E(...) /* no-op */ 158 #define GP_LOG_DATA(DATA, SIZE, ...) /* no-op */ 159 160 #elif defined(__GNUC__) 161 #define GP_DEBUG(msg, params...) /* no-op */ 162 #define GP_LOG_D(...) /* no-op */ 163 #define GP_LOG_E(...) /* no-op */ 164 #define GP_LOG_DATA(DATA, SIZE, ...) /* no-op */ 165 #else 166 #define GP_DEBUG (void) 167 #define GP_LOG_D (void /* no-op */ 168 #define GP_LOG_E (void) /* no-op */ 169 #define GP_LOG_DATA(void) /* no-op */ 170 #endif 171 #endif /* _GPHOTO2_INTERNAL_CODE */ 172 173 #endif /* DISABLE_DEBUGGING */ 174 175 #ifdef _GPHOTO2_INTERNAL_CODE 176 177 typedef struct StringFlagItem { 178 char *str; 179 unsigned int flag; 180 } StringFlagItem; 181 182 typedef void (*string_item_func) (const char *str, void *data); 183 184 const char * 185 gpi_enum_to_string(const unsigned int _enum, 186 const StringFlagItem *map); 187 188 int 189 gpi_string_to_enum(const char *str, 190 unsigned int *result, 191 const StringFlagItem *map); 192 193 void 194 gpi_flags_to_string_list(const unsigned int flags, 195 const StringFlagItem *map, 196 string_item_func func, void *data); 197 198 int 199 gpi_string_or_to_flags(const char *str, 200 unsigned int *flags, 201 const StringFlagItem *map); 202 203 unsigned int 204 gpi_string_to_flag(const char *str, 205 const StringFlagItem *map); 206 207 unsigned int 208 gpi_string_list_to_flags(const char *str[], 209 const StringFlagItem *map); 210 211 /* Allocates a sufficiently large buffer and interpolates the format 212 * string with the proveded va_list args. The returned memory has to 213 * be freed by the caller. */ 214 char* 215 gpi_vsnprintf (const char* format, va_list args); 216 217 #define C_MEM(MEM) do {\ 218 if ((MEM) == NULL) {\ 219 GP_LOG_E ("Out of memory: '%s' failed.", #MEM);\ 220 return GP_ERROR_NO_MEMORY;\ 221 }\ 222 } while(0) 223 224 #define C_PARAMS(PARAMS) do {\ 225 if (!(PARAMS)) {\ 226 GP_LOG_E ("Invalid parameters: '%s' is NULL/FALSE.", #PARAMS);\ 227 return GP_ERROR_BAD_PARAMETERS;\ 228 }\ 229 } while(0) 230 231 #define C_PARAMS_MSG(PARAMS, MSG, ...) do {\ 232 if (!(PARAMS)) {\ 233 GP_LOG_E ("Invalid parameters: " #MSG " ('%s' is NULL/FALSE.)", ##__VA_ARGS__, #PARAMS);\ 234 return GP_ERROR_BAD_PARAMETERS;\ 235 }\ 236 } while(0) 237 238 #endif /* _GPHOTO2_INTERNAL_CODE */ 239 240 #endif /* __GPHOTO2_PORT_LOG_H__ */ 241