Commit | Line | Data |
---|---|---|
b6fb82a2 RP |
1 | /** @file |
2 | * @brief implementation of tracing functionality. | |
3 | * | |
4 | * @copyright © Copyright 2008 by Intra2net AG | |
5 | * @license commercial | |
6 | * | |
7 | * info@intra2net.com | |
8 | * | |
9 | * @note This module is not thread safe! | |
10 | * @todo make this module thread safe (only useful when we can use threads...) | |
11 | */ | |
12 | ||
13 | #include "tracefunc.hpp" | |
14 | ||
15 | #include <list> | |
16 | #include <vector> | |
17 | #include <sstream> | |
18 | ||
19 | ||
20 | namespace I2n | |
21 | { | |
22 | namespace Tracer | |
23 | { | |
24 | ||
25 | using Logger::GlobalLogger; | |
26 | ||
27 | ||
28 | namespace | |
29 | { | |
30 | ||
31 | typedef std::list< ScopeTracker* > ScopeTrackerList; | |
32 | ||
33 | ScopeTrackerList scope_tracker_list; | |
34 | ||
35 | ||
36 | std::vector< std::string > indents; | |
37 | ||
38 | ||
39 | /** | |
40 | * @brief ensures indent level string to exist up to the desired level. | |
41 | * @param level the desired indent level. | |
42 | */ | |
43 | void ensure_indent_level(int level) | |
44 | { | |
45 | while (indents.size() <= level) | |
46 | { | |
47 | indents.push_back( indents.back() + " " ); | |
48 | } | |
49 | } // eo ensure_indent_level(int) | |
50 | ||
51 | ||
52 | /** | |
53 | * @brief module initializer. | |
54 | */ | |
55 | class __Initializer | |
56 | { | |
57 | public: | |
58 | __Initializer() | |
59 | { | |
60 | // pre initialize indent strings: | |
61 | indents.clear(); | |
62 | indents.reserve(10); | |
63 | indents.push_back(""); | |
64 | for(int i=10; i-->0;) | |
65 | { | |
66 | indents.push_back( indents.back() + " " ); | |
67 | } | |
68 | } | |
69 | } __initializer; | |
70 | ||
71 | ||
72 | } // eo namespace <anonymous> | |
73 | ||
74 | ||
75 | /* | |
76 | ** implementation of ScopeTracker | |
77 | */ | |
78 | ||
79 | /** | |
80 | * @brief constructor. initializes object with a source location and emits a ENTER message. | |
81 | * @param loc the source location. | |
82 | * | |
83 | * the message is indented according to the current depth of nested ScopeTracker instances. | |
84 | */ | |
85 | ScopeTracker::ScopeTracker( | |
86 | const SourceLocation& loc) | |
87 | : Location(loc) | |
88 | , Depth(0) | |
89 | , FuncDepth(0) | |
90 | { | |
91 | if (!scope_tracker_list.empty()) | |
92 | { | |
93 | ScopeTracker* last_tracker= scope_tracker_list.back(); | |
94 | if (Location) | |
95 | { | |
96 | if (last_tracker->Location | |
97 | && last_tracker->Location.File == Location.File | |
98 | && last_tracker->Location.FunctionName == Location.FunctionName) | |
99 | { | |
100 | FuncDepth= last_tracker->FuncDepth+1; | |
101 | } | |
102 | } | |
103 | Depth= last_tracker->Depth + 1; | |
104 | } | |
105 | ensure_indent_level(Depth); | |
106 | scope_tracker_list.push_back(this); | |
107 | { | |
108 | std::ostringstream ostr; | |
109 | if (Location.FunctionName.empty()) | |
110 | { | |
111 | ostr << "<unknown> (global scope?)"; | |
112 | } | |
113 | else | |
114 | { | |
115 | ostr << Location.FunctionName; | |
116 | if (FuncDepth>0) | |
117 | { | |
118 | ostr << "#" << FuncDepth+1; | |
119 | } | |
120 | } | |
121 | Tag= ostr.str(); | |
122 | } | |
123 | // spit a message | |
124 | if (Logger::has_log_level(Logger::LogLevel::Debug)) | |
125 | { | |
126 | GlobalLogger.debug() << indents[Depth] << "ENTER " << Tag; | |
127 | } | |
128 | } // eo ScopeTrcaker::ScopeTracker(const SourceLocation&) | |
129 | ||
130 | ||
131 | /** | |
132 | * @brief destructor. emits a LEAVE message. | |
133 | * | |
134 | * | |
135 | */ | |
136 | ScopeTracker::~ScopeTracker() | |
137 | { | |
138 | // spit a message | |
139 | if (Logger::has_log_level(Logger::LogLevel::Debug)) | |
140 | { | |
141 | GlobalLogger.debug() << indents[Depth] << "LEAVE " << Tag; | |
142 | } | |
143 | if (scope_tracker_list.empty()) | |
144 | { | |
145 | return; | |
146 | } | |
147 | if (scope_tracker_list.back() == this) | |
148 | { | |
149 | scope_tracker_list.pop_back(); | |
150 | } | |
151 | else | |
152 | { | |
153 | // oh hell, this should never be the case! | |
154 | //TODO | |
155 | GlobalLogger.error() << "inconsistency detected in scope tracker"; | |
156 | } | |
157 | } // eo ScopeTracker::~ScopeTracker() | |
158 | ||
159 | ||
160 | ||
161 | ||
162 | } // eo namespace Tracer | |
163 | } // eo namespace I2n |