blob: 21582ad4aed0bc384d5947fcb83046a45e9f7feb [file] [log] [blame]
jerrymf1579332013-02-07 01:56:28 +00001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2008. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
5/*----------------------------------------------------------------------------*/
6
7#include "ErrorBase.h"
8#include "Synchronized.h"
9#include "nivision.h"
10#define WPI_ERRORS_DEFINE_STRINGS
11#include "WPIErrors.h"
12
13#include <errnoLib.h>
14#include <symLib.h>
15#include <sysSymTbl.h>
16
17SEM_ID ErrorBase::_globalErrorMutex = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
18Error ErrorBase::_globalError;
19/**
20 * @brief Initialize the instance status to 0 for now.
21 */
22ErrorBase::ErrorBase()
23{}
24
25ErrorBase::~ErrorBase()
26{}
27
28/**
29 * @brief Retrieve the current error.
30 * Get the current error information associated with this sensor.
31 */
32Error& ErrorBase::GetError()
33{
34 return m_error;
35}
36
37const Error& ErrorBase::GetError() const
38{
39 return m_error;
40}
41
42/**
43 * @brief Clear the current error information associated with this sensor.
44 */
45void ErrorBase::ClearError() const
46{
47 m_error.Clear();
48}
49
50/**
51 * @brief Set error information associated with a C library call that set an error to the "errno" global variable.
52 *
53 * @param contextMessage A custom message from the code that set the error.
54 * @param filename Filename of the error source
55 * @param function Function of the error source
56 * @param lineNumber Line number of the error source
57 */
58void ErrorBase::SetErrnoError(const char *contextMessage,
59 const char* filename, const char* function, UINT32 lineNumber) const
60{
61 char err[256];
62 int errNo = errnoGet();
63 if (errNo == 0)
64 {
65 sprintf(err, "OK: %s", contextMessage);
66 }
67 else
68 {
69 char *statName = new char[MAX_SYS_SYM_LEN + 1];
70 int pval;
71 SYM_TYPE ptype;
72 symFindByValue(statSymTbl, errNo, statName, &pval, &ptype);
73 if (pval != errNo)
74 snprintf(err, 256, "Unknown errno 0x%08X: %s", errNo, contextMessage);
75 else
76 snprintf(err, 256, "%s (0x%08X): %s", statName, errNo, contextMessage);
77 delete [] statName;
78 }
79
80 // Set the current error information for this object.
81 m_error.Set(-1, err, filename, function, lineNumber, this);
82
83 // Update the global error if there is not one already set.
84 Synchronized mutex(_globalErrorMutex);
85 if (_globalError.GetCode() == 0) {
86 _globalError.Clone(m_error);
87 }
88}
89
90/**
91 * @brief Set the current error information associated from the nivision Imaq API.
92 *
93 * @param success The return from the function
94 * @param contextMessage A custom message from the code that set the error.
95 * @param filename Filename of the error source
96 * @param function Function of the error source
97 * @param lineNumber Line number of the error source
98 */
99void ErrorBase::SetImaqError(int success, const char *contextMessage, const char* filename, const char* function, UINT32 lineNumber) const
100{
101 // If there was an error
102 if (success <= 0) {
103 char err[256];
104 sprintf(err, "%s: %s", contextMessage, imaqGetErrorText(imaqGetLastError()));
105
106 // Set the current error information for this object.
107 m_error.Set(imaqGetLastError(), err, filename, function, lineNumber, this);
108
109 // Update the global error if there is not one already set.
110 Synchronized mutex(_globalErrorMutex);
111 if (_globalError.GetCode() == 0) {
112 _globalError.Clone(m_error);
113 }
114 }
115}
116
117/**
118 * @brief Set the current error information associated with this sensor.
119 *
120 * @param code The error code
121 * @param contextMessage A custom message from the code that set the error.
122 * @param filename Filename of the error source
123 * @param function Function of the error source
124 * @param lineNumber Line number of the error source
125 */
126void ErrorBase::SetError(Error::Code code, const char *contextMessage,
127 const char* filename, const char* function, UINT32 lineNumber) const
128{
129 // If there was an error
130 if (code != 0) {
131 // Set the current error information for this object.
132 m_error.Set(code, contextMessage, filename, function, lineNumber, this);
133
134 // Update the global error if there is not one already set.
135 Synchronized mutex(_globalErrorMutex);
136 if (_globalError.GetCode() == 0) {
137 _globalError.Clone(m_error);
138 }
139 }
140}
141
142/**
143 * @brief Set the current error information associated with this sensor.
144 *
145 * @param errorMessage The error message from WPIErrors.h
146 * @param contextMessage A custom message from the code that set the error.
147 * @param filename Filename of the error source
148 * @param function Function of the error source
149 * @param lineNumber Line number of the error source
150 */
151void ErrorBase::SetWPIError(const char *errorMessage, const char *contextMessage,
152 const char* filename, const char* function, UINT32 lineNumber) const
153{
154 char err[256];
155 sprintf(err, "%s: %s", errorMessage, contextMessage);
156
157 // Set the current error information for this object.
158 m_error.Set(-1, err, filename, function, lineNumber, this);
159
160 // Update the global error if there is not one already set.
161 Synchronized mutex(_globalErrorMutex);
162 if (_globalError.GetCode() == 0) {
163 _globalError.Clone(m_error);
164 }
165}
166
167void ErrorBase::CloneError(ErrorBase *rhs) const
168{
169 m_error.Clone(rhs->GetError());
170}
171
172/**
173@brief Check if the current error code represents a fatal error.
174
175@return true if the current error is fatal.
176*/
177bool ErrorBase::StatusIsFatal() const
178{
179 return m_error.GetCode() < 0;
180}
181
182void ErrorBase::SetGlobalError(Error::Code code, const char *contextMessage,
183 const char* filename, const char* function, UINT32 lineNumber)
184{
185 // If there was an error
186 if (code != 0) {
187 Synchronized mutex(_globalErrorMutex);
188
189 // Set the current error information for this object.
190 _globalError.Set(code, contextMessage, filename, function, lineNumber, NULL);
191 }
192}
193
194void ErrorBase::SetGlobalWPIError(const char *errorMessage, const char *contextMessage,
195 const char* filename, const char* function, UINT32 lineNumber)
196{
197 char err[256];
198 sprintf(err, "%s: %s", errorMessage, contextMessage);
199
200 Synchronized mutex(_globalErrorMutex);
201 if (_globalError.GetCode() != 0) {
202 _globalError.Clear();
203 }
204 _globalError.Set(-1, err, filename, function, lineNumber, NULL);
205}
206
207/**
208 * Retrieve the current global error.
209*/
210Error& ErrorBase::GetGlobalError()
211{
212 Synchronized mutex(_globalErrorMutex);
213 return _globalError;
214}
215