mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0031731: Draw Harness - colorize errors and exception messages
Draw_Interpretor, CommandCmd() - catched exceptions and messages put into Tcl string result before throwing a Tcl exception (return 1) are now print in intense red (using Message::SendFail()). Duplication of exception message in std::cout and Tcl output has been removed. Draw Harness plugins have been updated to use either Message::SendFail() or theDI instead of std::cout/std::cerr for printing colored error message before throwing a Tcl exception.
This commit is contained in:
@@ -59,7 +59,7 @@ extern Standard_Boolean Draw_ParseFailed;
|
||||
|
||||
Standard_EXPORT Draw_Viewer dout;
|
||||
Standard_EXPORT Draw_Interpretor theCommands;
|
||||
Standard_EXPORT Standard_Boolean Draw_Batch;
|
||||
Standard_EXPORT Standard_Boolean Draw_Batch = Standard_False;
|
||||
Standard_EXPORT Standard_Boolean Draw_Spying = Standard_False;
|
||||
Standard_EXPORT Standard_Boolean Draw_Chrono = Standard_False;
|
||||
Standard_EXPORT Standard_Boolean Draw_VirtualWindows = Standard_False;
|
||||
@@ -504,14 +504,7 @@ void Draw_Appli(int argc, char** argv, const FDraw_InitAppli Draw_InitAppli)
|
||||
if (!isInteractiveForced)
|
||||
{
|
||||
// disable console messages colorization to avoid spoiling log with color codes
|
||||
for (Message_SequenceOfPrinters::Iterator aPrinterIter (Message::DefaultMessenger()->Printers());
|
||||
aPrinterIter.More(); aPrinterIter.Next())
|
||||
{
|
||||
if (Handle(Message_PrinterOStream) aPrinter = Handle(Message_PrinterOStream)::DownCast (aPrinterIter.Value()))
|
||||
{
|
||||
aPrinter->SetToColorize (Standard_False);
|
||||
}
|
||||
}
|
||||
theCommands.SetToColorize (Standard_False);
|
||||
}
|
||||
ReadInitFile (aRunFile);
|
||||
// provide a clean exit, this is useful for some analysis tools
|
||||
@@ -637,7 +630,15 @@ Standard_Boolean Draw_Interprete(const char* com)
|
||||
|
||||
if (*theCommands.Result())
|
||||
{
|
||||
if (c > 0 && theCommands.ToColorize())
|
||||
{
|
||||
Message_PrinterOStream::SetConsoleTextColor (&std::cout, Message_ConsoleColor_Red, true);
|
||||
}
|
||||
std::cout << theCommands.Result() << std::endl;
|
||||
if (c > 0 && theCommands.ToColorize())
|
||||
{
|
||||
Message_PrinterOStream::SetConsoleTextColor (&std::cout, Message_ConsoleColor_Default, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (Draw_Chrono && hadchrono) {
|
||||
|
@@ -259,9 +259,9 @@ static Standard_Integer dlog(Draw_Interpretor& di, Standard_Integer n, const cha
|
||||
{
|
||||
if (n != 2 && n != 3)
|
||||
{
|
||||
std::cout << "Enable or disable logging: " << a[0] << " {on|off}" << std::endl;
|
||||
std::cout << "Reset log: " << a[0] << " reset" << std::endl;
|
||||
std::cout << "Get log content: " << a[0] << " get" << std::endl;
|
||||
Message::SendFail() << "Enable or disable logging: " << a[0] << " {on|off}\n"
|
||||
<< "Reset log: " << a[0] << " reset\n"
|
||||
<< "Get log content: " << a[0] << " get";
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -292,7 +292,7 @@ static Standard_Integer dlog(Draw_Interpretor& di, Standard_Integer n, const cha
|
||||
di << (di.GetDoLog() ? "on" : "off");
|
||||
}
|
||||
else {
|
||||
std::cout << "Unrecognized option(s): " << a[1] << std::endl;
|
||||
Message::SendFail() << "Unrecognized option(s): " << a[1];
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -302,7 +302,7 @@ static Standard_Integer decho(Draw_Interpretor& di, Standard_Integer n, const ch
|
||||
{
|
||||
if (n != 2)
|
||||
{
|
||||
std::cout << "Enable or disable echoing: " << a[0] << " {on|off}" << std::endl;
|
||||
Message::SendFail() << "Enable or disable echoing: " << a[0] << " {on|off}";
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ static Standard_Integer decho(Draw_Interpretor& di, Standard_Integer n, const ch
|
||||
di.SetDoEcho (Standard_False);
|
||||
}
|
||||
else {
|
||||
std::cout << "Unrecognized option: " << a[1] << std::endl;
|
||||
Message::SendFail() << "Unrecognized option: " << a[1];
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@@ -762,7 +762,7 @@ static int dlocale (Draw_Interpretor& di, Standard_Integer n, const char** argv)
|
||||
else if ( ! strcmp (cat, "LC_TIME") ) category = LC_TIME;
|
||||
else
|
||||
{
|
||||
std::cout << "Error: cannot recognize argument " << cat << " as one of LC_ macros" << std::endl;
|
||||
Message::SendFail() << "Error: cannot recognize argument " << cat << " as one of LC_ macros";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -884,7 +884,7 @@ static int dparallel (Draw_Interpretor& theDI,
|
||||
const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]);
|
||||
if (aVal <= 0 || aVal > aDefPool->NbThreads())
|
||||
{
|
||||
std::cout << "Syntax error: maximum number of threads to use should be <= of threads in the pool\n";
|
||||
Message::SendFail() << "Syntax error: maximum number of threads to use should be <= of threads in the pool";
|
||||
return 1;
|
||||
}
|
||||
aDefPool->SetNbDefaultThreadsToLaunch (aVal);
|
||||
@@ -915,7 +915,7 @@ static int dparallel (Draw_Interpretor& theDI,
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Syntax error: unknown argument '" << anArg << "'\n";
|
||||
Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -989,7 +989,7 @@ static int dsetsignal (Draw_Interpretor& theDI, Standard_Integer theArgNb, const
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Syntax error: unknown argument '" << anArg << "'\n";
|
||||
Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1023,7 +1023,7 @@ static int dtracelevel (Draw_Interpretor& theDI,
|
||||
Message_Gravity aLevel = Message_Info;
|
||||
if (theArgNb < 1 || theArgNb > 2)
|
||||
{
|
||||
std::cout << "Error: wrong number of arguments! See usage:\n";
|
||||
Message::SendFail() << "Error: wrong number of arguments! See usage:";
|
||||
theDI.PrintHelp (theArgVec[0]);
|
||||
return 1;
|
||||
}
|
||||
@@ -1054,7 +1054,7 @@ static int dtracelevel (Draw_Interpretor& theDI,
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error: unknown gravity '" << theArgVec[1] << "'!\n";
|
||||
Message::SendFail() << "Error: unknown gravity '" << theArgVec[1] << "'";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -1062,14 +1062,14 @@ static int dtracelevel (Draw_Interpretor& theDI,
|
||||
Handle(Message_Messenger) aMessenger = Message::DefaultMessenger();
|
||||
if (aMessenger.IsNull())
|
||||
{
|
||||
std::cout << "Error: default messenger is unavailable!\n";
|
||||
Message::SendFail() << "Error: default messenger is unavailable";
|
||||
return 1;
|
||||
}
|
||||
|
||||
Message_SequenceOfPrinters& aPrinters = aMessenger->ChangePrinters();
|
||||
if (aPrinters.Length() < 1)
|
||||
{
|
||||
std::cout << "Error: no printers registered in default Messenger!\n";
|
||||
Message::SendFail() << "Error: no printers registered in default Messenger";
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1108,7 +1108,7 @@ static int dtracelevel (Draw_Interpretor& theDI,
|
||||
//function : dputs
|
||||
//purpose :
|
||||
//==============================================================================
|
||||
static int dputs (Draw_Interpretor& ,
|
||||
static int dputs (Draw_Interpretor& theDI,
|
||||
Standard_Integer theArgNb,
|
||||
const char** theArgVec)
|
||||
{
|
||||
@@ -1169,6 +1169,11 @@ static int dputs (Draw_Interpretor& ,
|
||||
}
|
||||
else if (anArgIter + 1 == theArgNb)
|
||||
{
|
||||
if (!theDI.ToColorize())
|
||||
{
|
||||
toIntense = false;
|
||||
aColor = Message_ConsoleColor_Default;
|
||||
}
|
||||
if (toIntense || aColor != Message_ConsoleColor_Default)
|
||||
{
|
||||
Message_PrinterOStream::SetConsoleTextColor (aStream, aColor, toIntense);
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <Draw_ProgressIndicator.hxx>
|
||||
#include <Draw_Text2D.hxx>
|
||||
#include <Draw_Text3D.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Standard_Stream.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
@@ -195,12 +196,12 @@ static Standard_Integer wzoom(Draw_Interpretor& di, Standard_Integer argc, const
|
||||
id = atoi(argv[1]);
|
||||
if ((id < 0) || (id >= MAXVIEW))
|
||||
{
|
||||
std::cout << "Incorrect view-id, must be in 0.."<<MAXVIEW-1<<std::endl;
|
||||
Message::SendFail() << "Incorrect view-id, must be in 0.." << (MAXVIEW-1);
|
||||
return 1;
|
||||
}
|
||||
if (!dout.HasView(id))
|
||||
{
|
||||
std::cout <<"View "<<id<<" does not exist."<<std::endl;
|
||||
Message::SendFail() << "View " << id << " does not exist";
|
||||
return 1;
|
||||
}
|
||||
X1 = atoi (argv [2]);
|
||||
|
@@ -15,18 +15,20 @@
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#include <Draw_Interpretor.hxx>
|
||||
|
||||
#include <Draw_Appli.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Message_PrinterOStream.hxx>
|
||||
#include <OSD.hxx>
|
||||
#include <OSD_File.hxx>
|
||||
#include <OSD_Path.hxx>
|
||||
#include <OSD_Process.hxx>
|
||||
#include <Standard_SStream.hxx>
|
||||
#include <Standard_RangeError.hxx>
|
||||
#include <Standard_ErrorHandler.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
#include <TCollection_ExtendedString.hxx>
|
||||
#include <OSD_Process.hxx>
|
||||
#include <OSD_Path.hxx>
|
||||
#include <OSD.hxx>
|
||||
#include <OSD_File.hxx>
|
||||
|
||||
#include <string.h>
|
||||
#include <tcl.h>
|
||||
@@ -114,8 +116,7 @@ namespace {
|
||||
|
||||
static Standard_Integer CommandCmd (ClientData theClientData, Tcl_Interp* interp, Standard_Integer argc, const char* argv[])
|
||||
{
|
||||
static Standard_Integer code;
|
||||
code = TCL_OK;
|
||||
Standard_Integer code = TCL_OK;
|
||||
Draw_Interpretor::CallBackData* aCallback = (Draw_Interpretor::CallBackData* )theClientData;
|
||||
Draw_Interpretor& di = *(aCallback->myDI);
|
||||
|
||||
@@ -143,24 +144,26 @@ static Standard_Integer CommandCmd (ClientData theClientData, Tcl_Interp* interp
|
||||
dumpArgs (std::cout, argc, argv);
|
||||
|
||||
// run command
|
||||
try {
|
||||
try
|
||||
{
|
||||
OCC_CATCH_SIGNALS
|
||||
|
||||
// get exception if control-break has been pressed
|
||||
OSD::ControlBreak();
|
||||
|
||||
// OCC680: Transfer UTF-8 directly to OCC commands without locale usage
|
||||
|
||||
Standard_Integer fres = aCallback->Invoke ( di, argc, argv /*anArgs.GetArgv()*/ );
|
||||
if (fres != 0)
|
||||
if (fres != 0)
|
||||
{
|
||||
code = TCL_ERROR;
|
||||
}
|
||||
}
|
||||
catch (Standard_Failure const& anException) {
|
||||
catch (Standard_Failure const& anException)
|
||||
{
|
||||
// fail if Draw_ExitOnCatch is set
|
||||
std::cout << "An exception was caught " << anException << std::endl;
|
||||
const char* toExitOnCatch = Tcl_GetVar (interp, "Draw_ExitOnCatch", TCL_GLOBAL_ONLY);
|
||||
if (toExitOnCatch != NULL && Draw::Atoi (toExitOnCatch))
|
||||
{
|
||||
Message::SendFail() << "An exception was caught " << anException;
|
||||
#ifdef _WIN32
|
||||
Tcl_Exit(0);
|
||||
#else
|
||||
@@ -168,18 +171,17 @@ static Standard_Integer CommandCmd (ClientData theClientData, Tcl_Interp* interp
|
||||
#endif
|
||||
}
|
||||
|
||||
// get the error message
|
||||
Standard_SStream ss;
|
||||
ss << "** Exception ** " << anException << std::ends;
|
||||
ss << "An exception was caught " << anException << std::ends;
|
||||
Tcl_SetResult(interp,(char*)(ss.str().c_str()),TCL_VOLATILE);
|
||||
code = TCL_ERROR;
|
||||
}
|
||||
catch (std::exception const& theStdException)
|
||||
{
|
||||
std::cout << "An exception was caught " << theStdException.what() << " [" << typeid(theStdException).name() << "]" << std::endl;
|
||||
const char* toExitOnCatch = Tcl_GetVar (interp, "Draw_ExitOnCatch", TCL_GLOBAL_ONLY);
|
||||
if (toExitOnCatch != NULL && Draw::Atoi (toExitOnCatch))
|
||||
{
|
||||
Message::SendFail() << "An exception was caught " << theStdException.what() << " [" << typeid(theStdException).name() << "]";
|
||||
#ifdef _WIN32
|
||||
Tcl_Exit (0);
|
||||
#else
|
||||
@@ -187,18 +189,17 @@ static Standard_Integer CommandCmd (ClientData theClientData, Tcl_Interp* interp
|
||||
#endif
|
||||
}
|
||||
|
||||
// get the error message
|
||||
Standard_SStream ss;
|
||||
ss << "** Exception ** " << theStdException.what() << " [" << typeid(theStdException).name() << "]" << std::ends;
|
||||
Tcl_SetResult (interp, (char*)(ss.str().c_str()), TCL_VOLATILE);
|
||||
ss << "An exception was caught " << theStdException.what() << " [" << typeid(theStdException).name() << "]" << std::ends;
|
||||
Tcl_SetResult(interp,(char*)(ss.str().c_str()),TCL_VOLATILE);
|
||||
code = TCL_ERROR;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << "UNKNOWN exception was caught " << std::endl;
|
||||
const char* toExitOnCatch = Tcl_GetVar (interp, "Draw_ExitOnCatch", TCL_GLOBAL_ONLY);
|
||||
if (toExitOnCatch != NULL && Draw::Atoi (toExitOnCatch))
|
||||
{
|
||||
Message::SendFail() << "UNKNOWN exception was caught ";
|
||||
#ifdef _WIN32
|
||||
Tcl_Exit (0);
|
||||
#else
|
||||
@@ -206,10 +207,9 @@ static Standard_Integer CommandCmd (ClientData theClientData, Tcl_Interp* interp
|
||||
#endif
|
||||
}
|
||||
|
||||
// get the error message
|
||||
Standard_SStream ss;
|
||||
ss << "** Exception ** UNKNOWN" << std::ends;
|
||||
Tcl_SetResult (interp, (char* )(ss.str().c_str()), TCL_VOLATILE);
|
||||
ss << "UNKNOWN exception was caught " << std::ends;
|
||||
Tcl_SetResult(interp,(char*)(ss.str().c_str()),TCL_VOLATILE);
|
||||
code = TCL_ERROR;
|
||||
}
|
||||
|
||||
@@ -244,15 +244,34 @@ static void CommandDelete (ClientData theClientData)
|
||||
|
||||
//=======================================================================
|
||||
//function : Draw_Interpretor
|
||||
//purpose :
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Draw_Interpretor::Draw_Interpretor() :
|
||||
isAllocated(Standard_False), myDoLog(Standard_False), myDoEcho(Standard_False), myFDLog(-1)
|
||||
Draw_Interpretor::Draw_Interpretor()
|
||||
: // the tcl interpreter is not created immediately as it is kept
|
||||
// by a global variable and created and deleted before the main()
|
||||
myInterp (NULL),
|
||||
isAllocated (Standard_False),
|
||||
myDoLog (Standard_False),
|
||||
myDoEcho (Standard_False),
|
||||
myToColorize (Standard_True),
|
||||
myFDLog (-1)
|
||||
{
|
||||
// The tcl interpreter is not created immediately as it is kept
|
||||
// by a global variable and created and deleted before the main().
|
||||
myInterp = NULL;
|
||||
//
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Draw_Interpretor
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Draw_Interpretor::Draw_Interpretor (const Draw_PInterp& theInterp)
|
||||
: myInterp (theInterp),
|
||||
isAllocated (Standard_False),
|
||||
myDoLog (Standard_False),
|
||||
myDoEcho (Standard_False),
|
||||
myToColorize (Standard_True),
|
||||
myFDLog (-1)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -269,17 +288,20 @@ void Draw_Interpretor::Init()
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : Draw_Interpretor
|
||||
//purpose :
|
||||
//function : SetToColorize
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Draw_Interpretor::Draw_Interpretor(const Draw_PInterp& p) :
|
||||
isAllocated(Standard_False),
|
||||
myInterp(p),
|
||||
myDoLog(Standard_False),
|
||||
myDoEcho(Standard_False),
|
||||
myFDLog(-1)
|
||||
void Draw_Interpretor::SetToColorize (Standard_Boolean theToColorize)
|
||||
{
|
||||
myToColorize = theToColorize;
|
||||
for (Message_SequenceOfPrinters::Iterator aPrinterIter (Message::DefaultMessenger()->Printers());
|
||||
aPrinterIter.More(); aPrinterIter.Next())
|
||||
{
|
||||
if (Handle(Message_PrinterOStream) aPrinter = Handle(Message_PrinterOStream)::DownCast (aPrinterIter.Value()))
|
||||
{
|
||||
aPrinter->SetToColorize (Standard_False);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
|
@@ -251,6 +251,12 @@ public:
|
||||
//! Returns current value of the log file descriptor
|
||||
Standard_Integer GetLogFileDescriptor() { return myFDLog; }
|
||||
|
||||
//! Return TRUE if console output should be colorized; TRUE by default.
|
||||
Standard_Boolean ToColorize() const { return myToColorize; }
|
||||
|
||||
//! Set if console output should be colorized.
|
||||
Standard_EXPORT void SetToColorize (Standard_Boolean theToColorize);
|
||||
|
||||
protected:
|
||||
|
||||
Standard_EXPORT void add (Standard_CString theCommandName,
|
||||
@@ -261,10 +267,11 @@ protected:
|
||||
|
||||
private:
|
||||
|
||||
Standard_Boolean isAllocated;
|
||||
Draw_PInterp myInterp;
|
||||
Standard_Boolean isAllocated;
|
||||
Standard_Boolean myDoLog;
|
||||
Standard_Boolean myDoEcho;
|
||||
Standard_Boolean myToColorize;
|
||||
Standard_Integer myFDLog; //!< file descriptor of log file
|
||||
|
||||
public:
|
||||
|
@@ -258,7 +258,7 @@ static Standard_Integer dtryload (Draw_Interpretor& di, Standard_Integer n, cons
|
||||
{
|
||||
if (n != 2)
|
||||
{
|
||||
std::cout << "Error: specify path to library to be loaded" << std::endl;
|
||||
Message::SendFail() << "Error: specify path to library to be loaded";
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include <Draw_Number.hxx>
|
||||
#include <Draw_ProgressIndicator.hxx>
|
||||
#include <Draw_SequenceOfDrawable3D.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <NCollection_Map.hxx>
|
||||
#include <Standard_SStream.hxx>
|
||||
#include <Standard_Stream.hxx>
|
||||
@@ -388,7 +389,7 @@ static Standard_Integer draw(Draw_Interpretor& , Standard_Integer n, const char*
|
||||
if (n < 3) return 1;
|
||||
Standard_Integer id = Draw::Atoi(a[1]);
|
||||
if (!dout.HasView(id)) {
|
||||
std::cout << "bad view number in draw"<<std::endl;
|
||||
Message::SendFail() << "bad view number in draw";
|
||||
return 1;
|
||||
}
|
||||
Standard_Integer mo = Draw::Atoi(a[2]);
|
||||
@@ -587,7 +588,7 @@ static Standard_Integer set(Draw_Interpretor& di, Standard_Integer n, const char
|
||||
static Standard_Integer dsetenv(Draw_Interpretor& /*di*/, Standard_Integer argc, const char** argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
std::cout << "Use: " << argv[0] << " {varname} [value]" << std::endl;
|
||||
Message::SendFail() << "Use: " << argv[0] << " {varname} [value]";
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -610,7 +611,7 @@ static Standard_Integer dsetenv(Draw_Interpretor& /*di*/, Standard_Integer argc,
|
||||
static Standard_Integer dgetenv(Draw_Interpretor& di, Standard_Integer argc, const char** argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
std::cout << "Use: " << argv[0] << " {varname}" << std::endl;
|
||||
Message::SendFail() << "Use: " << argv[0] << " {varname}";
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user