summaryrefslogtreecommitdiff
path: root/libgphoto2_port/gphoto2/gphoto2-port-log.h
blob: 3d35d5938f121892dbea786427bdcabc06aa8e39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
/** \file gphoto2-port-log.h
 *
 * Copyright 2001 Lutz Mueller <lutz@users.sf.net>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA  02110-1301  USA
 */

#ifndef __GPHOTO2_PORT_LOG_H__
#define __GPHOTO2_PORT_LOG_H__

#include <stdarg.h>

/**
 * \brief Logging level
 * Specifies the logging severity level.
 */
typedef enum {
	GP_LOG_ERROR = 0,	/**< \brief Log message is an error information. */
	GP_LOG_VERBOSE = 1,	/**< \brief Log message is an verbose debug information. */
	GP_LOG_DEBUG = 2,	/**< \brief Log message is an debug information. */
	GP_LOG_DATA = 3		/**< \brief Log message is a data hex dump. */
} GPLogLevel;

/**
 * GP_LOG_ALL:
 * 
 * Used by frontends if they want to be sure their 
 * callback function receives all messages. Defined 
 * as the highest debug level. Can make frontend code 
 * more understandable and extension of log levels
 * easier.
 **/
#define GP_LOG_ALL GP_LOG_DATA

/**
 * \brief Logging function hook
 * 
 * This is the function frontends can use to receive logging information
 * from the libgphoto2 framework. It is set using gp_log_add_func() and 
 * removed using gp_log_remove_func() and will then receive the logging
 * messages of the level specified.
 *
 * \param level the log level of the passed message, as set by the camera driver or libgphoto2
 * \param domain the logging domain as set by the camera driver, or libgphoto2 function
 * \param str the logmessage, without linefeed
 * \param data the caller private data that was passed to gp_log_add_func()
 */
typedef void (* GPLogFunc) (GPLogLevel level, const char *domain, const char *str, void *data);

#ifndef DISABLE_DEBUGGING

int  gp_log_add_func    (GPLogLevel level, GPLogFunc func, void *data);
int  gp_log_remove_func (int id);

/* Logging */
void gp_log      (GPLogLevel level, const char *domain,
		  const char *format, ...)
#ifdef __GNUC__
	__attribute__((__format__(printf,3,4)))
#endif
;
void gp_log_with_source_location(
		  GPLogLevel level, const char *file, int line, const char *func,
		  const char *format, ...)
#ifdef __GNUC__
	__attribute__((__format__(printf,5,6)))
#endif
;
void gp_logv     (GPLogLevel level, const char *domain, const char *format,
		  va_list args)
#ifdef __GNUC__
	__attribute__((__format__(printf,3,0)))
#endif
;
void gp_log_data (const char *domain, const char *data, unsigned int size,
		  const char *format, ...)
#ifdef __GNUC__
__attribute__((__format__(printf,4,5)))
#endif
;

/*
 * GP_DEBUG:
 * msg: message to log
 * params: params to message
 *
 * Logs message at log level #GP_LOG_DEBUG by calling #gp_log() with
 * an automatically generated domain
 * You have to define GP_MODULE as "mymod" for your module
 * mymod before using #GP_DEBUG().
 */

#ifdef _GPHOTO2_INTERNAL_CODE
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define GP_DEBUG(...) \
        gp_log(GP_LOG_DEBUG, GP_MODULE "/" __FILE__, __VA_ARGS__)

/*
 * GP_LOG_D/E:
 * simple helper macros for convenient and consistent logging of error
 * and debug messages including information about the source location.
 */
#define GP_LOG_D(...) gp_log(GP_LOG_DEBUG, __func__, __VA_ARGS__)
#define GP_LOG_E(...) gp_log_with_source_location(GP_LOG_ERROR, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define GP_LOG_DATA(DATA, SIZE, MSG, ...) gp_log_data(__func__, DATA, SIZE, MSG, ##__VA_ARGS__)

