Commit | Line | Data |
---|---|---|
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 | ||
54 | static 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 | 69 | extern Standard_Boolean Draw_Batch; |
70 | ||
71 | static clock_t CPU_LIMIT; // Cpu_limit in Sec. | |
0b309a75 | 72 | static OSD_Timer aTimer; |
7fd59977 | 73 | |
74 | //======================================================================= | |
75 | // chronom | |
76 | //======================================================================= | |
77 | ||
78 | extern Standard_Boolean Draw_Chrono; | |
79 | ||
80 | static 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 | 148 | static 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 | ||
225 | static 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 | ||
240 | extern Standard_Boolean Draw_Spying; | |
04232180 | 241 | extern std::filebuf Draw_Spyfile; |
7fd59977 | 242 | |
243 | static 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 | 258 | static 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 | ||
301 | static 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 | 324 | static 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 | ||
337 | static 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 | ||
490 | static 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 | 505 | static 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 | 549 | static 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 | 554 | static 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) | |
573 | static 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 | 586 | static 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 | ||
650 | static Standard_Integer mallochook(Draw_Interpretor& di, Standard_Integer n, | |
651 | const char** a) | |
652 | { | |
653 | if (n < 2) | |
654 | { | |
655 | di << "\ | |
656 | usage: mallochook cmd\n\ | |
657 | where 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\ | |
673 | By 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 | ||
775 | static 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 | ||
807 | static 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 | //============================================================================== | |
877 | static 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 | ||
954 | static 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 | ||
969 | static 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 | ||
1054 | static 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 | //============================================================================== | |
1146 | static 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 | 1167 | static 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 | 1261 | void 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 | } |