/*----------------------------------------------------------------------------*/ | |
/* Copyright (c) FIRST 2008. All Rights Reserved. */ | |
/* Open Source Software - may be modified and shared by FRC teams. The code */ | |
/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */ | |
/*----------------------------------------------------------------------------*/ | |
#include "ErrorBase.h" | |
#include "Synchronized.h" | |
#include "nivision.h" | |
#define WPI_ERRORS_DEFINE_STRINGS | |
#include "WPIErrors.h" | |
#include <errnoLib.h> | |
#include <symLib.h> | |
#include <sysSymTbl.h> | |
SEM_ID ErrorBase::_globalErrorMutex = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE); | |
Error ErrorBase::_globalError; | |
/** | |
* @brief Initialize the instance status to 0 for now. | |
*/ | |
ErrorBase::ErrorBase() | |
{} | |
ErrorBase::~ErrorBase() | |
{} | |
/** | |
* @brief Retrieve the current error. | |
* Get the current error information associated with this sensor. | |
*/ | |
Error& ErrorBase::GetError() | |
{ | |
return m_error; | |
} | |
const Error& ErrorBase::GetError() const | |
{ | |
return m_error; | |
} | |
/** | |
* @brief Clear the current error information associated with this sensor. | |
*/ | |
void ErrorBase::ClearError() const | |
{ | |
m_error.Clear(); | |
} | |
/** | |
* @brief Set error information associated with a C library call that set an error to the "errno" global variable. | |
* | |
* @param contextMessage A custom message from the code that set the error. | |
* @param filename Filename of the error source | |
* @param function Function of the error source | |
* @param lineNumber Line number of the error source | |
*/ | |
void ErrorBase::SetErrnoError(const char *contextMessage, | |
const char* filename, const char* function, UINT32 lineNumber) const | |
{ | |
char err[256]; | |
int errNo = errnoGet(); | |
if (errNo == 0) | |
{ | |
sprintf(err, "OK: %s", contextMessage); | |
} | |
else | |
{ | |
char *statName = new char[MAX_SYS_SYM_LEN + 1]; | |
int pval; | |
SYM_TYPE ptype; | |
symFindByValue(statSymTbl, errNo, statName, &pval, &ptype); | |
if (pval != errNo) | |
snprintf(err, 256, "Unknown errno 0x%08X: %s", errNo, contextMessage); | |
else | |
snprintf(err, 256, "%s (0x%08X): %s", statName, errNo, contextMessage); | |
delete [] statName; | |
} | |
// Set the current error information for this object. | |
m_error.Set(-1, err, filename, function, lineNumber, this); | |
// Update the global error if there is not one already set. | |
Synchronized mutex(_globalErrorMutex); | |
if (_globalError.GetCode() == 0) { | |
_globalError.Clone(m_error); | |
} | |
} | |
/** | |
* @brief Set the current error information associated from the nivision Imaq API. | |
* | |
* @param success The return from the function | |
* @param contextMessage A custom message from the code that set the error. | |
* @param filename Filename of the error source | |
* @param function Function of the error source | |
* @param lineNumber Line number of the error source | |
*/ | |
void ErrorBase::SetImaqError(int success, const char *contextMessage, const char* filename, const char* function, UINT32 lineNumber) const | |
{ | |
// If there was an error | |
if (success <= 0) { | |
char err[256]; | |
sprintf(err, "%s: %s", contextMessage, imaqGetErrorText(imaqGetLastError())); | |
// Set the current error information for this object. | |
m_error.Set(imaqGetLastError(), err, filename, function, lineNumber, this); | |
// Update the global error if there is not one already set. | |
Synchronized mutex(_globalErrorMutex); | |
if (_globalError.GetCode() == 0) { | |
_globalError.Clone(m_error); | |
} | |
} | |
} | |
/** | |
* @brief Set the current error information associated with this sensor. | |
* | |
* @param code The error code | |
* @param contextMessage A custom message from the code that set the error. | |
* @param filename Filename of the error source | |
* @param function Function of the error source | |
* @param lineNumber Line number of the error source | |
*/ | |
void ErrorBase::SetError(Error::Code code, const char *contextMessage, | |
const char* filename, const char* function, UINT32 lineNumber) const | |
{ | |
// If there was an error | |
if (code != 0) { | |
// Set the current error information for this object. | |
m_error.Set(code, contextMessage, filename, function, lineNumber, this); | |
// Update the global error if there is not one already set. | |
Synchronized mutex(_globalErrorMutex); | |
if (_globalError.GetCode() == 0) { | |
_globalError.Clone(m_error); | |
} | |
} | |
} | |
/** | |
* @brief Set the current error information associated with this sensor. | |
* | |
* @param errorMessage The error message from WPIErrors.h | |
* @param contextMessage A custom message from the code that set the error. | |
* @param filename Filename of the error source | |
* @param function Function of the error source | |
* @param lineNumber Line number of the error source | |
*/ | |
void ErrorBase::SetWPIError(const char *errorMessage, const char *contextMessage, | |
const char* filename, const char* function, UINT32 lineNumber) const | |
{ | |
char err[256]; | |
sprintf(err, "%s: %s", errorMessage, contextMessage); | |
// Set the current error information for this object. | |
m_error.Set(-1, err, filename, function, lineNumber, this); | |
// Update the global error if there is not one already set. | |
Synchronized mutex(_globalErrorMutex); | |
if (_globalError.GetCode() == 0) { | |
_globalError.Clone(m_error); | |
} | |
} | |
void ErrorBase::CloneError(ErrorBase *rhs) const | |
{ | |
m_error.Clone(rhs->GetError()); | |
} | |
/** | |
@brief Check if the current error code represents a fatal error. | |
@return true if the current error is fatal. | |
*/ | |
bool ErrorBase::StatusIsFatal() const | |
{ | |
return m_error.GetCode() < 0; | |
} | |
void ErrorBase::SetGlobalError(Error::Code code, const char *contextMessage, | |
const char* filename, const char* function, UINT32 lineNumber) | |
{ | |
// If there was an error | |
if (code != 0) { | |
Synchronized mutex(_globalErrorMutex); | |
// Set the current error information for this object. | |
_globalError.Set(code, contextMessage, filename, function, lineNumber, NULL); | |
} | |
} | |
void ErrorBase::SetGlobalWPIError(const char *errorMessage, const char *contextMessage, | |
const char* filename, const char* function, UINT32 lineNumber) | |
{ | |
char err[256]; | |
sprintf(err, "%s: %s", errorMessage, contextMessage); | |
Synchronized mutex(_globalErrorMutex); | |
if (_globalError.GetCode() != 0) { | |
_globalError.Clear(); | |
} | |
_globalError.Set(-1, err, filename, function, lineNumber, NULL); | |
} | |
/** | |
* Retrieve the current global error. | |
*/ | |
Error& ErrorBase::GetGlobalError() | |
{ | |
Synchronized mutex(_globalErrorMutex); | |
return _globalError; | |
} | |