bloom: Add some source documentation.
[adu.git] / error.h
1 /*
2  * Copyright (C) 2008 Andre Noll <maan@systemlinux.org>
3  *
4  * Licensed under the GPL v2. For licencing details see COPYING.
5  */
6
7 /** \file error.h \brief Error handling functions and macros. */
8
9 /**
10  * This bit indicates whether a number is considered a system error code.
11  * If yes, the system errno is just the result of clearing this bit from
12  * the given number.
13  */
14 #define SYSTEM_ERROR_BIT 30
15
16 /** Check whether the system error bit is set. */
17 #define IS_SYSTEM_ERROR(num) (!!((num) & (1 << SYSTEM_ERROR_BIT)))
18
19 /** Set the system error bit for the given number. */
20 #define ERRNO_TO_ERROR(num) ((num) | (1 << SYSTEM_ERROR_BIT))
21
22 /** The list of all adu error codes with descriptions. */
23 #define ALL_ERRORS \
24         _ERROR(SUCCESS, "success") \
25         _ERROR(SYNTAX, "syntax error") \
26         _ERROR(LOOP_COMPLETE, "loop complete") \
27         _ERROR(HASH_TABLE_OVERFLOW, "hash table too small") \
28         _ERROR(BAD_UID, "uid not found in hash table") \
29         _ERROR(ATOI_OVERFLOW, "value too large") \
30         _ERROR(STRTOLL, "unknown strtoll error") \
31         _ERROR(ATOI_NO_DIGITS, "no digits found in string") \
32         _ERROR(ATOI_JUNK_AT_END, "further characters after number") \
33         _ERROR(EMPTY, "file empty") \
34         _ERROR(MMAP, "mmap error") \
35         _ERROR(OSL, "osl error") \
36         _ERROR(SIGNAL_SIG_ERR, "signal() returned SIG_ERR") \
37         _ERROR(OUTPUT, "error writing output") \
38         _ERROR(MALFORMED_FORMAT, "malformed format string") \
39         _ERROR(BAD_ALIGN_SPEC, "bad alignment specifier") \
40         _ERROR(TRAILING_GARBAGE, "trailing garbage after specifier") \
41         _ERROR(UNIT, "no unit allowed here") \
42         _ERROR(BAD_UNIT, "invalid unit specifier") \
43         _ERROR(BAD_ATOM, "invalid atom") \
44         _ERROR(BAD_OUTPUT_ARG, "invalid name for output") \
45         _ERROR(REGEX, "regular expression error")
46
47
48 /**
49  * This is temporarily defined to expand to its first argument (prefixed by
50  * 'E_') and gets later redefined to expand to the error text only
51  */
52 #define _ERROR(err, msg) E_ ## err,
53
54 /**
55  * \cond (doxygen can not handle multiple definitions of the same macro).
56  *
57  * This just creates an enum consisting of the first argument of the above
58  * error list.
59  */
60 enum error_codes {
61         ALL_ERRORS
62 };
63 #undef _ERROR
64
65 /*
66  * Here we define the array of error texts used by adu_strerror().
67  */
68 #define _ERROR(err, msg) msg,
69 #define DEFINE_ERRLIST char *adu_errlist[] = {ALL_ERRORS}
70 /** \endcond */
71
72 extern int osl_errno;
73
74 /** Contains the description of all adu error codes. */
75 extern char *adu_errlist[];
76
77
78 /**
79  * adu's version of strerror(3).
80  *
81  * \param num The error number.
82  *
83  * \return The error text of \a num.
84  */
85 _static_inline_ const char *adu_strerror(int num)
86 {
87         assert(num > 0);
88         if (num == E_OSL) {
89                 assert(osl_errno > 0);
90                 return osl_strerror((osl_errno));
91         }
92         if (IS_SYSTEM_ERROR(num))
93                 return strerror((num) & ((1 << SYSTEM_ERROR_BIT) - 1));
94         return adu_errlist[num];
95 }
96
97 /**
98  * Wrapper for osl library calls.
99  *
100  * \param ret The return value of an osl library function.
101  *
102  * This should be used for all calls to osl functions that return an osl error
103  * code. It changes the return value to \p -E_OSL appropriately so that it can
104  * be used for printing the correct error message.
105  *
106  * \return \a ret if \a ret >= 0, \p -E_OSL otherwise.
107  */
108 _static_inline_ int osl(int ret)
109 {
110         if (ret >= 0)
111                 return ret;
112         osl_errno = -ret;
113         return -E_OSL;
114 }