0032308: Configuration - make Xlib dependency optional
[occt.git] / src / Draw / Draw_BasicCommands.cxx
CommitLineData
b311480e 1// Created on: 1995-02-23
2// Created by: Remi LEQUETTE
3// Copyright (c) 1995-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
b311480e 16
7fd59977 17
42cf5bc1 18#include <Draw.hxx>
7fd59977 19#include <Draw_Appli.hxx>
a60b9727 20#include <Draw_Chronometer.hxx>
42cf5bc1 21#include <Draw_Drawable3D.hxx>
7fd59977 22#include <Draw_Printer.hxx>
42cf5bc1 23#include <Draw_ProgressIndicator.hxx>
7fd59977 24#include <Message.hxx>
25#include <Message_Messenger.hxx>
63e5cfca 26#include <Message_PrinterOStream.hxx>
8a262fa1 27#include <OSD.hxx>
42cf5bc1 28#include <OSD_Chronometer.hxx>
f4dee9bb 29#include <OSD_Environment.hxx>
8a262fa1 30#include <OSD_Exception_CTRL_BREAK.hxx>
42cf5bc1 31#include <OSD_MAllocHook.hxx>
32#include <OSD_MemInfo.hxx>
fc867b96 33#include <OSD_Parallel.hxx>
34#include <OSD_ThreadPool.hxx>
42cf5bc1 35#include <Standard_Macro.hxx>
36#include <Standard_SStream.hxx>
37#include <Standard_Stream.hxx>
38#include <Standard_Version.hxx>
39#include <TCollection_AsciiString.hxx>
7fd59977 40
42cf5bc1 41#include <OSD_PerfMeter.h>
a60b9727 42#ifdef _WIN32
7fd59977 43
7fd59977 44#include <windows.h>
45#include <winbase.h>
46#include <process.h>
47#include <stdio.h>
48#include <stdlib.h>
a60b9727 49#include <time.h>
50#include <limits>
51
52#define RLIM_INFINITY 0x7fffffff
53
54static clock_t CPU_CURRENT; // cpu time already used at last
55 // cpulimit call. (sec.)
a60b9727 56#else /* _WIN32 */
57
58#include <sys/resource.h>
03155c18 59#include <signal.h>
0b309a75 60#include <unistd.h>
7fd59977 61
62#if defined (__hpux) || defined ( HPUX )
63#define RLIM_INFINITY 0x7fffffff
64#define RLIMIT_CPU 0
65#endif
66
a60b9727 67#endif /* _WIN32 */
7fd59977 68
a60b9727 69extern Standard_Boolean Draw_Batch;
70
71static clock_t CPU_LIMIT; // Cpu_limit in Sec.
0b309a75 72static OSD_Timer aTimer;
7fd59977 73
74//=======================================================================
75// chronom
76//=======================================================================
77
78extern Standard_Boolean Draw_Chrono;
79
80static Standard_Integer chronom(Draw_Interpretor& di,
81 Standard_Integer n,const char** a)
82{
83 if ((n == 1) || (*a[1] == '0') || (*a[1] == '1')) {
84 if (n == 1)
85 Draw_Chrono = !Draw_Chrono;
86 else
87 Draw_Chrono = (*a[1] == '1');
88
586db386 89 if (Draw_Chrono) di << "Chronometers activated.\n";
54adc5e9 90 else di << "Chronometers deactivated.\n";
7fd59977 91 }
92 else {
93 Handle(Draw_Drawable3D) D = Draw::Get(a[1]);
94 Handle(Draw_Chronometer) C;
95 if (!D.IsNull()) {
96 C = Handle(Draw_Chronometer)::DownCast(D);
97 }
98 if (C.IsNull()) {
99 C = new Draw_Chronometer();
100 Draw::Set(a[1],C,Standard_False);
101 }
102 if (n <= 2) {
103 C->Timer().Reset();
104 }
105 else {
44fae8b1 106 for (Standard_Integer anIter = 2; anIter < n; ++anIter)
107 {
108 TCollection_AsciiString anArg (a[anIter]);
109 anArg.LowerCase();
110
111 if (anArg == "reset")
112 {
113 C->Timer().Reset();
114 }
115 else if (anArg == "restart")
116 {
117 C->Timer().Restart();
118 }
119 else if (anArg == "start")
120 {
121 C->Timer().Start();
122 }
123 else if (anArg == "stop")
124 {
125 C->Timer().Stop();
126 }
127 else if (anArg == "show")
128 {
129 C->Timer().Show();
130 }
131 else if (anArg == "counter")
132 {
133 Standard_Real aSeconds,aCPUtime;
134 Standard_Integer aMinutes, aHours;
135 C->Timer().Show(aSeconds,aMinutes,aHours,aCPUtime);
136 std::cout << "COUNTER " << a[++anIter] << ": " << aCPUtime << "\n";
137 }
138 else
139 {
140 std::cerr << "Unknown argument '" << a[anIter] << "'!\n";
141 }
142 }
7fd59977 143 }
144 }
145 return 0;
146}
147
44fae8b1 148static Standard_Integer dchronom(Draw_Interpretor& theDI,
7fd59977 149 Standard_Integer n,const char** a)
150{
151 if ((n == 1) || (*a[1] == '0') || (*a[1] == '1')) {
152 if (n == 1)
153 Draw_Chrono = !Draw_Chrono;
154 else
155 Draw_Chrono = (*a[1] == '1');
156
44fae8b1 157 if (Draw_Chrono) theDI << "Chronometers activated.\n";
54adc5e9 158 else theDI << "Chronometers deactivated.\n";
7fd59977 159 }
160 else {
161 Handle(Draw_Drawable3D) D = Draw::Get(a[1]);
162 Handle(Draw_Chronometer) C;
163 if (!D.IsNull()) {
164 C = Handle(Draw_Chronometer)::DownCast(D);
165 }
166 if (C.IsNull()) {
167 C = new Draw_Chronometer();
44fae8b1 168 Draw::Set(a[1],C,Standard_False);
7fd59977 169 }
170 if (n <= 2) {
171 C->Timer().Reset();
172 }
173 else {
44fae8b1 174 for (Standard_Integer anIter = 2; anIter < n; ++anIter)
175 {
176 TCollection_AsciiString anArg (a[anIter]);
177 anArg.LowerCase();
178
179 if (anArg == "reset")
180 {
181 C->Timer().Reset();
182 }
183 else if (anArg == "restart")
184 {
185 C->Timer().Restart();
186 }
187 else if (anArg == "start")
188 {
189 C->Timer().Start();
190 }
191 else if (anArg == "stop")
192 {
193 C->Timer().Stop();
194 }
195 else if (anArg == "show")
196 {
197 Standard_SStream ss;
198 C->Timer().Show(ss);
199 theDI << ss;
200 }
201 else if (anArg == "counter")
202 {
203 Standard_Real aSeconds,aCPUtime;
204 Standard_Integer aMinutes, aHours;
205 C->Timer().Show(aSeconds,aMinutes,aHours,aCPUtime);
206 theDI << "COUNTER " << a[++anIter] << ": " << aCPUtime << "\n";
207 }
208 else
209 {
210 theDI << "Unknown argument '" << a[anIter] << "'!\n";
211 }
7fd59977 212 }
213 }
214 }
215 return 0;
216}
217
218
219
220//=======================================================================
221//function : ifbatch
222//purpose :
223//=======================================================================
224
225static Standard_Integer ifbatch(Draw_Interpretor& DI, Standard_Integer , const char** )
226{
227 if (Draw_Batch)
228 DI << "1";
229 else
230 DI << "0";
231
232 return 0;
233}
234
235//=======================================================================
236//function : spy
237//purpose :
238//=======================================================================
239
240extern Standard_Boolean Draw_Spying;
04232180 241extern std::filebuf Draw_Spyfile;
7fd59977 242
243static Standard_Integer spy(Draw_Interpretor& di, Standard_Integer n, const char** a)
244{
245 if (Draw_Spying)
246 Draw_Spyfile.close();
247 Draw_Spying = Standard_False;
248 if (n > 1) {
04232180 249 if (!Draw_Spyfile.open(a[1],std::ios::out)) {
586db386 250 di << "Cannot open "<<a[1]<<" for writing\n";
7fd59977 251 return 1;
252 }
253 Draw_Spying = Standard_True;
254 }
255 return 0;
256}
257
aa02980d 258static Standard_Integer dlog(Draw_Interpretor& di, Standard_Integer n, const char** a)
259{
260 if (n != 2 && n != 3)
261 {
d99f0355 262 Message::SendFail() << "Enable or disable logging: " << a[0] << " {on|off}\n"
263 << "Reset log: " << a[0] << " reset\n"
264 << "Get log content: " << a[0] << " get";
aa02980d 265 return 1;
266 }
267
268 if (! strcmp (a[1], "on") && n == 2)
269 {
270 di.SetDoLog (Standard_True);
04232180 271// di.Log() << "dlog on" << std::endl; // for symmetry
aa02980d 272 }
273 else if (! strcmp (a[1], "off") && n == 2)
274 {
275 di.SetDoLog (Standard_False);
276 }
277 else if (! strcmp (a[1], "reset") && n == 2)
278 {
e05c25c1 279 di.ResetLog();
aa02980d 280 }
281 else if (! strcmp (a[1], "get") && n == 2)
282 {
e05c25c1 283 di << di.GetLog();
aa02980d 284 }
285 else if (! strcmp (a[1], "add") && n == 3)
286 {
e05c25c1 287 di.AddLog (a[2]);
288 di.AddLog ("\n");
289 }
290 else if (! strcmp (a[1], "status") && n == 2)
291 {
292 di << (di.GetDoLog() ? "on" : "off");
aa02980d 293 }
294 else {
d99f0355 295 Message::SendFail() << "Unrecognized option(s): " << a[1];
aa02980d 296 return 1;
297 }
298 return 0;
299}
300
301static Standard_Integer decho(Draw_Interpretor& di, Standard_Integer n, const char** a)
302{
303 if (n != 2)
304 {
d99f0355 305 Message::SendFail() << "Enable or disable echoing: " << a[0] << " {on|off}";
aa02980d 306 return 1;
307 }
308
309 if (! strcmp (a[1], "on"))
310 {
311 di.SetDoEcho (Standard_True);
312 }
313 else if (! strcmp (a[1], "off"))
314 {
315 di.SetDoEcho (Standard_False);
316 }
317 else {
d99f0355 318 Message::SendFail() << "Unrecognized option: " << a[1];
aa02980d 319 return 1;
320 }
321 return 0;
322}
323
8a262fa1 324static Standard_Integer dbreak(Draw_Interpretor& di, Standard_Integer, const char**)
325{
326 try {
327 OSD::ControlBreak();
328 }
a738b534 329 catch (OSD_Exception_CTRL_BREAK const&) {
8a262fa1 330 di << "User pressed Control-Break";
331 return 1; // Tcl exception
332 }
333
334 return 0;
335}
336
337static Standard_Integer dversion(Draw_Interpretor& di, Standard_Integer, const char**)
338{
339 // print OCCT version and OCCTY-specific macros used
340 di << "Open CASCADE Technology " << OCC_VERSION_STRING_EXT << "\n";
0797d9d3 341#ifdef OCCT_DEBUG
342 di << "Extended debug mode\n";
343#elif defined(_DEBUG)
8a262fa1 344 di << "Debug mode\n";
345#endif
87b68a0f 346#ifdef HAVE_TK
347 di << "Tk enabled (HAVE_TK)\n";
348#else
349 di << "Tk disabled\n";
350#endif
b69e576a 351#ifdef HAVE_XLIB
352 di << "Xlib enabled (HAVE_XLIB)\n";
353#elif !defined(_WIN32)
354 di << "Xlib disabled\n";
355#endif
8a262fa1 356#ifdef HAVE_TBB
357 di << "TBB enabled (HAVE_TBB)\n";
358#else
359 di << "TBB disabled\n";
360#endif
5c9493b3 361#ifdef HAVE_FREETYPE
362 di << "FreeType enabled (HAVE_FREETYPE)\n";
363#else
364 di << "FreeType disabled\n";
365#endif
8a262fa1 366#ifdef HAVE_FREEIMAGE
367 di << "FreeImage enabled (HAVE_FREEIMAGE)\n";
368#else
369 di << "FreeImage disabled\n";
370#endif
08f8a185 371#ifdef HAVE_FFMPEG
372 di << "FFmpeg enabled (HAVE_FFMPEG)\n";
373#else
374 di << "FFmpeg disabled\n";
375#endif
b8ef513c 376#ifdef HAVE_OPENGL_EXT
377 di << "OpenGL: enabled (HAVE_OPENGL_EXT)\n";
378#endif
379#ifdef HAVE_GLES2_EXT
380 di << "OpenGL ES: enabled (HAVE_GLES2_EXT)\n";
7ae4a307 381#endif
b40cdc2b 382#ifdef HAVE_OPENVR
383 di << "OpenVR enabled (HAVE_OPENVR)\n";
384#else
385 di << "OpenVR disabled\n";
386#endif
0a419c51 387#ifdef HAVE_RAPIDJSON
388 di << "RapidJSON enabled (HAVE_RAPIDJSON)\n";
389#else
390 di << "RapidJSON disabled\n";
391#endif
476e84b1 392#ifdef HAVE_VTK
393 di << "VTK enabled (HAVE_VTK)\n";
394#else
395 di << "VTK disabled\n";
396#endif
8a262fa1 397#ifdef No_Exception
398 di << "Exceptions disabled (No_Exception)\n";
399#else
400 di << "Exceptions enabled\n";
401#endif
402
403 // check compiler, OS, etc. using pre-processor macros provided by compiler
404 // see "Pre-defined C/C++ Compiler Macros" http://sourceforge.net/p/predef/wiki/
405 // note that only modern compilers that are known to be used for OCCT are recognized
406
407 // compiler; note that GCC and MSVC are last as other compilers (e.g. Intel) can also define __GNUC__ and _MSC_VER
408#if defined(__INTEL_COMPILER)
409 di << "Compiler: Intel " << __INTEL_COMPILER << "\n";
410#elif defined(__BORLANDC__)
411 di << "Compiler: Borland C++ (__BORLANDC__ = " << __BORLANDC__ << ")\n";
412#elif defined(__clang__)
413 di << "Compiler: Clang " << __clang_major__ << "." << __clang_minor__ << "." << __clang_patchlevel__ << "\n";
414#elif defined(__SUNPRO_C)
415 di << "Compiler: Sun Studio (__SUNPRO_C = " << __SUNPROC_C << ")\n";
416#elif defined(_MSC_VER)
f9f740d6 417 #if _MSC_VER < 1900
418 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";
419 #else
420 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";
421 #endif
8a262fa1 422#elif defined(__GNUC__)
423 di << "Compiler: GCC " << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__ << "\n";
424#else
425 di << "Compiler: unrecognized\n";
426#endif
427
428 // Cygwin and MinGW specifics
429#if defined(__CYGWIN__)
430 di << "Cygwin\n";
431#endif
432#if defined(__MINGW64__)
7c65581d 433 di << "MinGW 64 " << __MINGW64_VERSION_MAJOR << "." << __MINGW64_VERSION_MINOR << "\n";
8a262fa1 434#elif defined(__MINGW32__)
435 di << "MinGW 32 " << __MINGW32_MAJOR_VERSION << "." << __MINGW32_MINOR_VERSION << "\n";
436#endif
437
438 // architecture
439#if defined(__amd64) || defined(__x86_64) || defined(_M_AMD64)
440 di << "Architecture: AMD64\n";
441#elif defined(__i386) || defined(_M_IX86) || defined(__X86__)|| defined(_X86_)
442 di << "Architecture: Intel x86\n";
443#elif defined(_M_IA64) || defined(__ia64__)
444 di << "Architecture: Intel Itanium (IA 64)\n";
445#elif defined(__sparc__) || defined(__sparc)
446 di << "Architecture: SPARC\n";
fccc168a 447#elif defined(__aarch64__) && defined(__LP64__)
448 di << "Architecture: ARM 64-bit\n";
449#elif defined(__arm__) || defined(__arm64__)
450 #if defined(__LP64__)
451 di << "Architecture: ARM 64-bit\n";
452 #else
453 di << "Architecture: ARM 32-bit\n";
454 #endif
8a262fa1 455#else
456 di << "Architecture: unrecognized\n";
457#endif
458
459 // OS
460#if defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__)
461 di << "OS: Windows\n";
462#elif defined(__APPLE__) || defined(__MACH__)
463 di << "OS: Mac OS X\n";
464#elif defined(__sun)
465 di << "OS: SUN Solaris\n";
466#elif defined(__ANDROID__) /* must be before Linux */
467 #include <android/api-level.h>
468 di << "OS: Android (__ANDROID_API__ = " << __ANDROID_API__ << ")\n";
d8d01f6e 469#elif defined(__QNXNTO__)
470 di << "OS: QNX Neutrino\n";
471#elif defined(__QNX__)
472 di << "OS: QNX\n";
8a262fa1 473#elif defined(__linux__)
474 di << "OS: Linux\n";
475#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
476 #include <sys/param.h>
477 di << "OS: BSD (BSD = " << BSD << ")\n";
478#else
479 di << "OS: unrecognized\n";
480#endif
481
482 return 0;
483}
484
7fd59977 485//=======================================================================
486//function : wait
487//purpose :
488//=======================================================================
489
490static Standard_Integer Draw_wait(Draw_Interpretor& , Standard_Integer n, const char** a)
491{
492 Standard_Integer w = 10;
493 if (n > 1)
91322f44 494 w = Draw::Atoi(a[1]);
7fd59977 495 time_t ct = time(NULL) + w;
496 while (time(NULL) < ct) {};
497 return 0;
498}
499
47cbc555
A
500//=======================================================================
501//function : cpulimit
502//purpose :
503//=======================================================================
a60b9727 504#ifdef _WIN32
35e08fe8 505static unsigned int __stdcall CpuFunc (void * /*param*/)
47cbc555 506{
0b309a75 507 clock_t anElapCurrent;
47cbc555 508 clock_t aCurrent;
0b309a75 509
302f96fb 510 for(;;)
47cbc555
A
511 {
512 Sleep (5);
513 Standard_Real anUserSeconds, aSystemSeconds;
514 OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds);
515 aCurrent = clock_t(anUserSeconds + aSystemSeconds);
0b309a75 516 anElapCurrent = clock_t(aTimer.ElapsedTime());
47cbc555 517
d48df25d 518 if (CPU_LIMIT > 0 && (aCurrent - CPU_CURRENT) >= CPU_LIMIT)
47cbc555 519 {
0b309a75 520 aTimer.Stop();
667b5eb8 521 if (IsDebuggerPresent())
522 {
258a844b 523 std::cout << "Info: CPU limit (" << CPU_LIMIT << " sec) has been reached but ignored because of attached Debugger" << std::endl;
667b5eb8 524 return 0;
525 }
526 else
527 {
528 std::cout << "ERROR: Process killed by CPU limit (" << CPU_LIMIT << " sec)" << std::endl;
529 ExitProcess (2);
530 }
0b309a75 531 }
d48df25d 532 if (CPU_LIMIT > 0 && anElapCurrent >= CPU_LIMIT)
0b309a75 533 {
0b309a75 534 aTimer.Stop();
667b5eb8 535 if (IsDebuggerPresent())
536 {
258a844b 537 std::cout << "Info: Elapsed limit (" << CPU_LIMIT << " sec) has been reached but ignored because of attached Debugger" << std::endl;
667b5eb8 538 return 0;
539 }
540 else
541 {
542 std::cout << "ERROR: Process killed by elapsed limit (" << CPU_LIMIT << " sec)" << std::endl;
543 ExitProcess (2);
544 }
47cbc555
A
545 }
546 }
47cbc555 547}
a60b9727 548#else
0b309a75 549static void cpulimitSignalHandler (int)
a60b9727 550{
04232180 551 std::cout << "Process killed by CPU limit (" << CPU_LIMIT << " sec)" << std::endl;
a60b9727 552 exit(2);
553}
0b309a75 554static void *CpuFunc(void* /*threadarg*/)
555{
556 clock_t anElapCurrent;
557 for(;;)
558 {
559 sleep (5);
560 anElapCurrent = clock_t(aTimer.ElapsedTime());
d48df25d 561 if (CPU_LIMIT >0 && (anElapCurrent) >= CPU_LIMIT) {
04232180 562 std::cout << "Process killed by elapsed limit (" << CPU_LIMIT << " sec)" << std::endl;
0b309a75 563 exit(2);
564 }
565 }
566 return NULL;
567}
47cbc555 568#endif
7fd59977 569
f9797095 570// Returns time in seconds defined by the argument string,
571// multiplied by factor defined in environment variable
572// CSF_CPULIMIT_FACTOR (if it exists, 1 otherwise)
573static clock_t GetCpuLimit (const Standard_CString theParam)
35e08fe8 574{
f9797095 575 clock_t aValue = Draw::Atoi (theParam);
576
577 OSD_Environment aEnv("CSF_CPULIMIT_FACTOR");
578 TCollection_AsciiString aEnvStr = aEnv.Value();
579 if (!aEnvStr.IsEmpty())
580 {
581 aValue *= Draw::Atoi (aEnvStr.ToCString());
582 }
583 return aValue;
584}
585
7fd59977 586static Standard_Integer cpulimit(Draw_Interpretor& di, Standard_Integer n, const char** a)
587{
0b309a75 588 static int aFirst = 1;
a60b9727 589#ifdef _WIN32
590 // Windows specific code
47cbc555
A
591 unsigned int __stdcall CpuFunc (void *);
592 unsigned aThreadID;
593
0b309a75 594 if (n <= 1){
a60b9727 595 CPU_LIMIT = RLIM_INFINITY;
0b309a75 596 } else {
f9797095 597 CPU_LIMIT = GetCpuLimit (a[1]);
47cbc555
A
598 Standard_Real anUserSeconds, aSystemSeconds;
599 OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds);
a60b9727 600 CPU_CURRENT = clock_t(anUserSeconds + aSystemSeconds);
0b309a75 601 aTimer.Reset();
602 aTimer.Start();
47cbc555
A
603 if (aFirst) // Launch the thread only at the 1st call.
604 {
605 aFirst = 0;
606 _beginthreadex (NULL, 0, CpuFunc, NULL, 0, &aThreadID);
607 }
7fd59977 608 }
609
a60b9727 610#else
a60b9727 611 // Unix & Linux
a60b9727 612 rlimit rlp;
613 rlp.rlim_max = RLIM_INFINITY;
614 if (n <= 1)
615 rlp.rlim_cur = RLIM_INFINITY;
616 else
f9797095 617 rlp.rlim_cur = GetCpuLimit (a[1]);
a60b9727 618 CPU_LIMIT = rlp.rlim_cur;
619
620 int status;
621 status=setrlimit(RLIMIT_CPU,&rlp);
622 if (status !=0)
623 di << "status cpulimit setrlimit : " << status << "\n";
624
625 // set signal handler to print a message before death
626 struct sigaction act, oact;
627 memset (&act, 0, sizeof(act));
0b309a75 628 act.sa_handler = cpulimitSignalHandler;
a60b9727 629 sigaction (SIGXCPU, &act, &oact);
630
0b309a75 631 // cpulimit for elapsed time
632 aTimer.Reset();
633 aTimer.Start();
634 pthread_t cpulimitThread;
635 if (aFirst) // Launch the thread only at the 1st call.
636 {
637 aFirst = 0;
638 pthread_create(&cpulimitThread, NULL, CpuFunc, NULL);
639 }
7fd59977 640#endif
f9797095 641 di << "CPU and elapsed time limit set to " << (double)CPU_LIMIT << " seconds";
7fd59977 642 return 0;
643}
644
7af17f1e
MA
645//=======================================================================
646//function : mallochook
647//purpose :
648//=======================================================================
649
650static Standard_Integer mallochook(Draw_Interpretor& di, Standard_Integer n,
651 const char** a)
652{
653 if (n < 2)
654 {
655 di << "\
656usage: mallochook cmd\n\
657where cmd is one of:\n\
658 set [<op>] - set callback to malloc/free; op is one of the following:\n\
659 0 - set callback to NULL,\n\
660 1 - set callback OSD_MAllocHook::CollectBySize (default)\n\
661 2 - set callback OSD_MAllocHook::LogFileHandler\n\
662 reset - reset the CollectBySize handler\n\
663 report1 [<outfile>]\n\
664 - write report from CollectBySize handler in <outfile>\n\
665 open [<logfile>]\n\
666 - open file for writing the log with LogFileHandler\n\
667 close - close the log file with LogFileHandler\n\
668 report2 [<flag>] [<logfile>] [<outfile>]\n\
669 - scan <logfile> written with LogFileHandler\n\
670 and make synthesized report in <outfile>; <flag> can be:\n\
671 0 - simple stats by sizes (default),\n\
672 1 - with alive allocation numbers\n\
673By default <logfile> is \"mem-log.txt\", <outfile> is \"mem-stat.txt\""
674 << "\n";
675 return 0;
676 }
677 if (strcmp(a[1], "set") == 0)
678 {
91322f44 679 int aType = (n > 2 ? Draw::Atoi(a[2]) : 1);
7af17f1e
MA
680 if (aType < 0 || aType > 2)
681 {
586db386 682 di << "unknown op of the command set\n";
7af17f1e
MA
683 return 1;
684 }
685 else if (aType == 0)
686 {
687 OSD_MAllocHook::SetCallback(NULL);
586db386 688 di << "callback is unset\n";
7af17f1e
MA
689 }
690 else if (aType == 1)
691 {
692 OSD_MAllocHook::SetCallback(OSD_MAllocHook::GetCollectBySize());
586db386 693 di << "callback is set to CollectBySize\n";
7af17f1e
MA
694 }
695 else //if (aType == 2)
696 {
697 OSD_MAllocHook::SetCallback(OSD_MAllocHook::GetLogFileHandler());
586db386 698 di << "callback is set to LogFileHandler\n";
7af17f1e
MA
699 }
700 }
701 else if (strcmp(a[1], "reset") == 0)
702 {
703 OSD_MAllocHook::GetCollectBySize()->Reset();
586db386 704 di << "CollectBySize handler is reset\n";
7af17f1e
MA
705 }
706 else if (strcmp(a[1], "open") == 0)
707 {
708 const char* aFileName = (n > 2 ? a[2] : "mem-log.txt");
709 if (!OSD_MAllocHook::GetLogFileHandler()->Open(aFileName))
710 {
586db386 711 di << "cannot create file " << aFileName << " for writing\n";
7af17f1e
MA
712 return 1;
713 }
586db386 714 di << "log file " << aFileName << " is opened for writing\n";
7af17f1e
MA
715 }
716 else if (strcmp(a[1], "close") == 0)
717 {
718 OSD_MAllocHook::GetLogFileHandler()->Close();
586db386 719 di << "log file is closed\n";
7af17f1e
MA
720 }
721 else if (strcmp(a[1], "report1") == 0)
722 {
723 const char* aOutFile = "mem-stat.txt";
724 if (n > 2)
725 aOutFile = a[2];
726 if (OSD_MAllocHook::GetCollectBySize()->MakeReport(aOutFile))
727 {
586db386 728 di << "report " << aOutFile << " has been created\n";
7af17f1e
MA
729 }
730 else
731 {
732 di << "cannot create report " << aOutFile << "\n";
733 return 1;
734 }
735 }
736 else if (strcmp(a[1], "report2") == 0)
737 {
738 Standard_Boolean includeAlive = Standard_False;
739 const char* aLogFile = "mem-log.txt";
740 const char* aOutFile = "mem-stat.txt";
741 if (n > 2)
742 {
91322f44 743 includeAlive = (Draw::Atoi(a[2]) != 0);
7af17f1e
MA
744 if (n > 3)
745 {
746 aLogFile = a[3];
747 if (n > 4)
748 aOutFile = a[4];
749 }
750 }
751 if (OSD_MAllocHook::LogFileHandler::MakeReport(aLogFile, aOutFile, includeAlive))
752 {
586db386 753 di << "report " << aOutFile << " has been created\n";
7af17f1e
MA
754 }
755 else
756 {
757 di << "cannot create report " << aOutFile << " from the log file "
758 << aLogFile << "\n";
759 return 1;
760 }
761 }
762 else
763 {
764 di << "unrecognized command " << a[1] << "\n";
765 return 1;
766 }
767 return 0;
768}
769
91322f44 770//==============================================================================
771//function : dlocale
772//purpose :
773//==============================================================================
774
775static int dlocale (Draw_Interpretor& di, Standard_Integer n, const char** argv)
776{
777 int category = LC_ALL;
778 if (n > 1)
779 {
780 const char *cat = argv[1];
781 if ( ! strcmp (cat, "LC_ALL") ) category = LC_ALL;
782 else if ( ! strcmp (cat, "LC_COLLATE") ) category = LC_COLLATE;
783 else if ( ! strcmp (cat, "LC_CTYPE") ) category = LC_CTYPE;
784 else if ( ! strcmp (cat, "LC_MONETARY") ) category = LC_MONETARY;
785 else if ( ! strcmp (cat, "LC_NUMERIC") ) category = LC_NUMERIC;
786 else if ( ! strcmp (cat, "LC_TIME") ) category = LC_TIME;
787 else
788 {
d99f0355 789 Message::SendFail() << "Error: cannot recognize argument " << cat << " as one of LC_ macros";
91322f44 790 return 1;
791 }
792 }
793 const char* locale = (n > 2 ? argv[2] : NULL);
794 const char* result = setlocale (category, locale);
795 if (result)
796 di << result;
797 else
04232180 798 std::cout << "Error: unsupported locale specification: " << locale << std::endl;
91322f44 799 return 0;
800}
801
f0430952 802//==============================================================================
803//function : dmeminfo
804//purpose :
805//==============================================================================
806
807static int dmeminfo (Draw_Interpretor& theDI,
808 Standard_Integer theArgNb,
809 const char** theArgVec)
810{
f0430952 811 if (theArgNb <= 1)
812 {
1939cfd9 813 OSD_MemInfo aMemInfo;
f0430952 814 theDI << aMemInfo.ToString();
815 return 0;
816 }
817
1939cfd9 818 NCollection_Map<OSD_MemInfo::Counter> aCounters;
f0430952 819 for (Standard_Integer anIter = 1; anIter < theArgNb; ++anIter)
820 {
821 TCollection_AsciiString anArg (theArgVec[anIter]);
822 anArg.LowerCase();
823 if (anArg == "virt" || anArg == "v")
824 {
1939cfd9 825 aCounters.Add (OSD_MemInfo::MemVirtual);
f0430952 826 }
67a1064e 827 else if (anArg == "heap" || anArg == "h")
828 {
1939cfd9 829 aCounters.Add (OSD_MemInfo::MemHeapUsage);
67a1064e 830 }
f0430952 831 else if (anArg == "wset" || anArg == "w")
832 {
1939cfd9 833 aCounters.Add (OSD_MemInfo::MemWorkingSet);
f0430952 834 }
835 else if (anArg == "wsetpeak")
836 {
1939cfd9 837 aCounters.Add (OSD_MemInfo::MemWorkingSetPeak);
f0430952 838 }
839 else if (anArg == "swap")
840 {
1939cfd9 841 aCounters.Add (OSD_MemInfo::MemSwapUsage);
f0430952 842 }
843 else if (anArg == "swappeak")
844 {
1939cfd9 845 aCounters.Add (OSD_MemInfo::MemSwapUsagePeak);
f0430952 846 }
847 else if (anArg == "private")
848 {
1939cfd9 849 aCounters.Add (OSD_MemInfo::MemPrivate);
f0430952 850 }
851 else
852 {
853 std::cerr << "Unknown argument '" << theArgVec[anIter] << "'!\n";
854 }
855 }
1939cfd9 856
857 OSD_MemInfo aMemInfo (Standard_False);
858 aMemInfo.SetActive (Standard_False);
859 for (NCollection_Map<OSD_MemInfo::Counter>::Iterator aCountersIt (aCounters); aCountersIt.More(); aCountersIt.Next())
860 {
861 aMemInfo.SetActive (aCountersIt.Value(), Standard_True);
862 }
863 aMemInfo.Update();
864
865 for (NCollection_Map<OSD_MemInfo::Counter>::Iterator aCountersIt (aCounters); aCountersIt.More(); aCountersIt.Next())
866 {
867 theDI << Standard_Real (aMemInfo.Value (aCountersIt.Value())) << " ";
868 }
f0430952 869 theDI << "\n";
870 return 0;
871}
7fd59977 872
fc867b96 873//==============================================================================
874//function : dparallel
875//purpose :
876//==============================================================================
877static int dparallel (Draw_Interpretor& theDI,
878 Standard_Integer theArgNb,
879 const char** theArgVec)
880{
881 const Handle(OSD_ThreadPool)& aDefPool = OSD_ThreadPool::DefaultPool();
882 if (theArgNb <= 1)
883 {
884 theDI << "NbLogicalProcessors: " << OSD_Parallel::NbLogicalProcessors() << "\n"
885 << "NbThreads: " << aDefPool->NbThreads() << "\n"
886 << "NbDefThreads: " << aDefPool->NbDefaultThreadsToLaunch() << "\n"
887 << "UseOcct: " << (OSD_Parallel::ToUseOcctThreads() ? 1 : 0);
888 return 0;
889 }
890
891 for (Standard_Integer anIter = 1; anIter < theArgNb; ++anIter)
892 {
893 TCollection_AsciiString anArg (theArgVec[anIter]);
894 anArg.LowerCase();
895 if (anIter + 1 < theArgNb
896 && (anArg == "-nbthreads"
897 || anArg == "-threads"))
898 {
899 const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]);
900 aDefPool->Init (aVal);
901 }
902 else if (anIter + 1 < theArgNb
903 && (anArg == "-nbdefthreads"
904 || anArg == "-defthreads"
905 || anArg == "-nbmaxdefthreads"
906 || anArg == "-maxdefthreads"))
907 {
908 const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]);
909 if (aVal <= 0 || aVal > aDefPool->NbThreads())
910 {
d99f0355 911 Message::SendFail() << "Syntax error: maximum number of threads to use should be <= of threads in the pool";
fc867b96 912 return 1;
913 }
914 aDefPool->SetNbDefaultThreadsToLaunch (aVal);
915 }
916 else if (anIter + 1 < theArgNb
917 && (anArg == "-useocct"
918 || anArg == "-touseocct"
919 || anArg == "-occt"))
920 {
921 const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]);
922 OSD_Parallel::SetUseOcctThreads (aVal == 1);
923 if (OSD_Parallel::ToUseOcctThreads() != (aVal == 1))
924 {
925 std::cout << "Warning: unable to switch threads library - no options available\n";
926 }
927 }
928 else if (anIter + 1 < theArgNb
929 && (anArg == "-usetbb"
930 || anArg == "-tousetbb"
931 || anArg == "-tbb"))
932 {
933 const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]);
934 OSD_Parallel::SetUseOcctThreads (aVal == 0);
935 if (OSD_Parallel::ToUseOcctThreads() != (aVal == 0))
936 {
937 std::cout << "Warning: unable to switch threads library - no options available\n";
938 }
939 }
940 else
941 {
d99f0355 942 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
fc867b96 943 return 1;
944 }
945 }
946 return 0;
947}
948
618617fe 949//==============================================================================
950//function : dperf
951//purpose :
952//==============================================================================
953
954static int dperf (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
955{
956 // reset if argument is provided and it is not '0'
957 int reset = (theArgNb > 1 ? theArgVec[1][0] != '0' && theArgVec[1][0] != '\0' : 0);
958 char buffer[25600];
959 perf_sprint_all_meters (buffer, 25600 - 1, reset);
960 theDI << buffer;
961 return 0;
962}
963
f4dee9bb 964//==============================================================================
965//function : dsetsignal
966//purpose :
967//==============================================================================
968
969static int dsetsignal (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
970{
44b80414 971 OSD_SignalMode aMode = OSD_SignalMode_Set;
972 Standard_Boolean aSetFPE = OSD::ToCatchFloatingSignals();
7fb9d6d5 973 Standard_Integer aStackLen = OSD::SignalStackTraceLength();
44b80414 974
975 // default for FPE signal is defined by CSF_FPE variable, if set
976 OSD_Environment aEnv("CSF_FPE");
977 TCollection_AsciiString aEnvStr = aEnv.Value();
978 if (!aEnvStr.IsEmpty())
f4dee9bb 979 {
44b80414 980 aSetFPE = (aEnvStr.Value(1) != '0');
f4dee9bb 981 }
44b80414 982
983 // parse arguments
984 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
985 {
986 TCollection_AsciiString anArg(theArgVec[anArgIter]);
987 anArg.LowerCase();
988 if (anArg == "asis")
989 {
990 aMode = OSD_SignalMode_AsIs;
991 }
992 else if (anArg == "set")
993 {
994 aMode = OSD_SignalMode_Set;
995 }
996 else if (anArg == "unhandled")
997 {
998 aMode = OSD_SignalMode_SetUnhandled;
999 }
1000 else if (anArg == "unset")
1001 {
1002 aMode = OSD_SignalMode_Unset;
1003 }
1004 else if (anArg == "1" || anArg == "on")
1005 {
1006 aSetFPE = Standard_True;
1007 }
1008 else if (anArg == "0" || anArg == "off")
1009 {
1010 aSetFPE = Standard_False;
1011 }
1012 else if (anArg == "default")
1013 {
1014 }
7fb9d6d5 1015 else if (anArgIter + 1 < theArgNb
1016 && (anArg == "-stracktracelength"
1017 || anArg == "-stracktracelen"
1018 || anArg == "-stracklength"
1019 || anArg == "-stracklen"))
1020 {
1021 aStackLen = Draw::Atoi (theArgVec[++anArgIter]);
1022 }
44b80414 1023 else
1024 {
d99f0355 1025 Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'";
44b80414 1026 return 1;
1027 }
1028 }
1029
1030 OSD::SetSignal(aMode, aSetFPE);
7fb9d6d5 1031 OSD::SetSignalStackTraceLength (aStackLen);
44b80414 1032
1033 // report actual status in the end
1034 const char* aModeStr = 0;
1035 switch (OSD::SignalMode())
f4dee9bb 1036 {
7fb9d6d5 1037 default:
1038 case OSD_SignalMode_AsIs: aModeStr = "asis"; break;
1039 case OSD_SignalMode_Set: aModeStr = "set"; break;
1040 case OSD_SignalMode_SetUnhandled: aModeStr = "unhandled"; break;
1041 case OSD_SignalMode_Unset: aModeStr = "unset"; break;
f4dee9bb 1042 }
44b80414 1043 theDI << "Signal mode: " << aModeStr << "\n"
7fb9d6d5 1044 << "Catch FPE: " << (OSD::ToCatchFloatingSignals() ? "1" : "0") << "\n"
1045 << "Stack Trace Length: " << aStackLen << "\n";
f4dee9bb 1046 return 0;
1047}
1048
785a9540 1049//==============================================================================
1050//function : dtracelevel
1051//purpose :
1052//==============================================================================
1053
1054static int dtracelevel (Draw_Interpretor& theDI,
1055 Standard_Integer theArgNb,
1056 const char** theArgVec)
1057{
1058 Message_Gravity aLevel = Message_Info;
1059 if (theArgNb < 1 || theArgNb > 2)
1060 {
d99f0355 1061 Message::SendFail() << "Error: wrong number of arguments! See usage:";
785a9540 1062 theDI.PrintHelp (theArgVec[0]);
1063 return 1;
1064 }
1065 else if (theArgNb == 2)
1066 {
1067 TCollection_AsciiString aVal (theArgVec[1]);
1068 aVal.LowerCase();
1069 if (aVal == "trace")
1070 {
1071 aLevel = Message_Trace;
1072 }
1073 else if (aVal == "info")
1074 {
1075 aLevel = Message_Info;
1076 }
1077 else if (aVal == "warn"
1078 || aVal == "warning")
1079 {
1080 aLevel = Message_Warning;
1081 }
1082 else if (aVal == "alarm")
1083 {
1084 aLevel = Message_Alarm;
1085 }
1086 else if (aVal == "fail")
1087 {
1088 aLevel = Message_Fail;
1089 }
1090 else
1091 {
d99f0355 1092 Message::SendFail() << "Error: unknown gravity '" << theArgVec[1] << "'";
785a9540 1093 return 1;
1094 }
1095 }
1096
1097 Handle(Message_Messenger) aMessenger = Message::DefaultMessenger();
1098 if (aMessenger.IsNull())
1099 {
d99f0355 1100 Message::SendFail() << "Error: default messenger is unavailable";
785a9540 1101 return 1;
1102 }
1103
1104 Message_SequenceOfPrinters& aPrinters = aMessenger->ChangePrinters();
1105 if (aPrinters.Length() < 1)
1106 {
d99f0355 1107 Message::SendFail() << "Error: no printers registered in default Messenger";
785a9540 1108 return 0;
1109 }
1110
1111 for (Standard_Integer aPrinterIter = 1; aPrinterIter <= aPrinters.Length(); ++aPrinterIter)
1112 {
1113 Handle(Message_Printer)& aPrinter = aPrinters.ChangeValue (aPrinterIter);
1114 if (theArgNb == 1)
1115 {
1116 if (aPrinterIter == 1)
1117 {
1118 aLevel = aPrinter->GetTraceLevel();
1119 }
1120 else if (aLevel == aPrinter->GetTraceLevel())
1121 {
1122 continue;
1123 }
1124
1125 switch (aPrinter->GetTraceLevel())
1126 {
1127 case Message_Trace: theDI << "trace"; break;
1128 case Message_Info: theDI << "info"; break;
1129 case Message_Warning: theDI << "warn"; break;
1130 case Message_Alarm: theDI << "alarm"; break;
1131 case Message_Fail: theDI << "fail"; break;
1132 }
1133 continue;
1134 }
1135
1136 aPrinter->SetTraceLevel (aLevel);
1137 }
1138
1139 return 0;
1140}
1141
7fb9d6d5 1142//==============================================================================
1143//function : ddebugtraces
1144//purpose :
1145//==============================================================================
1146static int ddebugtraces (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
1147{
1148 if (theArgNb < 2)
1149 {
1150 theDI << Standard_Failure::DefaultStackTraceLength();
1151 return 0;
1152 }
1153 else if (theArgNb != 2)
1154 {
1155 theDI << "Syntax error: wrong number of arguments";
1156 return 1;
1157 }
1158
1159 Standard_Failure::SetDefaultStackTraceLength (Draw::Atoi (theArgVec[1]));
1160 return 0;
1161}
1162
63e5cfca 1163//==============================================================================
1164//function : dputs
1165//purpose :
1166//==============================================================================
d99f0355 1167static int dputs (Draw_Interpretor& theDI,
63e5cfca 1168 Standard_Integer theArgNb,
1169 const char** theArgVec)
1170{
1171 Standard_OStream* aStream = &std::cout;
1172 bool isNoNewline = false, toIntense = false;
1173 Message_ConsoleColor aColor = Message_ConsoleColor_Default;
1174 for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter)
1175 {
1176 TCollection_AsciiString anArg (theArgVec[anArgIter]);
1177 anArg.LowerCase();
1178 if (anArg == "-nonewline")
1179 {
1180 isNoNewline = true;
1181 }
1182 else if (anArg == "stdcout")
1183 {
1184 aStream = &std::cout;
1185 }
1186 else if (anArg == "stdcerr")
1187 {
1188 aStream = &std::cerr;
1189 }
1190 else if (anArg == "-intense")
1191 {
1192 toIntense = true;
1193 }
1194 else if (anArg == "-black")
1195 {
1196 aColor = Message_ConsoleColor_Black;
1197 }
1198 else if (anArg == "-white")
1199 {
1200 aColor = Message_ConsoleColor_White;
1201 }
1202 else if (anArg == "-red")
1203 {
1204 aColor = Message_ConsoleColor_Red;
1205 }
1206 else if (anArg == "-blue")
1207 {
1208 aColor = Message_ConsoleColor_Blue;
1209 }
1210 else if (anArg == "-green")
1211 {
1212 aColor = Message_ConsoleColor_Green;
1213 }
1214 else if (anArg == "-yellow")
1215 {
1216 aColor = Message_ConsoleColor_Yellow;
1217 }
1218 else if (anArg == "-cyan")
1219 {
1220 aColor = Message_ConsoleColor_Cyan;
1221 }
1222 else if (anArg == "-magenta")
1223 {
1224 aColor = Message_ConsoleColor_Magenta;
1225 }
1226 else if (anArgIter + 1 == theArgNb)
1227 {
d99f0355 1228 if (!theDI.ToColorize())
1229 {
1230 toIntense = false;
1231 aColor = Message_ConsoleColor_Default;
1232 }
63e5cfca 1233 if (toIntense || aColor != Message_ConsoleColor_Default)
1234 {
1235 Message_PrinterOStream::SetConsoleTextColor (aStream, aColor, toIntense);
1236 }
1237
1238 *aStream << theArgVec[anArgIter];
1239 if (!isNoNewline)
1240 {
1241 *aStream << std::endl;
1242 }
1243
1244 if (toIntense || aColor != Message_ConsoleColor_Default)
1245 {
1246 Message_PrinterOStream::SetConsoleTextColor (aStream, Message_ConsoleColor_Default, false);
1247 }
1248 return 0;
1249 }
1250 else
1251 {
1252 Message::SendFail() << "Syntax error at '" << anArg << "'";
1253 return 1;
1254 }
1255 }
1256
1257 Message::SendFail() << "Syntax error: wrong number of arguments";
1258 return 1;
1259}
1260
7fd59977 1261void Draw::BasicCommands(Draw_Interpretor& theCommands)
1262{
1263 static Standard_Boolean Done = Standard_False;
1264 if (Done) return;
1265 Done = Standard_True;
1266
04232180 1267 std::ios::sync_with_stdio();
aa02980d 1268
7fd59977 1269 const char* g = "DRAW General Commands";
785a9540 1270
7fd59977 1271 theCommands.Add("batch", "returns 1 in batch mode",
1272 __FILE__,ifbatch,g);
1273 theCommands.Add("spy","spy [file], Save commands in file. no file close",
1274 __FILE__,spy,g);
1275 theCommands.Add("wait","wait [time(10)], wait time seconds",
1276 __FILE__,Draw_wait,g);
1277 theCommands.Add("cpulimit","cpulimit [nbseconds], no args remove limits",
1278 __FILE__,cpulimit,g);
7d3225b5 1279 theCommands.Add("chrono","chrono [name action [action...]] \n Operates named timer.\n"
1280 " Supported actions: reset, start, stop, restart, show, counter [text].\n"
1281 " Without arguments enables / disables global timer for all DRAW commands.",
7fd59977 1282 __FILE__,chronom,g);
7d3225b5 1283 theCommands.Add("dchrono","see help of chrono command",
7fd59977 1284 __FILE__,dchronom,g);
7af17f1e
MA
1285 theCommands.Add("mallochook",
1286 "debug memory allocation/deallocation, w/o args for help",
1287 __FILE__, mallochook, g);
f0430952 1288 theCommands.Add ("meminfo",
67a1064e 1289 "meminfo [virt|v] [heap|h] [wset|w] [wsetpeak] [swap] [swappeak] [private]"
f0430952 1290 " : memory counters for this process",
1291 __FILE__, dmeminfo, g);
618617fe 1292 theCommands.Add("dperf","dperf [reset] -- show performance counters, reset if argument is provided",
1293 __FILE__,dperf,g);
7fb9d6d5 1294 theCommands.Add("dsetsignal",
1295 "dsetsignal [{asIs|set|unhandled|unset}=set] [{0|1|default=$CSF_FPE}]"
1296 "\n\t\t: [-strackTraceLength Length]"
1297 "\n\t\t: Sets OSD signal handler, with FPE option if argument is given."
1298 "\n\t\t: -strackTraceLength specifies length of stack trace to put into exceptions redirected from signals.",
f4dee9bb 1299 __FILE__,dsetsignal,g);
aa02980d 1300
fc867b96 1301 theCommands.Add("dparallel",
1302 "dparallel [-occt {0|1}] [-nbThreads Count] [-nbDefThreads Count]"
1303 "\n\t\t: Manages global parallelization parameters:"
1304 "\n\t\t: -occt use OCCT implementation or external library (if available)"
1305 "\n\t\t: -nbThreads specify the number of threads in default thread pool"
1306 "\n\t\t: -nbDefThreads specify the upper limit of threads to be used for default thread pool"
1307 "\n\t\t: within single parallelization call (should be <= of overall number of threads),"
1308 "\n\t\t: so that nested algorithm can also use this pool",
1309 __FILE__,dparallel,g);
1310
785a9540 1311 // Logging commands; note that their names are hard-coded in the code
aa02980d 1312 // of Draw_Interpretor, thus should not be changed without update of that code!
1313 theCommands.Add("dlog", "manage logging of commands and output; run without args to get help",
1314 __FILE__,dlog,g);
1315 theCommands.Add("decho", "switch on / off echo of commands to cout; run without args to get help",
1316 __FILE__,decho,g);
785a9540 1317 theCommands.Add("dtracelevel", "dtracelevel [trace|info|warn|alarm|fail]",
1318 __FILE__, dtracelevel, g);
7fb9d6d5 1319 theCommands.Add("ddebugtraces",
1320 "ddebugtraces nbTraces"
1321 "\n\t\t: Sets the number of lines for the stack trace within Standard_Failure constructor."
1322 "\n\t\t: Intended for debug purposes.",
1323 __FILE__, ddebugtraces, g);
785a9540 1324
8a262fa1 1325 theCommands.Add("dbreak", "raises Tcl exception if user has pressed Control-Break key",
1326 __FILE__,dbreak,g);
1327 theCommands.Add("dversion", "provides information on OCCT build configuration (version, compiler, OS, C library, etc.)",
1328 __FILE__,dversion,g);
91322f44 1329 theCommands.Add("dlocale", "set and / or query locate of C subsystem (function setlocale())",
1330 __FILE__,dlocale,g);
63e5cfca 1331
1332 theCommands.Add("dputs",
1333 "dputs [-intense] [-black|-white|-red|-green|-blue|-yellow|-cyan|-magenta]"
1334 "\n\t\t: [-nonewline] [stdcout|stdcerr] text"
1335 "\n\t\t: Puts text into console output",
1336 __FILE__,dputs,g);
7fd59977 1337}