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