af6c0550ed4699a2e1b3debd32ee36876e80a994
[dss.git] / error.h
1 extern char *dss_errlist[];
2 extern char *dss_error_txt;
3
4 __printf_2_3 void dss_log(int ll, const char* fmt,...);
5
6 /**
7  * This bit indicates whether a number is considered a system error number
8  * If yes, the system errno is just the result of clearing this bit from
9  * the given number.
10  */
11 #define SYSTEM_ERROR_BIT 30
12
13 /** Check whether the system error bit is set. */
14 #define IS_SYSTEM_ERROR(num) (!!((num) & (1 << SYSTEM_ERROR_BIT)))
15
16 /** Set the system error bit for the given number. */
17 #define ERRNO_TO_DSS_ERROR(num) ((num) | (1 << SYSTEM_ERROR_BIT))
18
19 /** Check whether a given number is a system error number.
20  *
21  * \param num The value to be checked.
22  * \param _errno The system error number.
23  *
24  * \return True if \a num is dss' representation of the system
25  * error identified by \a _errno.
26  */
27 static inline int is_errno(int num, int _errno)
28 {
29         assert(num > 0 && _errno > 0);
30         return ERRNO_TO_DSS_ERROR(_errno) == num;
31 }
32
33 /**
34  * dss' version of strerror(3).
35  *
36  * \param num The error number.
37  *
38  * \return The error text of \a num.
39  */
40 static inline char *dss_strerror(int num)
41 {
42         assert(num > 0);
43         if (IS_SYSTEM_ERROR(num))
44                 return strerror((num) & ((1 << SYSTEM_ERROR_BIT) - 1));
45         else
46                 return dss_errlist[num];
47 }
48
49 #define DSS_ERRORS \
50         DSS_ERROR(SUCCESS, "success") \
51         DSS_ERROR(SYNTAX, "syntax error") \
52         DSS_ERROR(ATOI_OVERFLOW, "value too large") \
53         DSS_ERROR(STRTOLL, "unknown strtoll error") \
54         DSS_ERROR(ATOI_NO_DIGITS, "no digits found in string") \
55         DSS_ERROR(ATOI_JUNK_AT_END, "further characters after number") \
56         DSS_ERROR(INVALID_NUMBER, "invalid number") \
57         DSS_ERROR(STRFTIME, "strftime() failed") \
58         DSS_ERROR(LOCALTIME, "localtime() failed") \
59         DSS_ERROR(NULL_OPEN, "can not open /dev/null") \
60         DSS_ERROR(DUP_PIPE, "exec error: can not create pipe") \
61         DSS_ERROR(INVOLUNTARY_EXIT, "unexpected termination cause") \
62         DSS_ERROR(BAD_EXIT_CODE, "unexpected exit code") \
63         DSS_ERROR(SIGNAL_SIG_ERR, "signal() returned SIG_ERR")
64
65 /**
66  * This is temporarily defined to expand to its first argument (prefixed by
67  * 'E_') and gets later redefined to expand to the error text only
68  */
69 #define DSS_ERROR(err, msg) E_ ## err,
70
71 enum dss_error_codes {
72         DSS_ERRORS
73 };
74 #undef DSS_ERROR
75 #define DSS_ERROR(err, msg) msg,
76 #define DEFINE_DSS_ERRLIST char *dss_errlist[] = {DSS_ERRORS}