epoc32/include/stdapis/stlport/stl/debug/_debug.c
author William Roberts <williamr@symbian.org>
Tue, 16 Mar 2010 16:12:26 +0000
branchSymbian2
changeset 2 2fe1408b6811
parent 0 061f57f2323e
permissions -rw-r--r--
Final list of Symbian^2 public API header files
     1 /*
     2  * © Portions copyright (c) 2006-2007 Nokia Corporation.  All rights reserved.
     3  *
     4  * Copyright (c) 1997
     5  * Moscow Center for SPARC Technology
     6  *
     7  * Copyright (c) 1999 
     8  * Boris Fomitchev
     9  *
    10  * This material is provided "as is", with absolutely no warranty expressed
    11  * or implied. Any use is at your own risk.
    12  *
    13  * Permission to use or copy this software for any purpose is hereby granted 
    14  * without fee, provided the above notices are retained on all copies.
    15  * Permission to modify the code and to distribute modified code is granted,
    16  * provided the above notices are retained, and a notice that the code was
    17  * modified is included with the above copyright notice.
    18  *
    19  */
    20 
    21 # ifndef _STLP_DEBUG_C
    22 #  define  _STLP_DEBUG_C
    23 
    24 #if defined ( _STLP_DEBUG )
    25 
    26 # ifdef _STLP_THREADS
    27 #  ifndef _STLP_NEED_MUTABLE 
    28 #   define _STLP_ACQUIRE_LOCK(_Lock) _Lock._M_acquire_lock();
    29 #   define _STLP_RELEASE_LOCK(_Lock) _Lock._M_release_lock();
    30 #  else
    31 #   define _STLP_ACQUIRE_LOCK(_Lock) ((_STLP_mutex&)_Lock)._M_acquire_lock();
    32 #   define _STLP_RELEASE_LOCK(_Lock) ((_STLP_mutex&)_Lock)._M_release_lock();
    33 #  endif /* _STLP_NEED_MUTABLE */
    34 # else
    35 #  define _STLP_ACQUIRE_LOCK(_Lock)
    36 #  define _STLP_RELEASE_LOCK(_Lock)
    37 # endif /* _STLP_THREADS */
    38 
    39 _STLP_BEGIN_NAMESPACE
    40 
    41 //==========================================================
    42 //  global non-inline functions
    43 //==========================================================
    44 
    45 // [ i1, i2)
    46 template <class _Iterator>
    47 inline bool  _STLP_CALL
    48 __in_range_aux(const _Iterator& __it, const _Iterator& __first,
    49                const _Iterator& __last, const random_access_iterator_tag &) {
    50     return ( __it >= __first && 
    51              __it < __last);
    52 }
    53 
    54 template <class _Iterator1, class _Iterator>
    55 # if defined (_STLP_MSVC) && (_STLP_MSVC >= 1100)
    56 inline bool _STLP_CALL  __in_range_aux(_Iterator1 __it, const _Iterator& __first,
    57 # else
    58 inline bool _STLP_CALL  __in_range_aux(const _Iterator1& __it, const _Iterator& __first,
    59 # endif
    60                                        const _Iterator& __last, const forward_iterator_tag &) {
    61     _Iterator1 __i(__first);
    62     for (;  __i != __last && __i != __it; ++__i);
    63     return (__i!=__last);
    64 }
    65 
    66 # if defined (_STLP_NONTEMPL_BASE_MATCH_BUG)
    67 template <class _Iterator1, class _Iterator>
    68 inline bool  _STLP_CALL
    69 __in_range_aux(const _Iterator1& __it, const _Iterator& __first,
    70                const _Iterator& __last, const bidirectional_iterator_tag &) {
    71     _Iterator1 __i(__first);
    72     for (;  __i != __last && __i != __it; ++__i);
    73     return (__i !=__last);
    74 }
    75 # endif
    76 
    77 template <class _Iterator>
    78 bool _STLP_CALL  __check_range(const _Iterator& __first, const _Iterator& __last) {
    79     _STLP_VERBOSE_RETURN(__valid_range(__first,__last), _StlMsg_INVALID_RANGE )
    80     return true;
    81 }
    82 
    83 template <class _Iterator>
    84 bool _STLP_CALL  __check_range(const _Iterator& __it, 
    85                                const _Iterator& __start, const _Iterator& __finish) {
    86     _STLP_VERBOSE_RETURN(__in_range(__it,__start, __finish), 
    87                          _StlMsg_NOT_IN_RANGE_1)
    88     return true;
    89 }
    90 
    91 template <class _Iterator>
    92 bool _STLP_CALL  __check_range(const _Iterator& __first, const _Iterator& __last, 
    93                                const _Iterator& __start, const _Iterator& __finish) {
    94     _STLP_VERBOSE_RETURN(__in_range(__first, __last, __start, __finish), 
    95                          _StlMsg_NOT_IN_RANGE_2)
    96     return true;
    97 }
    98 
    99 //===============================================================
   100 
   101 template <class _Iterator>
   102 void  _STLP_CALL __invalidate_range(const __owned_list* __base, 
   103                                     const _Iterator& __first,
   104                                     const _Iterator& __last)
   105 {
   106     typedef _Iterator* _Safe_iterator_ptr;
   107     typedef __owned_link _L_type;
   108     _STLP_ACQUIRE_LOCK(__base->_M_lock)
   109     _L_type* __pos;
   110     _L_type* __prev;
   111 
   112     for (__prev = (_L_type*)&__base->_M_node, __pos= (_L_type*)__prev->_M_next; 
   113          __pos!=0;) {	    
   114         if ((!(&__first == (_Iterator*)__pos || &__last == (_Iterator*)__pos))
   115             &&  __in_range_aux(
   116 			       ((_Iterator*)__pos)->_M_iterator,
   117 			       __first._M_iterator,
   118 			       __last._M_iterator,
   119 			       _STLP_ITERATOR_CATEGORY(__first, _Iterator))) {
   120 	  __pos->_M_owner = 0;
   121 	  __pos = (_L_type*) (__prev->_M_next = __pos->_M_next);
   122 	}
   123 	else {
   124 	  __prev = __pos;
   125 	  __pos=(_L_type*)__pos->_M_next;
   126 	}
   127     }
   128     _STLP_RELEASE_LOCK(__base->_M_lock)    
   129 }
   130 
   131 template <class _Iterator>
   132 void  _STLP_CALL __invalidate_iterator(const __owned_list* __base, 
   133                                        const _Iterator& __it)
   134 {
   135     typedef __owned_link   _L_type;
   136     _L_type*  __position, *__prev;
   137     _STLP_ACQUIRE_LOCK(__base->_M_lock)
   138     for (__prev = (_L_type*)&__base->_M_node, __position = (_L_type*)__prev->_M_next; 
   139          __position!= 0;) {
   140       // this requires safe iterators to be derived from __owned_link
   141        if ((__position != (_L_type*)&__it) && ((_Iterator*)__position)->_M_iterator ==__it._M_iterator) {
   142 	    __position->_M_owner = 0;
   143 	    __position = (_L_type*) (__prev->_M_next = __position->_M_next);
   144         }
   145        else {
   146 	 __prev = __position;
   147 	 __position=(_L_type*)__position->_M_next;
   148        }
   149     }
   150     _STLP_RELEASE_LOCK(__base->_M_lock)
   151 }
   152 
   153 _STLP_END_NAMESPACE
   154 
   155 # endif /* _STLP_DEBUG */
   156 
   157 # if defined (_STLP_EXPOSE_GLOBALS_IMPLEMENTATION)
   158 
   159 // dwa 12/26/99 -- for abort
   160 #  if defined (_STLP_USE_NEW_C_HEADERS)
   161 #   include <cstdlib>
   162 #  else
   163 #   include <stdlib.h>
   164 #  endif
   165 
   166 # if defined (_STLP_WIN32)
   167 #  include <stl/_threads.h>
   168 # endif
   169 
   170 //==========================================================
   171 // .c section
   172 //  owned_list non-inline methods and global functions 
   173 //==========================================================
   174 
   175 #if defined ( _STLP_ASSERTIONS )
   176 
   177 _STLP_BEGIN_NAMESPACE
   178 
   179 # ifndef _STLP_STRING_LITERAL
   180 # define _STLP_STRING_LITERAL(__x) __x
   181 # endif
   182 
   183 # ifdef _STLP_WINCE
   184 #  define _STLP_PERCENT_S "%hs" 
   185 # else
   186 #  define _STLP_PERCENT_S "%s" 
   187 # endif
   188 
   189 # define _STLP_MESSAGE_TABLE_BODY = { \
   190 _STLP_STRING_LITERAL("\n" _STLP_PERCENT_S "(%d): STL error: %s\n"), \
   191 _STLP_STRING_LITERAL(_STLP_PERCENT_S "(%d): STL assertion failure : " _STLP_PERCENT_S "\n" _STLP_ASSERT_MSG_TRAILER), \
   192 _STLP_STRING_LITERAL("\n" _STLP_PERCENT_S "(%d): STL error : " _STLP_PERCENT_S "\n" _STLP_PERCENT_S "(%d): STL assertion failure:     " _STLP_PERCENT_S " \n" _STLP_ASSERT_MSG_TRAILER), \
   193 _STLP_STRING_LITERAL("Invalid argument to operation (see operation documentation)"),                  \
   194 _STLP_STRING_LITERAL("Taking an iterator out of destroyed (or otherwise corrupted) container"),       \
   195 _STLP_STRING_LITERAL("Trying to extract an object out from empty container"),\
   196 _STLP_STRING_LITERAL("Past-the-end iterator could not be erased"),  \
   197 _STLP_STRING_LITERAL("Index out of bounds"),  \
   198 _STLP_STRING_LITERAL("Container doesn't own the iterator"),  \
   199 _STLP_STRING_LITERAL("Uninitialized or invalidated (by mutating operation) iterator used"),  \
   200 _STLP_STRING_LITERAL("Uninitialized or invalidated (by mutating operation) lefthand iterator in expression"),  \
   201 _STLP_STRING_LITERAL("Uninitialized or invalidated (by mutating operation) righthand iterator in expression"),  \
   202 _STLP_STRING_LITERAL("Iterators used in expression are from different owners"),  \
   203 _STLP_STRING_LITERAL("Iterator could not be dereferenced (past-the-end ?)"),  \
   204 _STLP_STRING_LITERAL("Range [first,last) is invalid"),  \
   205 _STLP_STRING_LITERAL("Iterator is not in range [first,last)"),  \
   206 _STLP_STRING_LITERAL("Range [first,last) is not in range [start,finish)"),  \
   207 _STLP_STRING_LITERAL("The advance would produce invalid iterator"),  \
   208 _STLP_STRING_LITERAL("Iterator is singular (advanced beyond the bounds ?)"),  \
   209 _STLP_STRING_LITERAL("Memory block deallocated twice"),  \
   210 _STLP_STRING_LITERAL("Deallocating a block that was never allocated"),  \
   211 _STLP_STRING_LITERAL("Deallocating a memory block allocated for another type"),  \
   212 _STLP_STRING_LITERAL("Size of block passed to deallocate() doesn't match block size"),  \
   213 _STLP_STRING_LITERAL("Pointer underrun - safety margin at front of memory block overwritten"),  \
   214 _STLP_STRING_LITERAL("Pointer overrrun - safety margin at back of memory block overwritten"),   \
   215 _STLP_STRING_LITERAL("Attempt to dereference null pointer returned by auto_ptr::get()"),   \
   216 _STLP_STRING_LITERAL("Unknown problem") \
   217   }
   218 
   219 # if ( _STLP_STATIC_TEMPLATE_DATA > 0 )
   220 #ifdef __SYMBIAN32__
   221 template <class _Dummy>
   222 const char* __stl_debug_engine<_Dummy>::_Message_table[_StlMsg_MAX];//  _STLP_MESSAGE_TABLE_BODY;
   223 #else
   224 template <class _Dummy>
   225 const char* __stl_debug_engine<_Dummy>::_Message_table[_StlMsg_MAX]  _STLP_MESSAGE_TABLE_BODY;
   226 #endif
   227 
   228 # else
   229 __DECLARE_INSTANCE(const char*, __stl_debug_engine<bool>::_Message_table[_StlMsg_MAX],
   230 		   _STLP_MESSAGE_TABLE_BODY);
   231 
   232 # endif
   233 
   234 # undef _STLP_STRING_LITERAL
   235 # undef _STLP_PERCENT_S
   236 _STLP_END_NAMESPACE
   237 
   238 // abort()
   239 #    include <cstdlib>
   240 
   241 #  if !defined( _STLP_DEBUG_MESSAGE )
   242 
   243 #    include <cstdarg>
   244 #    include <cstdio>
   245 
   246 _STLP_BEGIN_NAMESPACE
   247 
   248 template <class _Dummy>
   249 void _STLP_CALL  
   250 __stl_debug_engine<_Dummy>::_Message(const char * __format_str, ...)
   251 {
   252 	STLPORT_CSTD::va_list __args;
   253 	va_start( __args, __format_str );
   254 
   255 # if defined (_STLP_WINCE)
   256 	TCHAR __buffer[512];
   257 	int _convert = strlen(__format_str) + 1;
   258 	LPWSTR _lpw = (LPWSTR)alloca(_convert*sizeof(wchar_t));
   259 	_lpw[0] = '\0';
   260 	MultiByteToWideChar(GetACP(), 0, __format_str, -1, _lpw, _convert);
   261 	wvsprintf(__buffer, _lpw, __args);
   262 	//	wvsprintf(__buffer, __format_str, __args);
   263 	_STLP_WINCE_TRACE(__buffer);
   264 # elif defined (_STLP_WIN32) && ( defined(_STLP_MSVC) || defined (__ICL) || defined (__BORLANDC__)) && ! defined (__WINS__)
   265     char __buffer [4096];
   266     _vsnprintf(__buffer, sizeof(__buffer) / sizeof(char),
   267                __format_str, __args);
   268     OutputDebugStringA(__buffer);
   269 # elif defined (__amigaos__)
   270     STLPORT_CSTD::vfprintf(stderr, __format_str, (char *)__args);
   271 # else
   272     STLPORT_CSTD::vfprintf(stderr, __format_str, __args);
   273 # endif /* WINCE */
   274 
   275 # ifdef _STLP_DEBUG_MESSAGE_POST
   276 	_STLP_DEBUG_MESSAGE_POST
   277 # endif
   278 
   279     va_end(__args);
   280 
   281 }
   282 
   283 _STLP_END_NAMESPACE
   284 
   285 #  endif /* _STLP_DEBUG_MESSAGE */
   286 
   287 
   288 _STLP_BEGIN_NAMESPACE
   289 
   290 
   291 template <class _Dummy>
   292 void _STLP_CALL  
   293 __stl_debug_engine<_Dummy>::_IndexedError(int __error_ind, const char* __f, int __l)
   294 {
   295   __stl_debug_message(_Message_table[_StlFormat_ERROR_RETURN], 
   296 		      __f, __l, _Message_table[__error_ind]);
   297 }
   298 
   299 template <class _Dummy>
   300 void _STLP_CALL  
   301 __stl_debug_engine<_Dummy>::_VerboseAssert(const char* __expr, int __error_ind, const char* __f, int __l)
   302 {
   303   __stl_debug_message(_Message_table[_StlFormat_VERBOSE_ASSERTION_FAILURE],
   304 		      __f, __l, _Message_table[__error_ind], __f, __l, __expr);
   305   __stl_debug_terminate();
   306 }
   307 
   308 template <class _Dummy>
   309 void _STLP_CALL 
   310 __stl_debug_engine<_Dummy>::_Assert(const char* __expr, const char* __f, int __l)
   311 {
   312   __stl_debug_message(_Message_table[_StlFormat_ASSERTION_FAILURE],__f, __l, __expr);
   313   __stl_debug_terminate();
   314 }
   315 
   316 // if exceptions are present, sends unique exception
   317 // if not, calls abort() to terminate
   318 template <class _Dummy>
   319 void _STLP_CALL 
   320 __stl_debug_engine<_Dummy>::_Terminate()
   321 {
   322 # ifdef _STLP_USE_NAMESPACES
   323   using namespace _STLP_STD;
   324 # endif
   325 # if defined (_STLP_USE_EXCEPTIONS) && ! defined (_STLP_NO_DEBUG_EXCEPTIONS)
   326   throw __stl_debug_exception();
   327 # else
   328   _STLP_ABORT();
   329 # endif
   330 }
   331 
   332 _STLP_END_NAMESPACE
   333 
   334 # endif /* _STLP_ASSERTIONS */
   335 
   336 #ifdef _STLP_DEBUG
   337 
   338 _STLP_BEGIN_NAMESPACE
   339 
   340 //==========================================================
   341 //  owned_list non-inline methods 
   342 //==========================================================
   343 
   344 template <class _Dummy>
   345 void  _STLP_CALL
   346 __stl_debug_engine<_Dummy>::_Invalidate_all(__owned_list* __l) {
   347   _STLP_ACQUIRE_LOCK(__l->_M_lock);
   348   _Stamp_all(__l, 0);
   349   __l->_M_node._M_next =0;
   350   _STLP_RELEASE_LOCK(__l->_M_lock);
   351 }
   352 
   353 // boris : this is unasafe routine; should be used from within critical section only !
   354 template <class _Dummy>
   355 void  _STLP_CALL
   356 __stl_debug_engine<_Dummy>::_Stamp_all(__owned_list* __l, __owned_list* __o) {
   357   // crucial
   358   if (__l->_M_node._M_owner) {
   359     for (__owned_link*  __position = (__owned_link*)__l->_M_node._M_next; 
   360 	 __position != 0; __position= (__owned_link*)__position->_M_next) {
   361       _STLP_ASSERT(__position->_Owner()== __l)
   362       __position->_M_owner=__o;
   363     }
   364   }
   365 }
   366 
   367 template <class _Dummy>
   368 void  _STLP_CALL
   369 __stl_debug_engine<_Dummy>::_Verify(const __owned_list* __l) {
   370   _STLP_ACQUIRE_LOCK(__l->_M_lock);
   371   if (__l) {
   372     _STLP_ASSERT(__l->_M_node._Owner() != 0)
   373     for (__owned_link* __position = (__owned_link*)__l->_M_node._M_next; 
   374          __position != 0; __position= (__owned_link*)__position->_M_next) {
   375       _STLP_ASSERT(__position->_Owner()== __l)
   376     }
   377   }
   378   _STLP_RELEASE_LOCK(__l->_M_lock);
   379 }
   380 
   381 template <class _Dummy>
   382 void _STLP_CALL  
   383 __stl_debug_engine<_Dummy>::_Swap_owners(__owned_list& __x, __owned_list& __y) {
   384 
   385   //  according to the standard : --no swap() function invalidates any references, 
   386   //  pointers,  or  iterators referring to the elements of the containers being swapped.
   387 
   388   __owned_link* __tmp;
   389 
   390   // boris : there is a deadlock potential situation here if we lock two containers sequentially.
   391   // As user is supposed to provide its own synchronization around swap() ( it is unsafe to do any container/iterator access
   392   // in parallel with swap()), we just do not use any locking at all -- that behaviour is closer to non-debug version
   393 
   394   __tmp = __x._M_node._M_next;
   395 
   396   _Stamp_all(&__x, &__y);
   397   _Stamp_all(&__y, &__x);
   398 
   399   __x._M_node._M_next = __y._M_node._M_next;
   400   __y._M_node._M_next = __tmp;  
   401 
   402 }
   403 
   404 template <class _Dummy>
   405 void _STLP_CALL 
   406 __stl_debug_engine<_Dummy>::_M_detach(__owned_list* __l, __owned_link* __c_node) {
   407   if (__l  != 0) {
   408 
   409     _STLP_VERBOSE_ASSERT(__l->_Owner()!=0, _StlMsg_INVALID_CONTAINER)
   410 
   411     _STLP_ACQUIRE_LOCK(__l->_M_lock)
   412       // boris : re-test the condition in case someone else already deleted us
   413       if(__c_node->_M_owner != 0) {
   414         __owned_link* __prev, *__next;
   415         
   416         for (__prev = &__l->_M_node; (__next = __prev->_M_next) != __c_node; 
   417              __prev = __next) {
   418           _STLP_ASSERT(__next && __next->_Owner() == __l)
   419             }
   420         
   421         __prev->_M_next = __c_node->_M_next;
   422         __c_node->_M_owner=0;
   423       }
   424     _STLP_RELEASE_LOCK(__l->_M_lock)
   425   }
   426 }
   427 
   428 template <class _Dummy>
   429 void _STLP_CALL 
   430 __stl_debug_engine<_Dummy>::_M_attach(__owned_list* __l, __owned_link* __c_node) {
   431   if (__l ==0) {
   432     (__c_node)->_M_owner = 0;    
   433   } else {
   434     _STLP_VERBOSE_ASSERT(__l->_Owner()!=0, _StlMsg_INVALID_CONTAINER)
   435     _STLP_ACQUIRE_LOCK(__l->_M_lock)
   436     __c_node->_M_owner = __l;
   437     __c_node->_M_next = __l->_M_node._M_next;
   438     __l->_M_node._M_next = __c_node;
   439     _STLP_RELEASE_LOCK(__l->_M_lock)
   440   }
   441 }
   442 
   443 
   444 template <class _Dummy>
   445 void* _STLP_CALL
   446 __stl_debug_engine<_Dummy>::_Get_container_ptr(const __owned_link* __l) {
   447   const __owned_list* __owner    = __l->_Owner();
   448   _STLP_VERBOSE_RETURN_0(__owner != 0, _StlMsg_INVALID_ITERATOR)
   449   void* __ret = __CONST_CAST(void*,__owner->_Owner());
   450   _STLP_VERBOSE_RETURN_0(__ret !=0, _StlMsg_INVALID_CONTAINER)
   451   return __ret;
   452 }
   453 
   454 template <class _Dummy>
   455 bool _STLP_CALL
   456 __stl_debug_engine<_Dummy>::_Check_same_owner( const __owned_link& __i1, 
   457                                                const __owned_link& __i2)
   458 {
   459   _STLP_VERBOSE_RETURN(__i1._Valid(), _StlMsg_INVALID_LEFTHAND_ITERATOR)
   460   _STLP_VERBOSE_RETURN(__i2._Valid(), _StlMsg_INVALID_RIGHTHAND_ITERATOR)
   461   _STLP_VERBOSE_RETURN((__i1._Owner()==__i2._Owner()), _StlMsg_DIFFERENT_OWNERS)
   462   return true;
   463 }
   464 
   465 template <class _Dummy>
   466 bool  _STLP_CALL
   467 __stl_debug_engine<_Dummy>::_Check_same_owner_or_null( const __owned_link& __i1, 
   468 						       const __owned_link& __i2)
   469 {
   470   _STLP_VERBOSE_RETURN(__i1._Owner()==__i2._Owner(), _StlMsg_DIFFERENT_OWNERS)
   471   return true;
   472 }
   473 
   474 template <class _Dummy>
   475 bool _STLP_CALL
   476 __stl_debug_engine<_Dummy>::_Check_if_owner( const __owned_list * __l, const __owned_link& __it)
   477 {
   478   const __owned_list* __owner_ptr = __it._Owner();
   479   _STLP_VERBOSE_RETURN(__owner_ptr!=0, _StlMsg_INVALID_ITERATOR)
   480   _STLP_VERBOSE_RETURN(__l==__owner_ptr, _StlMsg_NOT_OWNER)
   481   return true;
   482 }
   483 
   484 
   485 _STLP_END_NAMESPACE
   486 
   487 #endif /* _STLP_DEBUG */
   488 
   489 #endif /* if defined (EXPOSE_GLOBALS_IMPLEMENTATION) */
   490 
   491 #endif /* header guard */
   492 
   493 // Local Variables:
   494 // mode:C++
   495 // End:
   496