1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sw.hxx" 26 27 #ifdef DBG_UTIL 28 29 #include <tools/stream.hxx> 30 #include "dbgloop.hxx" 31 #include "errhdl.hxx" 32 33 DbgLoopStack DbgLoop::aDbgLoopStack; 34 35 /************************************************************************* 36 * class DbgLoopStack 37 *************************************************************************/ 38 39 DbgLoopStack::DbgLoopStack() 40 { 41 Reset(); 42 } 43 44 void DbgLoopStack::Reset() 45 { 46 nPtr = 0; 47 pDbg = 0; 48 for( sal_uInt16 i = 0; i < DBG_MAX_STACK; ++i ) 49 aCount[i] = 0; 50 } 51 52 /************************************************************************* 53 * DbgLoopStack::Push() 54 *************************************************************************/ 55 56 void DbgLoopStack::Push( const void *pThis ) 57 { 58 // Wir muessen irgendwie mitbekommen, wann die erste Stackposition 59 // resettet werden soll, z.B. wenn wir einen Nullpointer uebergeben 60 if( !nPtr && ( pDbg != pThis || !pThis ) ) 61 { 62 aCount[1] = 0; 63 pDbg = pThis; 64 } 65 66 ++nPtr; 67 if( DBG_MAX_STACK > nPtr ) 68 { 69 // Wenn eine loop entdeckt wird, wird der counter wieder zurueckgesetzt. 70 ASSERT( DBG_MAX_LOOP > aCount[nPtr], "DbgLoopStack::Push: loop detected" ); 71 if( DBG_MAX_LOOP > aCount[nPtr] ) 72 ++(aCount[nPtr]); 73 else 74 aCount[nPtr] = 0; 75 } 76 } 77 78 /************************************************************************* 79 * DbgLoopStack::Pop() 80 *************************************************************************/ 81 82 void DbgLoopStack::Pop() 83 { 84 if( DBG_MAX_STACK > nPtr ) 85 { 86 ASSERT( nPtr, "DbgLoopStack::Pop: can't pop the stack" ); 87 88 ASSERT( aCount[nPtr], "DbgLoopStack::Pop: can't dec the count" ); 89 if( DBG_MAX_STACK > nPtr + 1 ) 90 aCount[nPtr + 1] = 0; 91 } 92 --nPtr; 93 } 94 95 /************************************************************************* 96 * DbgLoopStack::Print() 97 *************************************************************************/ 98 99 void DbgLoopStack::Print( SvStream &rOS ) const 100 { 101 rOS << "POS: " << nPtr << '\n'; 102 sal_uInt16 i; 103 for( i = 0; i < DBG_MAX_STACK; ++i ) 104 rOS << i << " "; 105 rOS << '\n'; 106 for( i = 0; i < DBG_MAX_STACK; ++i ) 107 rOS << aCount[i] << " "; 108 rOS << '\n'; 109 } 110 111 #ifdef STAND_ALONE 112 // compile with: cl /AL /DSTAND_ALONE dbgloop.cxx 113 114 /************************************************************************* 115 * main() 116 *************************************************************************/ 117 118 #include <stdlib.h> 119 120 void AssertFail( const char *pErr, const char *pFile, sal_uInt16 nLine ) 121 { 122 cout << pErr << '\n'; 123 PrintLoopStack( cout ); 124 exit(0); 125 } 126 127 class Test 128 { 129 public: 130 void Run() const; 131 }; 132 133 void Test::Run() const 134 { 135 cout << "---" << '\n'; 136 for( sal_uInt16 i = 0; i < 10; ++i ) 137 { 138 cout << "i" << i; 139 DBG_LOOP; 140 PrintLoopStack( cout ); 141 for( sal_uInt16 j = 0; j < 10; ++j ) 142 { 143 cout << " j" << j; 144 DBG_LOOP; 145 PrintLoopStack( cout ); 146 } 147 cout << '\n'; 148 } 149 PrintLoopStack( cout ); 150 } 151 152 int main() 153 { 154 // unterschiedliche Instanzen waehlen wg. pDbg != pThis 155 Test aTest1; 156 aTest1.Run(); 157 Test aTest2; 158 aTest2.Run(); 159 return 0; 160 } 161 #endif 162 163 #endif // DBG_UTIL 164 165