#elif defined(__GNUC__) &&  __GNUC__ >= 2
#define GP_DEBUG(msg, params...) \
        gp_log(GP_LOG_DEBUG, GP_MODULE "/" __FILE__, msg, ##params)
/*
 * GP_LOG_D/E:
 * simple helper macros for convenient and consistent logging of error
 * and debug messages including information about the source location.
 */
#define GP_LOG_D(...) gp_log(GP_LOG_DEBUG, __func__, __VA_ARGS__)
#define GP_LOG_E(...) gp_log_with_source_location(GP_LOG_ERROR, __FILE__, __LINE__, __func__, __VA_ARGS__)
#define GP_LOG_DATA(DATA, SIZE, MSG, ...) gp_log_data(__func__, DATA, SIZE, MSG, ##__VA_ARGS__)

#else
# ifdef __GNUC__
#  warning Disabling GP_DEBUG because variadic macros are not allowed
# endif
#define GP_DEBUG (void) 
#define GP_LOG_D(...) /* no-op */
#define GP_LOG_E(...) /* no-op */
#define GP_LOG_DATA(DATA, SIZE, ...) /* no-op */
#endif
#endif /* _GPHOTO2_INTERNAL_CODE */

#else /* DISABLE_DEBUGGING */

/* Stub these functions out if debugging is disabled */
#define gp_log_add_func(level, func, data) (0)
#define gp_log_remove_func(id) (0)
#define gp_log(level, domain, format, args...) /**/
#define gp_log_with_source_location(level, file, line, func, format, ...)
#define gp_logv(level, domain, format, args) /**/
#define gp_log_data(domain, data, size) /**/

#ifdef _GPHOTO2_INTERNAL_CODE
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define GP_DEBUG(...) /* no-op */
#define GP_LOG_D(...) /* no-op */
#define GP_LOG_E(...) /* no-op */
#define GP_LOG_DATA(DATA, SIZE, ...) /* no-op */

#elif defined(__GNUC__)
#define GP_DEBUG(msg, params...) /* no-op */
#define GP_LOG_D(...) /* no-op */
#define GP_LOG_E(...) /* no-op */
#define GP_LOG_DATA(DATA, SIZE, ...) /* no-op */
#else
#define GP_DEBUG (void)
#define GP_LOG_D (void /* no-op */
#define GP_LOG_E (void) /* no-op */
#define GP_LOG_DATA(void) /* no-op */
#endif
#endif /* _GPHOTO2_INTERNAL_CODE */

#endif /* DISABLE_DEBUGGING */

#ifdef _GPHOTO2_INTERNAL_CODE

  typedef struct StringFlagItem {
    char *str;
    unsigned int flag;
  } StringFlagItem;

  typedef void (*string_item_func) (const char *str, void *data);

  const char * 
  gpi_enum_to_string(const unsigned int _enum, 
		     const StringFlagItem *map);

  int
  gpi_string_to_enum(const char *str,
		     unsigned int *result,
		     const StringFlagItem *map);

  void 
  gpi_flags_to_string_list(const unsigned int flags, 
			   const StringFlagItem *map,
			   string_item_func func, void *data);
  
  int 
  gpi_string_or_to_flags(const char *str, 
			 unsigned int *flags,
			 const StringFlagItem *map);

  unsigned int 
  gpi_string_to_flag(const char *str, 
		     const StringFlagItem *map);

  unsigned int 
  gpi_string_list_to_flags(const char *str[], 
			   const StringFlagItem *map);

  /* Allocates a sufficiently large buffer and interpolates the format
   * string with the proveded va_list args. The returned memory has to
   * be freed by the caller. */
  char*
  gpi_vsnprintf (const char* format, va_list args);

#define C_MEM(MEM) do {\
	if ((MEM) == NULL) {\
		GP_LOG_E ("Out of memory: '%s' failed.", #MEM);\
		return GP_ERROR_NO_MEMORY;\
	}\
} while(0)

#define C_PARAMS(PARAMS) do {\
	if (!(PARAMS)) {\
		GP_LOG_E ("Invalid parameters: '%s' is NULL/FALSE.", #PARAMS);\
		return GP_ERROR_BAD_PARAMETERS;\
	}\
} while(0)

#define C_PARAMS_MSG(PARAMS, MSG, ...) do {\
	if (!(PARAMS)) {\
		GP_LOG_E ("Invalid parameters: " #MSG " ('%s' is NULL/FALSE.)", ##__VA_ARGS__, #PARAMS);\
		return GP_ERROR_BAD_PARAMETERS;\
	}\
} while(0)

#endif /* _GPHOTO2_INTERNAL_CODE */

#endif /* __GPHOTO2_PORT_LOG_H__ */