1 /*
2  * $Id$
3  *
4  * Copyright (C) 2009, Rutger Hofman, VU Amsterdam
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19  * 02111-1307, USA.
20  *
21  */
22 
23 #ifndef URJ_ERROR_H
24 #define URJ_ERROR_H
25 
26 #include <stdio.h>
27 #include <errno.h>
28 
29 #include "log.h"
30 
31 /**
32  * Error types
33  */
34 typedef enum URJ_ERROR
35 {
36     URJ_ERROR_OK        = 0,
37     URJ_ERROR_ALREADY,
38     URJ_ERROR_OUT_OF_MEMORY,
39     URJ_ERROR_NO_CHAIN,
40     URJ_ERROR_NO_PART,
41     URJ_ERROR_NO_ACTIVE_INSTRUCTION,
42     URJ_ERROR_NO_DATA_REGISTER,
43     URJ_ERROR_INVALID,
44     URJ_ERROR_NOTFOUND,
45     URJ_ERROR_NO_BUS_DRIVER,
46     URJ_ERROR_BUFFER_EXHAUSTED,
47     URJ_ERROR_ILLEGAL_STATE,
48     URJ_ERROR_ILLEGAL_TRANSITION,
49     URJ_ERROR_OUT_OF_BOUNDS,
50     URJ_ERROR_TIMEOUT,
51     URJ_ERROR_UNSUPPORTED,
52     URJ_ERROR_SYNTAX,
53     URJ_ERROR_FILEIO,                   /**< I/O error from fread/fwrite */
54 
55     URJ_ERROR_IO,                       /**< I/O error from OS */
56     URJ_ERROR_FTD,                      /**< error from ftdi/ftd2xx */
57     URJ_ERROR_USB,                      /**< error from libusb */
58 
59     URJ_ERROR_BUS,
60     URJ_ERROR_BUS_DMA,
61 
62     URJ_ERROR_FLASH,
63     URJ_ERROR_FLASH_DETECT,
64     URJ_ERROR_FLASH_PROGRAM,
65     URJ_ERROR_FLASH_ERASE,
66     URJ_ERROR_FLASH_LOCK,
67     URJ_ERROR_FLASH_UNLOCK,
68 
69     URJ_ERROR_BSDL_VHDL,
70     URJ_ERROR_BSDL_BSDL,
71 
72     URJ_ERROR_BFIN,
73 
74     URJ_ERROR_PLD,
75 
76     URJ_ERROR_UNIMPLEMENTED,
77 
78     URJ_ERROR_FIRMWARE,
79 }
80 urj_error_t;
81 
82 /** Max length of message string that can be recorded. */
83 #define URJ_ERROR_MSG_LEN       256
84 
85 /**
86  * Error state.
87  */
88 typedef struct URJ_ERROR_STATE
89 {
90     urj_error_t         errnum;                 /**< error number */
91     int                 sys_errno;              /**< errno if URJ_ERROR_IO */
92     const char         *file;                   /**< file where error is set */
93     const char         *function;               /**< function --,,-- */
94     int                 line;                   /**< line no --,,-- */
95     char                msg[URJ_ERROR_MSG_LEN]; /**< printf-style message */
96 }
97 urj_error_state_t;
98 
99 extern urj_error_state_t        urj_error_state;
100 
101 /**
102  * Descriptive string for error type
103  */
104 extern const char *urj_error_string (urj_error_t error);
105 
106 /**
107  * Set error state.
108  *
109  * @param e urj_error_t value
110  * @param ... error detail message that consists of a printf argument set.
111  *      It needs to start with a const char *fmt, followed by arguments used
112  *      by fmt.
113  */
114 #define urj_error_set(e, ...) \
115     do { \
116         urj_error_state.errnum = e; \
117         urj_error_state.file = __FILE__; \
118         urj_error_state.function = __func__; \
119         urj_error_state.line = __LINE__; \
120         snprintf (urj_error_state.msg, sizeof urj_error_state.msg, \
121                   __VA_ARGS__); \
122     } while (0)
123 
124 /**
125  * Set I/O error state: do as urj_error_set, but also store errno in
126  * #urj_error_state and then reset errno.
127  *
128  * @param ... error detail message that consists of a printf argument set.
129  *      It needs to start with a const char *fmt, followed by arguments used
130  *      by fmt. The error code (URJ_ERROR_IO) is added by this macro.
131  */
132 #define urj_error_IO_set(...) \
133     do { \
134         urj_error_set (URJ_ERROR_IO, __VA_ARGS__); \
135         urj_error_state.sys_errno = errno; \
136         errno = 0; \
137     } while (0)
138 
139 /**
140  * The error number
141  */
142 urj_error_t urj_error_get (void);
143 
144 /**
145  * Reset the error state.
146  */
147 void urj_error_reset (void);
148 /**
149  * The error state in human-readable form.
150  *
151  * This function is not reentrant.
152  *
153  * @return a pointer to a static area.
154  */
155 const char *urj_error_describe (void);
156 
157 #endif /* URJ_ERROR_H */
158