00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "Error.h"
00012
00013
00014 string Error::log = "";
00015 string Error::langue = ERROR_DEFLANG;
00016 vector<ThreadCallStack *> Error::callStacks;
00017 vector<ErrorDesc *> Error::descError;
00018
00019 Error::Error()
00020 {
00021 unsigned int i = 0;
00022
00023 loc = "";
00024 line = 0;
00025 currentCallStack = NULL;
00026
00027 for(i = 0; i < callStacks.size(); i++)
00028 {
00029 if(callStacks[i]->id == ThreadId())
00030 {
00031 currentCallStack = callStacks[i];
00032 break;
00033 }
00034 }
00035
00036 if(!currentCallStack)
00037 {
00038 callStacks.push_back(new ThreadCallStack);
00039 currentCallStack = callStacks.back();
00040 }
00041
00042 currentCallStack->nbInstance++;
00043
00044 SetLangue(langue.data());
00045 }
00046
00047 Error::~Error()
00048 {
00049 unsigned int i = 0;
00050
00051 currentCallStack->nbInstance--;
00052
00053 if(currentCallStack->nbInstance == 0)
00054 {
00055 for(i = 0; i < callStacks.size(); i++)
00056 {
00057 if(callStacks[i] == currentCallStack)
00058 {
00059 callStacks.erase(callStacks.begin() + i);
00060 break;
00061 }
00062 }
00063
00064 delete currentCallStack;
00065 }
00066
00067 if(callStacks.size() == 0)
00068 {
00069 for(i = 0; i < descError.size(); i++)
00070 delete descError[i];
00071 }
00072 }
00073
00074 void Error::SetLangue(const char *pFile)
00075 {
00076 if(descError.size() == 0)
00077 {
00078 char desc[ERROR_BUFFER];
00079 fstream file(pFile, fstream::in);
00080 unsigned int i;
00081
00082 for(i = 0; i < descError.size(); i++)
00083 delete descError[i];
00084
00085 if(file.is_open())
00086 {
00087 descError.clear();
00088
00089 while(file.good())
00090 {
00091 file.getline(desc, ERROR_BUFFER);
00092 descError.push_back(new ErrorDesc);
00093 descError.back()->no = atoi(gettok(desc, 0, " :\t\n\r"));
00094 descError.back()->desc = gettok(desc, 1, ":\t\n\r");
00095 }
00096 file.close();
00097 }
00098 else
00099 cerr << "Canot open error language file" << endl;
00100
00101 langue = pFile;
00102 }
00103 }
00104
00105 void Error::AddFunc(const char *pFunc, const char *pFile)
00106 {
00107 currentCallStack->stack.push_back(new FuncInfos(pFunc, pFile, line));
00108 }
00109
00110 void Error::LogError(const char *pBuffer, ...)
00111 {
00112 char temp[ERROR_BUFFER];
00113 va_list args;
00114
00115 va_start(args, pBuffer);
00116 vsprintf(temp, pBuffer, args);
00117 va_end(args);
00118
00119 if(log != "")
00120 {
00121 fstream file(log.data(), fstream::app);
00122
00123 if(file.is_open())
00124 {
00125 file << temp;
00126 file.close();
00127 }
00128 else
00129 cerr << "Canot open error log file" << endl;
00130 }
00131
00132 cerr << temp;
00133 }
00134
00135 void Error::Perror(unsigned int iCode)
00136 {
00137 time_t tTime;
00138 tm *tmTime;
00139 unsigned int i = 0;
00140
00141 if(iCode == ERROR_C_NOERROR)
00142 return;
00143
00144 tTime = time(NULL);
00145 tmTime = localtime(&tTime);
00146
00147 LogError("\n");
00148
00149 for(i = 0; i < descError.size(); i++)
00150 {
00151 if(descError[i]->no == iCode)
00152 break;
00153 }
00154
00155 LogError("%02i/%02i/%02i %02i:%02i:%02i : %5i ERROR in '%s' (file '%s:%i'), code %i : %s\n",
00156 tmTime->tm_mday, tmTime->tm_mon, tmTime->tm_year + 1900, tmTime->tm_hour, tmTime->tm_min, tmTime->tm_sec,
00157 currentCallStack->id,
00158 currentCallStack->stack.front()->func.data(),
00159 currentCallStack->stack.front()->file.data(),
00160 currentCallStack->stack.front()->line,
00161 iCode,
00162 (i < descError.size() ? descError[i]->desc.data() : "No description")
00163 );
00164
00165 currentCallStack->stack.erase(currentCallStack->stack.begin());
00166
00167 while(currentCallStack->stack.size())
00168 {
00169 LogError("%02i/%02i/%02i %02i:%02i:%02i : %5i from '%s' (file '%s:%i')\n",
00170 tmTime->tm_mday, tmTime->tm_mon, tmTime->tm_year + 1900, tmTime->tm_hour, tmTime->tm_min, tmTime->tm_sec,
00171 currentCallStack->id,
00172 currentCallStack->stack.front()->func.data(),
00173 currentCallStack->stack.front()->file.data(),
00174 currentCallStack->stack.front()->line
00175 );
00176
00177 currentCallStack->stack.erase(currentCallStack->stack.begin());
00178 }
00179 }