Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
exception.cpp
Go to the documentation of this file.
1
29#define _RWSTD_LIB_SRC
30
31#if 3 == __GNUG__ && 3 > __GNUC_MINOR__ \
32 || 3 == __GNUC_MINOR__ && 1 >__GNUC_PATCHLEVEL__
33
34 // working around a gcc bug (PR #29570)
35# include <rw/_config.h>
36# ifndef _RWSTD_NO_EXTERN_TEMPLATE
37# define _RWSTD_NO_EXTERN_TEMPLATE
38# endif
39#endif // gcc >= 3.0 && gcc < 3.3.1
40
41#include <rw/_defs.h>
42
43#ifndef _RWSTD_EDG_ECCP
44# include <stdarg.h>
45#else
46 // use "special" magic for the EDG eccp demo
47# include <ansi/_cstdarg.h>
48
49_USING (_STD::va_list);
50
51#endif // EDG eccp demo
52
53#include <stdlib.h>
54#include <stdio.h>
55#include <string.h>
56
57#include <loc/_locale.h>
58#include <loc/_messages.h>
59
60#include <new>
61#include <stdexcept>
62#include <string>
63#include <typeinfo>
64
65#include <rw/_error.h>
66#include <rw/_iosfailure.h>
67#include <rw/_mutex.h>
68
69#include "podarray.h" // for __rw_aligned_buffer
70
71
72#ifdef _MSC_VER
73 // MSVC's libc prepends an underscore
74# define vsnprintf _vsnprintf
75# undef _RWSTD_NO_VSNPRINTF
76#endif
77
78#if defined (_RWSTD_NO_VSNPRINTF) && !defined (_RWSTD_NO_VSNPRINTF_IN_LIBC)
79
80// vsnprintf() not declared, but it is defined in libc
81extern "C" _RWSTD_DLLIMPORT int
82vsnprintf (char*, _RWSTD_SIZE_T, const char*, va_list) _LIBC_THROWS();
83
84// use vsnprintf()
85# undef _RWSTD_NO_VSNPRINTF
86#endif // _NO_VSNPRINTF && !_NO_VSNPRINTF_IN_LIBC || !_RWSTD_NO_PURE_C_HEADERS
87
88
89#ifndef _RWSTD_NO_VSNPRINTF
90# define _RWSTD_VSNPRINTF(buf, size, fmat, va) vsnprintf (buf, size, fmat, va)
91#else
92 // unsafely work around the lack of vsnprintf by using vsprintf()
93# define _RWSTD_VSNPRINTF(buf, ignore, fmat, va) vsprintf (buf, fmat, va)
94#endif // _RWSTD_NO_VSNPRINTF
95
96
97// declare global versions of exception handlers; will be
98// used only if the functions aren't defined in namespace std
99// in the compiler support library
100
101void terminate () _RWSTD_GNUC_ATTRIBUTE ((__noreturn__));
102
105
108
109void unexpected () _RWSTD_GNUC_ATTRIBUTE ((__noreturn__));
110
111#ifdef _MSC_VER
112 // MSVC 7 and 8 reliably define __uncaught_exception
113 // uncaught_exception() only seems to be defined by some compiler
114 // magic that requires the compiler's native C++ Standard library
115 // headers
116# undef _RWSTD_NO_GLOBAL_UNCAUGHT_EXCEPTION
117# define UNCAUGHT_EXCEPTION __uncaught_exception
118#endif // MSVC
119
120#ifndef UNCAUGHT_EXCEPTION
121# define UNCAUGHT_EXCEPTION uncaught_exception
122#endif // UNCAUGHT_EXCEPTION
123
125
126
128
129// define functions in namespace std to wrap any globals defined
130// defined in the compiler support library
131
132// functions are outlined to prevent linker errors in optimized shared builds
133
134// guard definitions when compiling with gcc with -fno-honor-std
135#ifndef _RWSTD_NO_HONOR_STD
136
137# if defined (_RWSTD_NO_STD_TERMINATE)
138
139// 18.6.3.3
141{
142# ifndef _RWSTD_NO_GLOBAL_TERMINATE
143
144 ::terminate ();
145
146# else // if defined (_RWSTD_NO_GLOBAL_TERMINATE)
147
148 abort ();
149
150# endif // _RWSTD_NO_GLOBAL_TERMINATE
151
152}
153
154# endif // _RWSTD_NO_STD_TERMINATE
155
156
157# if defined (_RWSTD_NO_STD_SET_TERMINATE)
158
159// 18.6.3.2
162{
163# ifndef _RWSTD_NO_GLOBAL_SET_TERMINATE
164
165 return ::set_terminate (handler);
166
167# else // if defined (_RWSTD_NO_GLOBAL_SET_TERMINATE)
168
169 static terminate_handler current;
170
172
173 terminate_handler save = current;
174
175 current = handler;
176
177 return save;
178
179# endif // _RWSTD_NO_GLOBAL_SET_TERMINATE
180
181}
182
183# endif // _RWSTD_NO_STD_SET_TERMINATE
184
185
186# if defined (_RWSTD_NO_STD_SET_UNEXPECTED)
187
188// 18.6.2.3
191{
192# ifndef _RWSTD_NO_GLOBAL_SET_UNEXPECTED
193
194 return ::set_unexpected (handler);
195
196# else // if defined (_RWSTD_NO_GLOBAL_SET_UNEXPECTED)
197
198 static unexpected_handler current;
199
201
202 unexpected_handler save = current;
203
204 current = handler;
205
206 return save;
207
208# endif // _RWSTD_NO_GLOBAL_SET_UNEXPECTED
209
210}
211
212# endif // _RWSTD_NO_STD_SET_UNEXPECTED
213
214
215# if defined (_RWSTD_NO_STD_UNEXPECTED)
216
217// 18.6.2.4
219{
220# ifndef _RWSTD_NO_GLOBAL_UNEXPECTED
221
222 ::unexpected ();
223
224# else // if defined (_RWSTD_NO_GLOBAL_UNEXPECTED)
225
226 abort ();
227
228# endif // _RWSTD_NO_GLOBAL_UNEXPECTED
229
230}
231
232# endif // _RWSTD_NO_STD_UNEXPECTED
233
234
235# if defined (_RWSTD_NO_STD_UNCAUGHT_EXCEPTION)
236
237// 18.6.4
239{
240# ifndef _RWSTD_NO_GLOBAL_UNCAUGHT_EXCEPTION
241
242 return ::UNCAUGHT_EXCEPTION ();
243
244# else // if defined (_RWSTD_NO_GLOBAL_UNCAUGHT_EXCEPTION)
245
246# ifndef _RWSTD_NO_EXCEPTIONS
247
248 return true;
249
250# else // if defined (_RWSTD_NO_EXCEPTIONS)
251
252 return false;
253
254# endif // _RWSTD_NO_EXCEPTIONS
255
256# endif // _RWSTD_NO_GLOBAL_UNCAUGHT_EXCEPTION
257}
258
259# endif // _RWSTD_NO_STD_UNCAUGHT_EXCEPTION
260
261#endif // _RWSTD_NO_HONOR_STD
262
263} // namespace std
264
265
266#if defined _RWSTD_EXCEPTION_INCLUDED
267
268// define exception and bad_exception members only if our own
269// implementation's <exception> header (as opposed to the compiler's
270// native C++ Standard library) has been included; SunPro always
271// #includes its own, regardless of compiler options
272
273//**************************************************************************
274// class exception members
275
276# if !defined (_RWSTD_NO_STD_EXCEPTION) \
277 || !defined (_RWSTD_NO_RUNTIME_IN_STD) \
278 || 2 == __GNUG__ && !defined (_RWSTD_NO_HONOR_STD)
279
281
282# endif // !_RWSTD_NO_STD_EXCEPTION || !_RWSTD_NO_RUNTIME_IN_STD ...
283
284
285#ifdef _RWSTD_NO_EXCEPTION_DEFAULT_CTOR
286
287exception::exception () _THROWS (())
288{
289#if defined (_MSC_VER)
290
291 _C_name = 0;
292 _C_flag = 0;
293
294#elif defined (__INTEL_COMPILER)
295
296 _C_name = "";
297
298#endif // _MSC_VER
299}
300
301#endif // _RWSTD_NO_EXCEPTION_DEFAULT_CTOR
302
303#ifdef _RWSTD_NO_EXCEPTION_COPY_CTOR
304
305exception::exception (const exception&) _THROWS (())
306{
307#if defined (_MSC_VER)
308
309 _C_name = 0;
310 _C_flag = 0;
311
312#elif defined (__INTEL_COMPILER)
313
314 _C_name = "";
315
316#endif // _MSC_VER
317}
318
319#endif // _RWSTD_NO_EXCEPTION_COPY_CTOR
320
321#ifdef _RWSTD_NO_EXCEPTION_DTOR
322
323exception::~exception () _THROWS (())
324{
325 // empty
326}
327
328#endif // _RWSTD_NO_EXCEPTION_DTOR
329
330#ifdef _RWSTD_NO_EXCEPTION_ASSIGNMENT
331
333exception::operator= (const exception&) _THROWS (())
334{
335 return *this;
336}
337
338#endif // _RWSTD_NO_EXCEPTION_ASSIGNMENT
339
340#ifdef _RWSTD_NO_EXCEPTION_WHAT
341
342const char* exception::what () const _THROWS (())
343{
345}
346
347#endif // _RWSTD_NO_EXCEPTION_WHAT
348
349
350# if !defined (_RWSTD_NO_STD_EXCEPTION) \
351 || !defined (_RWSTD_NO_RUNTIME_IN_STD) \
352 || 2 == __GNUG__ && !defined (_RWSTD_NO_HONOR_STD)
353
354} // namespace std
355
356# endif // !_RWSTD_NO_STD_EXCEPTION || !_RWSTD_NO_RUNTIME_IN_STD ...
357
358
359//**************************************************************************
360// class bad_exception members
361
362# if !defined (_RWSTD_NO_STD_BAD_EXCEPTION) \
363 || !defined (_RWSTD_NO_RUNTIME_IN_STD) \
364 || 2 == __GNUG__ && !defined (_RWSTD_NO_HONOR_STD)
365
367
368# endif // !_RWSTD_NO_STD_BAD_EXCEPTION || !_RWSTD_NO_RUNTIME_IN_STD ...
369
370
371#ifdef _RWSTD_NO_BAD_EXCEPTION_DEFAULT_CTOR
372
373bad_exception::bad_exception () _THROWS (())
374 : exception ()
375{
376}
377
378#endif // _RWSTD_NO_BAD_EXCEPTION_DEFAULT_CTOR
379
380#ifdef _RWSTD_NO_BAD_EXCEPTION_COPY_CTOR
381
382bad_exception::bad_exception (const bad_exception &rhs) _THROWS (())
383 : exception (rhs)
384{
385}
386
387#endif // _RWSTD_NO_BAD_EXCEPTION_COPY_CTOR
388
389#ifdef _RWSTD_NO_BAD_EXCEPTION_DTOR
390
391bad_exception::~bad_exception () _THROWS (())
392{
393 // empty
394}
395
396#endif // _RWSTD_NO_BAD_EXCEPTION_DTOR
397
398#ifdef _RWSTD_NO_BAD_EXCEPTION_ASSIGNMENT
399
401bad_exception::operator= (const bad_exception &rhs) _THROWS (())
402{
403 exception::operator= (rhs);
404
405 return *this;
406}
407
408#endif // _RWSTD_NO_BAD_EXCEPTION_ASSIGNMENT
409
410#ifdef _RWSTD_NO_BAD_EXCEPTION_WHAT
411
412const char* bad_exception::what () const _THROWS (())
413{
415}
416
417#endif // _RWSTD_NO_BAD_EXCEPTION_WHAT
418
419
420# if !defined (_RWSTD_NO_STD_BAD_EXCEPTION) \
421 || !defined (_RWSTD_NO_RUNTIME_IN_STD) \
422 || 2 == __GNUG__ && !defined (_RWSTD_NO_HONOR_STD)
423
424} // namespace std
425
426# endif // !_RWSTD_NO_STD_BAD_EXCEPTION || !_RWSTD_NO_RUNTIME_IN_STD ...
427
428#endif // _RWSTD_EXCEPTION_INCLUDED
429
430
433
434
435static _RWSTD_THREAD char
436__rw_what_buf [256];
437
438static _RWSTD_THREAD int
439__rw_what_refcnt;
440
441// free memory buffer allocated in __rw_vfmtwhat()
442_RWSTD_EXPORT void __rw_free_what_buf (char* buf)
443{
444 if (__rw_what_buf == buf) {
445 _RWSTD_ASSERT (0 < __rw_what_refcnt);
446 _RWSTD_THREAD_PREDECREMENT (__rw_what_refcnt, false);
447 }
448 else
449 delete[] buf;
450}
451
452// allocate a char array and format it sprintf-style
453// caller responsible for calling delete[] on returned pointer
454// unless a non-zero buffer of non-zero size is passed in
455static char*
456__rw_vfmtwhat (char *buf, // (allocate if 0)
457 _RWSTD_SIZE_T bufsize, // buffer size (0 if none)
458 const char *fmat, // printf-style fmat string
459 va_list va) // variable arguments
460{
461 _RWSTD_ASSERT (0 != fmat);
462 _RWSTD_ASSERT (0 == buf || bufsize);
463
464#ifndef _RWSTD_NO_VSNPRINTF
465 // initial size of buffer, may be increased as needed
466 _RWSTD_SIZE_T size = bufsize ? bufsize : 256;
467#else
468 // unsafely work around the lack of vsnprintf by using vsprintf()
469 _RWSTD_SIZE_T size = bufsize ? bufsize : strlen (fmat);
470 size = size < 1024 ? 1024 : size * 2;
471#endif // _RWSTD_NO_VSNPRINTF
472
473 if (!buf) {
474
475 if (1 == _RWSTD_THREAD_PREINCREMENT (__rw_what_refcnt, false)) {
476 buf = __rw_what_buf;
477 }
478 else {
479 buf = new char [size];
480
481 _RWSTD_THREAD_PREDECREMENT (__rw_what_refcnt, false);
482 }
483 }
484
485 for ( ; ; ) {
486
487 // vsnprintf() return value
488 //
489 // 7.19.6.12, p3 of C99:
490 //
491 // The vsnprintf function returns the number of characters that
492 // would have been written had n been sufficiently large, not
493 // counting the terminating null character, or a neg ative value
494 // if an encoding error occurred. Thus, the null-terminated output
495 // has been completely written if and only if the returned value
496 // is nonnegative and less than n.
497 //
498 // HP-UX and Windows are known to return a negative value for
499 // buffer overflow.
500
501 // On IRIX and Tru64 UNIX on overflow the function returns
502 // the number of bytes actually written to the buffer which
503 // makes it indistinguishable from a successful return value
504 // for a completely full buffer.
505
506 // Others (AIX, Linux, and Solaris) follow the C99 requirement.
507
508 int nwrote;
509
510 // copy va to a temporary and use it in each iteration
511 // of the loop since it may be modified by the call to
512 // vsnprintf() (e.g., on PowerPC/Linux)
513
514 va_list tmp_va;
515 _RWSTD_VA_COPY (tmp_va, va);
516
517 nwrote = _RWSTD_VSNPRINTF (buf, size, fmat, tmp_va);
518
519 va_end (tmp_va);
520
521 if (0 > nwrote) {
522
523#ifdef _RWSTD_NO_VSNPRINTF_VFLOW_VALID
524
525 // set the number of bytes written to 0 to indicate
526 // that the buffer isn't big enough without actually
527 // telling how big it needs to be
528 nwrote = 0;
529
530#else // if !defined (_RWSTD_NO_VSNPRINTF_VFLOW_VALID)
531
532 // conversion error
533 *buf = '\0';
534 break;
535
536#endif // _RWSTD_NO_VSNPRINTF_VFLOW_VALID
537
538 }
539
540#ifdef _RWSTD_NO_VSNPRINTF_VFLOW_VALID
541
542 if (nwrote >= int (size) - 1) {
543 // indicate insufficient buffer size
544 nwrote = 0;
545 }
546
547#endif // _RWSTD_NO_VSNPRINTF_VFLOW_VALID
548
549 if (0 == nwrote)
550 size *= 2;
551 else if (int (size) <= nwrote)
552 size = nwrote + 1U;
553 else
554 break;
555
556 // fail if a buffer of insufficient size was passed in
557 if (bufsize)
558 return 0;
559
560 __rw_free_what_buf (buf);
561 buf = new char [size];
562 }
563
564 return buf;
565}
566
567
568static
569char* __rw_vfmtwhat (char *buf, // buffer (allocate if 0)
570 _RWSTD_SIZE_T bufsize, // size of buffer or 0
571 int id, // catalog id of fmt string
572 va_list va) // variable arguments
573{
574 typedef _STD::messages<char> _Msgs;
575
576 static const char *__fname = 0; // catalog file
577 static int __catset = 1; // catalog set
578 static _Msgs::catalog __cat = -1; // catalog id
579
580 // facet must never be destroyed
581 static __rw_aligned_buffer<_Msgs> msgs;
582
583 // try to open catalog if first time through only
584 if (!__fname) {
585
587
588 // double-check to prevent a race opening a catalog more than once
589 if (!__fname) {
590
591 // get catalog name (absolute or relative) from the environment
592 char *__fn = getenv (_RWSTD_ERROR_ENVVAR);
593
594 // use default hardcoded name if variable doesn't exist
595 if (!__fn) {
596 // copy literal into static buffer (will be modified)
597 static char buffer[] = _RWSTD_ERROR_CATALOG;
598 __fn = buffer;
599 }
600
601 // catalog name may optionally be followed by a `:' and a set number
602 char *__set = strrchr (__fn, ':');
603 if (__set) {
604 *__set++ = '\0';
605 if ( 1 != sscanf (__set, "%d", &__catset)
606 || __catset <= 0)
607 __catset = 1;
608 }
609
610 new (msgs._C_store ()) _Msgs;
611
612 // assign `fname' _after_ opening catalog to prevent a race
613 // between calling messages<>::open() and messages<>::get()
614 // always use the classic locale, not the current snapshot
615 __cat = msgs._C_data ()->open (__fn, _STD::locale::classic ());
616 __fname = __fn;
617 }
618 }
619
620 if (-1 == __cat)
621 return 0; // indicate a falure to open catalog
622
624
625 // retrieve error message from catalog and use it to format args
626 _STD::string fmat = msgs._C_data ()->get (__cat, __catset, id, "");
627
628 if (fmat.empty ())
629 return 0; // failure to retrieve message
630
631 return __rw_vfmtwhat (buf, bufsize, fmat.data (), va);
632}
633
634#ifdef _RWSTD_REENTRANT
635
636extern const char* const __rw_mutex_exception =
637 "Thread synchronization exception.";
638
639#else // if !defined (_RWSTD_REENTRANT)
640
641// dummy empty object (not an actual mutex) - allows lib to "look"
642// the same in single-threaded mode as in multi-threaded mode
643__rw_mutex _RWSTD_EXPORT __rw_synchronized::_C_mutex;
644
645#endif // _RWSTD_REENTRANT
646
647
648static void __rw_throw_exception (int id, char *what)
649{
650#ifndef _RWSTD_NO_EXCEPTIONS
651
652 // exception, bad_exception, bad_cast, and bad_alloc
653 // each or may not be defined in namespace std; avoid
654 // complicated preprocessor logic by introducing the
655 // whole namespace into scope
656 _USING (namespace std);
657
658 switch (id) {
659 case _RWSTD_ERROR_FIRST + 1:
660 throw exception ();
661
662 case _RWSTD_ERROR_FIRST + 2:
663 throw bad_exception ();
664
665 case _RWSTD_ERROR_FIRST + 3:
666
667#ifndef _RWSTD_BAD_ALLOC
668# ifndef _RWSTD_NO_RUNTIME_IN_STD
669 throw std::bad_alloc ();
670# else
671 throw bad_alloc ();
672# endif // _RWSTD_NO_RUNTIME_IN_STD
673#else // if defined (_RWSTD_BAD_ALLOC)
674 throw _RWSTD_BAD_ALLOC ();
675#endif // _RWSTD_BAD_ALLOC
676
678 throw bad_cast ();
679
681 throw (_STD::logic_error&)_STD::logic_error ()._C_assign (what, 0);
682
684 throw (_STD::domain_error&)_STD::domain_error ()._C_assign (what, 0);
685
687 throw (_STD::invalid_argument&)
688 _STD::invalid_argument ()._C_assign (what, 0);
689
691 throw (_STD::length_error&)_STD::length_error ()._C_assign (what, 0);
692
694 throw (_STD::out_of_range&)_STD::out_of_range ()._C_assign (what, 0);
695
697 throw (_STD::runtime_error&)
698 _STD::runtime_error ()._C_assign (what, 0);
699
701 throw (_STD::range_error&)_STD::range_error ()._C_assign (what, 0);
702
704 throw (_STD::overflow_error&)
705 _STD::overflow_error ()._C_assign (what, 0);
706
708 throw (_STD::underflow_error&)
709 _STD::underflow_error ()._C_assign (what, 0);
710
711#ifndef _RWSTD_NO_EXT_FAILURE
712
714 throw (__rw_failbit_set&)
715 __rw_failbit_set ()._C_assign (what, 0);
716
718 throw (__rw_badbit_set&)
719 __rw_badbit_set ()._C_assign (what, 0);
720
722 throw (__rw_eofbit_set&)
723 __rw_eofbit_set ()._C_assign (what, 0);
724
725#else // if defined (_RWSTD_NO_EXT_FAILURE)
726
730 // fall through...
731
732#endif // _RWSTD_NO_EXT_FAILURE
733
735 throw (__rw_failure&)
736 __rw_failure ()._C_assign (what, 0);
737
744 throw (_STD::runtime_error&)
745 _STD::runtime_error ()._C_assign (what, 0);
746 }
747
748 __rw_free_what_buf (what);
749
750#else // if defined (_RWSTD_NO_EXCEPTIONS)
751
752 if (what) {
753 fprintf (stderr,"Exception: %s.\n", what);
754 __rw_free_what_buf (what);
755 }
756 else {
757 const char *__str;
758 switch (id) {
759 case _RWSTD_ERROR_FIRST + 0: __str = _RWSTD_ERROR_EXCEPTION; break;
760 case _RWSTD_ERROR_FIRST + 1: __str = _RWSTD_ERROR_BAD_EXCEPTION; break;
761 case _RWSTD_ERROR_FIRST + 2: __str = _RWSTD_ERROR_BAD_ALLOC; break;
762 default: __str = "unknown exception";
763 }
764
765 fprintf (stderr, "Exception: %s.\n", __str);
766 }
767
768 abort ();
769
770#endif // _RWSTD_NO_EXCEPTIONS
771}
772
773// may be assigned to a user-defined handler (e.g., to prevent
774// the library from throwing exceptions or to implement logging)
775_RWSTD_EXPORT void (*__rw_throw_proc)(int, char*) = __rw_throw_exception;
776
777
778_RWSTD_EXPORT void __rw_throw (int id, ...)
779{
780 if (!__rw_throw_proc)
781 return;
782
783 // do not allocate or format string for exception,
784 // bad_alloc, bad_cast, bad_exception, or bad_cast
785 if (id <= _RWSTD_ERROR_BAD_CAST) {
786 __rw_throw_proc (id, 0);
787 }
788 else {
789 va_list va;
790 va_start (va, id);
791
792#ifdef va_copy
793
794 // copy va to a temporary and use it in the first call
795 // to __rw_vfmtwhat() since it may be modified by the
796 // call and rendered invalid for subsequent use (e.g.,
797 // on PowerPC/Linux)
798
799 va_list tmp_va;
800 va_copy (tmp_va, va);
801
802 // try to format a string (look up format in a catalog)...
803 char *what = _RW::__rw_vfmtwhat (0, 0, id, tmp_va);
804
805 va_end (tmp_va);
806
807#else // if !defined (va_copy)
808
809 char *what = _RW::__rw_vfmtwhat (0, 0, id, va);
810
811#endif // va_copy
812
813
814 if (!what) {
815 // obtain an index into table of error strings
816 id -= _RWSTD_ERROR_FIRST;
817
818 static const char* const errors[] = { _RWSTD_ERROR_STRINGS };
819
820 // make sure index is valid
821 if (id < 0 || id >= int (sizeof errors / sizeof *errors))
822 id = 0;
823
824 // use error string to format
825 what = _RW::__rw_vfmtwhat (0, 0, errors [id], va);
826 }
827
828 // end va list before throwing
829 va_end (va);
830
831 // throw_proc takes ownership of allocated string
832 __rw_throw_proc (id, what);
833 }
834}
835
836
837__rw_exception::__rw_exception () _THROWS (())
838 : _STD::exception (), _C_what (0) { }
839
840
841__rw_exception::__rw_exception (const __rw_exception &rhs)
842 : _STD::exception (rhs), _C_what (0)
843{
844 _C_assign (rhs.what ());
845}
846
847
848/* explicit */ __rw_exception::__rw_exception (const char *str)
849 : _STD::exception (), _C_what (0)
850{
851 _C_assign (str);
852}
853
854
855// outlined to avoid circular dependency on <string>
856__rw_exception::__rw_exception (const _STD::string &whatstr)
857 : _C_what (0)
858{
859 _C_assign (whatstr.c_str (), whatstr.length ());
860}
861
862
863// outlined to avoid functional compatibility issues
864/* virtual */ __rw_exception::~__rw_exception () _THROWS (())
865{
866 __rw_free_what_buf (_C_what);
867
868#ifdef _C_dummy_what
869 // zero out dummy member of the base exception class
870 // to prevent the base dtor from trying to do the same
871 // (MSVC 6.0 only)
872 _C_dummy_what = 0;
873#endif // _C_dummy_what
874
875}
876
877
878// empty exception specification necessary in order to preserve
879// the no-exception guarantee provided by std::exception to
880// derived classes (e.g., logic_error)
881__rw_exception& __rw_exception::
882operator= (const __rw_exception &__rhs) _THROWS (())
883{
884 _C_assign (__rhs.what ());
885
886 return *this;
887}
888
889
890/* virtual */ const char* __rw_exception::
891what () const _THROWS (())
892{
893 // `what' may be 0 indicating the empty string as an optimization
894 return _C_what ? _C_what : "";
895}
896
897
898// assigns the argument to our string by allocating sufficient space
899// and copying the string; if `what' is null or `what' points to the
900// empty string (""), deletes buffer and assigns 0
901// if `what' is non-null and non-empty but `len' is 0, simply assigns
902// `what' to the internal pointer and takes ownership of it
903__rw_exception& __rw_exception::
904_C_assign (const char *whatstr, size_t len /* = ~0 */)
905{
906 if (whatstr != _C_what) {
907 char *tmp = 0;
908
909 if (whatstr && *whatstr) {
910
911 if (whatstr == __rw_what_buf) {
912 if (len)
913 _RWSTD_THREAD_PREINCREMENT (__rw_what_refcnt, false);
914 tmp = __rw_what_buf;
915 }
916 else {
917 if (_RWSTD_SIZE_MAX == len)
918 len = strlen (whatstr);
919
920 if (len) {
921 // allocate own buffer and copy string
922 tmp = new char [len + 1];
923 memcpy (tmp, whatstr, len + 1);
924 }
925 else {
926 // special case: do not allocate, just use passed in pointer
927 tmp = _RWSTD_CONST_CAST (char*, whatstr);
928 }
929 }
930 }
931
932 __rw_free_what_buf (_C_what);
933 _C_what = tmp;
934 }
935 return *this;
936}
937
938
939// trivial dtors outlined to reduce code bloat caused by compilers that
940// emit the vtbl in every translation unit containing the definition of
941// the class
942
943// virtual dtor
944/* virtual */ __rw_failure::~__rw_failure () _THROWS (())
945{
946 // no-op
947}
948
949
950/* virtual */ __rw_badbit_set::~__rw_badbit_set () _THROWS (())
951{
952 // no-op
953}
954
955
956/* virtual */ __rw_eofbit_set::~__rw_eofbit_set () _THROWS (())
957{
958 // no-op
959}
960
961
962/* virtual */ __rw_failbit_set::~__rw_failbit_set () _THROWS (())
963{
964 // no-op
965}
966
967
968} // namespace __rw
#define rhs
Definition 17.names.cpp:536
#define __fn
Definition 17.names.cpp:596
#define buf
Definition 17.names.cpp:452
#define buffer
Definition 17.names.cpp:453
#define tmp
Definition 17.names.cpp:553
#define len
Definition 17.names.cpp:488
#define save
Definition 17.names.cpp:538
const char *const errors[]
Definition 19.cerrno.cpp:34
#define bad_alloc
void handler()
void(* terminate_handler)()
void(* unexpected_handler)()
#define _THROWS()
int set_terminate()
int set_unexpected()
bool(* uncaught_exception)()
#define _RWSTD_THREAD
Definition TLS.cpp:30
#define _RWSTD_GNUC_ATTRIBUTE(attr)
Definition _config-gcc.h:85
#define _RWSTD_DLLIMPORT
Definition _config.h:391
#define va_end(ignore)
#define va_start(va, name)
#define stderr
#define _RWSTD_THREAD_PREDECREMENT(x, mutex)
Definition _defs.h:728
#define _RWSTD_THREAD_PREINCREMENT(x, mutex)
Definition _defs.h:723
#define _STD
Definition _defs.h:571
#define _RWSTD_VA_COPY(va_dst, va_src)
Definition _defs.h:1597
#define _RWSTD_EXPORT
Definition _defs.h:485
#define _LIBC_THROWS()
Definition _defs.h:1152
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _USING(name)
Definition _defs.h:568
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
#define _RWSTD_MT_STATIC_GUARD(name)
Definition _defs.h:696
#define _RWSTD_ERROR_FACET_NOT_FOUND
Definition _error.h:104
#define _RWSTD_ERROR_OVERFLOW_ERROR
Definition _error.h:96
#define _RWSTD_ERROR_BAD_ALLOC
Definition _error.h:144
#define _RWSTD_ERROR_IOSTATE_BIT_SET
Definition _error.h:102
#define _RWSTD_ERROR_BAD_CAST
Definition _error.h:88
#define _RWSTD_ERROR_BAD_POINTER
Definition _error.h:109
#define _RWSTD_ERROR_RUNTIME_ERROR
Definition _error.h:94
#define _RWSTD_ERROR_LOCALE_BAD_NAME
Definition _error.h:105
#define _RWSTD_ERROR_STRINGS
Definition _error.h:113
#define _RWSTD_ERROR_FAILBIT_SET
Definition _error.h:99
#define _RWSTD_ERROR_FIRST
Definition _error.h:78
#define _RWSTD_ERROR_RANGE_ERROR
Definition _error.h:95
#define _RWSTD_ERROR_LOGIC_ERROR
Definition _error.h:89
#define _RWSTD_ERROR_LENGTH_ERROR
Definition _error.h:92
#define _RWSTD_ERROR_INVALID_ARGUMENT
Definition _error.h:91
#define _RWSTD_ERROR_BADBIT_SET
Definition _error.h:100
#define _RWSTD_ERROR_LOCALE_BAD_CAT
Definition _error.h:111
#define _RWSTD_ERROR_OUT_OF_RANGE
Definition _error.h:93
#define _RWSTD_ERROR_CATALOG
Definition _error.h:67
#define _RWSTD_ERROR_UNDERFLOW_ERROR
Definition _error.h:97
#define _RWSTD_ERROR_CODECVT
Definition _error.h:107
#define _RWSTD_ERROR_BAD_EXCEPTION
Definition _error.h:143
#define _RWSTD_ERROR_EXCEPTION
Definition _error.h:142
#define _RWSTD_ERROR_DOMAIN_ERROR
Definition _error.h:90
#define _RWSTD_ERROR_ENVVAR
Definition _error.h:73
#define _RWSTD_ERROR_LOCALE_ERROR_NAME
Definition _error.h:106
#define _RWSTD_ERROR_EOFBIT_SET
Definition _error.h:101
#define exception
Definition _math.h:43
const char * str
Definition exec.cpp:170
Definition json.h:5363
#define _RWSTD_BAD_ALLOC
Definition rw_new.h:141
#define _RWSTD_VSNPRINTF(buf, size, fmat, va)
Definition exception.cpp:90
#define UNCAUGHT_EXCEPTION
void terminate() _RWSTD_GNUC_ATTRIBUTE((__noreturn__))
void unexpected() _RWSTD_GNUC_ATTRIBUTE((__noreturn__))