38
|
1 /*
|
|
2 * zlib license.
|
|
3 */
|
|
4 /*
|
|
5 Copyright (c) 2003 Eric Wing <ewing . public @ playcontrol.net>
|
|
6
|
|
7 This software is provided 'as-is', without any express or implied warranty.
|
|
8 In no event will the authors be held liable for any damages arising from
|
|
9 the use of this software.
|
|
10
|
|
11 Permission is granted to anyone to use this software for any purpose,
|
|
12 including commercial applications, and to alter it and redistribute it
|
|
13 freely, subject to the following restrictions:
|
|
14
|
|
15 1. The origin of this software must not be misrepresented; you must not
|
|
16 claim that you wrote the original software. If you use this software in a
|
|
17 product, an acknowledgment in the product documentation would be
|
|
18 appreciated but is not required.
|
|
19
|
|
20 2. Altered source versions must be plainly marked as such, and must not be
|
|
21 misrepresented as being the original software.
|
|
22
|
|
23 3. This notice may not be removed or altered from any source distribution.
|
|
24
|
|
25 */
|
|
26 /**
|
|
27 * @file
|
|
28 * This is a Thread Safe Error handling Library. (How safe is still to be
|
|
29 * determined.) The name ErrorLib was already taken. TSError might work, but
|
|
30 * Terror was more fun to use. Named tErrorLib just in case of
|
|
31 * any conflicts with others who use "terror".
|
|
32 *
|
|
33 * This library is a generalized error flagging library. When an error
|
|
34 * occurs, this library allows you to set an error condition (a number
|
|
35 * and/or string) which can be fetched by at a later time (perhaps in a
|
|
36 * different module). It is analgous to perror or glGetError(), though
|
|
37 * perhaps a closer analogy might be to SDL_SetError() as this library
|
|
38 * allows you to deal with both integer numbers as well as printf-style
|
|
39 * formatted strings.
|
|
40 *
|
|
41 * This library also attempts to implement a certain degree of thread
|
|
42 * safety. The problem with a general access error system used
|
|
43 * by multiple threads is the risk of clobbering error messages set
|
|
44 * in one thread by error messages set in other threads before you
|
|
45 * get a chance to read them. This library solves that problem by
|
|
46 * creating separate error message structures for every unique thread.
|
|
47 *
|
|
48 * This library is unique in several ways. First, this is an entirely
|
|
49 * self-contained, error-handling-only library. Most people seem to at
|
|
50 * best rewrite their own error handling system for each library they write
|
|
51 * (and at worst, don't write any error handling system at all).
|
|
52 *
|
|
53 * Second, because this library is intended for just error handling,
|
|
54 * it was designed with the idea that it could be dropped into any
|
|
55 * library you choose and you are allowed to have separate/isolated
|
|
56 * error "pools". So for example, if you were writing multiple modules,
|
|
57 * such as a graphics library, a sound library, and an application core,
|
|
58 * you might desire to have separate error pools for each system so
|
|
59 * they don't collide.
|
|
60 * In order to accommodate the possible multiple instance of pools, the
|
|
61 * library has been factored into an object-oriented structure. Since
|
|
62 * this library is C-based, it does impose an additional parameter to
|
|
63 * be passed around than what people might be used to, but this
|
|
64 * API could be wrapped easily that hides the object pointer using a
|
|
65 * static or global variable for your module if you choose.
|
|
66 *
|
|
67 * Finally, this library allows the use of either/both integer or string
|
|
68 * errors. Integer error numbers allow for quick access and easy comparison.
|
|
69 * It may also allow for easier internationalization of error messages
|
|
70 * if you maintain a look-up-table.
|
|
71 * String error messages are nice because you know what the problem is
|
|
72 * immediately (don't have to hunt down or figure out what error 427 means).
|
|
73 * They also help make the code self documenting. And if you have errors
|
|
74 * nested down in function call layers, you can easily report the
|
|
75 * function call stack by appending information to the error string
|
|
76 * at each function call.
|
|
77 *
|
|
78 * Keep in mind that this library isn't meant to replace other error
|
|
79 * reporting conventions, but to supplement them. Functions that return
|
|
80 * error values (true/false,int) and logging systems (Logger) are still
|
|
81 * good systems that may address other issues. You might continue
|
|
82 * using error codes for your functions and then use tErrorLib to
|
|
83 * fetch the error string when you need them. And to log the error,
|
|
84 * you might pass the string into Logger.
|
|
85 *
|
|
86 * There are two different ways to use this library with respect to
|
|
87 * retrieving errors. You can treat each thread separately and let each
|
|
88 * live in its own separate world. When you retrieve the error, you only
|
|
89 * retrieve the error for the current thread. You should use the
|
|
90 * TError_GetErrorOnCurrentThread family of functions for this scenario.
|
|
91 * Alternatively, you can use this library to always return you the last
|
|
92 * set error regardless of the thread it was set in. You should use the
|
|
93 * TError_GetLastError family of functions for this scenario.
|
|
94 *
|
|
95 * Sample Usage:
|
|
96 * @code
|
|
97 * TErrorPool* err_pool;
|
|
98 * TErrorStatus error_status;
|
|
99 *
|
|
100 * err_pool = TError_CreateErrorPool();
|
|
101 * if(NULL == err_pool)
|
|
102 * {
|
|
103 * fprintf(stderr, "Error, could not create error pool\n");
|
|
104 * exit(1);
|
|
105 * }
|
|
106 *
|
|
107 * // Set a hypothetical error
|
|
108 * TError_SetError(err_pool, -1234, "Demo error #%d: %s", 222, "Hello");
|
|
109 *
|
|
110 * // Check/get the error using the isolated thread usage model.
|
|
111 * // Might use TError_GetErrorNumOnCurrentThread or TError_GetErrorStrOnCurrentThread instead
|
|
112 * error_status = TError_GetErrorOnCurrentThread(err_pool);
|
|
113 * // Make sure the string is not NULL before printing it with printf.
|
|
114 * // (Some systems let you print NULL, but on Solaris, it seg faults.)
|
|
115 * if(NULL != error_status.errorString)
|
|
116 * {
|
|
117 * printf("%d: %s", error_status.errorNumber, error_status.errorString);
|
|
118 * }
|
|
119 *
|
|
120 * // not really necessary to call since single threaded and
|
|
121 * // going to delete the entire pool right after, but here for show.
|
|
122 * TError_DeleteEntryOnCurrentThread(err_pool);
|
|
123 *
|
|
124 * TError_FreeErrorPool(err_pool);
|
|
125 *
|
|
126 * @endcode
|
|
127 *
|
|
128 * Sample API Wrapping:
|
|
129 * This is an example of how you might want to wrap this library into
|
|
130 * your own API code so you don't have to expose the error pool.
|
|
131 * This example uses the last set error usage model.
|
|
132 * (If you didn't want to use both integers and strings, you could
|
|
133 * also make that decision here.)
|
|
134 *
|
|
135 * @code
|
|
136 * #include "tErrorLib.h"
|
|
137 * static TErrorPool* s_ErrorPool = NULL; // static error pool for this module
|
|
138 *
|
|
139 * int MyLibraryInit()
|
|
140 * {
|
|
141 * // Presumably you have you application specific code here too.
|
|
142 * s_ErrorPool = TError_CreateErrorPool();
|
|
143 * if(NULL == s_ErrorPool)
|
|
144 * {
|
|
145 * return 0; // couldn't allocate memory
|
|
146 * }
|
|
147 * return 1;
|
|
148 * }
|
|
149 *
|
|
150 * void MyLibraryQuit()
|
|
151 * {
|
|
152 * TError_FreeErrorPool(s_ErrorPool);
|
|
153 * s_ErrorPool = NULL;
|
|
154 * }
|
|
155 *
|
|
156 * void MyLibrarySetError(int err_num, const char* err_str, ...)
|
|
157 * {
|
|
158 * va_list argp;
|
|
159 * va_start(argp, err_str);
|
|
160 * TError_SetErrorv(s_ErrorPool, err_num, err_str, argp);
|
|
161 * va_end(argp);
|
|
162 * }
|
|
163 *
|
|
164 * const char* MyLibraryGetError()
|
|
165 * {
|
|
166 * const char* ret_error = TError_GetLastErrorStr(s_ErrorPool);
|
|
167 * if(NULL == ret_error)
|
|
168 * {
|
|
169 * return ""; // provide an empty string to make it safe for people using printf without checking.
|
|
170 * }
|
|
171 * return ret_error;
|
|
172 * }
|
|
173 * @endcode
|
|
174 *
|
|
175 * @note By default, this library attempts to use vasprintf to generate
|
|
176 * the printf-style formatted strings. vasprintf is a GNU extension
|
|
177 * which solves the problem of having enough memory allocated in a buffer
|
|
178 * to handle an arbitrary length formatted string which you don't know
|
|
179 * in advance. I recommend you use this implementation if your library
|
|
180 * can support it as it will allow you to always generate correct strings.
|
|
181 * (Stack traces can become long and exceed your preallocated buffer sizes.)
|
|
182 * For compatibility, an alternative vsnprintf implementation is provided.
|
|
183 * If a string is too large, it will be truncated. vsnprintf is specified
|
|
184 * in C99, but it critcal for avoid security related issues surrounding
|
|
185 * sprintf and vsprintf. If your library lacks vsnprintf, you're asking
|
|
186 * for trouble. I currently do not try to handle this case.
|
|
187 *
|
|
188 * @note By default, this library assumes 0 is the no-error value.
|
|
189 * In addition, if you are using the string-only based APIs, the integer
|
|
190 * components will be automatically filled to 0 (for no-error) and
|
|
191 * 1 (for error). If these numbers conflict with your conventions,
|
|
192 * you may be able to change these values in the implementation file
|
|
193 * and recompile the library. Look for the defines for TERROR_ERROR_VALUE
|
|
194 * and TERROR_NOERROR_VALUE.
|
|
195 *
|
|
196 * @note This version attempts to provide enough thread safety to get by
|
|
197 * but it may not be totally safe during creation and destruction of
|
|
198 * instances (partly since locking is done inside the object-level),
|
|
199 * so don't create or destroy pools when there is possible contention.
|
|
200 * Strings you pass into the functions are not necessarily locked so
|
|
201 * be careful if you are modifying strings that are shared among
|
|
202 * your threads.
|
|
203 *
|
|
204 * @note Error strings returned are pointers to tErrorLib's internal
|
|
205 * copies of strings. Do not modify these or delete them. Also keep in
|
|
206 * mind that the pointers to these strings may become invalid when
|
|
207 * a new error is set (on a per-thread basis). So if you need a copy
|
|
208 * of the error string, you should make your own copy.
|
|
209 *
|
|
210 * @warning For code that frequently generates and destroys many threads,
|
|
211 * be aware that you should pay attention to memory management with this
|
|
212 * library. This library works by creating a unique error message
|
|
213 * structure for each thread. When the thread dies, the error pool
|
|
214 * will still contain a structure for that thread (if it had called
|
|
215 * this library in that thread). Just before the thread dies (but after
|
|
216 * any final error calls), you should call TError_DeleteEntryOnCurrentThread()
|
|
217 * to free the memory for that thread. Otherwise you will have a
|
|
218 * pseudo-memory-leak. (Pseudo in the sense that once you free the error pool,
|
|
219 * all memory will be freed, regardless of whether you remembered to call
|
|
220 * this function.)
|
|
221 * @see TERROR_NOERROR_VALUE, TError_DeleteEntryOnCurrentThread
|
|
222 *
|
|
223 * @author Eric Wing
|
|
224 */
|
|
225
|
|
226 #ifndef TERRORLIB_H
|
|
227 #define TERRORLIB_H
|
|
228
|
|
229 #ifdef __cplusplus
|
|
230 extern "C" {
|
|
231 #endif
|
|
232
|
|
233 #include <stdarg.h> /* for va_list */
|
|
234
|
|
235 /**
|
|
236 * This library determines if there is an error by checking
|
|
237 * both the error number and error string. If the error string is NULL
|
|
238 * and the error number is 0 (TERROR_NOERROR_VALUE), then it
|
|
239 * is considered a non-error. Because this library allows you to
|
|
240 * use just numbers or just strings, a value must be filled in internally
|
|
241 * as a place holder. It also must return some default/no-error values
|
|
242 * for GetError if there was no error. In these situations,
|
|
243 * NULL is set for strings and 0 (TERROR_NOERROR_VALUE)
|
|
244 * is set for numbers. This will become a point of confusion if you use
|
|
245 * 0 as an error code to denote a legitimate error and have a NULL error
|
|
246 * string.
|
|
247 *
|
|
248 * To accommodate this problem, this define is provided to let you
|
|
249 * redefine what the no-error value is (though this is untested).
|
|
250 * If you have the opportunity to write code that doesn't rely on 0 denoting
|
|
251 * an error, I recommend using this library as is, instead of trying
|
|
252 * to change this. If you do change this value, remember you must recompile
|
|
253 * the entire library. Also make sure that TERROR_ERROR_VALUE (in
|
|
254 * implementation file) is not equal to your changed value.
|
|
255 *
|
|
256 * For most cases, if you just want to check if there was an
|
|
257 * error, you can check if the error_number == 0. But if
|
|
258 * you are thinking that you may want to redefine what the no-error
|
|
259 * value is in the future (say -99999), then you can use this
|
|
260 * constant name instead (e.g. error_number == TERROR_NOERROR_VALUE).
|
|
261 */
|
|
262 #define TERROR_NOERROR_VALUE 0
|
|
263
|
|
264
|
|
265 #ifndef DOXYGEN_SHOULD_IGNORE_THIS
|
|
266 /** @cond DOXYGEN_SHOULD_IGNORE_THIS */
|
|
267
|
|
268 /* Note: For Doxygen to produce clean output, you should set the
|
|
269 * PREDEFINED option to remove TERROR_TERROR_DECLSPEC, TERROR_CALL, and
|
|
270 * the DOXYGEN_SHOULD_IGNORE_THIS blocks.
|
|
271 * PREDEFINED = DOXYGEN_SHOULD_IGNORE_THIS=1 TERROR_TERROR_DECLSPEC= TERROR_CALL=
|
|
272 */
|
|
273
|
|
274 /** Windows needs to know explicitly which functions to export in a DLL. */
|
|
275 #if defined(_WIN32)
|
|
276 #if defined(TERROR_BUILD_LIBRARY)
|
|
277 #define TERROR_DECLSPEC __declspec(dllexport)
|
|
278 #else
|
|
279 #define TERROR_DECLSPEC __declspec(dllimport)
|
|
280 #endif
|
|
281 #else
|
|
282 #if defined(ALMIXER_BUILD_LIBRARY)
|
|
283 #if defined (__GNUC__) && __GNUC__ >= 4
|
|
284 #define TERROR_DECLSPEC __attribute__((visibility("default")))
|
|
285 #else
|
|
286 #define TERROR_DECLSPEC
|
|
287 #endif
|
|
288 #else
|
|
289 #define TERROR_DECLSPEC
|
|
290 #endif
|
|
291 #endif
|
|
292
|
|
293 /* For Windows, by default, use the C calling convention */
|
|
294 #if defined(_WIN32)
|
|
295 #define TERROR_CALL __cdecl
|
|
296 #else
|
|
297 #define TERROR_CALL
|
|
298 #endif
|
|
299
|
|
300
|
|
301 /* Version number is set here.
|
|
302 * Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
|
|
303 */
|
|
304 #define TERROR_MAJOR_VERSION 0
|
|
305 #define TERROR_MINOR_VERSION 1
|
|
306 #define TERROR_PATCH_VERSION 0
|
|
307
|
|
308 /** @endcond DOXYGEN_SHOULD_IGNORE_THIS */
|
|
309 #endif /* DOXYGEN_SHOULD_IGNORE_THIS */
|
|
310
|
|
311
|
|
312 /**
|
|
313 * Struct that contains the version information of this library.
|
|
314 * This represents the library's version as three levels: major revision
|
|
315 * (increments with massive changes, additions, and enhancements),
|
|
316 * minor revision (increments with backwards-compatible changes to the
|
|
317 * major revision), and patchlevel (increments with fixes to the minor
|
|
318 * revision).
|
|
319 * @see TERROR_GET_COMPILED_VERSION, TError_GetLinkedVersion
|
|
320 */
|
|
321 typedef struct
|
|
322 {
|
|
323 int major; /**< major revision. */
|
|
324 int minor; /**< minor revision. */
|
|
325 int patch; /**< patch revision. */
|
|
326 } TErrorVersion;
|
|
327
|
|
328
|
|
329 /**
|
|
330 * Struct that contains all the data needed to represent an error (pool)
|
|
331 * instance. This is the object you pass around to all instance
|
|
332 * based error functions. Don't touch the data in the struct directly.
|
|
333 * This should be considered an opaque data type.
|
|
334 */
|
|
335 typedef struct
|
|
336 {
|
|
337 void* mutexLock; /**< You probably shouldn't touch this either. */
|
|
338 void* opaqueData; /**< Don't touch this. */
|
|
339 } TErrorPool;
|
|
340
|
|
341 /**
|
|
342 * Struct that contains both the error number and error string.
|
|
343 * This is returned by the TError_GetError functions which
|
|
344 * allows you to fetch both the errorNumber and errorString.
|
|
345 * (Other API functions only let you get one or the other).
|
|
346 * You may read the values directly, but do not modify the string.
|
|
347 * Keep in mind that once a SetError is called again for your thread,
|
|
348 * the pointer may become invalid. Copy this data out if you need
|
|
349 * to keep it.
|
|
350 */
|
|
351 typedef struct
|
|
352 {
|
|
353 int errorNumber; /**< The error number. */
|
|
354 const char* errorString; /**< The error string (read-only). */
|
|
355 } TErrorStatus;
|
|
356
|
|
357
|
|
358 /**
|
|
359 * This macro fills in a TError_Version structure with the version of the
|
|
360 * library you compiled against. This is determined by what header the
|
|
361 * compiler uses. Note that if you dynamically linked the library, you might
|
|
362 * have a slightly newer or older version at runtime. That version can be
|
|
363 * determined with TError_GetLinkedVersion(), which, unlike
|
|
364 * TERROR_GET_COMPILED_VERSION, is not a macro.
|
|
365 *
|
|
366 * @param X A pointer to a TError_Version struct to initialize.
|
|
367 *
|
|
368 * @see TErrorVersion, TError_GetLinkedVersion
|
|
369 */
|
|
370 #define TERROR_GET_COMPILED_VERSION(X) \
|
|
371 { \
|
|
372 if(NULL != (X)) \
|
|
373 { \
|
|
374 (X)->major = TERROR_MAJOR_VERSION; \
|
|
375 (X)->minor = TERROR_MINOR_VERSION; \
|
|
376 (X)->patch = TERROR_PATCH_VERSION; \
|
|
377 } \
|
|
378 }
|
|
379
|
|
380 /**
|
|
381 * Gets the library version of tErrorLib you are using.
|
|
382 * This gets the version of tErrorLib that is linked against your program.
|
|
383 * If you are using a shared library (DLL) version of tError, then it is
|
|
384 * possible that it will be different than the version you compiled against.
|
|
385 *
|
|
386 * This is a real function; the macro TERROR_GET_COMPILED_VERSION
|
|
387 * tells you what version of tErrorLib you compiled against:
|
|
388 *
|
|
389 * @code
|
|
390 * TErrorVersion compiled;
|
|
391 * TErrorVersion linked;
|
|
392 *
|
|
393 * TERROR_GET_COMPILED_VERSION(&compiled);
|
|
394 * TError_GetLinkedVersion(&linked);
|
|
395 * printf("We compiled against tError version %d.%d.%d ...\n",
|
|
396 * compiled.major, compiled.minor, compiled.patch);
|
|
397 * printf("But we linked against tError version %d.%d.%d.\n",
|
|
398 * linked.major, linked.minor, linked.patch);
|
|
399 * @endcode
|
|
400 *
|
|
401 * @see TErrorVersion, TERROR_GET_COMPILED_VERSION
|
|
402 */
|
|
403 extern TERROR_DECLSPEC void TERROR_CALL TError_GetLinkedVersion(TErrorVersion* ver);
|
|
404
|
|
405 /**
|
|
406 * This creates a new error pool instance.
|
|
407 * An error pool is a self-contained object that holds its own
|
|
408 * errors. You may have multiple error pools to isolate errors for
|
|
409 * different subsystems if you choose.
|
|
410 *
|
|
411 * For most (if not all) other tErrorLib functions, you will
|
|
412 * pass this instance to each function when you call them.
|
|
413 *
|
|
414 * @return Returns a pointer to an error pool which is the
|
|
415 * instance variable (if successful) or NULL on failure.
|
|
416 *
|
|
417 * @see TError_FreeErrorPool
|
|
418 */
|
|
419 extern TERROR_DECLSPEC TErrorPool* TERROR_CALL TError_CreateErrorPool(void);
|
|
420
|
|
421 /**
|
|
422 * This frees an error pool instance.
|
|
423 * This properly frees the memory of an error pool instance created by
|
|
424 * CreateErrorPool. Whenever you create a TErrorPool
|
|
425 * instance, you should always remember to balance it with a
|
|
426 * FreeErrorPool() call.
|
|
427 *
|
|
428 * @param err_pool A pointer to the error pool instance you want to free.
|
|
429 *
|
|
430 * @see TError_CreateErrorPool
|
|
431 */
|
|
432 extern TERROR_DECLSPEC void TERROR_CALL TError_FreeErrorPool(TErrorPool* err_pool);
|
|
433
|
|
434 /**
|
|
435 * This function will delete the error message memory that has been
|
|
436 * allocated for the thread you call this function in.
|
|
437 * This reflects a deficiency in this library's design.
|
|
438 * If a thread terminates, this library will still have
|
|
439 * allocated memory for it if it had set an error.
|
|
440 * If you plan on killing a thread, call this function in that
|
|
441 * thread before it dies so the memory can be freed.
|
|
442 * Do not call SetError* again in this thread or memory
|
|
443 * will be reallocated.
|
|
444 * It is safe to call if no memory has actually be allocated for the
|
|
445 * error for the current thread.
|
|
446 * If you cannot use this function to free the memory for some reason,
|
|
447 * this is a pseudo-memory-leak. By pseudo, I mean that you won't
|
|
448 * completely leak. When you delete the entire memory pool, it will
|
|
449 * be able to free all error message structures that were associated
|
|
450 * with the pool so you can recover this memory.
|
|
451 *
|
|
452 * @param err_pool The error pool instance you want to use.
|
|
453 */
|
|
454 extern TERROR_DECLSPEC void TError_DeleteEntryOnCurrentThread(TErrorPool* err_pool);
|
|
455
|
|
456
|
|
457 /**
|
|
458 * This function sets an error.
|
|
459 * Calling this function will set an error (for this thread)
|
|
460 * with the specified error number and error string which
|
|
461 * can later be retrieved by a GetError call.
|
|
462 * The function usage is similar to printf.
|
|
463 * If both the err_num is set to 0 (see other notes TERROR_NOERROR_VALUE)
|
|
464 * and the err_str is set to NULL, then this is considered clearing an
|
|
465 * error and no error will be marked.
|
|
466 *
|
|
467 * @param err_pool The error pool instance you want to use.
|
|
468 *
|
|
469 * @param err_num The error number you want to use for this error.
|
|
470 * The value for this number is up to you, based on your own
|
|
471 * conventions. But this library reserves one number to denote "no error".
|
|
472 * This number for initial implementation and documentation purposes is 0,
|
|
473 * and is defined in the implementation as TERROR_NOERROR_VALUE.
|
|
474 * You can still specify this number to be anything you choose
|
|
475 * if and only if you also always specify an error string that is not NULL.
|
|
476 * As long as an error string exists, the system will recognize there
|
|
477 * is an error. But if you have a NULL string and use 0 to denote an
|
|
478 * error, this will be interpreted as a clear error message.
|
|
479 * So I recommend you treat 0 as a no-error value and avoid using it
|
|
480 * as an error value in your code to avoid confusion.
|
|
481 *
|
|
482 * @param err_str This is where your error text goes. It is compatible with
|
|
483 * printf style format strings. There is no imposed limit on how long
|
|
484 * the strings can be if you are using the vasprintf backend. The
|
|
485 * vsnprintf implemention will automatically truncate the string if it
|
|
486 * is too long.
|
|
487 * You if don't wish to specify an error string, you may enter NULL here.
|
|
488 * But remember to note the effect if this string is NULL and the err_num is
|
|
489 * set to 0 (TERROR_NOERROR_VALUE).
|
|
490 *
|
|
491 * @param ... This is the variable argument list used to accomodate
|
|
492 * printf style format strings.
|
|
493 *
|
|
494 * @see TError_SetErrorv, TError_SetErrorNoFormat, TError_SetErrorNum,
|
|
495 * TError_SetErrorStr, TError_SetErrorStrv, TError_SetErrorStrNoFormat,
|
|
496 * TERROR_NOERROR_VALUE
|
|
497 */
|
|
498 extern TERROR_DECLSPEC void TERROR_CALL TError_SetError(TErrorPool* err_pool, int err_num, const char* err_str, ...);
|
|
499
|
|
500
|
|
501 /**
|
|
502 * This function sets an error.
|
|
503 * This is the va_list version of TError_SetError.
|
|
504 * The same rules apply to this as with TError_SetError.
|
|
505 *
|
|
506 * @see TError_SetError
|
|
507 */
|
|
508 extern TERROR_DECLSPEC void TERROR_CALL TError_SetErrorv(TErrorPool* err_pool, int err_num, const char* err_str, va_list argp);
|
|
509
|
|
510 /**
|
|
511 * This is a "No Format Strings Allowed" version of SetError.
|
|
512 * This version of SetError disallows the use of format strings.
|
|
513 * This was written if you needed to expose the SetError function to
|
|
514 * an untrusted source because it is quite easy to crash a system (or worse)
|
|
515 * with an invalid format string. An untrusted source might include
|
|
516 * arguments passed through the command line, any user input that
|
|
517 * gets fed to Logger, or strings taken from runtime generated sources
|
|
518 * like scripts.
|
|
519 * I was probably being overly paranoid when I created this function,
|
|
520 * and there may be ways to achive this level of safety without
|
|
521 * this function, but here it is anyway.
|
|
522 * In addition, if your compiler has problems with both vasprintf and
|
|
523 * vsnprintf, (you will have to modify some source code) you might
|
|
524 * consider basing all SetError functions around this function because
|
|
525 * since the strings are known length because there is no argument
|
|
526 * expansion.
|
|
527 *
|
|
528 * @see TError_SetError
|
|
529 */
|
|
530 extern TERROR_DECLSPEC void TERROR_CALL TError_SetErrorNoFormat(TErrorPool* err_pool, int err_num, const char* err_str);
|
|
531
|
|
532 /**
|
|
533 * This function sets an error.
|
|
534 * This version only lets you set the error number. The backend
|
|
535 * will automatically set the error string to NULL.
|
|
536 * This API call is intended to be used only if you don't plan on using
|
|
537 * any error strings in your code.
|
|
538 * Also be aware of the notes about TERROR_NOERROR_VALUE.
|
|
539 *
|
|
540 * @see TError_SetError, TERROR_NOERROR_VALUE
|
|
541 */
|
|
542 extern TERROR_DECLSPEC void TERROR_CALL TError_SetErrorNum(TErrorPool* err_pool, int err_num);
|
|
543
|
|
544 /**
|
|
545 * This function sets an error.
|
|
546 * This version only lets you set the error string. The backend
|
|
547 * will automatically set the error number to TERROR_NOERROR_VALUE
|
|
548 * which is currently implemented as 0.
|
|
549 * This API call is intended to be used only if you don't plan on using
|
|
550 * any error numbers in your code.
|
|
551 * Also be aware of the notes about TERROR_NOERROR_VALUE if you use NULL
|
|
552 * strings.
|
|
553 *
|
|
554 * @see TError_SetError, TERROR_NOERROR_VALUE
|
|
555 */
|
|
556 extern TERROR_DECLSPEC void TERROR_CALL TError_SetErrorStr(TErrorPool* err_pool, const char* err_str, ...);
|
|
557
|
|
558 /**
|
|
559 * This function sets an error.
|
|
560 * This is the va_list version of TError_SetErrorStr.
|
|
561 *
|
|
562 * @see TError_SetError, TError_SetErrorStr, TERROR_NOERROR_VALUE
|
|
563 */
|
|
564 extern TERROR_DECLSPEC void TERROR_CALL TError_SetErrorStrv(TErrorPool* err_pool, const char* err_str, va_list argp);
|
|
565
|
|
566 /**
|
|
567 * This function sets an error.
|
|
568 * This is the "No Format Strings Allowed" version of TError_SetErrorStr.
|
|
569 *
|
|
570 * @see TError_SetError, TError_SetErrorNoFormat,
|
|
571 * TError_SetErrorStr, TERROR_NOERROR_VALUE
|
|
572 */
|
|
573 extern TERROR_DECLSPEC void TERROR_CALL TError_SetErrorStrNoFormat(TErrorPool* err_pool, const char* err_str);
|
|
574
|
|
575 /**
|
|
576 * This function gets the last error to be set by one of the SetError
|
|
577 * functions (from within your current thread). This version of the function
|
|
578 * returns just the error number.
|
|
579 * After this function is called, the error will be cleared, so your
|
|
580 * next call to a GetError function (with no SetError calls in between)
|
|
581 * will return a struct set with no-error values.
|
|
582 *
|
|
583 * @param err_pool The error pool instance you want to use.
|
|
584 *
|
|
585 * @return Returns the error number.
|
|
586 * If no error was set, the error number will be set
|
|
587 * to 0 (TERROR_NOERROR_VALUE).
|
|
588 *
|
|
589 * @see TError_GetErrorOnCurrentThread, TError_GetErrorStrOnCurrentThread, TERROR_NOERROR_VALUE
|
|
590 */
|
|
591 extern TERROR_DECLSPEC int TERROR_CALL TError_GetErrorNumOnCurrentThread(TErrorPool* err_pool);
|
|
592
|
|
593 /**
|
|
594 * This function gets the last error to be set by one of the SetError
|
|
595 * functions (from within your current thread). This version of the function
|
|
596 * returns a pointer to the error string.
|
|
597 * After this function is called, the error will be cleared, so your
|
|
598 * next call to a GetError function (with no SetError calls in between)
|
|
599 * will return a struct set with no-error values.
|
|
600 *
|
|
601 * @param err_pool The error pool instance you want to use.
|
|
602 *
|
|
603 * @return Returns the pointer to the error string.
|
|
604 * The pointer is to tErrorLib's own copy
|
|
605 * of the error message so you should not modify this string. Furthermore,
|
|
606 * the pointer may become invalid at the next call to SetError within this
|
|
607 * same thread, so if you need to keep the string, you must make your
|
|
608 * own copy of it.
|
|
609 * If no error was set, the error string will be set to NULL.
|
|
610 *
|
|
611 * @see TError_GetErrorNumOnCurrentThread, TError_GetErrorOnCurrentThread, TERROR_NOERROR_VALUE
|
|
612 */
|
|
613 extern TERROR_DECLSPEC const char* TERROR_CALL TError_GetErrorStrOnCurrentThread(TErrorPool* err_pool);
|
|
614
|
|
615 /**
|
|
616 * This function gets the last error to be set by one of the SetError
|
|
617 * functions (from within your current thread). This version of the function
|
|
618 * returns a struct containing the error number and a pointer to the
|
|
619 * error string.
|
|
620 * After this function is called, the error will be cleared, so your
|
|
621 * next call to a GetError function (with no SetError calls in between)
|
|
622 * will return a struct set with no-error values.
|
|
623 *
|
|
624 * @param err_pool The error pool instance you want to use.
|
|
625 *
|
|
626 * @return Returns (by-value) a struct containing the error number and
|
|
627 * pointer to the error string. The pointer is to tErrorLib's own copy
|
|
628 * of the error message so you should not modify this string. Furthermore,
|
|
629 * the pointer may become invalid at the next call to SetError within this
|
|
630 * same thread, so if you need to keep the string, you must make your
|
|
631 * own copy of it.
|
|
632 * If no error was set, the error number will be set to 0 (TERROR_NOERROR_VALUE)
|
|
633 * and the error string will be set to NULL.
|
|
634 *
|
|
635 * @see TError_GetErrorNumOnCurrentThread, TError_GetErrorStrOnCurrentThread, TERROR_NOERROR_VALUE
|
|
636 */
|
|
637 extern TERROR_DECLSPEC TErrorStatus TERROR_CALL TError_GetErrorOnCurrentThread(TErrorPool* err_pool);
|
|
638
|
|
639
|
|
640 /**
|
|
641 * This function gets the last error to be set by one of the SetError
|
|
642 * functions (regardless of thread).
|
|
643 * This version of the function
|
|
644 * returns just the error number.
|
|
645 * After this function is called, the error will be cleared, so your
|
|
646 * next call to a GetError function (with no SetError calls in between)
|
|
647 * will return a struct set with no-error values.
|
|
648 *
|
|
649 * @param err_pool The error pool instance you want to use.
|
|
650 *
|
|
651 * @return Returns the error number.
|
|
652 * If no error was set, the error number will be set
|
|
653 * to 0 (TERROR_NOERROR_VALUE).
|
|
654 *
|
|
655 * @see TError_GetLastError, TError_GetLastErrorStr, TERROR_NOERROR_VALUE
|
|
656 */
|
|
657 extern TERROR_DECLSPEC int TERROR_CALL TError_GetLastErrorNum(TErrorPool* err_pool);
|
|
658
|
|
659 /**
|
|
660 * This function gets the last error to be set by one of the SetError
|
|
661 * functions (regardless of thread).
|
|
662 * This version of the function
|
|
663 * returns a pointer to the error string.
|
|
664 * After this function is called, the error will be cleared, so your
|
|
665 * next call to a GetError function (with no SetError calls in between)
|
|
666 * will return a struct set with no-error values.
|
|
667 *
|
|
668 * @param err_pool The error pool instance you want to use.
|
|
669 *
|
|
670 * @return Returns the pointer to the error string.
|
|
671 * The pointer is to tErrorLib's own copy
|
|
672 * of the error message so you should not modify this string. Furthermore,
|
|
673 * the pointer may become invalid at the next call to SetError within this
|
|
674 * same thread, so if you need to keep the string, you must make your
|
|
675 * own copy of it.
|
|
676 * If no error was set, the error string will be set to NULL.
|
|
677 *
|
|
678 * @see TError_GetLastErrorNum, TError_GetLastError, TERROR_NOERROR_VALUE
|
|
679 */
|
|
680 extern TERROR_DECLSPEC const char* TERROR_CALL TError_GetLastErrorStr(TErrorPool* err_pool);
|
|
681
|
|
682 /**
|
|
683 * This function gets the last error to be set by one of the SetError
|
|
684 * functions (regardless of thread).
|
|
685 * This version of the function
|
|
686 * returns a struct containing the error number and a pointer to the
|
|
687 * error string.
|
|
688 * After this function is called, the error will be cleared, so your
|
|
689 * next call to a GetError function (with no SetError calls in between)
|
|
690 * will return a struct set with no-error values.
|
|
691 *
|
|
692 * @param err_pool The error pool instance you want to use.
|
|
693 *
|
|
694 * @return Returns (by-value) a struct containing the error number and
|
|
695 * pointer to the error string. The pointer is to tErrorLib's own copy
|
|
696 * of the error message so you should not modify this string. Furthermore,
|
|
697 * the pointer may become invalid at the next call to SetError within this
|
|
698 * same thread, so if you need to keep the string, you must make your
|
|
699 * own copy of it.
|
|
700 * If no error was set, the error number will be set to 0 (TERROR_NOERROR_VALUE)
|
|
701 * and the error string will be set to NULL.
|
|
702 *
|
|
703 * @see TError_GetLastErrorNum, TError_GetLastErrorStr, TERROR_NOERROR_VALUE
|
|
704 */
|
|
705 extern TERROR_DECLSPEC TErrorStatus TERROR_CALL TError_GetLastError(TErrorPool* err_pool);
|
|
706
|
|
707
|
|
708 #ifdef __cplusplus
|
|
709 }
|
|
710 #endif
|
|
711
|
|
712
|
|
713 #endif /* TERRORLIB_H */
|
|
714
|