0024275: Cppcheck warnings on uninitialized class members
[occt.git] / src / Draw / Draw_BasicCommands.cxx
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
21 #include <Standard_Macro.hxx>
22 #include <Standard_Stream.hxx>
23 #include <Standard_SStream.hxx>
24 #include <Standard_Version.hxx>
25
26 #include <Draw.ixx>
27 #include <Draw_Appli.hxx>
28 #include <Draw_Chronometer.hxx>
29 #include <Draw_Printer.hxx>
30
31 #include <Message.hxx>
32 #include <Message_Messenger.hxx>
33
34 #include <OSD_MemInfo.hxx>
35 #include <OSD_MAllocHook.hxx>
36 #include <OSD_Chronometer.hxx>
37 #include <OSD.hxx>
38 #include <OSD_Exception_CTRL_BREAK.hxx>
39
40 #ifdef _WIN32
41
42 #include <windows.h>
43 #include <winbase.h>
44 #include <process.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <time.h>
48 #include <limits>
49
50 #define RLIM_INFINITY   0x7fffffff
51
52 static 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>
61 #endif
62
63 #ifdef HAVE_STRINGS_H
64 # include <strings.h>
65 #endif
66
67 #if defined(HAVE_TIME_H)
68 # include <time.h>
69 #endif
70
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
78
79 #if defined (__hpux) || defined ( HPUX )
80 #define RLIM_INFINITY   0x7fffffff
81 #define RLIMIT_CPU      0
82 #endif
83
84 #endif /* _WIN32 */
85
86 extern Standard_Boolean Draw_Batch;
87
88 static clock_t CPU_LIMIT;   // Cpu_limit in Sec.
89
90 //=======================================================================
91 // chronom
92 //=======================================================================
93
94 extern Standard_Boolean Draw_Chrono;
95
96 static 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
135 static 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
184 static 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
199 extern Standard_Boolean Draw_Spying;
200 extern filebuf Draw_Spyfile;
201
202 static 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
217 static 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
255 static 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
278 static 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
291 static 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 HAVE_OPENCL
314   di << "OpenCL enabled (HAVE_OPENCL)\n";
315 #else
316   di << "OpenCL disabled\n";
317 #endif
318 #ifdef No_Exception
319   di << "Exceptions disabled (No_Exception)\n";
320 #else
321   di << "Exceptions enabled\n";
322 #endif
323
324   // check compiler, OS, etc. using pre-processor macros provided by compiler
325   // see "Pre-defined C/C++ Compiler Macros" http://sourceforge.net/p/predef/wiki/
326   // note that only modern compilers that are known to be used for OCCT are recognized
327
328   // compiler; note that GCC and MSVC are last as other compilers (e.g. Intel) can also define __GNUC__ and _MSC_VER
329 #if defined(__INTEL_COMPILER)
330   di << "Compiler: Intel " << __INTEL_COMPILER << "\n";
331 #elif defined(__BORLANDC__)
332   di << "Compiler: Borland C++ (__BORLANDC__ = " << __BORLANDC__ << ")\n";
333 #elif defined(__clang__)
334   di << "Compiler: Clang " << __clang_major__ << "." << __clang_minor__ << "." << __clang_patchlevel__ << "\n";
335 #elif defined(__SUNPRO_C)
336   di << "Compiler: Sun Studio (__SUNPRO_C = " << __SUNPROC_C << ")\n";
337 #elif defined(_MSC_VER)
338   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";
339 #elif defined(__GNUC__)
340   di << "Compiler: GCC " << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__ << "\n";
341 #else
342   di << "Compiler: unrecognized\n";
343 #endif
344
345   // Cygwin and MinGW specifics
346 #if defined(__CYGWIN__)
347   di << "Cygwin\n";
348 #endif
349 #if defined(__MINGW64__)
350   di << "MinGW 64 " << __MINGW64_MAJOR_VERSION << "." << __MINGW64_MINOR_VERSION << "\n";
351 #elif defined(__MINGW32__)
352   di << "MinGW 32 " << __MINGW32_MAJOR_VERSION << "." << __MINGW32_MINOR_VERSION << "\n";
353 #endif 
354
355   // architecture
356 #if defined(__amd64) || defined(__x86_64) || defined(_M_AMD64)
357   di << "Architecture: AMD64\n";
358 #elif defined(__i386) || defined(_M_IX86) || defined(__X86__)|| defined(_X86_)
359   di << "Architecture: Intel x86\n";
360 #elif defined(_M_IA64) || defined(__ia64__)
361   di << "Architecture: Intel Itanium (IA 64)\n";
362 #elif defined(__sparc__) || defined(__sparc)
363   di << "Architecture: SPARC\n";
364 #else
365   di << "Architecture: unrecognized\n";
366 #endif
367
368   // OS
369 #if defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__)
370   di << "OS: Windows\n";
371 #elif defined(__APPLE__) || defined(__MACH__)
372   di << "OS: Mac OS X\n";
373 #elif defined(__sun) 
374   di << "OS: SUN Solaris\n";
375 #elif defined(__ANDROID__) /* must be before Linux */
376   #include <android/api-level.h>
377   di << "OS: Android (__ANDROID_API__ = " << __ANDROID_API__ << ")\n";
378 #elif defined(__linux__)
379   di << "OS: Linux\n";
380 #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
381   #include <sys/param.h>
382   di << "OS: BSD (BSD = " << BSD << ")\n";
383 #else
384   di << "OS: unrecognized\n";
385 #endif
386
387   return 0;
388 }
389
390 //=======================================================================
391 //function : wait
392 //purpose  : 
393 //=======================================================================
394
395 static Standard_Integer Draw_wait(Draw_Interpretor& , Standard_Integer n, const char** a)
396 {
397   Standard_Integer w = 10;
398   if (n > 1)
399     w = Draw::Atoi(a[1]);
400   time_t ct = time(NULL) + w;
401   while (time(NULL) < ct) {};
402   return 0;
403 }
404
405 //=======================================================================
406 //function : cpulimit
407 //purpose  : 
408 //=======================================================================
409 #ifdef _WIN32
410 static unsigned int __stdcall CpuFunc (void * /*param*/)
411 {
412   clock_t aCurrent;
413   for(;;)
414   {
415     Sleep (5);
416     Standard_Real anUserSeconds, aSystemSeconds;
417     OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds);
418     aCurrent = clock_t(anUserSeconds + aSystemSeconds);
419     
420     if ((aCurrent - CPU_CURRENT) >= CPU_LIMIT)
421     {
422       cout << "Process killed by CPU limit (" << CPU_LIMIT << " sec)" << endl;
423       ExitProcess (2);
424 //      return 0;
425     }
426   }
427 }
428 #else
429 static void CpuFunc (int)
430 {
431   cout << "Process killed by CPU limit (" << CPU_LIMIT << " sec)" << endl;
432   exit(2);
433 }
434 #endif
435
436 #ifdef _WIN32
437 static Standard_Integer cpulimit(Draw_Interpretor&, Standard_Integer n, const char** a)
438 {
439 #else
440 static Standard_Integer cpulimit(Draw_Interpretor& di, Standard_Integer n, const char** a)
441 {
442 #endif
443 #ifdef _WIN32
444   // Windows specific code
445
446   static int aFirst = 1;
447
448   unsigned int __stdcall CpuFunc (void *);
449   unsigned aThreadID;
450
451   if (n <= 1)
452     CPU_LIMIT = RLIM_INFINITY;
453   else
454   {
455     CPU_LIMIT = Draw::Atoi (a[1]);
456     Standard_Real anUserSeconds, aSystemSeconds;
457     OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds);
458     CPU_CURRENT = clock_t(anUserSeconds + aSystemSeconds);
459
460     if (aFirst) // Launch the thread only at the 1st call.
461     {
462       aFirst = 0;
463       _beginthreadex (NULL, 0, CpuFunc, NULL, 0, &aThreadID);
464     }
465   }
466
467 #else 
468
469   // Unix & Linux
470
471   rlimit rlp;
472   rlp.rlim_max = RLIM_INFINITY;
473   if (n <= 1)
474     rlp.rlim_cur = RLIM_INFINITY;
475   else
476     rlp.rlim_cur = Draw::Atoi(a[1]);
477   CPU_LIMIT = rlp.rlim_cur;
478
479   int status;
480   status=setrlimit(RLIMIT_CPU,&rlp);
481   if (status !=0)
482     di << "status cpulimit setrlimit : " << status << "\n";
483
484   // set signal handler to print a message before death
485   struct sigaction act, oact;
486   memset (&act, 0, sizeof(act));
487   act.sa_handler = CpuFunc;
488   sigaction (SIGXCPU, &act, &oact);
489
490 #endif
491
492   return 0;
493 }
494
495 //=======================================================================
496 //function : mallochook
497 //purpose  : 
498 //=======================================================================
499
500 static Standard_Integer mallochook(Draw_Interpretor& di, Standard_Integer n,
501                                    const char** a)
502 {
503   if (n < 2)
504   {
505     di << "\
506 usage: mallochook cmd\n\
507 where cmd is one of:\n\
508   set [<op>]      - set callback to malloc/free; op is one of the following:\n\
509                     0 - set callback to NULL,\n\
510                     1 - set callback OSD_MAllocHook::CollectBySize (default)\n\
511                     2 - set callback OSD_MAllocHook::LogFileHandler\n\
512   reset           - reset the CollectBySize handler\n\
513   report1 [<outfile>]\n\
514                   - write report from CollectBySize handler in <outfile>\n\
515   open [<logfile>]\n\
516                   - open file for writing the log with LogFileHandler\n\
517   close           - close the log file with LogFileHandler\n\
518   report2 [<flag>] [<logfile>] [<outfile>]\n\
519                   - scan <logfile> written with LogFileHandler\n\
520                     and make synthesized report in <outfile>; <flag> can be:\n\
521                     0 - simple stats by sizes (default),\n\
522                     1 - with alive allocation numbers\n\
523 By default <logfile> is \"mem-log.txt\", <outfile> is \"mem-stat.txt\""
524       << "\n";
525     return 0;
526   }
527   if (strcmp(a[1], "set") == 0)
528   {
529     int aType = (n > 2 ? Draw::Atoi(a[2]) : 1);
530     if (aType < 0 || aType > 2)
531     {
532       di << "unknown op of the command set" << "\n";
533       return 1;
534     }
535     else if (aType == 0)
536     {
537       OSD_MAllocHook::SetCallback(NULL);
538       di << "callback is unset" << "\n";
539     }
540     else if (aType == 1)
541     {
542       OSD_MAllocHook::SetCallback(OSD_MAllocHook::GetCollectBySize());
543       di << "callback is set to CollectBySize" << "\n";
544     }
545     else //if (aType == 2)
546     {
547       OSD_MAllocHook::SetCallback(OSD_MAllocHook::GetLogFileHandler());
548       di << "callback is set to LogFileHandler" << "\n";
549     }
550   }
551   else if (strcmp(a[1], "reset") == 0)
552   {
553     OSD_MAllocHook::GetCollectBySize()->Reset();
554     di << "CollectBySize handler is reset" << "\n";
555   }
556   else if (strcmp(a[1], "open") == 0)
557   {
558     const char* aFileName = (n > 2 ? a[2] : "mem-log.txt");
559     if (!OSD_MAllocHook::GetLogFileHandler()->Open(aFileName))
560     {
561       di << "cannot create file " << aFileName << " for writing" << "\n";
562       return 1;
563     }
564     di << "log file " << aFileName << " is opened for writing" << "\n";
565   }
566   else if (strcmp(a[1], "close") == 0)
567   {
568     OSD_MAllocHook::GetLogFileHandler()->Close();
569     di << "log file is closed" << "\n";
570   }
571   else if (strcmp(a[1], "report1") == 0)
572   {
573     const char* aOutFile = "mem-stat.txt";
574     if (n > 2)
575       aOutFile = a[2];
576     if (OSD_MAllocHook::GetCollectBySize()->MakeReport(aOutFile))
577     {
578       di << "report " << aOutFile << " has been created" << "\n";
579     }
580     else
581     {
582       di << "cannot create report " << aOutFile << "\n";
583       return 1;
584     }
585   }
586   else if (strcmp(a[1], "report2") == 0)
587   {
588     Standard_Boolean includeAlive = Standard_False;
589     const char* aLogFile = "mem-log.txt";
590     const char* aOutFile = "mem-stat.txt";
591     if (n > 2)
592     {
593       includeAlive = (Draw::Atoi(a[2]) != 0);
594       if (n > 3)
595       {
596         aLogFile = a[3];
597         if (n > 4)
598           aOutFile = a[4];
599       }
600     }
601     if (OSD_MAllocHook::LogFileHandler::MakeReport(aLogFile, aOutFile, includeAlive))
602     {
603       di << "report " << aOutFile << " has been created" << "\n";
604     }
605     else
606     {
607       di << "cannot create report " << aOutFile << " from the log file "
608         << aLogFile << "\n";
609       return 1;
610     }
611   }
612   else
613   {
614     di << "unrecognized command " << a[1] << "\n";
615     return 1;
616   }
617   return 0;
618 }
619
620 //==============================================================================
621 //function : dlocale
622 //purpose  :
623 //==============================================================================
624
625 static int dlocale (Draw_Interpretor& di, Standard_Integer n, const char** argv)
626 {
627   int category = LC_ALL;
628   if (n > 1)
629   {
630     const char *cat = argv[1];
631     if ( ! strcmp (cat, "LC_ALL") ) category = LC_ALL;
632     else if ( ! strcmp (cat, "LC_COLLATE") ) category = LC_COLLATE;
633     else if ( ! strcmp (cat, "LC_CTYPE") ) category = LC_CTYPE;
634     else if ( ! strcmp (cat, "LC_MONETARY") ) category = LC_MONETARY;
635     else if ( ! strcmp (cat, "LC_NUMERIC") ) category = LC_NUMERIC;
636     else if ( ! strcmp (cat, "LC_TIME") ) category = LC_TIME;
637     else 
638     {
639       cout << "Error: cannot recognize argument " << cat << " as one of LC_ macros" << endl;
640       return 1;
641     }
642   }
643   const char* locale = (n > 2 ? argv[2] : NULL);
644   const char* result = setlocale (category, locale);
645   if (result)
646     di << result;
647   else 
648     cout << "Error: unsupported locale specification: " << locale << endl;
649   return 0;
650 }
651
652 //==============================================================================
653 //function : dmeminfo
654 //purpose  :
655 //==============================================================================
656
657 static int dmeminfo (Draw_Interpretor& theDI,
658                      Standard_Integer  theArgNb,
659                      const char**      theArgVec)
660 {
661   OSD_MemInfo aMemInfo;
662   if (theArgNb <= 1)
663   {
664     theDI << aMemInfo.ToString();
665     return 0;
666   }
667
668   for (Standard_Integer anIter = 1; anIter < theArgNb; ++anIter)
669   {
670     TCollection_AsciiString anArg (theArgVec[anIter]);
671     anArg.LowerCase();
672     if (anArg == "virt" || anArg == "v")
673     {
674       theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemVirtual)) << " ";
675     }
676     else if (anArg == "heap" || anArg == "h")
677     {
678       theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemHeapUsage)) << " ";
679     }
680     else if (anArg == "wset" || anArg == "w")
681     {
682       theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemWorkingSet)) << " ";
683     }
684     else if (anArg == "wsetpeak")
685     {
686       theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemWorkingSetPeak)) << " ";
687     }
688     else if (anArg == "swap")
689     {
690       theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemSwapUsage)) << " ";
691     }
692     else if (anArg == "swappeak")
693     {
694       theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemSwapUsagePeak)) << " ";
695     }
696     else if (anArg == "private")
697     {
698       theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemPrivate)) << " ";
699     }
700     else
701     {
702       std::cerr << "Unknown argument '" << theArgVec[anIter] << "'!\n";
703     }
704   }
705   theDI << "\n";
706   return 0;
707 }
708
709 void Draw::BasicCommands(Draw_Interpretor& theCommands)
710 {
711   static Standard_Boolean Done = Standard_False;
712   if (Done) return;
713   Done = Standard_True;
714
715   ios::sync_with_stdio();
716
717   const char* g = "DRAW General Commands";
718   
719   theCommands.Add("batch", "returns 1 in batch mode",
720                   __FILE__,ifbatch,g);
721   theCommands.Add("spy","spy [file], Save commands in file. no file close",
722                   __FILE__,spy,g);
723   theCommands.Add("wait","wait [time(10)], wait time seconds",
724                   __FILE__,Draw_wait,g);
725   theCommands.Add("cpulimit","cpulimit [nbseconds], no args remove limits",
726                   __FILE__,cpulimit,g);
727   theCommands.Add("chrono","chrono [ name start/stop/reset/show]",
728                   __FILE__,chronom,g);
729   theCommands.Add("dchrono","dchrono [ name start/stop/reset/show]",
730                   __FILE__,dchronom,g);
731   theCommands.Add("mallochook",
732                   "debug memory allocation/deallocation, w/o args for help",
733                   __FILE__, mallochook, g);
734   theCommands.Add ("meminfo",
735     "meminfo [virt|v] [heap|h] [wset|w] [wsetpeak] [swap] [swappeak] [private]"
736     " : memory counters for this process",
737           __FILE__, dmeminfo, g);
738
739   // Logging commands; note that their names are hard-coded in the code 
740   // of Draw_Interpretor, thus should not be changed without update of that code!
741   theCommands.Add("dlog", "manage logging of commands and output; run without args to get help",
742                   __FILE__,dlog,g);
743   theCommands.Add("decho", "switch on / off echo of commands to cout; run without args to get help",
744                   __FILE__,decho,g);
745   
746   theCommands.Add("dbreak", "raises Tcl exception if user has pressed Control-Break key",
747                   __FILE__,dbreak,g);
748   theCommands.Add("dversion", "provides information on OCCT build configuration (version, compiler, OS, C library, etc.)",
749                   __FILE__,dversion,g);
750   theCommands.Add("dlocale", "set and / or query locate of C subsystem (function setlocale())",
751                   __FILE__,dlocale,g);
752 }