Switch license from Intranator license to GPLv2 + linking exception (ACKed by Steffen)
[libi2ncommon] / src / tracefunc.cpp
CommitLineData
0e23f538
TJ
1/*
2The software in this package is distributed under the GNU General
3Public License version 2 (with a special exception described below).
4
5A copy of GNU General Public License (GPL) is included in this distribution,
6in the file COPYING.GPL.
7
8As a special exception, if other files instantiate templates or use macros
9or inline functions from this file, or you compile this file and link it
10with other works to produce a work based on this file, this file
11does not by itself cause the resulting work to be covered
12by the GNU General Public License.
13
14However the source code for this file must still be made available
15in accordance with section (3) of the GNU General Public License.
16
17This exception does not invalidate any other reasons why a work based
18on this file might be covered by the GNU General Public License.
19*/
b6fb82a2
RP
20/** @file
21 * @brief implementation of tracing functionality.
22 *
23 * @copyright © Copyright 2008 by Intra2net AG
b6fb82a2
RP
24 *
25 * @note This module is not thread safe!
26 * @todo make this module thread safe (only useful when we can use threads...)
27 */
28
29#include "tracefunc.hpp"
30
31#include <list>
32#include <vector>
33#include <sstream>
34
35
36namespace I2n
37{
38namespace Tracer
39{
40
41using Logger::GlobalLogger;
42
43
44namespace
45{
46
47typedef std::list< ScopeTracker* > ScopeTrackerList;
48
49ScopeTrackerList scope_tracker_list;
50
51
52std::vector< std::string > indents;
53
54
55/**
56 * @brief ensures indent level string to exist up to the desired level.
57 * @param level the desired indent level.
58 */
59void ensure_indent_level(int level)
60{
61 while (indents.size() <= level)
62 {
63 indents.push_back( indents.back() + " " );
64 }
65} // eo ensure_indent_level(int)
66
67
68/**
69 * @brief module initializer.
70 */
71class __Initializer
72{
73 public:
74 __Initializer()
75 {
76 // pre initialize indent strings:
77 indents.clear();
78 indents.reserve(10);
79 indents.push_back("");
80 for(int i=10; i-->0;)
81 {
82 indents.push_back( indents.back() + " " );
83 }
84 }
85} __initializer;
86
87
88} // eo namespace <anonymous>
89
90
91/*
92** implementation of ScopeTracker
93*/
94
95/**
96 * @brief constructor. initializes object with a source location and emits a ENTER message.
97 * @param loc the source location.
98 *
99 * the message is indented according to the current depth of nested ScopeTracker instances.
100 */
101ScopeTracker::ScopeTracker(
102 const SourceLocation& loc)
103: Location(loc)
104, Depth(0)
105, FuncDepth(0)
106{
107 if (!scope_tracker_list.empty())
108 {
109 ScopeTracker* last_tracker= scope_tracker_list.back();
110 if (Location)
111 {
112 if (last_tracker->Location
113 && last_tracker->Location.File == Location.File
114 && last_tracker->Location.FunctionName == Location.FunctionName)
115 {
116 FuncDepth= last_tracker->FuncDepth+1;
117 }
118 }
119 Depth= last_tracker->Depth + 1;
120 }
121 ensure_indent_level(Depth);
122 scope_tracker_list.push_back(this);
123 {
124 std::ostringstream ostr;
125 if (Location.FunctionName.empty())
126 {
127 ostr << "<unknown> (global scope?)";
128 }
129 else
130 {
131 ostr << Location.FunctionName;
132 if (FuncDepth>0)
133 {
134 ostr << "#" << FuncDepth+1;
135 }
136 }
137 Tag= ostr.str();
138 }
139 // spit a message
140 if (Logger::has_log_level(Logger::LogLevel::Debug))
141 {
142 GlobalLogger.debug() << indents[Depth] << "ENTER " << Tag;
143 }
144} // eo ScopeTrcaker::ScopeTracker(const SourceLocation&)
145
146
147/**
148 * @brief destructor. emits a LEAVE message.
149 *
150 *
151 */
152ScopeTracker::~ScopeTracker()
153{
154 // spit a message
155 if (Logger::has_log_level(Logger::LogLevel::Debug))
156 {
157 GlobalLogger.debug() << indents[Depth] << "LEAVE " << Tag;
158 }
159 if (scope_tracker_list.empty())
160 {
161 return;
162 }
163 if (scope_tracker_list.back() == this)
164 {
165 scope_tracker_list.pop_back();
166 }
167 else
168 {
169 // oh hell, this should never be the case!
170 //TODO
171 GlobalLogger.error() << "inconsistency detected in scope tracker";
172 }
173} // eo ScopeTracker::~ScopeTracker()
174
175
176
177
178} // eo namespace Tracer
179} // eo namespace I2n