1 /*------------------------------------------------------------------------
2 * Copyright 2007-2009 (c) Jeff Brown <spadix@users.sourceforge.net>
3 *
4 * This file is part of the ZBar Bar Code Reader.
5 *
6 * The ZBar Bar Code Reader is free software; you can redistribute it
7 * and/or modify it under the terms of the GNU Lesser Public License as
8 * published by the Free Software Foundation; either version 2.1 of
9 * the License, or (at your option) any later version.
10 *
11 * The ZBar Bar Code Reader is distributed in the hope that it will be
12 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser Public License
17 * along with the ZBar Bar Code Reader; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19 * Boston, MA 02110-1301 USA
20 *
21 * http://sourceforge.net/projects/zbar
22 *------------------------------------------------------------------------*/
23 #ifndef _ERROR_H_
24 #define _ERROR_H_
25
26 #ifdef HAVE_INTTYPES_H
27 # include <inttypes.h>
28 #endif
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <errno.h>
33 #include <assert.h>
34
35 #include <zbar.h>
36
37 #ifdef _WIN32
38 # include <windows.h>
39 #endif
40
41 #if __STDC_VERSION__ < 199901L
42 # if __GNUC__ >= 2
43 # define __func__ __FUNCTION__
44 # else
45 # define __func__ "<unknown>"
46 # endif
47 #endif
48
49 #define ERRINFO_MAGIC (0x5252457a) /* "zERR" (LE) */
50
51 typedef enum errsev_e {
52 SEV_FATAL = -2, /* application must terminate */
53 SEV_ERROR = -1, /* might be able to recover and continue */
54 SEV_OK = 0,
55 SEV_WARNING = 1, /* unexpected condition */
56 SEV_NOTE = 2, /* fyi */
57 } errsev_t;
58
59 typedef enum errmodule_e {
60 ZBAR_MOD_PROCESSOR,
61 ZBAR_MOD_VIDEO,
62 ZBAR_MOD_WINDOW,
63 ZBAR_MOD_IMAGE_SCANNER,
64 ZBAR_MOD_UNKNOWN,
65 } errmodule_t;
66
67 typedef struct errinfo_s {
68 uint32_t magic; /* just in case */
69 errmodule_t module; /* reporting module */
70 char *buf; /* formatted and passed to application */
71 int errnum; /* errno for system errors */
72
73 errsev_t sev;
74 zbar_error_t type;
75 const char *func; /* reporting function */
76 const char *detail; /* description */
77 char *arg_str; /* single string argument */
78 int arg_int; /* single integer argument */
79 } errinfo_t;
80
81 extern int _zbar_verbosity;
82
83 /* FIXME don't we need varargs hacks here? */
84
85 #ifdef _WIN32
86 # define ZFLUSH fflush(stderr);
87 #else
88 # define ZFLUSH
89 #endif
90
91 #ifdef ZNO_MESSAGES
92
93 # ifdef __GNUC__
94 /* older versions of gcc (< 2.95) require a named varargs parameter */
95 # define zprintf(args...)
96 # else
97 /* unfortunately named vararg parameter is a gcc-specific extension */
98 # define zprintf(...)
99 # endif
100
101 #else
102
103 # ifdef __GNUC__
104 # define zprintf(level, format, args...) do { \
105 if(_zbar_verbosity >= level) { \
106 fprintf(stderr, "%s: " format, __func__ , ##args); \
107 ZFLUSH \
108 } \
109 } while(0)
110 # else
111 # define zprintf(level, format, ...) do { \
112 if(_zbar_verbosity >= level) { \
113 fprintf(stderr, "%s: " format, __func__ , ##__VA_ARGS__); \
114 ZFLUSH \
115 } \
116 } while(0)
117 # endif
118
119 #endif
120
err_copy(void * dst_c,void * src_c)121 static inline int err_copy (void *dst_c,
122 void *src_c)
123 {
124 errinfo_t *dst = dst_c;
125 errinfo_t *src = src_c;
126 assert(dst->magic == ERRINFO_MAGIC);
127 assert(src->magic == ERRINFO_MAGIC);
128
129 dst->errnum = src->errnum;
130 dst->sev = src->sev;
131 dst->type = src->type;
132 dst->func = src->func;
133 dst->detail = src->detail;
134 dst->arg_str = src->arg_str;
135 src->arg_str = NULL; /* unused at src, avoid double free */
136 dst->arg_int = src->arg_int;
137 return(-1);
138 }
139
err_capture(const void * container,errsev_t sev,zbar_error_t type,const char * func,const char * detail)140 static inline int err_capture (const void *container,
141 errsev_t sev,
142 zbar_error_t type,
143 const char *func,
144 const char *detail)
145 {
146 errinfo_t *err = (errinfo_t*)container;
147 assert(err->magic == ERRINFO_MAGIC);
148 if(type == ZBAR_ERR_SYSTEM)
149 err->errnum = errno;
150 #ifdef _WIN32
151 else if(type == ZBAR_ERR_WINAPI)
152 err->errnum = GetLastError();
153 #endif
154 err->sev = sev;
155 err->type = type;
156 err->func = func;
157 err->detail = detail;
158 if(_zbar_verbosity >= 1)
159 _zbar_error_spew(err, 0);
160 return(-1);
161 }
162
err_capture_str(const void * container,errsev_t sev,zbar_error_t type,const char * func,const char * detail,const char * arg)163 static inline int err_capture_str (const void *container,
164 errsev_t sev,
165 zbar_error_t type,
166 const char *func,
167 const char *detail,
168 const char *arg)
169 {
170 errinfo_t *err = (errinfo_t*)container;
171 assert(err->magic == ERRINFO_MAGIC);
172 if(err->arg_str)
173 free(err->arg_str);
174 err->arg_str = strdup(arg);
175 return(err_capture(container, sev, type, func, detail));
176 }
177
err_capture_int(const void * container,errsev_t sev,zbar_error_t type,const char * func,const char * detail,int arg)178 static inline int err_capture_int (const void *container,
179 errsev_t sev,
180 zbar_error_t type,
181 const char *func,
182 const char *detail,
183 int arg)
184 {
185 errinfo_t *err = (errinfo_t*)container;
186 assert(err->magic == ERRINFO_MAGIC);
187 err->arg_int = arg;
188 return(err_capture(container, sev, type, func, detail));
189 }
190
err_capture_num(const void * container,errsev_t sev,zbar_error_t type,const char * func,const char * detail,int num)191 static inline int err_capture_num (const void *container,
192 errsev_t sev,
193 zbar_error_t type,
194 const char *func,
195 const char *detail,
196 int num)
197 {
198 errinfo_t *err = (errinfo_t*)container;
199 assert(err->magic == ERRINFO_MAGIC);
200 err->errnum = num;
201 return(err_capture(container, sev, type, func, detail));
202 }
203
err_init(errinfo_t * err,errmodule_t module)204 static inline void err_init (errinfo_t *err,
205 errmodule_t module)
206 {
207 err->magic = ERRINFO_MAGIC;
208 err->module = module;
209 }
210
err_cleanup(errinfo_t * err)211 static inline void err_cleanup (errinfo_t *err)
212 {
213 assert(err->magic == ERRINFO_MAGIC);
214 if(err->buf) {
215 free(err->buf);
216 err->buf = NULL;
217 }
218 if(err->arg_str) {
219 free(err->arg_str);
220 err->arg_str = NULL;
221 }
222 }
223
224 #endif
225