0023818: Extend OSD_MemInfo to report C heap statistics
[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
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
7fd59977 21#include <Standard_Macro.hxx>
22#include <Standard_Stream.hxx>
23#include <Standard_SStream.hxx>
8a262fa1 24#include <Standard_Version.hxx>
7fd59977 25
26#include <Draw.ixx>
27#include <Draw_Appli.hxx>
a60b9727 28#include <Draw_Chronometer.hxx>
7fd59977 29#include <Draw_Printer.hxx>
30
31#include <Message.hxx>
32#include <Message_Messenger.hxx>
a60b9727 33
f0430952 34#include <OSD_MemInfo.hxx>
a60b9727 35#include <OSD_MAllocHook.hxx>
36#include <OSD_Chronometer.hxx>
8a262fa1 37#include <OSD.hxx>
38#include <OSD_Exception_CTRL_BREAK.hxx>
7fd59977 39
a60b9727 40#ifdef _WIN32
7fd59977 41
7fd59977 42#include <windows.h>
43#include <winbase.h>
44#include <process.h>
45#include <stdio.h>
46#include <stdlib.h>
a60b9727 47#include <time.h>
48#include <limits>
49
50#define RLIM_INFINITY 0x7fffffff
51
52static clock_t CPU_CURRENT; // cpu time already used at last
53 // cpulimit call. (sec.)
54
55#else /* _WIN32 */
56
57#include <sys/resource.h>
58
59#ifdef HAVE_CONFIG_H
60# include <config.h>
7fd59977 61#endif
62
a60b9727 63#ifdef HAVE_STRINGS_H
64# include <strings.h>
7fd59977 65#endif
66
a60b9727 67#if defined(HAVE_TIME_H)
68# include <time.h>
7fd59977 69#endif
70
a60b9727 71#ifdef HAVE_SIGNAL_H
72# include <signal.h>
73#endif
74
75#ifdef HAVE_SYS_SIGNAL_H
76# include <sys/signal.h>
77#endif
7fd59977 78
79#if defined (__hpux) || defined ( HPUX )
80#define RLIM_INFINITY 0x7fffffff
81#define RLIMIT_CPU 0
82#endif
83
a60b9727 84#endif /* _WIN32 */
7fd59977 85
a60b9727 86extern Standard_Boolean Draw_Batch;
87
88static clock_t CPU_LIMIT; // Cpu_limit in Sec.
7fd59977 89
90//=======================================================================
91// chronom
92//=======================================================================
93
94extern Standard_Boolean Draw_Chrono;
95
96static Standard_Integer chronom(Draw_Interpretor& di,
97 Standard_Integer n,const char** a)
98{
99 if ((n == 1) || (*a[1] == '0') || (*a[1] == '1')) {
100 if (n == 1)
101 Draw_Chrono = !Draw_Chrono;
102 else
103 Draw_Chrono = (*a[1] == '1');
104
105 if (Draw_Chrono) di << "Chronometers activated."<<"\n";
106 else di << "Chronometers desactivated."<<"\n";
107 }
108 else {
109 Handle(Draw_Drawable3D) D = Draw::Get(a[1]);
110 Handle(Draw_Chronometer) C;
111 if (!D.IsNull()) {
112 C = Handle(Draw_Chronometer)::DownCast(D);
113 }
114 if (C.IsNull()) {
115 C = new Draw_Chronometer();
116 Draw::Set(a[1],C,Standard_False);
117 }
118 if (n <= 2) {
119 C->Timer().Reset();
120 }
121 else {
122 if (!strcasecmp(a[2],"reset"))
123 C->Timer().Reset();
124 if (!strcasecmp(a[2],"start"))
125 C->Timer().Start();
126 if (!strcasecmp(a[2],"stop"))
127 C->Timer().Stop();
128 if (!strcasecmp(a[2],"show"))
129 C->Timer().Show();
130 }
131 }
132 return 0;
133}
134
135static Standard_Integer dchronom(Draw_Interpretor& I,
136 Standard_Integer n,const char** a)
137{
138 if ((n == 1) || (*a[1] == '0') || (*a[1] == '1')) {
139 if (n == 1)
140 Draw_Chrono = !Draw_Chrono;
141 else
142 Draw_Chrono = (*a[1] == '1');
143
144 if (Draw_Chrono) I << "Chronometers activated."<<"\n";
145 else I << "Chronometers desactivated."<<"\n";
146 }
147 else {
148 Handle(Draw_Drawable3D) D = Draw::Get(a[1]);
149 Handle(Draw_Chronometer) C;
150 if (!D.IsNull()) {
151 C = Handle(Draw_Chronometer)::DownCast(D);
152 }
153 if (C.IsNull()) {
154 C = new Draw_Chronometer();
155 Draw::Set(a[1],C,Standard_False);
156 }
157 if (n <= 2) {
158 C->Timer().Reset();
159 }
160 else {
161 if (!strcasecmp(a[2],"reset"))
162 C->Timer().Reset();
163 if (!strcasecmp(a[2],"start"))
164 C->Timer().Start();
165 if (!strcasecmp(a[2],"stop"))
166 C->Timer().Stop();
167 if (!strcasecmp(a[2],"show")) {
168 Standard_SStream ss;
169 C->Timer().Show(ss);
170 I << ss;
171 }
172 }
173 }
174 return 0;
175}
176
177
178
179//=======================================================================
180//function : ifbatch
181//purpose :
182//=======================================================================
183
184static Standard_Integer ifbatch(Draw_Interpretor& DI, Standard_Integer , const char** )
185{
186 if (Draw_Batch)
187 DI << "1";
188 else
189 DI << "0";
190
191 return 0;
192}
193
194//=======================================================================
195//function : spy
196//purpose :
197//=======================================================================
198
199extern Standard_Boolean Draw_Spying;
200extern filebuf Draw_Spyfile;
201
202static Standard_Integer spy(Draw_Interpretor& di, Standard_Integer n, const char** a)
203{
204 if (Draw_Spying)
205 Draw_Spyfile.close();
206 Draw_Spying = Standard_False;
207 if (n > 1) {
208 if (!Draw_Spyfile.open(a[1],ios::out)) {
209 di << "Cannot open "<<a[1]<<" for writing"<<"\n";
210 return 1;
211 }
212 Draw_Spying = Standard_True;
213 }
214 return 0;
215}
216
aa02980d 217static Standard_Integer dlog(Draw_Interpretor& di, Standard_Integer n, const char** a)
218{
219 if (n != 2 && n != 3)
220 {
221 cout << "Enable or disable logging: " << a[0] << " {on|off}" << endl;
222 cout << "Reset log: " << a[0] << " reset" << endl;
223 cout << "Get log content: " << a[0] << " get" << endl;
224 return 1;
225 }
226
227 if (! strcmp (a[1], "on") && n == 2)
228 {
229 di.SetDoLog (Standard_True);
230// di.Log() << "dlog on" << endl; // for symmetry
231 }
232 else if (! strcmp (a[1], "off") && n == 2)
233 {
234 di.SetDoLog (Standard_False);
235 }
236 else if (! strcmp (a[1], "reset") && n == 2)
237 {
238 di.Log().str("");
239 }
240 else if (! strcmp (a[1], "get") && n == 2)
241 {
242 di << di.Log().str().c_str();
243 }
244 else if (! strcmp (a[1], "add") && n == 3)
245 {
246 di.Log() << a[2] << "\n";
247 }
248 else {
249 cout << "Unrecognized option(s): " << a[1] << endl;
250 return 1;
251 }
252 return 0;
253}
254
255static Standard_Integer decho(Draw_Interpretor& di, Standard_Integer n, const char** a)
256{
257 if (n != 2)
258 {
259 cout << "Enable or disable echoing: " << a[0] << " {on|off}" << endl;
260 return 1;
261 }
262
263 if (! strcmp (a[1], "on"))
264 {
265 di.SetDoEcho (Standard_True);
266 }
267 else if (! strcmp (a[1], "off"))
268 {
269 di.SetDoEcho (Standard_False);
270 }
271 else {
272 cout << "Unrecognized option: " << a[1] << endl;
273 return 1;
274 }
275 return 0;
276}
277
8a262fa1 278static Standard_Integer dbreak(Draw_Interpretor& di, Standard_Integer, const char**)
279{
280 try {
281 OSD::ControlBreak();
282 }
283 catch (OSD_Exception_CTRL_BREAK) {
284 di << "User pressed Control-Break";
285 return 1; // Tcl exception
286 }
287
288 return 0;
289}
290
291static Standard_Integer dversion(Draw_Interpretor& di, Standard_Integer, const char**)
292{
293 // print OCCT version and OCCTY-specific macros used
294 di << "Open CASCADE Technology " << OCC_VERSION_STRING_EXT << "\n";
295#if defined(DEB) || defined(_DEBUG)
296 di << "Debug mode\n";
297#endif
298#ifdef HAVE_TBB
299 di << "TBB enabled (HAVE_TBB)\n";
300#else
301 di << "TBB disabled\n";
302#endif
303#ifdef HAVE_GL2PS
304 di << "GL2PS enabled (HAVE_GL2PS)\n";
305#else
306 di << "GL2PS disabled\n";
307#endif
308#ifdef HAVE_FREEIMAGE
309 di << "FreeImage enabled (HAVE_FREEIMAGE)\n";
310#else
311 di << "FreeImage disabled\n";
312#endif
313#ifdef No_Exception
314 di << "Exceptions disabled (No_Exception)\n";
315#else
316 di << "Exceptions enabled\n";
317#endif
318
319 // check compiler, OS, etc. using pre-processor macros provided by compiler
320 // see "Pre-defined C/C++ Compiler Macros" http://sourceforge.net/p/predef/wiki/
321 // note that only modern compilers that are known to be used for OCCT are recognized
322
323 // compiler; note that GCC and MSVC are last as other compilers (e.g. Intel) can also define __GNUC__ and _MSC_VER
324#if defined(__INTEL_COMPILER)
325 di << "Compiler: Intel " << __INTEL_COMPILER << "\n";
326#elif defined(__BORLANDC__)
327 di << "Compiler: Borland C++ (__BORLANDC__ = " << __BORLANDC__ << ")\n";
328#elif defined(__clang__)
329 di << "Compiler: Clang " << __clang_major__ << "." << __clang_minor__ << "." << __clang_patchlevel__ << "\n";
330#elif defined(__SUNPRO_C)
331 di << "Compiler: Sun Studio (__SUNPRO_C = " << __SUNPROC_C << ")\n";
332#elif defined(_MSC_VER)
333 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";
334#elif defined(__GNUC__)
335 di << "Compiler: GCC " << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__ << "\n";
336#else
337 di << "Compiler: unrecognized\n";
338#endif
339
340 // Cygwin and MinGW specifics
341#if defined(__CYGWIN__)
342 di << "Cygwin\n";
343#endif
344#if defined(__MINGW64__)
345 di << "MinGW 64 " << __MINGW64_MAJOR_VERSION << "." << __MINGW64_MINOR_VERSION << "\n";
346#elif defined(__MINGW32__)
347 di << "MinGW 32 " << __MINGW32_MAJOR_VERSION << "." << __MINGW32_MINOR_VERSION << "\n";
348#endif
349
350 // architecture
351#if defined(__amd64) || defined(__x86_64) || defined(_M_AMD64)
352 di << "Architecture: AMD64\n";
353#elif defined(__i386) || defined(_M_IX86) || defined(__X86__)|| defined(_X86_)
354 di << "Architecture: Intel x86\n";
355#elif defined(_M_IA64) || defined(__ia64__)
356 di << "Architecture: Intel Itanium (IA 64)\n";
357#elif defined(__sparc__) || defined(__sparc)
358 di << "Architecture: SPARC\n";
359#else
360 di << "Architecture: unrecognized\n";
361#endif
362
363 // OS
364#if defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__)
365 di << "OS: Windows\n";
366#elif defined(__APPLE__) || defined(__MACH__)
367 di << "OS: Mac OS X\n";
368#elif defined(__sun)
369 di << "OS: SUN Solaris\n";
370#elif defined(__ANDROID__) /* must be before Linux */
371 #include <android/api-level.h>
372 di << "OS: Android (__ANDROID_API__ = " << __ANDROID_API__ << ")\n";
373#elif defined(__linux__)
374 di << "OS: Linux\n";
375#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
376 #include <sys/param.h>
377 di << "OS: BSD (BSD = " << BSD << ")\n";
378#else
379 di << "OS: unrecognized\n";
380#endif
381
382 return 0;
383}
384
7fd59977 385//=======================================================================
386//function : wait
387//purpose :
388//=======================================================================
389
390static Standard_Integer Draw_wait(Draw_Interpretor& , Standard_Integer n, const char** a)
391{
392 Standard_Integer w = 10;
393 if (n > 1)
91322f44 394 w = Draw::Atoi(a[1]);
7fd59977 395 time_t ct = time(NULL) + w;
396 while (time(NULL) < ct) {};
397 return 0;
398}
399
47cbc555
A
400//=======================================================================
401//function : cpulimit
402//purpose :
403//=======================================================================
a60b9727 404#ifdef _WIN32
47cbc555
A
405static unsigned int __stdcall CpuFunc (void * param)
406{
407 clock_t aCurrent;
408 while (1)
409 {
410 Sleep (5);
411 Standard_Real anUserSeconds, aSystemSeconds;
412 OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds);
413 aCurrent = clock_t(anUserSeconds + aSystemSeconds);
414
a60b9727 415 if ((aCurrent - CPU_CURRENT) >= CPU_LIMIT)
47cbc555 416 {
a60b9727 417 cout << "Process killed by CPU limit (" << CPU_LIMIT << " sec)" << endl;
47cbc555
A
418 ExitProcess (2);
419 return 0;
420 }
421 }
422 return 0;
423}
a60b9727 424#else
425static void CpuFunc (int)
426{
427 cout << "Process killed by CPU limit (" << CPU_LIMIT << " sec)" << endl;
428 exit(2);
429}
47cbc555 430#endif
7fd59977 431
432static Standard_Integer cpulimit(Draw_Interpretor& di, Standard_Integer n, const char** a)
433{
a60b9727 434#ifdef _WIN32
435 // Windows specific code
7fd59977 436
47cbc555 437 static int aFirst = 1;
7fd59977 438
47cbc555
A
439 unsigned int __stdcall CpuFunc (void *);
440 unsigned aThreadID;
441
442 if (n <= 1)
a60b9727 443 CPU_LIMIT = RLIM_INFINITY;
47cbc555
A
444 else
445 {
91322f44 446 CPU_LIMIT = Draw::Atoi (a[1]);
47cbc555
A
447 Standard_Real anUserSeconds, aSystemSeconds;
448 OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds);
a60b9727 449 CPU_CURRENT = clock_t(anUserSeconds + aSystemSeconds);
47cbc555
A
450
451 if (aFirst) // Launch the thread only at the 1st call.
452 {
453 aFirst = 0;
454 _beginthreadex (NULL, 0, CpuFunc, NULL, 0, &aThreadID);
455 }
7fd59977 456 }
457
a60b9727 458#else
459
460 // Unix & Linux
461
462 rlimit rlp;
463 rlp.rlim_max = RLIM_INFINITY;
464 if (n <= 1)
465 rlp.rlim_cur = RLIM_INFINITY;
466 else
91322f44 467 rlp.rlim_cur = Draw::Atoi(a[1]);
a60b9727 468 CPU_LIMIT = rlp.rlim_cur;
469
470 int status;
471 status=setrlimit(RLIMIT_CPU,&rlp);
472 if (status !=0)
473 di << "status cpulimit setrlimit : " << status << "\n";
474
475 // set signal handler to print a message before death
476 struct sigaction act, oact;
477 memset (&act, 0, sizeof(act));
478 act.sa_handler = CpuFunc;
479 sigaction (SIGXCPU, &act, &oact);
480
7fd59977 481#endif
482
483 return 0;
484}
485
7af17f1e
MA
486//=======================================================================
487//function : mallochook
488//purpose :
489//=======================================================================
490
491static Standard_Integer mallochook(Draw_Interpretor& di, Standard_Integer n,
492 const char** a)
493{
494 if (n < 2)
495 {
496 di << "\
497usage: mallochook cmd\n\
498where cmd is one of:\n\
499 set [<op>] - set callback to malloc/free; op is one of the following:\n\
500 0 - set callback to NULL,\n\
501 1 - set callback OSD_MAllocHook::CollectBySize (default)\n\
502 2 - set callback OSD_MAllocHook::LogFileHandler\n\
503 reset - reset the CollectBySize handler\n\
504 report1 [<outfile>]\n\
505 - write report from CollectBySize handler in <outfile>\n\
506 open [<logfile>]\n\
507 - open file for writing the log with LogFileHandler\n\
508 close - close the log file with LogFileHandler\n\
509 report2 [<flag>] [<logfile>] [<outfile>]\n\
510 - scan <logfile> written with LogFileHandler\n\
511 and make synthesized report in <outfile>; <flag> can be:\n\
512 0 - simple stats by sizes (default),\n\
513 1 - with alive allocation numbers\n\
514By default <logfile> is \"mem-log.txt\", <outfile> is \"mem-stat.txt\""
515 << "\n";
516 return 0;
517 }
518 if (strcmp(a[1], "set") == 0)
519 {
91322f44 520 int aType = (n > 2 ? Draw::Atoi(a[2]) : 1);
7af17f1e
MA
521 if (aType < 0 || aType > 2)
522 {
523 di << "unknown op of the command set" << "\n";
524 return 1;
525 }
526 else if (aType == 0)
527 {
528 OSD_MAllocHook::SetCallback(NULL);
529 di << "callback is unset" << "\n";
530 }
531 else if (aType == 1)
532 {
533 OSD_MAllocHook::SetCallback(OSD_MAllocHook::GetCollectBySize());
534 di << "callback is set to CollectBySize" << "\n";
535 }
536 else //if (aType == 2)
537 {
538 OSD_MAllocHook::SetCallback(OSD_MAllocHook::GetLogFileHandler());
539 di << "callback is set to LogFileHandler" << "\n";
540 }
541 }
542 else if (strcmp(a[1], "reset") == 0)
543 {
544 OSD_MAllocHook::GetCollectBySize()->Reset();
545 di << "CollectBySize handler is reset" << "\n";
546 }
547 else if (strcmp(a[1], "open") == 0)
548 {
549 const char* aFileName = (n > 2 ? a[2] : "mem-log.txt");
550 if (!OSD_MAllocHook::GetLogFileHandler()->Open(aFileName))
551 {
552 di << "cannot create file " << aFileName << " for writing" << "\n";
553 return 1;
554 }
555 di << "log file " << aFileName << " is opened for writing" << "\n";
556 }
557 else if (strcmp(a[1], "close") == 0)
558 {
559 OSD_MAllocHook::GetLogFileHandler()->Close();
560 di << "log file is closed" << "\n";
561 }
562 else if (strcmp(a[1], "report1") == 0)
563 {
564 const char* aOutFile = "mem-stat.txt";
565 if (n > 2)
566 aOutFile = a[2];
567 if (OSD_MAllocHook::GetCollectBySize()->MakeReport(aOutFile))
568 {
569 di << "report " << aOutFile << " has been created" << "\n";
570 }
571 else
572 {
573 di << "cannot create report " << aOutFile << "\n";
574 return 1;
575 }
576 }
577 else if (strcmp(a[1], "report2") == 0)
578 {
579 Standard_Boolean includeAlive = Standard_False;
580 const char* aLogFile = "mem-log.txt";
581 const char* aOutFile = "mem-stat.txt";
582 if (n > 2)
583 {
91322f44 584 includeAlive = (Draw::Atoi(a[2]) != 0);
7af17f1e
MA
585 if (n > 3)
586 {
587 aLogFile = a[3];
588 if (n > 4)
589 aOutFile = a[4];
590 }
591 }
592 if (OSD_MAllocHook::LogFileHandler::MakeReport(aLogFile, aOutFile, includeAlive))
593 {
594 di << "report " << aOutFile << " has been created" << "\n";
595 }
596 else
597 {
598 di << "cannot create report " << aOutFile << " from the log file "
599 << aLogFile << "\n";
600 return 1;
601 }
602 }
603 else
604 {
605 di << "unrecognized command " << a[1] << "\n";
606 return 1;
607 }
608 return 0;
609}
610
91322f44 611//==============================================================================
612//function : dlocale
613//purpose :
614//==============================================================================
615
616static int dlocale (Draw_Interpretor& di, Standard_Integer n, const char** argv)
617{
618 int category = LC_ALL;
619 if (n > 1)
620 {
621 const char *cat = argv[1];
622 if ( ! strcmp (cat, "LC_ALL") ) category = LC_ALL;
623 else if ( ! strcmp (cat, "LC_COLLATE") ) category = LC_COLLATE;
624 else if ( ! strcmp (cat, "LC_CTYPE") ) category = LC_CTYPE;
625 else if ( ! strcmp (cat, "LC_MONETARY") ) category = LC_MONETARY;
626 else if ( ! strcmp (cat, "LC_NUMERIC") ) category = LC_NUMERIC;
627 else if ( ! strcmp (cat, "LC_TIME") ) category = LC_TIME;
628 else
629 {
630 cout << "Error: cannot recognize argument " << cat << " as one of LC_ macros" << endl;
631 return 1;
632 }
633 }
634 const char* locale = (n > 2 ? argv[2] : NULL);
635 const char* result = setlocale (category, locale);
636 if (result)
637 di << result;
638 else
639 cout << "Error: unsupported locale specification: " << locale << endl;
640 return 0;
641}
642
f0430952 643//==============================================================================
644//function : dmeminfo
645//purpose :
646//==============================================================================
647
648static int dmeminfo (Draw_Interpretor& theDI,
649 Standard_Integer theArgNb,
650 const char** theArgVec)
651{
652 OSD_MemInfo aMemInfo;
653 if (theArgNb <= 1)
654 {
655 theDI << aMemInfo.ToString();
656 return 0;
657 }
658
659 for (Standard_Integer anIter = 1; anIter < theArgNb; ++anIter)
660 {
661 TCollection_AsciiString anArg (theArgVec[anIter]);
662 anArg.LowerCase();
663 if (anArg == "virt" || anArg == "v")
664 {
665 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemVirtual)) << " ";
666 }
67a1064e 667 else if (anArg == "heap" || anArg == "h")
668 {
669 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemHeapUsage)) << " ";
670 }
f0430952 671 else if (anArg == "wset" || anArg == "w")
672 {
673 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemWorkingSet)) << " ";
674 }
675 else if (anArg == "wsetpeak")
676 {
677 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemWorkingSetPeak)) << " ";
678 }
679 else if (anArg == "swap")
680 {
681 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemSwapUsage)) << " ";
682 }
683 else if (anArg == "swappeak")
684 {
685 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemSwapUsagePeak)) << " ";
686 }
687 else if (anArg == "private")
688 {
689 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemPrivate)) << " ";
690 }
691 else
692 {
693 std::cerr << "Unknown argument '" << theArgVec[anIter] << "'!\n";
694 }
695 }
696 theDI << "\n";
697 return 0;
698}
7fd59977 699
700void Draw::BasicCommands(Draw_Interpretor& theCommands)
701{
702 static Standard_Boolean Done = Standard_False;
703 if (Done) return;
704 Done = Standard_True;
705
aa02980d 706 ios::sync_with_stdio();
707
7fd59977 708 const char* g = "DRAW General Commands";
709
710 theCommands.Add("batch", "returns 1 in batch mode",
711 __FILE__,ifbatch,g);
712 theCommands.Add("spy","spy [file], Save commands in file. no file close",
713 __FILE__,spy,g);
714 theCommands.Add("wait","wait [time(10)], wait time seconds",
715 __FILE__,Draw_wait,g);
716 theCommands.Add("cpulimit","cpulimit [nbseconds], no args remove limits",
717 __FILE__,cpulimit,g);
718 theCommands.Add("chrono","chrono [ name start/stop/reset/show]",
719 __FILE__,chronom,g);
720 theCommands.Add("dchrono","dchrono [ name start/stop/reset/show]",
721 __FILE__,dchronom,g);
7af17f1e
MA
722 theCommands.Add("mallochook",
723 "debug memory allocation/deallocation, w/o args for help",
724 __FILE__, mallochook, g);
f0430952 725 theCommands.Add ("meminfo",
67a1064e 726 "meminfo [virt|v] [heap|h] [wset|w] [wsetpeak] [swap] [swappeak] [private]"
f0430952 727 " : memory counters for this process",
728 __FILE__, dmeminfo, g);
aa02980d 729
730 // Logging commands; note that their names are hard-coded in the code
731 // of Draw_Interpretor, thus should not be changed without update of that code!
732 theCommands.Add("dlog", "manage logging of commands and output; run without args to get help",
733 __FILE__,dlog,g);
734 theCommands.Add("decho", "switch on / off echo of commands to cout; run without args to get help",
735 __FILE__,decho,g);
8a262fa1 736
737 theCommands.Add("dbreak", "raises Tcl exception if user has pressed Control-Break key",
738 __FILE__,dbreak,g);
739 theCommands.Add("dversion", "provides information on OCCT build configuration (version, compiler, OS, C library, etc.)",
740 __FILE__,dversion,g);
91322f44 741 theCommands.Add("dlocale", "set and / or query locate of C subsystem (function setlocale())",
742 __FILE__,dlocale,g);
7fd59977 743}