// Created on: 1995-02-23
// Created by: Remi LEQUETTE
// Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
//
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
//
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
-#include <Standard_Macro.hxx>
-#include <Standard_Stream.hxx>
-#include <Standard_SStream.hxx>
-
-#include <Draw.ixx>
+#include <Draw.hxx>
#include <Draw_Appli.hxx>
+#include <Draw_Chronometer.hxx>
+#include <Draw_Drawable3D.hxx>
#include <Draw_Printer.hxx>
-
+#include <Draw_ProgressIndicator.hxx>
#include <Message.hxx>
#include <Message_Messenger.hxx>
+#include <OSD.hxx>
+#include <OSD_Chronometer.hxx>
+#include <OSD_Environment.hxx>
+#include <OSD_Exception_CTRL_BREAK.hxx>
+#include <OSD_MAllocHook.hxx>
#include <OSD_MemInfo.hxx>
+#include <Standard_Macro.hxx>
+#include <Standard_SStream.hxx>
+#include <Standard_Stream.hxx>
+#include <Standard_Version.hxx>
+#include <TCollection_AsciiString.hxx>
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#if defined(HAVE_TIME_H) || defined(WNT)
-# include <time.h>
-#endif
-
-#ifdef HAVE_SIGNAL_H
-# include <signal.h>
-#endif
+#include <OSD_PerfMeter.h>
+#ifdef _WIN32
-#ifndef WNT
-# include <sys/resource.h>
-# ifdef HAVE_STRINGS_H
-# include <strings.h>
-# endif
-#else
-//WNT
-extern Standard_Boolean Draw_Batch;
#include <windows.h>
#include <winbase.h>
#include <process.h>
#include <stdio.h>
#include <stdlib.h>
-#ifdef HAVE_LIMITS
-# include <limits>
-#elif defined (HAVE_LIMITS_H)
-# include <limits.h>
-#endif
-
-#ifdef WNT
-# include <limits>
-#endif
+#include <time.h>
+#include <limits>
-static clock_t MDTV_CPU_LIMIT; // Cpu_limit in Sec.
-static clock_t MDTV_CPU_CURRENT; // cpu time already used at last
- // cpulimit call. (sec.)
-//#define strcasecmp strcmp Already defined
#define RLIM_INFINITY 0x7fffffff
-#endif
-#include <Draw_Chronometer.hxx>
-#include <OSD_MAllocHook.hxx>
-#include <OSD_Chronometer.hxx>
+static clock_t CPU_CURRENT; // cpu time already used at last
+ // cpulimit call. (sec.)
+#else /* _WIN32 */
+
+#include <sys/resource.h>
+#include <signal.h>
+#include <unistd.h>
#if defined (__hpux) || defined ( HPUX )
#define RLIM_INFINITY 0x7fffffff
#define RLIMIT_CPU 0
#endif
+#endif /* _WIN32 */
+
+extern Standard_Boolean Draw_Batch;
+static clock_t CPU_LIMIT; // Cpu_limit in Sec.
+static OSD_Timer aTimer;
//=======================================================================
// chronom
else
Draw_Chrono = (*a[1] == '1');
- if (Draw_Chrono) di << "Chronometers activated."<<"\n";
- else di << "Chronometers desactivated."<<"\n";
+ if (Draw_Chrono) di << "Chronometers activated.\n";
+ else di << "Chronometers desactivated.\n";
}
else {
Handle(Draw_Drawable3D) D = Draw::Get(a[1]);
C->Timer().Reset();
}
else {
- if (!strcasecmp(a[2],"reset"))
- C->Timer().Reset();
- if (!strcasecmp(a[2],"start"))
- C->Timer().Start();
- if (!strcasecmp(a[2],"stop"))
- C->Timer().Stop();
- if (!strcasecmp(a[2],"show"))
- C->Timer().Show();
+ for (Standard_Integer anIter = 2; anIter < n; ++anIter)
+ {
+ TCollection_AsciiString anArg (a[anIter]);
+ anArg.LowerCase();
+
+ if (anArg == "reset")
+ {
+ C->Timer().Reset();
+ }
+ else if (anArg == "restart")
+ {
+ C->Timer().Restart();
+ }
+ else if (anArg == "start")
+ {
+ C->Timer().Start();
+ }
+ else if (anArg == "stop")
+ {
+ C->Timer().Stop();
+ }
+ else if (anArg == "show")
+ {
+ C->Timer().Show();
+ }
+ else if (anArg == "counter")
+ {
+ Standard_Real aSeconds,aCPUtime;
+ Standard_Integer aMinutes, aHours;
+ C->Timer().Show(aSeconds,aMinutes,aHours,aCPUtime);
+ std::cout << "COUNTER " << a[++anIter] << ": " << aCPUtime << "\n";
+ }
+ else
+ {
+ std::cerr << "Unknown argument '" << a[anIter] << "'!\n";
+ }
+ }
}
}
return 0;
}
-static Standard_Integer dchronom(Draw_Interpretor& I,
+static Standard_Integer dchronom(Draw_Interpretor& theDI,
Standard_Integer n,const char** a)
{
if ((n == 1) || (*a[1] == '0') || (*a[1] == '1')) {
else
Draw_Chrono = (*a[1] == '1');
- if (Draw_Chrono) I << "Chronometers activated."<<"\n";
- else I << "Chronometers desactivated."<<"\n";
+ if (Draw_Chrono) theDI << "Chronometers activated.\n";
+ else theDI << "Chronometers desactivated.\n";
}
else {
Handle(Draw_Drawable3D) D = Draw::Get(a[1]);
}
if (C.IsNull()) {
C = new Draw_Chronometer();
- Draw::Set(a[1],C,Standard_False);
+ Draw::Set(a[1],C,Standard_False);
}
if (n <= 2) {
C->Timer().Reset();
}
else {
- if (!strcasecmp(a[2],"reset"))
- C->Timer().Reset();
- if (!strcasecmp(a[2],"start"))
- C->Timer().Start();
- if (!strcasecmp(a[2],"stop"))
- C->Timer().Stop();
- if (!strcasecmp(a[2],"show")) {
- Standard_SStream ss;
- C->Timer().Show(ss);
- I << ss;
+ for (Standard_Integer anIter = 2; anIter < n; ++anIter)
+ {
+ TCollection_AsciiString anArg (a[anIter]);
+ anArg.LowerCase();
+
+ if (anArg == "reset")
+ {
+ C->Timer().Reset();
+ }
+ else if (anArg == "restart")
+ {
+ C->Timer().Restart();
+ }
+ else if (anArg == "start")
+ {
+ C->Timer().Start();
+ }
+ else if (anArg == "stop")
+ {
+ C->Timer().Stop();
+ }
+ else if (anArg == "show")
+ {
+ Standard_SStream ss;
+ C->Timer().Show(ss);
+ theDI << ss;
+ }
+ else if (anArg == "counter")
+ {
+ Standard_Real aSeconds,aCPUtime;
+ Standard_Integer aMinutes, aHours;
+ C->Timer().Show(aSeconds,aMinutes,aHours,aCPUtime);
+ theDI << "COUNTER " << a[++anIter] << ": " << aCPUtime << "\n";
+ }
+ else
+ {
+ theDI << "Unknown argument '" << a[anIter] << "'!\n";
+ }
}
}
}
Draw_Spying = Standard_False;
if (n > 1) {
if (!Draw_Spyfile.open(a[1],ios::out)) {
- di << "Cannot open "<<a[1]<<" for writing"<<"\n";
+ di << "Cannot open "<<a[1]<<" for writing\n";
return 1;
}
Draw_Spying = Standard_True;
return 0;
}
+static Standard_Integer dlog(Draw_Interpretor& di, Standard_Integer n, const char** a)
+{
+ if (n != 2 && n != 3)
+ {
+ cout << "Enable or disable logging: " << a[0] << " {on|off}" << endl;
+ cout << "Reset log: " << a[0] << " reset" << endl;
+ cout << "Get log content: " << a[0] << " get" << endl;
+ return 1;
+ }
+
+ if (! strcmp (a[1], "on") && n == 2)
+ {
+ di.SetDoLog (Standard_True);
+// di.Log() << "dlog on" << endl; // for symmetry
+ }
+ else if (! strcmp (a[1], "off") && n == 2)
+ {
+ di.SetDoLog (Standard_False);
+ }
+ else if (! strcmp (a[1], "reset") && n == 2)
+ {
+ di.ResetLog();
+ }
+ else if (! strcmp (a[1], "get") && n == 2)
+ {
+ di << di.GetLog();
+ }
+ else if (! strcmp (a[1], "add") && n == 3)
+ {
+ di.AddLog (a[2]);
+ di.AddLog ("\n");
+ }
+ else if (! strcmp (a[1], "status") && n == 2)
+ {
+ di << (di.GetDoLog() ? "on" : "off");
+ }
+ else {
+ cout << "Unrecognized option(s): " << a[1] << endl;
+ return 1;
+ }
+ return 0;
+}
+
+static Standard_Integer decho(Draw_Interpretor& di, Standard_Integer n, const char** a)
+{
+ if (n != 2)
+ {
+ cout << "Enable or disable echoing: " << a[0] << " {on|off}" << endl;
+ return 1;
+ }
+
+ if (! strcmp (a[1], "on"))
+ {
+ di.SetDoEcho (Standard_True);
+ }
+ else if (! strcmp (a[1], "off"))
+ {
+ di.SetDoEcho (Standard_False);
+ }
+ else {
+ cout << "Unrecognized option: " << a[1] << endl;
+ return 1;
+ }
+ return 0;
+}
+
+static Standard_Integer dbreak(Draw_Interpretor& di, Standard_Integer, const char**)
+{
+ try {
+ OSD::ControlBreak();
+ }
+ catch (OSD_Exception_CTRL_BREAK) {
+ di << "User pressed Control-Break";
+ return 1; // Tcl exception
+ }
+
+ return 0;
+}
+
+static Standard_Integer dversion(Draw_Interpretor& di, Standard_Integer, const char**)
+{
+ // print OCCT version and OCCTY-specific macros used
+ di << "Open CASCADE Technology " << OCC_VERSION_STRING_EXT << "\n";
+#ifdef OCCT_DEBUG
+ di << "Extended debug mode\n";
+#elif defined(_DEBUG)
+ di << "Debug mode\n";
+#endif
+#ifdef HAVE_TBB
+ di << "TBB enabled (HAVE_TBB)\n";
+#else
+ di << "TBB disabled\n";
+#endif
+#ifdef HAVE_FREEIMAGE
+ di << "FreeImage enabled (HAVE_FREEIMAGE)\n";
+#else
+ di << "FreeImage disabled\n";
+#endif
+#ifdef HAVE_FFMPEG
+ di << "FFmpeg enabled (HAVE_FFMPEG)\n";
+#else
+ di << "FFmpeg disabled\n";
+#endif
+#ifdef HAVE_GLES2
+ di << "OpenGL: ES2\n";
+#else
+ di << "OpenGL: desktop\n";
+#endif
+#ifdef HAVE_VTK
+ di << "VTK enabled (HAVE_VTK)\n";
+#else
+ di << "VTK disabled\n";
+#endif
+#ifdef No_Exception
+ di << "Exceptions disabled (No_Exception)\n";
+#else
+ di << "Exceptions enabled\n";
+#endif
+
+ // check compiler, OS, etc. using pre-processor macros provided by compiler
+ // see "Pre-defined C/C++ Compiler Macros" http://sourceforge.net/p/predef/wiki/
+ // note that only modern compilers that are known to be used for OCCT are recognized
+
+ // compiler; note that GCC and MSVC are last as other compilers (e.g. Intel) can also define __GNUC__ and _MSC_VER
+#if defined(__INTEL_COMPILER)
+ di << "Compiler: Intel " << __INTEL_COMPILER << "\n";
+#elif defined(__BORLANDC__)
+ di << "Compiler: Borland C++ (__BORLANDC__ = " << __BORLANDC__ << ")\n";
+#elif defined(__clang__)
+ di << "Compiler: Clang " << __clang_major__ << "." << __clang_minor__ << "." << __clang_patchlevel__ << "\n";
+#elif defined(__SUNPRO_C)
+ di << "Compiler: Sun Studio (__SUNPRO_C = " << __SUNPROC_C << ")\n";
+#elif defined(_MSC_VER)
+ #if _MSC_VER < 1900
+ di << "Compiler: MS Visual C++ " << (int)(_MSC_VER/100-6) << "." << (int)((_MSC_VER/10)-60-10*(int)(_MSC_VER/100-6)) << " (_MSC_FULL_VER = " << _MSC_FULL_VER << ")\n";
+ #else
+ di << "Compiler: MS Visual C++ " << (int)(_MSC_VER/100-5) << "." << (int)((_MSC_VER/10)-50-10*(int)(_MSC_VER/100-5)) << " (_MSC_FULL_VER = " << _MSC_FULL_VER << ")\n";
+ #endif
+#elif defined(__GNUC__)
+ di << "Compiler: GCC " << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__ << "\n";
+#else
+ di << "Compiler: unrecognized\n";
+#endif
+
+ // Cygwin and MinGW specifics
+#if defined(__CYGWIN__)
+ di << "Cygwin\n";
+#endif
+#if defined(__MINGW64__)
+ di << "MinGW 64 " << __MINGW64_VERSION_MAJOR << "." << __MINGW64_VERSION_MINOR << "\n";
+#elif defined(__MINGW32__)
+ di << "MinGW 32 " << __MINGW32_MAJOR_VERSION << "." << __MINGW32_MINOR_VERSION << "\n";
+#endif
+
+ // architecture
+#if defined(__amd64) || defined(__x86_64) || defined(_M_AMD64)
+ di << "Architecture: AMD64\n";
+#elif defined(__i386) || defined(_M_IX86) || defined(__X86__)|| defined(_X86_)
+ di << "Architecture: Intel x86\n";
+#elif defined(_M_IA64) || defined(__ia64__)
+ di << "Architecture: Intel Itanium (IA 64)\n";
+#elif defined(__sparc__) || defined(__sparc)
+ di << "Architecture: SPARC\n";
+#else
+ di << "Architecture: unrecognized\n";
+#endif
+
+ // OS
+#if defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__)
+ di << "OS: Windows\n";
+#elif defined(__APPLE__) || defined(__MACH__)
+ di << "OS: Mac OS X\n";
+#elif defined(__sun)
+ di << "OS: SUN Solaris\n";
+#elif defined(__ANDROID__) /* must be before Linux */
+ #include <android/api-level.h>
+ di << "OS: Android (__ANDROID_API__ = " << __ANDROID_API__ << ")\n";
+#elif defined(__QNXNTO__)
+ di << "OS: QNX Neutrino\n";
+#elif defined(__QNX__)
+ di << "OS: QNX\n";
+#elif defined(__linux__)
+ di << "OS: Linux\n";
+#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
+ #include <sys/param.h>
+ di << "OS: BSD (BSD = " << BSD << ")\n";
+#else
+ di << "OS: unrecognized\n";
+#endif
+
+ return 0;
+}
+
//=======================================================================
//function : wait
//purpose :
{
Standard_Integer w = 10;
if (n > 1)
- w = atoi(a[1]);
+ w = Draw::Atoi(a[1]);
time_t ct = time(NULL) + w;
while (time(NULL) < ct) {};
return 0;
//function : cpulimit
//purpose :
//=======================================================================
-#ifdef WNT
-static unsigned int __stdcall CpuFunc (void * param)
+#ifdef _WIN32
+static unsigned int __stdcall CpuFunc (void * /*param*/)
{
+ clock_t anElapCurrent;
clock_t aCurrent;
- while (1)
+
+ for(;;)
{
Sleep (5);
Standard_Real anUserSeconds, aSystemSeconds;
OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds);
aCurrent = clock_t(anUserSeconds + aSystemSeconds);
+ anElapCurrent = clock_t(aTimer.ElapsedTime());
- if ((aCurrent - MDTV_CPU_CURRENT) >= MDTV_CPU_LIMIT)
+ if (CPU_LIMIT > 0 && (aCurrent - CPU_CURRENT) >= CPU_LIMIT)
{
- printf ("CpuFunc : Fin sur Cpu Limit \n");
- ExitProcess (2);
- return 0;
+ aTimer.Stop();
+ if (IsDebuggerPresent())
+ {
+ std::cout << "ERROR: CPU limit (" << CPU_LIMIT << " sec) has been reached but ignored because of attached Debugger" << std::endl;
+ return 0;
+ }
+ else
+ {
+ std::cout << "ERROR: Process killed by CPU limit (" << CPU_LIMIT << " sec)" << std::endl;
+ ExitProcess (2);
+ }
+ }
+ if (CPU_LIMIT > 0 && anElapCurrent >= CPU_LIMIT)
+ {
+ aTimer.Stop();
+ if (IsDebuggerPresent())
+ {
+ std::cout << "ERROR: Elapsed limit (" << CPU_LIMIT << " sec) has been reached but ignored because of attached Debugger" << std::endl;
+ return 0;
+ }
+ else
+ {
+ std::cout << "ERROR: Process killed by elapsed limit (" << CPU_LIMIT << " sec)" << std::endl;
+ ExitProcess (2);
+ }
}
}
- return 0;
+}
+#else
+static void cpulimitSignalHandler (int)
+{
+ cout << "Process killed by CPU limit (" << CPU_LIMIT << " sec)" << endl;
+ exit(2);
+}
+static void *CpuFunc(void* /*threadarg*/)
+{
+ clock_t anElapCurrent;
+ for(;;)
+ {
+ sleep (5);
+ anElapCurrent = clock_t(aTimer.ElapsedTime());
+ if (CPU_LIMIT >0 && (anElapCurrent) >= CPU_LIMIT) {
+ cout << "Process killed by elapsed limit (" << CPU_LIMIT << " sec)" << endl;
+ exit(2);
+ }
+ }
+ return NULL;
}
#endif
-static Standard_Integer cpulimit(Draw_Interpretor& di, Standard_Integer n, const char** a)
+#ifdef _WIN32
+static Standard_Integer cpulimit(Draw_Interpretor&, Standard_Integer n, const char** a)
{
-#ifndef WNT
- rlimit rlp;
- rlp.rlim_max = RLIM_INFINITY;
- if (n <= 1)
- rlp.rlim_cur = RLIM_INFINITY;
- else
- rlp.rlim_cur = atoi(a[1]);
-
- int status;
- status=setrlimit(RLIMIT_CPU,&rlp);
- if (status !=0)
- di << "status cpulimit setrlimit : " << status << "\n";
-
#else
-//WNT
+static Standard_Integer cpulimit(Draw_Interpretor& di, Standard_Integer n, const char** a)
+{
+#endif
static int aFirst = 1;
-
+#ifdef _WIN32
+ // Windows specific code
unsigned int __stdcall CpuFunc (void *);
unsigned aThreadID;
- if (n <= 1)
- MDTV_CPU_LIMIT = RLIM_INFINITY;
- else
- {
- MDTV_CPU_LIMIT = atoi (a[1]);
+ if (n <= 1){
+ CPU_LIMIT = RLIM_INFINITY;
+ } else {
+ CPU_LIMIT = Draw::Atoi (a[1]);
Standard_Real anUserSeconds, aSystemSeconds;
OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds);
- MDTV_CPU_CURRENT = clock_t(anUserSeconds + aSystemSeconds);
-
+ CPU_CURRENT = clock_t(anUserSeconds + aSystemSeconds);
+ aTimer.Reset();
+ aTimer.Start();
if (aFirst) // Launch the thread only at the 1st call.
{
aFirst = 0;
}
}
-#endif
+#else
+ // Unix & Linux
+ rlimit rlp;
+ rlp.rlim_max = RLIM_INFINITY;
+ if (n <= 1)
+ rlp.rlim_cur = RLIM_INFINITY;
+ else
+ rlp.rlim_cur = Draw::Atoi(a[1]);
+ CPU_LIMIT = rlp.rlim_cur;
+
+ int status;
+ status=setrlimit(RLIMIT_CPU,&rlp);
+ if (status !=0)
+ di << "status cpulimit setrlimit : " << status << "\n";
+ // set signal handler to print a message before death
+ struct sigaction act, oact;
+ memset (&act, 0, sizeof(act));
+ act.sa_handler = cpulimitSignalHandler;
+ sigaction (SIGXCPU, &act, &oact);
+
+ // cpulimit for elapsed time
+ aTimer.Reset();
+ aTimer.Start();
+ pthread_t cpulimitThread;
+ if (aFirst) // Launch the thread only at the 1st call.
+ {
+ aFirst = 0;
+ pthread_create(&cpulimitThread, NULL, CpuFunc, NULL);
+ }
+#endif
return 0;
}
+
//=======================================================================
//function : mallochook
//purpose :
}
if (strcmp(a[1], "set") == 0)
{
- int aType = (n > 2 ? atoi(a[2]) : 1);
+ int aType = (n > 2 ? Draw::Atoi(a[2]) : 1);
if (aType < 0 || aType > 2)
{
- di << "unknown op of the command set" << "\n";
+ di << "unknown op of the command set\n";
return 1;
}
else if (aType == 0)
{
OSD_MAllocHook::SetCallback(NULL);
- di << "callback is unset" << "\n";
+ di << "callback is unset\n";
}
else if (aType == 1)
{
OSD_MAllocHook::SetCallback(OSD_MAllocHook::GetCollectBySize());
- di << "callback is set to CollectBySize" << "\n";
+ di << "callback is set to CollectBySize\n";
}
else //if (aType == 2)
{
OSD_MAllocHook::SetCallback(OSD_MAllocHook::GetLogFileHandler());
- di << "callback is set to LogFileHandler" << "\n";
+ di << "callback is set to LogFileHandler\n";
}
}
else if (strcmp(a[1], "reset") == 0)
{
OSD_MAllocHook::GetCollectBySize()->Reset();
- di << "CollectBySize handler is reset" << "\n";
+ di << "CollectBySize handler is reset\n";
}
else if (strcmp(a[1], "open") == 0)
{
const char* aFileName = (n > 2 ? a[2] : "mem-log.txt");
if (!OSD_MAllocHook::GetLogFileHandler()->Open(aFileName))
{
- di << "cannot create file " << aFileName << " for writing" << "\n";
+ di << "cannot create file " << aFileName << " for writing\n";
return 1;
}
- di << "log file " << aFileName << " is opened for writing" << "\n";
+ di << "log file " << aFileName << " is opened for writing\n";
}
else if (strcmp(a[1], "close") == 0)
{
OSD_MAllocHook::GetLogFileHandler()->Close();
- di << "log file is closed" << "\n";
+ di << "log file is closed\n";
}
else if (strcmp(a[1], "report1") == 0)
{
aOutFile = a[2];
if (OSD_MAllocHook::GetCollectBySize()->MakeReport(aOutFile))
{
- di << "report " << aOutFile << " has been created" << "\n";
+ di << "report " << aOutFile << " has been created\n";
}
else
{
const char* aOutFile = "mem-stat.txt";
if (n > 2)
{
- includeAlive = (atoi(a[2]) != 0);
+ includeAlive = (Draw::Atoi(a[2]) != 0);
if (n > 3)
{
aLogFile = a[3];
}
if (OSD_MAllocHook::LogFileHandler::MakeReport(aLogFile, aOutFile, includeAlive))
{
- di << "report " << aOutFile << " has been created" << "\n";
+ di << "report " << aOutFile << " has been created\n";
}
else
{
return 0;
}
+//==============================================================================
+//function : dlocale
+//purpose :
+//==============================================================================
+
+static int dlocale (Draw_Interpretor& di, Standard_Integer n, const char** argv)
+{
+ int category = LC_ALL;
+ if (n > 1)
+ {
+ const char *cat = argv[1];
+ if ( ! strcmp (cat, "LC_ALL") ) category = LC_ALL;
+ else if ( ! strcmp (cat, "LC_COLLATE") ) category = LC_COLLATE;
+ else if ( ! strcmp (cat, "LC_CTYPE") ) category = LC_CTYPE;
+ else if ( ! strcmp (cat, "LC_MONETARY") ) category = LC_MONETARY;
+ else if ( ! strcmp (cat, "LC_NUMERIC") ) category = LC_NUMERIC;
+ else if ( ! strcmp (cat, "LC_TIME") ) category = LC_TIME;
+ else
+ {
+ cout << "Error: cannot recognize argument " << cat << " as one of LC_ macros" << endl;
+ return 1;
+ }
+ }
+ const char* locale = (n > 2 ? argv[2] : NULL);
+ const char* result = setlocale (category, locale);
+ if (result)
+ di << result;
+ else
+ cout << "Error: unsupported locale specification: " << locale << endl;
+ return 0;
+}
+
//==============================================================================
//function : dmeminfo
//purpose :
{
theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemVirtual)) << " ";
}
+ else if (anArg == "heap" || anArg == "h")
+ {
+ theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemHeapUsage)) << " ";
+ }
else if (anArg == "wset" || anArg == "w")
{
theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemWorkingSet)) << " ";
return 0;
}
+//==============================================================================
+//function : dperf
+//purpose :
+//==============================================================================
+
+static int dperf (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
+{
+ // reset if argument is provided and it is not '0'
+ int reset = (theArgNb > 1 ? theArgVec[1][0] != '0' && theArgVec[1][0] != '\0' : 0);
+ char buffer[25600];
+ perf_sprint_all_meters (buffer, 25600 - 1, reset);
+ theDI << buffer;
+ return 0;
+}
+
+//==============================================================================
+//function : dsetsignal
+//purpose :
+//==============================================================================
+
+static int dsetsignal (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
+{
+ // arm FPE handler if argument is provided and its first symbol is not '0'
+ // or if environment variable CSF_FPE is set and its first symbol is not '0'
+ bool setFPE = false;
+ if (theArgNb > 1)
+ {
+ setFPE = (theArgVec[1][0] == '1' || theArgVec[1][0] == 't');
+ }
+ else
+ {
+ OSD_Environment aEnv ("CSF_FPE");
+ TCollection_AsciiString aEnvStr = aEnv.Value();
+ setFPE = (! aEnvStr.IsEmpty() && aEnvStr.Value(1) != '0');
+ }
+ OSD::SetSignal (setFPE);
+ theDI << "Signal handlers are set, with FPE " << (setFPE ? "armed" : "disarmed");
+ return 0;
+}
+
+//==============================================================================
+//function : dtracelevel
+//purpose :
+//==============================================================================
+
+static int dtracelevel (Draw_Interpretor& theDI,
+ Standard_Integer theArgNb,
+ const char** theArgVec)
+{
+ Message_Gravity aLevel = Message_Info;
+ if (theArgNb < 1 || theArgNb > 2)
+ {
+ std::cout << "Error: wrong number of arguments! See usage:\n";
+ theDI.PrintHelp (theArgVec[0]);
+ return 1;
+ }
+ else if (theArgNb == 2)
+ {
+ TCollection_AsciiString aVal (theArgVec[1]);
+ aVal.LowerCase();
+ if (aVal == "trace")
+ {
+ aLevel = Message_Trace;
+ }
+ else if (aVal == "info")
+ {
+ aLevel = Message_Info;
+ }
+ else if (aVal == "warn"
+ || aVal == "warning")
+ {
+ aLevel = Message_Warning;
+ }
+ else if (aVal == "alarm")
+ {
+ aLevel = Message_Alarm;
+ }
+ else if (aVal == "fail")
+ {
+ aLevel = Message_Fail;
+ }
+ else
+ {
+ std::cout << "Error: unknown gravity '" << theArgVec[1] << "'!\n";
+ return 1;
+ }
+ }
+
+ Handle(Message_Messenger) aMessenger = Message::DefaultMessenger();
+ if (aMessenger.IsNull())
+ {
+ std::cout << "Error: default messenger is unavailable!\n";
+ return 1;
+ }
+
+ Message_SequenceOfPrinters& aPrinters = aMessenger->ChangePrinters();
+ if (aPrinters.Length() < 1)
+ {
+ std::cout << "Error: no printers registered in default Messenger!\n";
+ return 0;
+ }
+
+ for (Standard_Integer aPrinterIter = 1; aPrinterIter <= aPrinters.Length(); ++aPrinterIter)
+ {
+ Handle(Message_Printer)& aPrinter = aPrinters.ChangeValue (aPrinterIter);
+ if (theArgNb == 1)
+ {
+ if (aPrinterIter == 1)
+ {
+ aLevel = aPrinter->GetTraceLevel();
+ }
+ else if (aLevel == aPrinter->GetTraceLevel())
+ {
+ continue;
+ }
+
+ switch (aPrinter->GetTraceLevel())
+ {
+ case Message_Trace: theDI << "trace"; break;
+ case Message_Info: theDI << "info"; break;
+ case Message_Warning: theDI << "warn"; break;
+ case Message_Alarm: theDI << "alarm"; break;
+ case Message_Fail: theDI << "fail"; break;
+ }
+ continue;
+ }
+
+ aPrinter->SetTraceLevel (aLevel);
+ }
+
+ return 0;
+}
+
void Draw::BasicCommands(Draw_Interpretor& theCommands)
{
static Standard_Boolean Done = Standard_False;
if (Done) return;
Done = Standard_True;
+ ios::sync_with_stdio();
+
const char* g = "DRAW General Commands";
-
+
theCommands.Add("batch", "returns 1 in batch mode",
__FILE__,ifbatch,g);
theCommands.Add("spy","spy [file], Save commands in file. no file close",
__FILE__,Draw_wait,g);
theCommands.Add("cpulimit","cpulimit [nbseconds], no args remove limits",
__FILE__,cpulimit,g);
- theCommands.Add("chrono","chrono [ name start/stop/reset/show]",
+ theCommands.Add("chrono","chrono [name action [action...]] \n Operates named timer.\n"
+ " Supported actions: reset, start, stop, restart, show, counter [text].\n"
+ " Without arguments enables / disables global timer for all DRAW commands.",
__FILE__,chronom,g);
- theCommands.Add("dchrono","dchrono [ name start/stop/reset/show]",
+ theCommands.Add("dchrono","see help of chrono command",
__FILE__,dchronom,g);
theCommands.Add("mallochook",
"debug memory allocation/deallocation, w/o args for help",
__FILE__, mallochook, g);
theCommands.Add ("meminfo",
- "meminfo [virt|v] [wset|w] [wsetpeak] [swap] [swappeak] [private]"
+ "meminfo [virt|v] [heap|h] [wset|w] [wsetpeak] [swap] [swappeak] [private]"
" : memory counters for this process",
__FILE__, dmeminfo, g);
+ theCommands.Add("dperf","dperf [reset] -- show performance counters, reset if argument is provided",
+ __FILE__,dperf,g);
+ theCommands.Add("dsetsignal","dsetsignal [fpe=0] -- set OSD signal handler, with FPE option if argument is given",
+ __FILE__,dsetsignal,g);
+
+ // Logging commands; note that their names are hard-coded in the code
+ // of Draw_Interpretor, thus should not be changed without update of that code!
+ theCommands.Add("dlog", "manage logging of commands and output; run without args to get help",
+ __FILE__,dlog,g);
+ theCommands.Add("decho", "switch on / off echo of commands to cout; run without args to get help",
+ __FILE__,decho,g);
+ theCommands.Add("dtracelevel", "dtracelevel [trace|info|warn|alarm|fail]",
+ __FILE__, dtracelevel, g);
+
+ theCommands.Add("dbreak", "raises Tcl exception if user has pressed Control-Break key",
+ __FILE__,dbreak,g);
+ theCommands.Add("dversion", "provides information on OCCT build configuration (version, compiler, OS, C library, etc.)",
+ __FILE__,dversion,g);
+ theCommands.Add("dlocale", "set and / or query locate of C subsystem (function setlocale())",
+ __FILE__,dlocale,g);
}