Handle select help options properly.
[adu.git] / error.h
1 /**
2  * This bit indicates whether a number is considered a system error code.
3  * If yes, the system errno is just the result of clearing this bit from
4  * the given number.
5  */
6 #define SYSTEM_ERROR_BIT 30
7
8 /** Check whether the system error bit is set. */
9 #define IS_SYSTEM_ERROR(num) (!!((num) & (1 << SYSTEM_ERROR_BIT)))
10
11 /** Set the system error bit for the given number. */
12 #define ERRNO_TO_ERROR(num) ((num) | (1 << SYSTEM_ERROR_BIT))
13
14 #define ALL_ERRORS \
15         _ERROR(SUCCESS, "success") \
16         _ERROR(SYNTAX, "syntax error") \
17         _ERROR(LOOP_COMPLETE, "loop complete") \
18         _ERROR(HASH_TABLE_OVERFLOW, "hash table too small") \
19         _ERROR(BAD_UID, "uid not found in hash table") \
20         _ERROR(ATOI_OVERFLOW, "value too large") \
21         _ERROR(STRTOLL, "unknown strtoll error") \
22         _ERROR(ATOI_NO_DIGITS, "no digits found in string") \
23         _ERROR(ATOI_JUNK_AT_END, "further characters after number") \
24         _ERROR(EMPTY, "file empty") \
25         _ERROR(MMAP, "mmap error") \
26         _ERROR(OSL, "osl error") \
27         _ERROR(SIGNAL_SIG_ERR, "signal() returned SIG_ERR") \
28         _ERROR(OUTPUT, "error writing output file") \
29
30
31 /**
32  * This is temporarily defined to expand to its first argument (prefixed by
33  * 'E_') and gets later redefined to expand to the error text only
34  */
35 #define _ERROR(err, msg) E_ ## err,
36
37 enum error_codes {
38         ALL_ERRORS
39 };
40 #undef _ERROR
41 #define _ERROR(err, msg) msg,
42 #define DEFINE_ERRLIST char *adu_errlist[] = {ALL_ERRORS}
43
44 extern int osl_errno;
45 extern char *adu_errlist[];
46
47
48 /**
49  * adu's version of strerror(3).
50  *
51  * \param num The error number.
52  *
53  * \return The error text of \a num.
54  */
55 static inline const char *adu_strerror(int num)
56 {
57         assert(num > 0);
58         if (num == E_OSL) {
59                 assert(osl_errno > 0);
60                 return osl_strerror((osl_errno));
61         }
62         if (IS_SYSTEM_ERROR(num))
63                 return strerror((num) & ((1 << SYSTEM_ERROR_BIT) - 1));
64         return adu_errlist[num];
65 }
66
67 /**
68  * Wrapper for osl library calls.
69  *
70  * This should be used for all calls to osl functions that return an osl error
71  * code. It changes the return value to \p -E_OSL appropriately so that it can
72  * be used for printing the correct error message.
73  *
74  * \return \a ret if \a ret >= 0, \p -E_OSL otherwise.
75  */
76 static inline int osl(int ret)
77 {
78         if (ret >= 0)
79                 return ret;
80         osl_errno = -ret;
81         return -E_OSL;
82 }