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
DbgLoopStack()39 DbgLoopStack::DbgLoopStack()
40 {
41 Reset();
42 }
43
Reset()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
Push(const void * pThis)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
Pop()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
Print(SvStream & rOS) const99 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
AssertFail(const char * pErr,const char * pFile,sal_uInt16 nLine)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
Run() const133 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
main()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