00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "PreCompiled.h"
00026
00027 #ifndef _PreComp_
00028 # include <time.h>
00029 # include <stdio.h>
00030 # ifdef FC_OS_WIN32
00031 # include <io.h>
00032 # include <windows.h>
00033 # endif
00034 # include "fcntl.h"
00035 #endif
00036
00037 #include "Console.h"
00038 #include "Exception.h"
00039 #include "PyObjectBase.h"
00040
00041 using namespace Base;
00042
00043
00044
00045 char format[4024];
00046 const unsigned int format_len = 4024;
00047
00048
00049
00050
00051
00052
00053 ConsoleSingleton::ConsoleSingleton(void)
00054 :_bVerbose(false)
00055 {
00056
00057 }
00058
00059 ConsoleSingleton::~ConsoleSingleton()
00060 {
00061 for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++)
00062 delete (*Iter);
00063
00064 }
00065
00066
00067
00068
00069
00073 void ConsoleSingleton::SetMode(ConsoleMode m)
00074 {
00075 if(m && Verbose)
00076 _bVerbose = true;
00077 }
00081 void ConsoleSingleton::UnsetMode(ConsoleMode m)
00082 {
00083 if(m && Verbose)
00084 _bVerbose = false;
00085 }
00086
00103 ConsoleMsgFlags ConsoleSingleton::SetEnabledMsgType(const char* sObs, ConsoleMsgFlags type, bool b)
00104 {
00105 ConsoleObserver* pObs = Get(sObs);
00106 if ( pObs ){
00107 ConsoleMsgFlags flags=0;
00108
00109 if ( type&MsgType_Err ){
00110 if ( pObs->bErr != b )
00111 flags |= MsgType_Err;
00112 pObs->bErr = b;
00113 }
00114 if ( type&MsgType_Wrn ){
00115 if ( pObs->bWrn != b )
00116 flags |= MsgType_Wrn;
00117 pObs->bWrn = b;
00118 }
00119 if ( type&MsgType_Txt ){
00120 if ( pObs->bMsg != b )
00121 flags |= MsgType_Txt;
00122 pObs->bMsg = b;
00123 }
00124 if ( type&MsgType_Log ){
00125 if ( pObs->bLog != b )
00126 flags |= MsgType_Log;
00127 pObs->bLog = b;
00128 }
00129 return flags;
00130 }
00131 else {
00132 return 0;
00133 }
00134 }
00135
00150 void ConsoleSingleton::Message( const char *pMsg, ... )
00151 {
00152 va_list namelessVars;
00153 va_start(namelessVars, pMsg);
00154 vsnprintf(format, format_len, pMsg, namelessVars);
00155 va_end(namelessVars);
00156 NotifyMessage(format);
00157 }
00158
00174 void ConsoleSingleton::Warning( const char *pMsg, ... )
00175 {
00176 va_list namelessVars;
00177 va_start(namelessVars, pMsg);
00178 vsnprintf(format, format_len, pMsg, namelessVars);
00179 va_end(namelessVars);
00180 NotifyWarning(format);
00181 }
00182
00198 void ConsoleSingleton::Error( const char *pMsg, ... )
00199 {
00200 va_list namelessVars;
00201 va_start(namelessVars, pMsg);
00202 vsnprintf(format, format_len, pMsg, namelessVars);
00203 va_end(namelessVars);
00204 NotifyError(format);
00205 }
00206
00207
00225 void ConsoleSingleton::Log( const char *pMsg, ... )
00226 {
00227 if (!_bVerbose)
00228 {
00229 va_list namelessVars;
00230 va_start(namelessVars, pMsg);
00231 vsnprintf(format, format_len, pMsg, namelessVars);
00232 va_end(namelessVars);
00233 NotifyLog(format);
00234 }
00235 }
00236
00237
00243 const char* ConsoleSingleton::Time(void)
00244 {
00245 struct tm *newtime;
00246 time_t aclock;
00247 time( &aclock );
00248 newtime = localtime( &aclock );
00249 char* st = asctime( newtime );
00250 st[24] = 0;
00251 return st;
00252 }
00253
00254
00255
00256
00257
00258
00265 void ConsoleSingleton::AttachObserver(ConsoleObserver *pcObserver)
00266 {
00267
00268 assert(_aclObservers.find(pcObserver) == _aclObservers.end() );
00269
00270 _aclObservers.insert(pcObserver);
00271 }
00272
00278 void ConsoleSingleton::DetachObserver(ConsoleObserver *pcObserver)
00279 {
00280 _aclObservers.erase(pcObserver);
00281 }
00282
00283 void ConsoleSingleton::NotifyMessage(const char *sMsg)
00284 {
00285 for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++)
00286 if((*Iter)->bMsg)
00287 (*Iter)->Message(sMsg);
00288 }
00289
00290 void ConsoleSingleton::NotifyWarning(const char *sMsg)
00291 {
00292 for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++)
00293 if((*Iter)->bWrn)
00294 (*Iter)->Warning(sMsg);
00295 }
00296
00297 void ConsoleSingleton::NotifyError(const char *sMsg)
00298 {
00299 for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++)
00300 if((*Iter)->bErr)
00301 (*Iter)->Error(sMsg);
00302 }
00303
00304 void ConsoleSingleton::NotifyLog(const char *sMsg)
00305 {
00306 for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++)
00307 if((*Iter)->bLog)
00308 (*Iter)->Log(sMsg);
00309 }
00310
00311 ConsoleObserver *ConsoleSingleton::Get(const char *Name)
00312 {
00313 const char* OName;
00314 for(std::set<ConsoleObserver * >::iterator Iter=_aclObservers.begin();Iter!=_aclObservers.end();Iter++)
00315 {
00316 OName = (*Iter)->Name();
00317 if(OName && strcmp(OName,Name) == 0)
00318 return *Iter;
00319 }
00320 return 0;
00321 }
00322
00323
00324
00325
00326
00327 ConsoleSingleton * ConsoleSingleton::_pcSingleton = 0;
00328
00329 void ConsoleSingleton::Destruct(void)
00330 {
00331
00332 assert(_pcSingleton);
00333 delete _pcSingleton;
00334 _pcSingleton=0;
00335 }
00336
00337 ConsoleSingleton & ConsoleSingleton::Instance(void)
00338 {
00339
00340 if(!_pcSingleton)
00341 {
00342 _pcSingleton = new ConsoleSingleton();
00343 }
00344 return *_pcSingleton;
00345 }
00346
00347
00348
00349
00350
00351 PyMethodDef ConsoleSingleton::Methods[] = {
00352 {"PrintMessage", (PyCFunction) ConsoleSingleton::sPyMessage, 1,
00353 "PrintMessage(string) -- Print a message to the output"},
00354 {"PrintLog", (PyCFunction) ConsoleSingleton::sPyLog, 1,
00355 "PrintLog(string) -- Print a log message to the output"},
00356 {"PrintError" , (PyCFunction) ConsoleSingleton::sPyError, 1,
00357 "PrintError(string) -- Print an error message to the output"},
00358 {"PrintWarning", (PyCFunction) ConsoleSingleton::sPyWarning, 1,
00359 "PrintWarning -- Print a warning to the output"},
00360 {"SetStatus", (PyCFunction) ConsoleSingleton::sPySetStatus, 1,
00361 "Set the status for either Log, Msg, Wrn or Error for an observer"},
00362 {"GetStatus", (PyCFunction) ConsoleSingleton::sPyGetStatus, 1,
00363 "Get the status for either Log, Msg, Wrn or Error for an observer"},
00364 {NULL, NULL, 0, NULL}
00365 };
00366
00367
00368 PyObject *ConsoleSingleton::sPyMessage(PyObject * , PyObject *args, PyObject * )
00369 {
00370 PyObject *output;
00371 if (!PyArg_ParseTuple(args, "O", &output))
00372 return NULL;
00373
00374 const char* string=0;
00375 PyObject* unicode=0;
00376 if (PyUnicode_Check(output)) {
00377 unicode = PyUnicode_AsEncodedObject(output, "utf-8", "strict");
00378 if (unicode)
00379 string = PyString_AsString(unicode);
00380 }
00381 else if (PyString_Check(output)) {
00382 string = PyString_AsString(output);
00383 }
00384 else {
00385 unicode = PyObject_Str(output);
00386 if (unicode)
00387 string = PyString_AsString(unicode);
00388 }
00389
00390 PY_TRY {
00391 if (string)
00392 Instance().Message("%s",string);
00393 } PY_CATCH;
00394
00395 Py_XDECREF(unicode);
00396
00397 Py_INCREF(Py_None);
00398 return Py_None;
00399 }
00400
00401 PyObject *ConsoleSingleton::sPyWarning(PyObject * , PyObject *args, PyObject * )
00402 {
00403 PyObject *output;
00404 if (!PyArg_ParseTuple(args, "O", &output))
00405 return NULL;
00406
00407 const char* string=0;
00408 PyObject* unicode=0;
00409 if (PyUnicode_Check(output)) {
00410 unicode = PyUnicode_AsEncodedObject(output, "utf-8", "strict");
00411 if (unicode)
00412 string = PyString_AsString(unicode);
00413 }
00414 else if (PyString_Check(output)) {
00415 string = PyString_AsString(output);
00416 }
00417 else {
00418 unicode = PyObject_Str(output);
00419 if (unicode)
00420 string = PyString_AsString(unicode);
00421 }
00422
00423 PY_TRY {
00424 if (string)
00425 Instance().Warning("%s",string);
00426 } PY_CATCH;
00427
00428 Py_XDECREF(unicode);
00429
00430 Py_INCREF(Py_None);
00431 return Py_None;
00432 }
00433
00434 PyObject *ConsoleSingleton::sPyError(PyObject * , PyObject *args, PyObject * )
00435 {
00436 PyObject *output;
00437 if (!PyArg_ParseTuple(args, "O", &output))
00438 return NULL;
00439
00440 const char* string=0;
00441 PyObject* unicode=0;
00442 if (PyUnicode_Check(output)) {
00443 unicode = PyUnicode_AsEncodedObject(output, "utf-8", "strict");
00444 if (unicode)
00445 string = PyString_AsString(unicode);
00446 }
00447 else if (PyString_Check(output)) {
00448 string = PyString_AsString(output);
00449 }
00450 else {
00451 unicode = PyObject_Str(output);
00452 if (unicode)
00453 string = PyString_AsString(unicode);
00454 }
00455
00456 PY_TRY {
00457 if (string)
00458 Instance().Error("%s",string);
00459 } PY_CATCH;
00460
00461 Py_XDECREF(unicode);
00462
00463 Py_INCREF(Py_None);
00464 return Py_None;
00465 }
00466
00467 PyObject *ConsoleSingleton::sPyLog(PyObject * , PyObject *args, PyObject * )
00468 {
00469 PyObject *output;
00470 if (!PyArg_ParseTuple(args, "O", &output))
00471 return NULL;
00472
00473 const char* string=0;
00474 PyObject* unicode=0;
00475 if (PyUnicode_Check(output)) {
00476 unicode = PyUnicode_AsEncodedObject(output, "utf-8", "strict");
00477 if (unicode)
00478 string = PyString_AsString(unicode);
00479 }
00480 else if (PyString_Check(output)) {
00481 string = PyString_AsString(output);
00482 }
00483 else {
00484 unicode = PyObject_Str(output);
00485 if (unicode)
00486 string = PyString_AsString(unicode);
00487 }
00488
00489 PY_TRY {
00490 if (string)
00491 Instance().Log("%s",string);
00492 } PY_CATCH;
00493
00494 Py_XDECREF(unicode);
00495
00496 Py_INCREF(Py_None);
00497 return Py_None;
00498 }
00499
00500 PyObject *ConsoleSingleton::sPyGetStatus(PyObject * , PyObject *args, PyObject * )
00501 {
00502 char *pstr1;
00503 char *pstr2;
00504 if (!PyArg_ParseTuple(args, "ss", &pstr1, &pstr2))
00505 return NULL;
00506
00507 PY_TRY{
00508 bool b=false;
00509 ConsoleObserver *pObs = Instance().Get(pstr1);
00510 if(!pObs)
00511 {
00512 Py_INCREF(Py_None);
00513 return Py_None;
00514 }
00515
00516 if(strcmp(pstr2,"Log") == 0)
00517 b = pObs->bLog;
00518 else if(strcmp(pstr2,"Wrn") == 0)
00519 b = pObs->bWrn;
00520 else if(strcmp(pstr2,"Msg") == 0)
00521 b = pObs->bMsg;
00522 else if(strcmp(pstr2,"Err") == 0)
00523 b = pObs->bErr;
00524
00525 return Py_BuildValue("i",b?1:0);
00526 }PY_CATCH;
00527 }
00528
00529 PyObject *ConsoleSingleton::sPySetStatus(PyObject * , PyObject *args, PyObject * )
00530 {
00531 char *pstr1;
00532 char *pstr2;
00533 int Bool;
00534 if (!PyArg_ParseTuple(args, "ssi", &pstr1, &pstr2,&Bool))
00535 return NULL;
00536
00537 PY_TRY{
00538 ConsoleObserver *pObs = Instance().Get(pstr1);
00539 if(pObs)
00540 {
00541 if(strcmp(pstr2,"Log") == 0)
00542 pObs->bLog = (Bool==0)?false:true;
00543 else if(strcmp(pstr2,"Wrn") == 0)
00544 pObs->bWrn = (Bool==0)?false:true;
00545 else if(strcmp(pstr2,"Msg") == 0)
00546 pObs->bMsg = (Bool==0)?false:true;
00547 else if(strcmp(pstr2,"Err") == 0)
00548 pObs->bErr = (Bool==0)?false:true;
00549 else
00550 Py_Error(PyExc_Exception,"Unknown Message Type (use Log,Err,Msg or Wrn)");
00551
00552 Py_INCREF(Py_None);
00553 return Py_None;
00554 } else {
00555 Py_Error(PyExc_Exception,"Unknown Console Type");
00556 }
00557
00558 } PY_CATCH;
00559 }
00560
00561
00562
00563
00564 ConsoleObserverFile::ConsoleObserverFile(const char *sFileName)
00565 : cFileStream(Base::FileInfo(sFileName))
00566 {
00567 if (!cFileStream.is_open())
00568 Console().Warning("Cannot open log file '%s'.\n", sFileName);
00569
00570 unsigned char bom[3] = {0xef, 0xbb, 0xbf};
00571 cFileStream.write((const char*)bom,3*sizeof(char));
00572 }
00573
00574 ConsoleObserverFile::~ConsoleObserverFile()
00575 {
00576 cFileStream.close();
00577 }
00578
00579 void ConsoleObserverFile::Warning(const char *sWarn)
00580 {
00581 cFileStream << "Wrn: " << sWarn;
00582 cFileStream.flush();
00583 }
00584
00585 void ConsoleObserverFile::Message(const char *sMsg)
00586 {
00587 cFileStream << "Msg: " << sMsg;
00588 cFileStream.flush();
00589 }
00590
00591 void ConsoleObserverFile::Error (const char *sErr)
00592 {
00593 cFileStream << "Err: " << sErr;
00594 cFileStream.flush();
00595 }
00596
00597 void ConsoleObserverFile::Log (const char *sLog)
00598 {
00599 cFileStream << "Log: " << sLog;
00600 cFileStream.flush();
00601 }
00602
00603
00604 ConsoleObserverStd::ConsoleObserverStd()
00605 {
00606 bLog = false;
00607 }
00608
00609 ConsoleObserverStd::~ConsoleObserverStd()
00610 {
00611 }
00612
00613 void ConsoleObserverStd::Message(const char *sMsg)
00614 {
00615 printf("%s",sMsg);
00616 }
00617
00618 void ConsoleObserverStd::Warning(const char *sWarn)
00619 {
00620 # if defined(FC_OS_WIN32)
00621 ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN| FOREGROUND_BLUE);
00622 # elif defined(FC_OS_LINUX)
00623 printf("\033[1;33m");
00624 # endif
00625 printf("%s",sWarn);
00626 # if defined(FC_OS_WIN32)
00627 ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
00628 # elif defined(FC_OS_LINUX)
00629 printf("\033[0m");
00630 # endif
00631 }
00632
00633 void ConsoleObserverStd::Error (const char *sErr)
00634 {
00635 # if defined(FC_OS_WIN32)
00636 ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED|FOREGROUND_INTENSITY );
00637 # elif defined(FC_OS_LINUX)
00638 printf("\033[1;31m");
00639 # endif
00640 printf("%s",sErr);
00641 # if defined(FC_OS_WIN32)
00642 ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
00643 # elif defined(FC_OS_LINUX)
00644 printf("\033[0m");
00645 # endif
00646 }
00647
00648 void ConsoleObserverStd::Log (const char *sErr)
00649 {
00650 # if defined(FC_OS_WIN32)
00651 ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED |FOREGROUND_GREEN);
00652 # elif defined(FC_OS_LINUX)
00653 printf("\033[1;36m");
00654 # endif
00655 printf("%s",sErr);
00656 # if defined(FC_OS_WIN32)
00657 ::SetConsoleTextAttribute(::GetStdHandle(STD_OUTPUT_HANDLE),FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
00658 # elif defined(FC_OS_LINUX)
00659 printf("\033[0m");
00660 # endif
00661 }
00662
00663 RedirectStdOutput::RedirectStdOutput()
00664 {
00665 buffer.reserve(80);
00666 }
00667
00668 int RedirectStdOutput::overflow(int c)
00669 {
00670 if (c != EOF)
00671 buffer.push_back((char)c);
00672 return c;
00673 }
00674
00675 int RedirectStdOutput::sync()
00676 {
00677
00678 if (!buffer.empty()) {
00679 Base::Console().Log("%s", buffer.c_str());
00680 buffer.clear();
00681 }
00682 return 0;
00683 }
00684
00685 RedirectStdLog::RedirectStdLog()
00686 {
00687 buffer.reserve(80);
00688 }
00689
00690 int RedirectStdLog::overflow(int c)
00691 {
00692 if (c != EOF)
00693 buffer.push_back((char)c);
00694 return c;
00695 }
00696
00697 int RedirectStdLog::sync()
00698 {
00699
00700 if (!buffer.empty()) {
00701 Base::Console().Log("%s", buffer.c_str());
00702 buffer.clear();
00703 }
00704 return 0;
00705 }
00706
00707 RedirectStdError::RedirectStdError()
00708 {
00709 buffer.reserve(80);
00710 }
00711
00712 int RedirectStdError::overflow(int c)
00713 {
00714 if (c != EOF)
00715 buffer.push_back((char)c);
00716 return c;
00717 }
00718
00719 int RedirectStdError::sync()
00720 {
00721 if (!buffer.empty()) {
00722 Base::Console().Error("%s", buffer.c_str());
00723 buffer.clear();
00724 }
00725 return 0;
00726 }