Garfield++ v1r0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
FunNameStack.h
Go to the documentation of this file.
1#ifndef FUNNAMESTACK_H
2#define FUNNAMESTACK_H
3/*
4Copyright (c) 1999 I. B. Smirnov
5
6Permission to use, copy, modify, distribute and sell this file
7and its documentation for any purpose is hereby granted without fee,
8provided that the above copyright notice, this permission notice,
9and notices about any modifications of the original text
10appear in all copies and in supporting documentation.
11It is provided "as is" without express or implied warranty.
12*/
13
14#include <stdlib.h>
15#include <string.h>
16#include <iostream>
19
20//#define USE_BOOST_MULTITHREADING
21//#define PRINT_MESSAGE_ABOUT_THREAD_INITIALIZATION
22// Prints a long message at initialization of FunNameStack.
23// The message is quite long and nusty and it is unlikely that
24// it can be visually missed even if it is interrupted by play of threads.
25// This nusty message is not necessary at the routine work.
26
27#ifdef USE_BOOST_MULTITHREADING
28#include "boost/thread/mutex.hpp"
29#endif
30
31/*
32// Here there is a good place to switch off the
33// initialization of the function names in all the programs
34#ifdef FUNNAMESTACK
35#undef FUNNAMESTACK
36#endif
37*/
38// Here there is a good place to switch off the
39// assertion checks in all the programs
40//#ifdef DO_CHECKS
41//#undef DO_CHECKS
42//#endif
43
44#define stackprt(stream) stream << FunNameStack::instance()
45// Definitions which can be switched off
46#ifdef FUNNAMESTACK
47#define mfunname(string) \
48 static char* FunNameIIII = string; \
49 FunNameWatch funnw(FunNameIIII)
50#define mfunname1(string) \
51 static char* FunNameIIII1 = string; \
52 FunNameWatch funnw1(FunNameIIII1)
53#define mfunname2(string) \
54 static char* FunNameIIII2 = string; \
55 FunNameWatch funnw2(FunNameIIII2)
56#define mfunname3(string) \
57 static char* FunNameIIII3 = string; \
58 FunNameWatch funnw3(FunNameIIII3)
59#define mfunname4(string) \
60 static char* FunNameIIII4 = string; \
61 FunNameWatch funnw4(FunNameIIII4)
62#define mfunname5(string) \
63 static char* FunNameIIII5 = string; \
64 FunNameWatch funnw5(FunNameIIII5)
65//#define stackprt(stream) stream<<funnamestack
66#else
67#define mfunname(string)
68#define mfunname1(string)
69#define mfunname2(string)
70#define mfunname3(string)
71#define mfunname4(string)
72#define mfunname5(string)
73//#define stackprt(stream)
74#endif
75
76// Permanent definitions
77#define mfunnamep(string) \
78 static const char* FunNameIIII = string; \
79 FunNameWatch funnw(FunNameIIII)
80#define mfunnamep1(string) \
81 static const char* FunNameIIII1 = string; \
82 FunNameWatch funnw1(FunNameIIII1)
83#define mfunnamep2(string) \
84 static const char* FunNameIIII2 = string; \
85 FunNameWatch funnw2(FunNameIIII2)
86#define mfunnamep3(string) \
87 static const char* FunNameIIII3 = string; \
88 FunNameWatch funnw3(FunNameIIII3)
89#define mfunnamep4(string) \
90 static const char* FunNameIIII4 = string; \
91 FunNameWatch funnw4(FunNameIIII4)
92#define mfunnamep5(string) \
93 static const char* FunNameIIII5 = string; \
94 FunNameWatch funnw5(FunNameIIII5)
95
96// Checks
97#define DO_CHECKS
98#ifdef DO_CHECKS
99
100#ifdef FUNNAMESTACK
101
102#define check_econd(condition, add, stream) \
103 if (condition) { \
104 funnw.ehdr(stream); \
105 stream << '\n' << #condition << '\n'; \
106 stream << add; \
107 spexit(stream); \
108 }
109#define check_wcond(condition, add, stream) \
110 if (condition) { \
111 funnw.whdr(stream); \
112 stream << '\n' << #condition << '\n'; \
113 stream << add; \
114 }
115
116#define check_econd1(condition, a1, stream) \
117 if (condition) { \
118 funnw.ehdr(stream); \
119 stream << '\n' << #condition << '\n'; \
120 stream << #a1 << '=' << (a1) << '\n'; \
121 spexit(stream); \
122 }
123#define check_wcond1(condition, a1, stream) \
124 if (condition) { \
125 funnw.whdr(stream); \
126 stream << '\n' << #condition << '\n'; \
127 stream << #a1 << '=' << (a1) << '\n'; \
128 }
129
130#define check_econd2(condition, a1, a2, stream) \
131 if (condition) { \
132 funnw.ehdr(stream); \
133 stream << '\n' << #condition << '\n'; \
134 stream << #a1 << '=' << (a1) << ' ' << #a2 << '=' << (a2) << '\n'; \
135 spexit(stream); \
136 }
137#define check_wcond2(condition, a1, a2, stream) \
138 if (condition) { \
139 funnw.whdr(stream); \
140 stream << '\n' << #condition << '\n'; \
141 stream << #a1 << '=' << (a1) << ' ' << #a2 << '=' << (a2) << '\n'; \
142 }
143
144#define check_econd3(condition, a1, a2, a3, stream) \
145 if (condition) { \
146 funnw.ehdr(stream); \
147 stream << '\n' << #condition << '\n'; \
148 stream << #a1 << '=' << (a1) << ' ' << #a2 << '=' << (a2) << ' ' << #a3 \
149 << '=' << (a3) << '\n'; \
150 spexit(stream); \
151 }
152#define check_wcond3(condition, a1, a2, a3, stream) \
153 if (condition) { \
154 funnw.whdr(stream); \
155 stream << '\n' << #condition << '\n'; \
156 stream << #a1 << '=' << (a1) << ' ' << #a2 << '=' << (a2) << ' ' << #a3 \
157 << '=' << (a3) << '\n'; \
158 }
159
160#define check_econd4(condition, a1, a2, a3, a4, stream) \
161 if (condition) { \
162 funnw.ehdr(stream); \
163 stream << '\n' << #condition << '\n'; \
164 stream << #a1 << '=' << (a1) << ' ' << #a2 << '=' << (a2) << ' ' << #a3 \
165 << '=' << (a3) << ' ' << #a4 << '=' << (a4) << '\n'; \
166 spexit(stream); \
167 }
168#define check_wcond4(condition, a1, a2, a3, a4, stream) \
169 if (condition) { \
170 funnw.whdr(stream); \
171 stream << '\n' << #condition << '\n'; \
172 stream << #a1 << '=' << (a1) << ' ' << #a2 << '=' << (a2) << ' ' << #a3 \
173 << '=' << (a3) << ' ' << #a4 << '=' << (a4) << '\n'; \
174 }
175
176#define check_econd11(a, signb, stream) \
177 if (a signb) { \
178 funnw.ehdr(stream); \
179 stream << '\n' << #a << #signb << '\n'; \
180 stream << #a << '=' << (a) << '\n'; \
181 spexit(stream); \
182 }
183#define check_wcond11(a, signb, stream) \
184 if (a signb) { \
185 funnw.whdr(stream); \
186 stream << '\n' << #a << #signb << '\n'; \
187 stream << #a << '=' << (a) << '\n'; \
188 }
189
190#define check_econd12(a, sign, b, stream) \
191 if (a sign b) { \
192 funnw.ehdr(stream); \
193 stream << '\n' << #a << #sign << #b << '\n'; \
194 stream << #a << '=' << (a) << ' ' << #b << '=' << (b) << '\n'; \
195 spexit(stream); \
196 }
197#define check_wcond12(a, sign, b, stream) \
198 if (a sign b) { \
199 funnw.whdr(stream); \
200 stream << '\n' << #a << #sign << #b << '\n'; \
201 stream << #a << '=' << (a) << ' ' << #b << '=' << (b) << '\n'; \
202 }
203
204//condition + additional any commands
205#define check_econd11a(a, signb, add, stream) \
206 if (a signb) { \
207 funnw.ehdr(stream); \
208 stream << '\n' << #a << #signb << '\n'; \
209 stream << #a << '=' << (a) << '\n'; \
210 stream << add; \
211 spexit(stream); \
212 }
213#define check_wcond11a(a, signb, add, stream) \
214 if (a signb) { \
215 funnw.whdr(stream); \
216 stream << '\n' << #a << #signb << '\n'; \
217 stream << #a << '=' << (a) << '\n'; \
218 stream << add; \
219 }
220
221#define check_econd12a(a, sign, b, add, stream) \
222 if (a sign b) { \
223 funnw.ehdr(stream); \
224 stream << '\n' << #a << #sign << #b << '\n'; \
225 stream << #a << '=' << (a) << ' ' << #b << '=' << (b) << '\n'; \
226 stream << add; \
227 spexit(stream); \
228 }
229#define check_wcond12a(a, sign, b, add, stream) \
230 if (a sign b) { \
231 funnw.whdr(stream); \
232 stream << '\n' << #a << #sign << #b << '\n'; \
233 stream << #a << '=' << (a) << ' ' << #b << '=' << (b) << '\n'; \
234 stream << add; \
235 }
236
237// and of two conditions for one variable
238#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream) \
239 if(a sign1_b1_sign0 a sign2_b2) { \
240 funnw.ehdr(stream); \
241 stream << '\n' << #a << #sign1_b1_sign0 << #a << #sign2_b2 << '\n'; \
242 stream << #a << '=' << (a) << '\n'; \
243 spexit(stream); \
244 }
245#define check_wcond21(a, sign1_b1_sign0, sign2_b2, stream) \
246 if(a sign1_b1_sign0 a sign2_b2) { \
247 funnw.whdr(stream); \
248 stream << '\n' << #a << #sign1_b1_sign0 << #a << #sign2_b2 << '\n'; \
249 stream << #a << '=' << (a) << '\n'; \
250 }
251
252// and of two conditions for one variable
253#define check_econd23(a, sign1, b1, sign0, sign2, b2, stream) \
254 if(a sign1 b1 sign0 a sign2 b2) { \
255 funnw.ehdr(stream); \
256 stream << '\n' << #a << #sign1 << #b1 << #sign0 << #a << #sign2 << #b2 \
257 << '\n'; \
258 stream << #a << '=' << (a) << ' ' << #b1 << '=' << (b1) << ' ' << #b2 \
259 << '=' << (b2) << '\n'; \
260 spexit(stream); \
261 }
262#define check_wcond23(a, sign1, b1, sign0, sign2, b2, stream) \
263 if(a sign1 b1 sign0 a sign2 b2) { \
264 funnw.whdr(stream); \
265 stream << '\n' << #a << #sign1 << #b1 << #sign0 << #a << #sign2 << #b2 \
266 << '\n'; \
267 stream << #a << '=' << (a) << ' ' << #b1 << '=' << (b1) << ' ' << #b2 \
268 << '=' << (b2) << '\n'; \
269 }
270
271// two conditions for four variables
272#define check_econd24(a1, sign1, b1, sign0, a2, sign2, b2, stream) \
273 if(a1 sign1 b1 sign0 a2 sign2 b2) { \
274 funnw.ehdr(stream); \
275 stream << '\n' << #a1 << #sign1 << #b1 << #sign0 << #a2 << #sign2 << #b2 \
276 << '\n'; \
277 stream << #a1 << '=' << (a1) << ' ' << #b1 << '=' << (b1) << '\n'; \
278 stream << #a2 << '=' << (a2) << ' ' << #b2 << '=' << (b2) << '\n'; \
279 spexit(stream); \
280 }
281#define check_wcond24(a1, sign1, b1, sign0, a2, sign2, b2, stream) \
282 if(a1 sign1 b1 sign0 a2 sign2 b2) { \
283 funnw.whdr(stream); \
284 stream << '\n' << #a1 << #sign1 << #b1 << #sign0 << #a2 << #sign2 << #b2 \
285 << '\n'; \
286 stream << #a1 << '=' << (a1) << ' ' << #b1 << '=' << (b1) << '\n'; \
287 stream << #a2 << '=' << (a2) << ' ' << #b2 << '=' << (b2) << '\n'; \
288 }
289
290#else // without FUNNAMESTACK, print only condition
291
292#define check_econd(condition, add, stream) \
293 if (condition) { \
294 stream << "ERROR:\n"; \
295 stream << '\n' << #condition << '\n'; \
296 stream << add; \
297 spexit(stream); \
298 }
299#define check_wcond(condition, add, stream) \
300 if (condition) { \
301 stream << "WARNING:\n"; \
302 stream << '\n' << #condition << '\n'; \
303 stream << add; \
304 }
305
306#define check_econd1(condition, a1, stream) \
307 if (condition) { \
308 stream << "ERROR:\n"; \
309 stream << '\n' << #condition << '\n'; \
310 stream << #a1 << '=' << (a1) << '\n'; \
311 spexit(stream); \
312 }
313#define check_wcond1(condition, a1, stream) \
314 if (condition) { \
315 stream << "WARNING:\n"; \
316 stream << '\n' << #condition << '\n'; \
317 stream << #a1 << '=' << (a1) << '\n'; \
318 }
319
320#define check_econd2(condition, a1, a2, stream) \
321 if (condition) { \
322 stream << "ERROR:\n"; \
323 stream << '\n' << #condition << '\n'; \
324 stream << #a1 << '=' << (a1) << ' ' << #a2 << '=' << (a2) << '\n'; \
325 spexit(stream); \
326 }
327#define check_wcond2(condition, a1, a2, stream) \
328 if (condition) { \
329 stream << "WARNING:\n"; \
330 stream << '\n' << #condition << '\n'; \
331 stream << #a1 << '=' << (a1) << ' ' << #a2 << '=' << (a2) << '\n'; \
332 }
333
334#define check_econd3(condition, a1, a2, a3, stream) \
335 if (condition) { \
336 stream << "ERROR:\n"; \
337 stream << '\n' << #condition << '\n'; \
338 stream << #a1 << '=' << (a1) << ' ' << #a2 << '=' << (a2) << ' ' << #a3 \
339 << '=' << (a3) << '\n'; \
340 spexit(stream); \
341 }
342#define check_wcond3(condition, a1, a2, a3, stream) \
343 if (condition) { \
344 stream << "WARNING:\n"; \
345 stream << '\n' << #condition << '\n'; \
346 stream << #a1 << '=' << (a1) << ' ' << #a2 << '=' << (a2) << ' ' << #a3 \
347 << '=' << (a3) << '\n'; \
348 }
349
350#define check_econd4(condition, a1, a2, a3, a4, stream) \
351 if (condition) { \
352 stream << "ERROR:\n"; \
353 stream << '\n' << #condition << '\n'; \
354 stream << #a1 << '=' << (a1) << ' ' << #a2 << '=' << (a2) << ' ' << #a3 \
355 << '=' << (a3) << ' ' << #a4 << '=' << (a4) << '\n'; \
356 spexit(stream); \
357 }
358#define check_wcond4(condition, a1, a2, a3, a4, stream) \
359 if (condition) { \
360 stream << "WARNING:\n"; \
361 stream << '\n' << #condition << '\n'; \
362 stream << #a1 << '=' << (a1) << ' ' << #a2 << '=' << (a2) << ' ' << #a3 \
363 << '=' << (a3) << ' ' << #a4 << '=' << (a4) << '\n'; \
364 }
365
366#define check_econd11(a, signb, stream) \
367 if (a signb) { \
368 stream << "ERROR:\n"; \
369 stream << '\n' << #a << #signb << '\n'; \
370 stream << #a << '=' << (a) << '\n'; \
371 spexit(stream); \
372 }
373#define check_wcond11(a, signb, stream) \
374 if (a signb) { \
375 stream << "WARNING:\n"; \
376 stream << '\n' << #a << #signb << '\n'; \
377 stream << #a << '=' << (a) << '\n'; \
378 }
379
380#define check_econd12(a, sign, b, stream) \
381 if (a sign b) { \
382 stream << "ERROR:\n"; \
383 stream << '\n' << #a << #sign << #b << '\n'; \
384 stream << #a << '=' << (a) << ' ' << #b << '=' << (b) << '\n'; \
385 spexit(stream); \
386 }
387#define check_wcond12(a, sign, b, stream) \
388 if (a sign b) { \
389 stream << "WARNING:\n"; \
390 stream << '\n' << #a << #sign << #b << '\n'; \
391 stream << #a << '=' << (a) << ' ' << #b << '=' << (b) << '\n'; \
392 }
393
394//condition + additional any commands
395#define check_econd11a(a, signb, add, stream) \
396 if (a signb) { \
397 stream << "ERROR:\n"; \
398 stream << '\n' << #a << #signb << '\n'; \
399 stream << #a << '=' << (a) << '\n'; \
400 stream << add; \
401 spexit(stream); \
402 }
403#define check_wcond11a(a, signb, add, stream) \
404 if (a signb) { \
405 stream << "WARNING:\n"; \
406 stream << '\n' << #a << #signb << '\n'; \
407 stream << #a << '=' << (a) << '\n'; \
408 stream << add; \
409 }
410
411#define check_econd12a(a, sign, b, add, stream) \
412 if (a sign b) { \
413 stream << "ERROR:\n"; \
414 stream << '\n' << #a << #sign << #b << '\n'; \
415 stream << #a << '=' << (a) << ' ' << #b << '=' << (b) << '\n'; \
416 stream << add; \
417 spexit(stream); \
418 }
419#define check_wcond12a(a, sign, b, add, stream) \
420 if (a sign b) { \
421 stream << "WARNING:\n"; \
422 stream << '\n' << #a << #sign << #b << '\n'; \
423 stream << #a << '=' << (a) << ' ' << #b << '=' << (b) << '\n'; \
424 stream << add; \
425 }
426
427// and of two conditions for one variable
428#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream) \
429 if(a sign1_b1_sign0 a sign2_b2) { \
430 stream << "ERROR:\n"; \
431 stream << '\n' << #a << #sign1_b1_sign0 << #a << #sign2_b2 << '\n'; \
432 stream << #a << '=' << (a) << '\n'; \
433 spexit(stream); \
434 }
435#define check_wcond21(a, sign1_b1_sign0, sign2_b2, stream) \
436 if(a sign1_b1_sign0 a sign2_b2) { \
437 stream << "WARNING:\n"; \
438 stream << '\n' << #a << #sign1_b1_sign0 << #a << #sign2_b2 << '\n'; \
439 stream << #a << '=' << (a) << '\n'; \
440 }
441
442// and of two conditions for one variable
443#define check_econd23(a, sign1, b1, sign0, sign2, b2, stream) \
444 if(a sign1 b1 sign0 a sign2 b2) { \
445 stream << "ERROR:\n"; \
446 stream << '\n' << #a << #sign1 << #b1 << #sign0 << #a << #sign2 << #b2 \
447 << '\n'; \
448 stream << #a << '=' << (a) << ' ' << #b1 << '=' << (b1) << ' ' << #b2 \
449 << '=' << (b2) << '\n'; \
450 spexit(stream); \
451 }
452#define check_wcond23(a, sign1, b1, sign0, sign2, b2, stream) \
453 if(a sign1 b1 sign0 a sign2 b2) { \
454 stream << "WARNING:\n"; \
455 stream << '\n' << #a << #sign1 << #b1 << #sign0 << #a << #sign2 << #b2 \
456 << '\n'; \
457 stream << #a << '=' << (a) << ' ' << #b1 << '=' << (b1) << ' ' << #b2 \
458 << '=' << (b2) << '\n'; \
459 }
460
461// two conditions for four variables
462#define check_econd24(a1, sign1, b1, sign0, a2, sign2, b2, stream) \
463 if(a1 sign1 b1 sign0 a2 sign2 b2) { \
464 stream << "ERROR:\n"; \
465 stream << '\n' << #a1 << #sign1 << #b1 << #sign0 << #a2 << #sign2 << #b2 \
466 << '\n'; \
467 stream << #a1 << '=' << (a1) << ' ' << #b1 << '=' << (b1) << '\n'; \
468 stream << #a2 << '=' << (a2) << ' ' << #b2 << '=' << (b2) << '\n'; \
469 spexit(stream); \
470 }
471#define check_wcond24(a1, sign1, b1, sign0, a2, sign2, b2, stream) \
472 if(a1 sign1 b1 sign0 a2 sign2 b2) { \
473 stream << "WARNING:\n"; \
474 stream << '\n' << #a1 << #sign1 << #b1 << #sign0 << #a2 << #sign2 << #b2 \
475 << '\n'; \
476 stream << #a1 << '=' << (a1) << ' ' << #b1 << '=' << (b1) << '\n'; \
477 stream << #a2 << '=' << (a2) << ' ' << #b2 << '=' << (b2) << '\n'; \
478 }
479
480#endif
481
482#else // without checks
483
484#define check_econd(condition, add, stream)
485#define check_wcond(condition, add, stream)
486
487#define check_econd1(condition, a1, stream)
488#define check_wcond1(condition, a1, stream)
489
490#define check_econd2(condition, a1, a2, stream)
491#define check_wcond2(condition, a1, a2, stream)
492
493#define check_econd3(condition, a1, a2, a3, stream)
494#define check_wcond3(condition, a1, a2, a3, stream)
495
496#define check_econd4(condition, a1, a2, a3, a4, stream)
497#define check_wcond4(condition, a1, a2, a3, a4, stream)
498
499#define check_econd11(a, signb, stream)
500#define check_wcond11(a, signb, stream)
501
502#define check_econd12(a, sign, b, stream)
503#define check_wcond12(a, sign, b, stream)
504
505#define check_econd11a(a, signb, add, stream)
506#define check_wcond11a(a, signb, add, stream)
507
508#define check_econd12a(a, sign, b, add, stream)
509#define check_wcond12a(a, sign, b, add, stream)
510
511// and of two conditions for one variable
512#define check_econd21(a, sign1_b1_sign0, sign2_b2, stream)
513#define check_wcond21(a, sign1_b1_sign0, sign2_b2, stream)
514
515// and of two conditions for one variable
516#define check_econd23(a, sign1, b1, sign0, sign2, b2, stream)
517#define check_wcond23(a, sign1, b1, sign0, sign2, b2, stream)
518
519// two conditions for four variables
520#define check_econd24(a1, sign1, b1, sign0, a2, sign2, b2, stream)
521#define check_wcond24(a1, sign1, b1, sign0, a2, sign2, b2, stream)
522
523#endif
524
526 public:
527 ExcFromSpexit(void) { ; }
528};
529
530void spexit_action(std::ostream& file);
531extern int s_throw_exception_in_spexit; // if == 1, does exit(1) of abort()
532 // depending on the key below
533extern int s_exit_without_core; // the key above have larger priority
534
535// Normal exit:
536#define spexit(stream) \
537 { \
538 stackprt(stream); \
539 stream << "File is " << __FILE__ << " , line number is " << __LINE__ \
540 << '\n'; \
541 spexit_action(stream); \
542 }
543
544const int pqname = 1000; // this depth of stack is completely OK
545 // for all correct programs.
546// If you have overflow, it is likely the infinite loop with recursion
547// in your program!
548
549// Converting to a quasi-singleton class:
550// The program operates only with main hidden exsemplar.
551// Nothing could be copied to, but it itself can be copied,
552// for example for passing with exception classes
553
554#ifdef USE_BOOST_MULTITHREADING
555/* For multithreading we will keep own stack for each thread.
556This complicates things a lot, but still managable.
557In one thread case the stack data qname and name[] are kept directly
558in a singleton object of FunNameStack class.
559For multithreading mode we need to introduce special intermediate class
560NameStack and initialize one object of this class per each found thread.
561*/
562//#include "wcpplib/safetl/AbsList.h" // this does not work, because it
563// refers through some sequence to this file.
564template <class T> class AbsList; // This is enough.
565
566class NameStack {
567 public:
568 int qname;
569 char* name[pqname];
570 pthread_t id;
571 int nmode; // 0 - name points to a string in outside world
572 // used for global object funnamestack
573 // 1 - name is inited by new and deleted by delete
574 // may be used for sending as parameter of exception
575 // It is not convenient for normal work due
576 // to time expense
577 NameStack(void) : qname(0), id(0), nmode(0) {
578 for (int n = 0; n < pqname; n++)
579 name[n] = NULL;
580 }
581 NameStack(const NameStack& f) : qname(0), id(0), nmode(0) { *this = f; }
582
583 NameStack& operator=(const NameStack& f);
584
585 ~NameStack(void) {
586 int n;
587 if (nmode == 1) for (n = 0; n < qname; n++)
588 delete name[n];
589 }
590};
591#endif
592
594 public:
595 static FunNameStack& instance();
596
597 // make instances of the class uncopyable to hidden exsemplar,
598 // but copyable away.
599 //
600
601 FunNameStack(const FunNameStack& f);
603
604 FunNameStack(void); // usually called inly from instance()
605 private:
606#ifdef USE_BOOST_MULTITHREADING
607 // Two next functions return NameStack corresponding to
608 // current thread.
609 NameStack* get_thread_stack(void) const;
610 NameStack* get_thread_stack_q(long& nthread, long& qthread) const;
611 // retrieve not only NameStack, but also nthread and qthread.
612
613 void remove_thread_stack(void);
614#endif
615//const static int pqname; // doesn't work on Sun
616#ifdef USE_BOOST_MULTITHREADING
617 AbsList<NameStack>* namestack;
618// Cannot put ActivePtr here because it uses FunNameStack itself
619// and wants it to be completed.
620#else
621 int qname;
622 char* name[pqname];
623#endif
624 int s_init; // 1 - sign that it is inited,
625 // any other value - not inited
626 // Now this variable is used only for debug printing.
627
628 int s_act; // 1 - active, 0 - not active
629 //( to switch without recompilation)
630 public:
631 int s_print; // works only is s_act=1;
632 // 0 - no print
633 // 1 - at each entry print the name of current function
634 // 2 - at each entry and each exit
635 // print the name of current function
636 // 3 - at each entry print all stack
637 // 4 - at each entry and exit print all stack
638 private:
639 int nmode; // 0 - name points to a string in outside world
640 // used for global object funnamestack
641 // 1 - name is inited by new and deleted by delete
642 // may be used for sending as parameter of exception
643 // It is not convenient for normal work due
644 // to time expense
645
646#ifdef USE_BOOST_MULTITHREADING
647 std::ostream& printname(std::ostream& file, NameStack* ns, int n); //
648#else
649 std::ostream& printname(std::ostream& file, int n); //
650#endif
651 public:
652 void set_parameters(int fs_act = 1, int fs_print = 0);
654
655 private:
656 void printput(
657 std::ostream& file); // called at insertion of new name in stack
658 void printdel(std::ostream& file); // called at deletion of name from stack
659 public:
660 //#ifdef USE_BOOST_MULTITHREADING
661 //wl_inline void put(char* fname);
662 //#else
663 wl_inline int put(const char* fname);
664 //#endif
665 wl_inline void del(int nname);
666 wl_inline void replace(const char* fname);
667 friend std::ostream& operator<<(std::ostream& file, const FunNameStack& f);
668};
669std::ostream& operator<<(std::ostream& file, const FunNameStack& f);
670
671// The following class is used solerly
672// to change parameters of main FunNameStack, where it needs to do
673// "globally", before main() is started.
674// see the file FunNameStack_ts.c for example.
676 public:
677 FunNameStack_Assist(int fs_act = 1, int fs_print = 0) {
678 FunNameStack::instance().set_parameters(fs_act = 1, fs_print);
679 }
680};
681
682//extern FunNameStack funnamestack;
683
684// Object of this class FunNameWatch is created at the beginning of function.
685// At creation it writes function name in stack.
686// At deletion it deletes the name from stack,
687// checking that it is last.
688
690 int nname; // index of this name in array of FunNameStack
691 const char* name; // it is memorized independenlty on s_act.
692 // Used for printing of headers.
693 public:
694 wl_inline FunNameWatch(const char* fname);
695 /*
696 FunNameWatch(char* fname):name(fname)
697 {
698#ifdef FUNNAMESTACK
699 nname=funnamestack.put(fname);
700#else
701 nname=0;
702#endif
703 }
704 */
705 //FunNameWatch(void):name(NULL), nname(-1) { ; } // temporary
706
708 /*
709 {
710#ifdef FUNNAMESTACK
711 if( nname>=0)
712 funnamestack.del(nname);
713#endif
714 }
715 */
716
717 // print header
718 std::ostream& hdr(std::ostream& file) const {
719 file << name << ": ";
720 return file;
721 }
722 // print header with word WARNING
723 std::ostream& whdr(std::ostream& file) const {
724 file << name << ": WARNING:\n";
725 return file;
726 }
727 // print header with word ERROR
728 std::ostream& ehdr(std::ostream& file) const {
729 file << name << ": ERROR:\n";
730 return file;
731 }
732};
733std::ostream& operator<<(std::ostream& file, const FunNameWatch& f);
734
735/* It is assumed to be general basical class for catching of errors.
736Any error thrown with FunNameStack can be catched with pointer to this class.
737*/
738class GenError : public FunNameStack {
739 public:
740 GenError(const FunNameStack& f) : FunNameStack(f) { ; }
741 GenError(const GenError& f) : FunNameStack(f) { ; }
742 virtual void print(std::ostream& file);
743 virtual void finish(std::ostream& file);
744 virtual ~GenError() {}
745};
746//std::ostream& operator<<(std::ostream& file, const GenError& f);
747#ifdef WCPPLIB_INLINE
748#include "wcpplib/util/FunNameStack.ic"
749#endif
750
751#endif
std::ostream & operator<<(std::ostream &file, const FunNameStack &f)
void spexit_action(std::ostream &file)
int s_exit_without_core
const int pqname
Definition: FunNameStack.h:544
int s_throw_exception_in_spexit
ExcFromSpexit(void)
Definition: FunNameStack.h:527
FunNameStack_Assist(int fs_act=1, int fs_print=0)
Definition: FunNameStack.h:677
wl_inline int put(const char *fname)
friend std::ostream & operator<<(std::ostream &file, const FunNameStack &f)
static FunNameStack & instance()
FunNameStack & operator=(const FunNameStack &f)
wl_inline void replace(const char *fname)
void set_parameters(int fs_act=1, int fs_print=0)
wl_inline void del(int nname)
wl_inline ~FunNameWatch()
std::ostream & ehdr(std::ostream &file) const
Definition: FunNameStack.h:728
std::ostream & whdr(std::ostream &file) const
Definition: FunNameStack.h:723
std::ostream & hdr(std::ostream &file) const
Definition: FunNameStack.h:718
wl_inline FunNameWatch(const char *fname)
virtual void print(std::ostream &file)
GenError(const GenError &f)
Definition: FunNameStack.h:741
virtual ~GenError()
Definition: FunNameStack.h:744
virtual void finish(std::ostream &file)
GenError(const FunNameStack &f)
Definition: FunNameStack.h:740
#define wl_inline
Definition: inlinec.h:15