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 | |
a34bddcf | 455 | #elif defined(__EMSCRIPTEN__) |
456 | #if defined(__LP64__) | |
457 | di << "Architecture: WASM 64-bit\n"; | |
458 | #else | |
459 | di << "Architecture: WASM 32-bit\n"; | |
460 | #endif | |
8a262fa1 | 461 | #else |
462 | di << "Architecture: unrecognized\n"; | |
463 | #endif | |
464 | ||
465 | // OS | |
466 | #if defined(_WIN32) || defined(__WINDOWS__) || defined(__WIN32__) | |
467 | di << "OS: Windows\n"; | |
468 | #elif defined(__APPLE__) || defined(__MACH__) | |
469 | di << "OS: Mac OS X\n"; | |
470 | #elif defined(__sun) | |
471 | di << "OS: SUN Solaris\n"; | |
472 | #elif defined(__ANDROID__) /* must be before Linux */ | |
473 | #include <android/api-level.h> | |
474 | di << "OS: Android (__ANDROID_API__ = " << __ANDROID_API__ << ")\n"; | |
d8d01f6e | 475 | #elif defined(__QNXNTO__) |
476 | di << "OS: QNX Neutrino\n"; | |
477 | #elif defined(__QNX__) | |
478 | di << "OS: QNX\n"; | |
8a262fa1 | 479 | #elif defined(__linux__) |
480 | di << "OS: Linux\n"; | |
481 | #elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__) | |
482 | #include <sys/param.h> | |
483 | di << "OS: BSD (BSD = " << BSD << ")\n"; | |
a34bddcf | 484 | #elif defined(__EMSCRIPTEN__) |
485 | di << "OS: WebAssembly (Emscripten SDK " << __EMSCRIPTEN_major__ << "." << __EMSCRIPTEN_minor__ << "." << __EMSCRIPTEN_tiny__ << ")\n"; | |
8a262fa1 | 486 | #else |
487 | di << "OS: unrecognized\n"; | |
488 | #endif | |
489 | ||
490 | return 0; | |
491 | } | |
492 | ||
7fd59977 | 493 | //======================================================================= |
494 | //function : wait | |
495 | //purpose : | |
496 | //======================================================================= | |
497 | ||
498 | static Standard_Integer Draw_wait(Draw_Interpretor& , Standard_Integer n, const char** a) | |
499 | { | |
500 | Standard_Integer w = 10; | |
501 | if (n > 1) | |
91322f44 | 502 | w = Draw::Atoi(a[1]); |
7fd59977 | 503 | time_t ct = time(NULL) + w; |
504 | while (time(NULL) < ct) {}; | |
505 | return 0; | |
506 | } | |
507 | ||
47cbc555 A |
508 | //======================================================================= |
509 | //function : cpulimit | |
510 | //purpose : | |
511 | //======================================================================= | |
a60b9727 | 512 | #ifdef _WIN32 |
35e08fe8 | 513 | static unsigned int __stdcall CpuFunc (void * /*param*/) |
47cbc555 | 514 | { |
0b309a75 | 515 | clock_t anElapCurrent; |
47cbc555 | 516 | clock_t aCurrent; |
0b309a75 | 517 | |
302f96fb | 518 | for(;;) |
47cbc555 A |
519 | { |
520 | Sleep (5); | |
521 | Standard_Real anUserSeconds, aSystemSeconds; | |
522 | OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds); | |
523 | aCurrent = clock_t(anUserSeconds + aSystemSeconds); | |
0b309a75 | 524 | anElapCurrent = clock_t(aTimer.ElapsedTime()); |
47cbc555 | 525 | |
d48df25d | 526 | if (CPU_LIMIT > 0 && (aCurrent - CPU_CURRENT) >= CPU_LIMIT) |
47cbc555 | 527 | { |
0b309a75 | 528 | aTimer.Stop(); |
667b5eb8 | 529 | if (IsDebuggerPresent()) |
530 | { | |
258a844b | 531 | std::cout << "Info: CPU limit (" << CPU_LIMIT << " sec) has been reached but ignored because of attached Debugger" << std::endl; |
667b5eb8 | 532 | return 0; |
533 | } | |
534 | else | |
535 | { | |
536 | std::cout << "ERROR: Process killed by CPU limit (" << CPU_LIMIT << " sec)" << std::endl; | |
537 | ExitProcess (2); | |
538 | } | |
0b309a75 | 539 | } |
d48df25d | 540 | if (CPU_LIMIT > 0 && anElapCurrent >= CPU_LIMIT) |
0b309a75 | 541 | { |
0b309a75 | 542 | aTimer.Stop(); |
667b5eb8 | 543 | if (IsDebuggerPresent()) |
544 | { | |
258a844b | 545 | std::cout << "Info: Elapsed limit (" << CPU_LIMIT << " sec) has been reached but ignored because of attached Debugger" << std::endl; |
667b5eb8 | 546 | return 0; |
547 | } | |
548 | else | |
549 | { | |
550 | std::cout << "ERROR: Process killed by elapsed limit (" << CPU_LIMIT << " sec)" << std::endl; | |
551 | ExitProcess (2); | |
552 | } | |
47cbc555 A |
553 | } |
554 | } | |
47cbc555 | 555 | } |
a60b9727 | 556 | #else |
0b309a75 | 557 | static void cpulimitSignalHandler (int) |
a60b9727 | 558 | { |
04232180 | 559 | std::cout << "Process killed by CPU limit (" << CPU_LIMIT << " sec)" << std::endl; |
a60b9727 | 560 | exit(2); |
561 | } | |
0b309a75 | 562 | static void *CpuFunc(void* /*threadarg*/) |
563 | { | |
564 | clock_t anElapCurrent; | |
565 | for(;;) | |
566 | { | |
567 | sleep (5); | |
568 | anElapCurrent = clock_t(aTimer.ElapsedTime()); | |
d48df25d | 569 | if (CPU_LIMIT >0 && (anElapCurrent) >= CPU_LIMIT) { |
04232180 | 570 | std::cout << "Process killed by elapsed limit (" << CPU_LIMIT << " sec)" << std::endl; |
0b309a75 | 571 | exit(2); |
572 | } | |
573 | } | |
574 | return NULL; | |
575 | } | |
47cbc555 | 576 | #endif |
7fd59977 | 577 | |
f9797095 | 578 | // Returns time in seconds defined by the argument string, |
579 | // multiplied by factor defined in environment variable | |
580 | // CSF_CPULIMIT_FACTOR (if it exists, 1 otherwise) | |
581 | static clock_t GetCpuLimit (const Standard_CString theParam) | |
35e08fe8 | 582 | { |
f9797095 | 583 | clock_t aValue = Draw::Atoi (theParam); |
584 | ||
585 | OSD_Environment aEnv("CSF_CPULIMIT_FACTOR"); | |
586 | TCollection_AsciiString aEnvStr = aEnv.Value(); | |
587 | if (!aEnvStr.IsEmpty()) | |
588 | { | |
589 | aValue *= Draw::Atoi (aEnvStr.ToCString()); | |
590 | } | |
591 | return aValue; | |
592 | } | |
593 | ||
7fd59977 | 594 | static Standard_Integer cpulimit(Draw_Interpretor& di, Standard_Integer n, const char** a) |
595 | { | |
0b309a75 | 596 | static int aFirst = 1; |
a60b9727 | 597 | #ifdef _WIN32 |
598 | // Windows specific code | |
47cbc555 A |
599 | unsigned int __stdcall CpuFunc (void *); |
600 | unsigned aThreadID; | |
601 | ||
0b309a75 | 602 | if (n <= 1){ |
a60b9727 | 603 | CPU_LIMIT = RLIM_INFINITY; |
0b309a75 | 604 | } else { |
f9797095 | 605 | CPU_LIMIT = GetCpuLimit (a[1]); |
47cbc555 A |
606 | Standard_Real anUserSeconds, aSystemSeconds; |
607 | OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds); | |
a60b9727 | 608 | CPU_CURRENT = clock_t(anUserSeconds + aSystemSeconds); |
0b309a75 | 609 | aTimer.Reset(); |
610 | aTimer.Start(); | |
47cbc555 A |
611 | if (aFirst) // Launch the thread only at the 1st call. |
612 | { | |
613 | aFirst = 0; | |
614 | _beginthreadex (NULL, 0, CpuFunc, NULL, 0, &aThreadID); | |
615 | } | |
7fd59977 | 616 | } |
617 | ||
a60b9727 | 618 | #else |
a60b9727 | 619 | // Unix & Linux |
a60b9727 | 620 | rlimit rlp; |
621 | rlp.rlim_max = RLIM_INFINITY; | |
622 | if (n <= 1) | |
623 | rlp.rlim_cur = RLIM_INFINITY; | |
624 | else | |
f9797095 | 625 | rlp.rlim_cur = GetCpuLimit (a[1]); |
a60b9727 | 626 | CPU_LIMIT = rlp.rlim_cur; |
627 | ||
628 | int status; | |
629 | status=setrlimit(RLIMIT_CPU,&rlp); | |
630 | if (status !=0) | |
631 | di << "status cpulimit setrlimit : " << status << "\n"; | |
632 | ||
633 | // set signal handler to print a message before death | |
634 | struct sigaction act, oact; | |
635 | memset (&act, 0, sizeof(act)); | |
0b309a75 | 636 | act.sa_handler = cpulimitSignalHandler; |
a60b9727 | 637 | sigaction (SIGXCPU, &act, &oact); |
638 | ||
0b309a75 | 639 | // cpulimit for elapsed time |
640 | aTimer.Reset(); | |
641 | aTimer.Start(); | |
642 | pthread_t cpulimitThread; | |
643 | if (aFirst) // Launch the thread only at the 1st call. | |
644 | { | |
645 | aFirst = 0; | |
646 | pthread_create(&cpulimitThread, NULL, CpuFunc, NULL); | |
647 | } | |
7fd59977 | 648 | #endif |
f9797095 | 649 | di << "CPU and elapsed time limit set to " << (double)CPU_LIMIT << " seconds"; |
7fd59977 | 650 | return 0; |
651 | } | |
652 | ||
7af17f1e MA |
653 | //======================================================================= |
654 | //function : mallochook | |
655 | //purpose : | |
656 | //======================================================================= | |
657 | ||
658 | static Standard_Integer mallochook(Draw_Interpretor& di, Standard_Integer n, | |
659 | const char** a) | |
660 | { | |
661 | if (n < 2) | |
662 | { | |
663 | di << "\ | |
664 | usage: mallochook cmd\n\ | |
665 | where cmd is one of:\n\ | |
666 | set [<op>] - set callback to malloc/free; op is one of the following:\n\ | |
667 | 0 - set callback to NULL,\n\ | |
668 | 1 - set callback OSD_MAllocHook::CollectBySize (default)\n\ | |
669 | 2 - set callback OSD_MAllocHook::LogFileHandler\n\ | |
670 | reset - reset the CollectBySize handler\n\ | |
671 | report1 [<outfile>]\n\ | |
672 | - write report from CollectBySize handler in <outfile>\n\ | |
673 | open [<logfile>]\n\ | |
674 | - open file for writing the log with LogFileHandler\n\ | |
675 | close - close the log file with LogFileHandler\n\ | |
676 | report2 [<flag>] [<logfile>] [<outfile>]\n\ | |
677 | - scan <logfile> written with LogFileHandler\n\ | |
678 | and make synthesized report in <outfile>; <flag> can be:\n\ | |
679 | 0 - simple stats by sizes (default),\n\ | |
680 | 1 - with alive allocation numbers\n\ | |
681 | By default <logfile> is \"mem-log.txt\", <outfile> is \"mem-stat.txt\"" | |
682 | << "\n"; | |
683 | return 0; | |
684 | } | |
685 | if (strcmp(a[1], "set") == 0) | |
686 | { | |
91322f44 | 687 | int aType = (n > 2 ? Draw::Atoi(a[2]) : 1); |
7af17f1e MA |
688 | if (aType < 0 || aType > 2) |
689 | { | |
586db386 | 690 | di << "unknown op of the command set\n"; |
7af17f1e MA |
691 | return 1; |
692 | } | |
693 | else if (aType == 0) | |
694 | { | |
695 | OSD_MAllocHook::SetCallback(NULL); | |
586db386 | 696 | di << "callback is unset\n"; |
7af17f1e MA |
697 | } |
698 | else if (aType == 1) | |
699 | { | |
700 | OSD_MAllocHook::SetCallback(OSD_MAllocHook::GetCollectBySize()); | |
586db386 | 701 | di << "callback is set to CollectBySize\n"; |
7af17f1e MA |
702 | } |
703 | else //if (aType == 2) | |
704 | { | |
705 | OSD_MAllocHook::SetCallback(OSD_MAllocHook::GetLogFileHandler()); | |
586db386 | 706 | di << "callback is set to LogFileHandler\n"; |
7af17f1e MA |
707 | } |
708 | } | |
709 | else if (strcmp(a[1], "reset") == 0) | |
710 | { | |
711 | OSD_MAllocHook::GetCollectBySize()->Reset(); | |
586db386 | 712 | di << "CollectBySize handler is reset\n"; |
7af17f1e MA |
713 | } |
714 | else if (strcmp(a[1], "open") == 0) | |
715 | { | |
716 | const char* aFileName = (n > 2 ? a[2] : "mem-log.txt"); | |
717 | if (!OSD_MAllocHook::GetLogFileHandler()->Open(aFileName)) | |
718 | { | |
586db386 | 719 | di << "cannot create file " << aFileName << " for writing\n"; |
7af17f1e MA |
720 | return 1; |
721 | } | |
586db386 | 722 | di << "log file " << aFileName << " is opened for writing\n"; |
7af17f1e MA |
723 | } |
724 | else if (strcmp(a[1], "close") == 0) | |
725 | { | |
726 | OSD_MAllocHook::GetLogFileHandler()->Close(); | |
586db386 | 727 | di << "log file is closed\n"; |
7af17f1e MA |
728 | } |
729 | else if (strcmp(a[1], "report1") == 0) | |
730 | { | |
731 | const char* aOutFile = "mem-stat.txt"; | |
732 | if (n > 2) | |
733 | aOutFile = a[2]; | |
734 | if (OSD_MAllocHook::GetCollectBySize()->MakeReport(aOutFile)) | |
735 | { | |
586db386 | 736 | di << "report " << aOutFile << " has been created\n"; |
7af17f1e MA |
737 | } |
738 | else | |
739 | { | |
740 | di << "cannot create report " << aOutFile << "\n"; | |
741 | return 1; | |
742 | } | |
743 | } | |
744 | else if (strcmp(a[1], "report2") == 0) | |
745 | { | |
746 | Standard_Boolean includeAlive = Standard_False; | |
747 | const char* aLogFile = "mem-log.txt"; | |
748 | const char* aOutFile = "mem-stat.txt"; | |
749 | if (n > 2) | |
750 | { | |
91322f44 | 751 | includeAlive = (Draw::Atoi(a[2]) != 0); |
7af17f1e MA |
752 | if (n > 3) |
753 | { | |
754 | aLogFile = a[3]; | |
755 | if (n > 4) | |
756 | aOutFile = a[4]; | |
757 | } | |
758 | } | |
759 | if (OSD_MAllocHook::LogFileHandler::MakeReport(aLogFile, aOutFile, includeAlive)) | |
760 | { | |
586db386 | 761 | di << "report " << aOutFile << " has been created\n"; |
7af17f1e MA |
762 | } |
763 | else | |
764 | { | |
765 | di << "cannot create report " << aOutFile << " from the log file " | |
766 | << aLogFile << "\n"; | |
767 | return 1; | |
768 | } | |
769 | } | |
770 | else | |
771 | { | |
772 | di << "unrecognized command " << a[1] << "\n"; | |
773 | return 1; | |
774 | } | |
775 | return 0; | |
776 | } | |
777 | ||
91322f44 | 778 | //============================================================================== |
779 | //function : dlocale | |
780 | //purpose : | |
781 | //============================================================================== | |
782 | ||
783 | static int dlocale (Draw_Interpretor& di, Standard_Integer n, const char** argv) | |
784 | { | |
785 | int category = LC_ALL; | |
786 | if (n > 1) | |
787 | { | |
788 | const char *cat = argv[1]; | |
789 | if ( ! strcmp (cat, "LC_ALL") ) category = LC_ALL; | |
790 | else if ( ! strcmp (cat, "LC_COLLATE") ) category = LC_COLLATE; | |
791 | else if ( ! strcmp (cat, "LC_CTYPE") ) category = LC_CTYPE; | |
792 | else if ( ! strcmp (cat, "LC_MONETARY") ) category = LC_MONETARY; | |
793 | else if ( ! strcmp (cat, "LC_NUMERIC") ) category = LC_NUMERIC; | |
794 | else if ( ! strcmp (cat, "LC_TIME") ) category = LC_TIME; | |
795 | else | |
796 | { | |
d99f0355 | 797 | Message::SendFail() << "Error: cannot recognize argument " << cat << " as one of LC_ macros"; |
91322f44 | 798 | return 1; |
799 | } | |
800 | } | |
801 | const char* locale = (n > 2 ? argv[2] : NULL); | |
802 | const char* result = setlocale (category, locale); | |
803 | if (result) | |
804 | di << result; | |
805 | else | |
04232180 | 806 | std::cout << "Error: unsupported locale specification: " << locale << std::endl; |
91322f44 | 807 | return 0; |
808 | } | |
809 | ||
f0430952 | 810 | //============================================================================== |
811 | //function : dmeminfo | |
812 | //purpose : | |
813 | //============================================================================== | |
814 | ||
815 | static int dmeminfo (Draw_Interpretor& theDI, | |
816 | Standard_Integer theArgNb, | |
817 | const char** theArgVec) | |
818 | { | |
f0430952 | 819 | if (theArgNb <= 1) |
820 | { | |
1939cfd9 | 821 | OSD_MemInfo aMemInfo; |
f0430952 | 822 | theDI << aMemInfo.ToString(); |
823 | return 0; | |
824 | } | |
825 | ||
1939cfd9 | 826 | NCollection_Map<OSD_MemInfo::Counter> aCounters; |
f0430952 | 827 | for (Standard_Integer anIter = 1; anIter < theArgNb; ++anIter) |
828 | { | |
829 | TCollection_AsciiString anArg (theArgVec[anIter]); | |
830 | anArg.LowerCase(); | |
831 | if (anArg == "virt" || anArg == "v") | |
832 | { | |
1939cfd9 | 833 | aCounters.Add (OSD_MemInfo::MemVirtual); |
f0430952 | 834 | } |
67a1064e | 835 | else if (anArg == "heap" || anArg == "h") |
836 | { | |
1939cfd9 | 837 | aCounters.Add (OSD_MemInfo::MemHeapUsage); |
67a1064e | 838 | } |
f0430952 | 839 | else if (anArg == "wset" || anArg == "w") |
840 | { | |
1939cfd9 | 841 | aCounters.Add (OSD_MemInfo::MemWorkingSet); |
f0430952 | 842 | } |
843 | else if (anArg == "wsetpeak") | |
844 | { | |
1939cfd9 | 845 | aCounters.Add (OSD_MemInfo::MemWorkingSetPeak); |
f0430952 | 846 | } |
847 | else if (anArg == "swap") | |
848 | { | |
1939cfd9 | 849 | aCounters.Add (OSD_MemInfo::MemSwapUsage); |
f0430952 | 850 | } |
851 | else if (anArg == "swappeak") | |
852 | { | |
1939cfd9 | 853 | aCounters.Add (OSD_MemInfo::MemSwapUsagePeak); |
f0430952 | 854 | } |
855 | else if (anArg == "private") | |
856 | { | |
1939cfd9 | 857 | aCounters.Add (OSD_MemInfo::MemPrivate); |
f0430952 | 858 | } |
859 | else | |
860 | { | |
861 | std::cerr << "Unknown argument '" << theArgVec[anIter] << "'!\n"; | |
862 | } | |
863 | } | |
1939cfd9 | 864 | |
865 | OSD_MemInfo aMemInfo (Standard_False); | |
866 | aMemInfo.SetActive (Standard_False); | |
867 | for (NCollection_Map<OSD_MemInfo::Counter>::Iterator aCountersIt (aCounters); aCountersIt.More(); aCountersIt.Next()) | |
868 | { | |
869 | aMemInfo.SetActive (aCountersIt.Value(), Standard_True); | |
870 | } | |
871 | aMemInfo.Update(); | |
872 | ||
873 | for (NCollection_Map<OSD_MemInfo::Counter>::Iterator aCountersIt (aCounters); aCountersIt.More(); aCountersIt.Next()) | |
874 | { | |
875 | theDI << Standard_Real (aMemInfo.Value (aCountersIt.Value())) << " "; | |
876 | } | |
f0430952 | 877 | theDI << "\n"; |
878 | return 0; | |
879 | } | |
7fd59977 | 880 | |
fc867b96 | 881 | //============================================================================== |
882 | //function : dparallel | |
883 | //purpose : | |
884 | //============================================================================== | |
885 | static int dparallel (Draw_Interpretor& theDI, | |
886 | Standard_Integer theArgNb, | |
887 | const char** theArgVec) | |
888 | { | |
889 | const Handle(OSD_ThreadPool)& aDefPool = OSD_ThreadPool::DefaultPool(); | |
890 | if (theArgNb <= 1) | |
891 | { | |
892 | theDI << "NbLogicalProcessors: " << OSD_Parallel::NbLogicalProcessors() << "\n" | |
893 | << "NbThreads: " << aDefPool->NbThreads() << "\n" | |
894 | << "NbDefThreads: " << aDefPool->NbDefaultThreadsToLaunch() << "\n" | |
895 | << "UseOcct: " << (OSD_Parallel::ToUseOcctThreads() ? 1 : 0); | |
896 | return 0; | |
897 | } | |
898 | ||
899 | for (Standard_Integer anIter = 1; anIter < theArgNb; ++anIter) | |
900 | { | |
901 | TCollection_AsciiString anArg (theArgVec[anIter]); | |
902 | anArg.LowerCase(); | |
903 | if (anIter + 1 < theArgNb | |
904 | && (anArg == "-nbthreads" | |
905 | || anArg == "-threads")) | |
906 | { | |
907 | const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]); | |
908 | aDefPool->Init (aVal); | |
909 | } | |
910 | else if (anIter + 1 < theArgNb | |
911 | && (anArg == "-nbdefthreads" | |
912 | || anArg == "-defthreads" | |
913 | || anArg == "-nbmaxdefthreads" | |
914 | || anArg == "-maxdefthreads")) | |
915 | { | |
916 | const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]); | |
917 | if (aVal <= 0 || aVal > aDefPool->NbThreads()) | |
918 | { | |
d99f0355 | 919 | Message::SendFail() << "Syntax error: maximum number of threads to use should be <= of threads in the pool"; |
fc867b96 | 920 | return 1; |
921 | } | |
922 | aDefPool->SetNbDefaultThreadsToLaunch (aVal); | |
923 | } | |
924 | else if (anIter + 1 < theArgNb | |
925 | && (anArg == "-useocct" | |
926 | || anArg == "-touseocct" | |
927 | || anArg == "-occt")) | |
928 | { | |
929 | const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]); | |
930 | OSD_Parallel::SetUseOcctThreads (aVal == 1); | |
931 | if (OSD_Parallel::ToUseOcctThreads() != (aVal == 1)) | |
932 | { | |
933 | std::cout << "Warning: unable to switch threads library - no options available\n"; | |
934 | } | |
935 | } | |
936 | else if (anIter + 1 < theArgNb | |
937 | && (anArg == "-usetbb" | |
938 | || anArg == "-tousetbb" | |
939 | || anArg == "-tbb")) | |
940 | { | |
941 | const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]); | |
942 | OSD_Parallel::SetUseOcctThreads (aVal == 0); | |
943 | if (OSD_Parallel::ToUseOcctThreads() != (aVal == 0)) | |
944 | { | |
945 | std::cout << "Warning: unable to switch threads library - no options available\n"; | |
946 | } | |
947 | } | |
948 | else | |
949 | { | |
d99f0355 | 950 | Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'"; |
fc867b96 | 951 | return 1; |
952 | } | |
953 | } | |
954 | return 0; | |
955 | } | |
956 | ||
618617fe | 957 | //============================================================================== |
958 | //function : dperf | |
959 | //purpose : | |
960 | //============================================================================== | |
961 | ||
962 | static int dperf (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec) | |
963 | { | |
964 | // reset if argument is provided and it is not '0' | |
965 | int reset = (theArgNb > 1 ? theArgVec[1][0] != '0' && theArgVec[1][0] != '\0' : 0); | |
966 | char buffer[25600]; | |
967 | perf_sprint_all_meters (buffer, 25600 - 1, reset); | |
968 | theDI << buffer; | |
969 | return 0; | |
970 | } | |
971 | ||
f4dee9bb | 972 | //============================================================================== |
973 | //function : dsetsignal | |
974 | //purpose : | |
975 | //============================================================================== | |
976 | ||
977 | static int dsetsignal (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec) | |
978 | { | |
44b80414 | 979 | OSD_SignalMode aMode = OSD_SignalMode_Set; |
980 | Standard_Boolean aSetFPE = OSD::ToCatchFloatingSignals(); | |
7fb9d6d5 | 981 | Standard_Integer aStackLen = OSD::SignalStackTraceLength(); |
44b80414 | 982 | |
983 | // default for FPE signal is defined by CSF_FPE variable, if set | |
984 | OSD_Environment aEnv("CSF_FPE"); | |
985 | TCollection_AsciiString aEnvStr = aEnv.Value(); | |
986 | if (!aEnvStr.IsEmpty()) | |
f4dee9bb | 987 | { |
44b80414 | 988 | aSetFPE = (aEnvStr.Value(1) != '0'); |
f4dee9bb | 989 | } |
44b80414 | 990 | |
991 | // parse arguments | |
992 | for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter) | |
993 | { | |
994 | TCollection_AsciiString anArg(theArgVec[anArgIter]); | |
995 | anArg.LowerCase(); | |
996 | if (anArg == "asis") | |
997 | { | |
998 | aMode = OSD_SignalMode_AsIs; | |
999 | } | |
1000 | else if (anArg == "set") | |
1001 | { | |
1002 | aMode = OSD_SignalMode_Set; | |
1003 | } | |
1004 | else if (anArg == "unhandled") | |
1005 | { | |
1006 | aMode = OSD_SignalMode_SetUnhandled; | |
1007 | } | |
1008 | else if (anArg == "unset") | |
1009 | { | |
1010 | aMode = OSD_SignalMode_Unset; | |
1011 | } | |
1012 | else if (anArg == "1" || anArg == "on") | |
1013 | { | |
1014 | aSetFPE = Standard_True; | |
1015 | } | |
1016 | else if (anArg == "0" || anArg == "off") | |
1017 | { | |
1018 | aSetFPE = Standard_False; | |
1019 | } | |
1020 | else if (anArg == "default") | |
1021 | { | |
1022 | } | |
7fb9d6d5 | 1023 | else if (anArgIter + 1 < theArgNb |
1024 | && (anArg == "-stracktracelength" | |
1025 | || anArg == "-stracktracelen" | |
1026 | || anArg == "-stracklength" | |
1027 | || anArg == "-stracklen")) | |
1028 | { | |
1029 | aStackLen = Draw::Atoi (theArgVec[++anArgIter]); | |
1030 | } | |
44b80414 | 1031 | else |
1032 | { | |
d99f0355 | 1033 | Message::SendFail() << "Syntax error: unknown argument '" << anArg << "'"; |
44b80414 | 1034 | return 1; |
1035 | } | |
1036 | } | |
1037 | ||
1038 | OSD::SetSignal(aMode, aSetFPE); | |
7fb9d6d5 | 1039 | OSD::SetSignalStackTraceLength (aStackLen); |
44b80414 | 1040 | |
1041 | // report actual status in the end | |
1042 | const char* aModeStr = 0; | |
1043 | switch (OSD::SignalMode()) | |
f4dee9bb | 1044 | { |
7fb9d6d5 | 1045 | default: |
1046 | case OSD_SignalMode_AsIs: aModeStr = "asis"; break; | |
1047 | case OSD_SignalMode_Set: aModeStr = "set"; break; | |
1048 | case OSD_SignalMode_SetUnhandled: aModeStr = "unhandled"; break; | |
1049 | case OSD_SignalMode_Unset: aModeStr = "unset"; break; | |
f4dee9bb | 1050 | } |
44b80414 | 1051 | theDI << "Signal mode: " << aModeStr << "\n" |
7fb9d6d5 | 1052 | << "Catch FPE: " << (OSD::ToCatchFloatingSignals() ? "1" : "0") << "\n" |
1053 | << "Stack Trace Length: " << aStackLen << "\n"; | |
f4dee9bb | 1054 | return 0; |
1055 | } | |
1056 | ||
785a9540 | 1057 | //============================================================================== |
1058 | //function : dtracelevel | |
1059 | //purpose : | |
1060 | //============================================================================== | |
1061 | ||
1062 | static int dtracelevel (Draw_Interpretor& theDI, | |
1063 | Standard_Integer theArgNb, | |
1064 | const char** theArgVec) | |
1065 | { | |
1066 | Message_Gravity aLevel = Message_Info; | |
1067 | if (theArgNb < 1 || theArgNb > 2) | |
1068 | { | |
d99f0355 | 1069 | Message::SendFail() << "Error: wrong number of arguments! See usage:"; |
785a9540 | 1070 | theDI.PrintHelp (theArgVec[0]); |
1071 | return 1; | |
1072 | } | |
1073 | else if (theArgNb == 2) | |
1074 | { | |
1075 | TCollection_AsciiString aVal (theArgVec[1]); | |
1076 | aVal.LowerCase(); | |
1077 | if (aVal == "trace") | |
1078 | { | |
1079 | aLevel = Message_Trace; | |
1080 | } | |
1081 | else if (aVal == "info") | |
1082 | { | |
1083 | aLevel = Message_Info; | |
1084 | } | |
1085 | else if (aVal == "warn" | |
1086 | || aVal == "warning") | |
1087 | { | |
1088 | aLevel = Message_Warning; | |
1089 | } | |
1090 | else if (aVal == "alarm") | |
1091 | { | |
1092 | aLevel = Message_Alarm; | |
1093 | } | |
1094 | else if (aVal == "fail") | |
1095 | { | |
1096 | aLevel = Message_Fail; | |
1097 | } | |
1098 | else | |
1099 | { | |
d99f0355 | 1100 | Message::SendFail() << "Error: unknown gravity '" << theArgVec[1] << "'"; |
785a9540 | 1101 | return 1; |
1102 | } | |
1103 | } | |
1104 | ||
1105 | Handle(Message_Messenger) aMessenger = Message::DefaultMessenger(); | |
1106 | if (aMessenger.IsNull()) | |
1107 | { | |
d99f0355 | 1108 | Message::SendFail() << "Error: default messenger is unavailable"; |
785a9540 | 1109 | return 1; |
1110 | } | |
1111 | ||
1112 | Message_SequenceOfPrinters& aPrinters = aMessenger->ChangePrinters(); | |
1113 | if (aPrinters.Length() < 1) | |
1114 | { | |
d99f0355 | 1115 | Message::SendFail() << "Error: no printers registered in default Messenger"; |
785a9540 | 1116 | return 0; |
1117 | } | |
1118 | ||
1119 | for (Standard_Integer aPrinterIter = 1; aPrinterIter <= aPrinters.Length(); ++aPrinterIter) | |
1120 | { | |
1121 | Handle(Message_Printer)& aPrinter = aPrinters.ChangeValue (aPrinterIter); | |
1122 | if (theArgNb == 1) | |
1123 | { | |
1124 | if (aPrinterIter == 1) | |
1125 | { | |
1126 | aLevel = aPrinter->GetTraceLevel(); | |
1127 | } | |
1128 | else if (aLevel == aPrinter->GetTraceLevel()) | |
1129 | { | |
1130 | continue; | |
1131 | } | |
1132 | ||
1133 | switch (aPrinter->GetTraceLevel()) | |
1134 | { | |
1135 | case Message_Trace: theDI << "trace"; break; | |
1136 | case Message_Info: theDI << "info"; break; | |
1137 | case Message_Warning: theDI << "warn"; break; | |
1138 | case Message_Alarm: theDI << "alarm"; break; | |
1139 | case Message_Fail: theDI << "fail"; break; | |
1140 | } | |
1141 | continue; | |
1142 | } | |
1143 | ||
1144 | aPrinter->SetTraceLevel (aLevel); | |
1145 | } | |
1146 | ||
1147 | return 0; | |
1148 | } | |
1149 | ||
7fb9d6d5 | 1150 | //============================================================================== |
1151 | //function : ddebugtraces | |
1152 | //purpose : | |
1153 | //============================================================================== | |
1154 | static int ddebugtraces (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec) | |
1155 | { | |
1156 | if (theArgNb < 2) | |
1157 | { | |
1158 | theDI << Standard_Failure::DefaultStackTraceLength(); | |
1159 | return 0; | |
1160 | } | |
1161 | else if (theArgNb != 2) | |
1162 | { | |
1163 | theDI << "Syntax error: wrong number of arguments"; | |
1164 | return 1; | |
1165 | } | |
1166 | ||
1167 | Standard_Failure::SetDefaultStackTraceLength (Draw::Atoi (theArgVec[1])); | |
1168 | return 0; | |
1169 | } | |
1170 | ||
63e5cfca | 1171 | //============================================================================== |
1172 | //function : dputs | |
1173 | //purpose : | |
1174 | //============================================================================== | |
d99f0355 | 1175 | static int dputs (Draw_Interpretor& theDI, |
63e5cfca | 1176 | Standard_Integer theArgNb, |
1177 | const char** theArgVec) | |
1178 | { | |
1179 | Standard_OStream* aStream = &std::cout; | |
1180 | bool isNoNewline = false, toIntense = false; | |
1181 | Message_ConsoleColor aColor = Message_ConsoleColor_Default; | |
1182 | for (Standard_Integer anArgIter = 1; anArgIter < theArgNb; ++anArgIter) | |
1183 | { | |
1184 | TCollection_AsciiString anArg (theArgVec[anArgIter]); | |
1185 | anArg.LowerCase(); | |
1186 | if (anArg == "-nonewline") | |
1187 | { | |
1188 | isNoNewline = true; | |
1189 | } | |
1190 | else if (anArg == "stdcout") | |
1191 | { | |
1192 | aStream = &std::cout; | |
1193 | } | |
1194 | else if (anArg == "stdcerr") | |
1195 | { | |
1196 | aStream = &std::cerr; | |
1197 | } | |
1198 | else if (anArg == "-intense") | |
1199 | { | |
1200 | toIntense = true; | |
1201 | } | |
1202 | else if (anArg == "-black") | |
1203 | { | |
1204 | aColor = Message_ConsoleColor_Black; | |
1205 | } | |
1206 | else if (anArg == "-white") | |
1207 | { | |
1208 | aColor = Message_ConsoleColor_White; | |
1209 | } | |
1210 | else if (anArg == "-red") | |
1211 | { | |
1212 | aColor = Message_ConsoleColor_Red; | |
1213 | } | |
1214 | else if (anArg == "-blue") | |
1215 | { | |
1216 | aColor = Message_ConsoleColor_Blue; | |
1217 | } | |
1218 | else if (anArg == "-green") | |
1219 | { | |
1220 | aColor = Message_ConsoleColor_Green; | |
1221 | } | |
1222 | else if (anArg == "-yellow") | |
1223 | { | |
1224 | aColor = Message_ConsoleColor_Yellow; | |
1225 | } | |
1226 | else if (anArg == "-cyan") | |
1227 | { | |
1228 | aColor = Message_ConsoleColor_Cyan; | |
1229 | } | |
1230 | else if (anArg == "-magenta") | |
1231 | { | |
1232 | aColor = Message_ConsoleColor_Magenta; | |
1233 | } | |
1234 | else if (anArgIter + 1 == theArgNb) | |
1235 | { | |
d99f0355 | 1236 | if (!theDI.ToColorize()) |
1237 | { | |
1238 | toIntense = false; | |
1239 | aColor = Message_ConsoleColor_Default; | |
1240 | } | |
63e5cfca | 1241 | if (toIntense || aColor != Message_ConsoleColor_Default) |
1242 | { | |
1243 | Message_PrinterOStream::SetConsoleTextColor (aStream, aColor, toIntense); | |
1244 | } | |
1245 | ||
1246 | *aStream << theArgVec[anArgIter]; | |
1247 | if (!isNoNewline) | |
1248 | { | |
1249 | *aStream << std::endl; | |
1250 | } | |
1251 | ||
1252 | if (toIntense || aColor != Message_ConsoleColor_Default) | |
1253 | { | |
1254 | Message_PrinterOStream::SetConsoleTextColor (aStream, Message_ConsoleColor_Default, false); | |
1255 | } | |
1256 | return 0; | |
1257 | } | |
1258 | else | |
1259 | { | |
1260 | Message::SendFail() << "Syntax error at '" << anArg << "'"; | |
1261 | return 1; | |
1262 | } | |
1263 | } | |
1264 | ||
1265 | Message::SendFail() << "Syntax error: wrong number of arguments"; | |
1266 | return 1; | |
1267 | } | |
1268 | ||
7fd59977 | 1269 | void Draw::BasicCommands(Draw_Interpretor& theCommands) |
1270 | { | |
1271 | static Standard_Boolean Done = Standard_False; | |
1272 | if (Done) return; | |
1273 | Done = Standard_True; | |
1274 | ||
04232180 | 1275 | std::ios::sync_with_stdio(); |
aa02980d | 1276 | |
7fd59977 | 1277 | const char* g = "DRAW General Commands"; |
785a9540 | 1278 | |
7fd59977 | 1279 | theCommands.Add("batch", "returns 1 in batch mode", |
1280 | __FILE__,ifbatch,g); | |
1281 | theCommands.Add("spy","spy [file], Save commands in file. no file close", | |
1282 | __FILE__,spy,g); | |
1283 | theCommands.Add("wait","wait [time(10)], wait time seconds", | |
1284 | __FILE__,Draw_wait,g); | |
1285 | theCommands.Add("cpulimit","cpulimit [nbseconds], no args remove limits", | |
1286 | __FILE__,cpulimit,g); | |
7d3225b5 | 1287 | theCommands.Add("chrono","chrono [name action [action...]] \n Operates named timer.\n" |
1288 | " Supported actions: reset, start, stop, restart, show, counter [text].\n" | |
1289 | " Without arguments enables / disables global timer for all DRAW commands.", | |
7fd59977 | 1290 | __FILE__,chronom,g); |
7d3225b5 | 1291 | theCommands.Add("dchrono","see help of chrono command", |
7fd59977 | 1292 | __FILE__,dchronom,g); |
7af17f1e MA |
1293 | theCommands.Add("mallochook", |
1294 | "debug memory allocation/deallocation, w/o args for help", | |
1295 | __FILE__, mallochook, g); | |
f0430952 | 1296 | theCommands.Add ("meminfo", |
67a1064e | 1297 | "meminfo [virt|v] [heap|h] [wset|w] [wsetpeak] [swap] [swappeak] [private]" |
f0430952 | 1298 | " : memory counters for this process", |
1299 | __FILE__, dmeminfo, g); | |
618617fe | 1300 | theCommands.Add("dperf","dperf [reset] -- show performance counters, reset if argument is provided", |
1301 | __FILE__,dperf,g); | |
7fb9d6d5 | 1302 | theCommands.Add("dsetsignal", |
1303 | "dsetsignal [{asIs|set|unhandled|unset}=set] [{0|1|default=$CSF_FPE}]" | |
1304 | "\n\t\t: [-strackTraceLength Length]" | |
1305 | "\n\t\t: Sets OSD signal handler, with FPE option if argument is given." | |
1306 | "\n\t\t: -strackTraceLength specifies length of stack trace to put into exceptions redirected from signals.", | |
f4dee9bb | 1307 | __FILE__,dsetsignal,g); |
aa02980d | 1308 | |
fc867b96 | 1309 | theCommands.Add("dparallel", |
1310 | "dparallel [-occt {0|1}] [-nbThreads Count] [-nbDefThreads Count]" | |
1311 | "\n\t\t: Manages global parallelization parameters:" | |
1312 | "\n\t\t: -occt use OCCT implementation or external library (if available)" | |
1313 | "\n\t\t: -nbThreads specify the number of threads in default thread pool" | |
1314 | "\n\t\t: -nbDefThreads specify the upper limit of threads to be used for default thread pool" | |
1315 | "\n\t\t: within single parallelization call (should be <= of overall number of threads)," | |
1316 | "\n\t\t: so that nested algorithm can also use this pool", | |
1317 | __FILE__,dparallel,g); | |
1318 | ||
785a9540 | 1319 | // Logging commands; note that their names are hard-coded in the code |
aa02980d | 1320 | // of Draw_Interpretor, thus should not be changed without update of that code! |
1321 | theCommands.Add("dlog", "manage logging of commands and output; run without args to get help", | |
1322 | __FILE__,dlog,g); | |
1323 | theCommands.Add("decho", "switch on / off echo of commands to cout; run without args to get help", | |
1324 | __FILE__,decho,g); | |
785a9540 | 1325 | theCommands.Add("dtracelevel", "dtracelevel [trace|info|warn|alarm|fail]", |
1326 | __FILE__, dtracelevel, g); | |
7fb9d6d5 | 1327 | theCommands.Add("ddebugtraces", |
1328 | "ddebugtraces nbTraces" | |
1329 | "\n\t\t: Sets the number of lines for the stack trace within Standard_Failure constructor." | |
1330 | "\n\t\t: Intended for debug purposes.", | |
1331 | __FILE__, ddebugtraces, g); | |
785a9540 | 1332 | |
8a262fa1 | 1333 | theCommands.Add("dbreak", "raises Tcl exception if user has pressed Control-Break key", |
1334 | __FILE__,dbreak,g); | |
1335 | theCommands.Add("dversion", "provides information on OCCT build configuration (version, compiler, OS, C library, etc.)", | |
1336 | __FILE__,dversion,g); | |
91322f44 | 1337 | theCommands.Add("dlocale", "set and / or query locate of C subsystem (function setlocale())", |
1338 | __FILE__,dlocale,g); | |
63e5cfca | 1339 | |
1340 | theCommands.Add("dputs", | |
1341 | "dputs [-intense] [-black|-white|-red|-green|-blue|-yellow|-cyan|-magenta]" | |
1342 | "\n\t\t: [-nonewline] [stdcout|stdcerr] text" | |
1343 | "\n\t\t: Puts text into console output", | |
1344 | __FILE__,dputs,g); | |
7fd59977 | 1345 | } |