1 /***************************************************************************
2  * SPDX-FileCopyrightText: 2021 S. MANKOWSKI stephane@mankowski.fr
3  * SPDX-FileCopyrightText: 2021 G. DE BURE support@mankowski.fr
4  * SPDX-License-Identifier: GPL-3.0-or-later
5  ***************************************************************************/
6 #ifndef SKGTRACES_H
7 #define SKGTRACES_H
8 /** @file
9  * This file defines classes SKGTraces an macros.
10  *
11  * @author Stephane MANKOWSKI / Guillaume DE BURE
12  */
13 #include <qmap.h>
14 #include <qstack.h>
15 #include <qstringlist.h>
16 #include <qtextstream.h>
17 
18 #include "skgdefine.h"
19 
20 /**
21 * Macro for traces
22 */
23 #define SKGTRACE                SKGTRACESUITE << SKGTraces::SKGIndentTrace
24 /**
25 * Macro for traces
26 */
27 #define SKGTRACESUITE           SKGTraces::SKGCout
28 /**
29 * Macro for traces
30 */
31 #define SKGTRACESEPARATOR SKGTRACE << "##############################################\n" << SKGFLUSH;
32 
33 #ifdef SKGNOTRACES
34 /**
35 * Macro for traces
36 */
37 #define IFSKGTRACEL(Level) if (false)
38 #else
39 /**
40 * Macro for traces
41 */
42 #define IFSKGTRACEL(Level) if ((Level) <= SKGTraces::SKGLevelTrace)
43 #endif
44 
45 /**
46  * Macro for traces
47  */
48 #define SKGTRACEL(Level) SKGTRACESUITEL(Level) << SKGTraces::SKGIndentTrace
49 /**
50  * Macro for traces
51  */
52 #define SKGTRACESUITEL(Level)   IFSKGTRACEL(Level) SKGTRACESUITE
53 
54 /**
55  * This structure represents one performance measure
56  */
57 struct SKGPerfoInfo {
58     /** The number of call for the method */
59     int NbCall;
60     /** The global time passed in the method */
61     double Time;
62     /** The time consumed by the method */
63     double TimePropre;
64     /** The minimum time passed in the method */
65     double TimeMin;
66     /** The maximum time passed in the method */
67     double TimeMax;
68 };
69 
70 /**
71  * A map of strings ==> SKGPerfoInfo
72  * @see SKGPerfoMapIterator
73  */
74 using SKGPerfoMap = QMap<QString, SKGPerfoInfo>;
75 
76 /**
77  * A iterator for SKGPerfoMap ==> SKGPerfoInfo
78  * @see SKGPerfoMap
79  */
80 using SKGPerfoMapIterator = QMap<QString, SKGPerfoInfo>::Iterator;
81 
82 /**
83  * A stack of strings
84  */
85 using SKGQStringStack = QStack<QString>;
86 
87 class SKGError;
88 
89 /**
90 * This class manages traces
91 */
92 class SKGBASEMODELER_EXPORT SKGTraces final
93 {
94 public:
95     /**
96     * Constructor
97     * @param iName The message to display
98     * @param iLevel The level to display this error.
99     * The error will be display if the level of traces asked is greater or equal than
100     * the level of this trace (iLevel)
101     * @param iRC A pointer of the error object of the calling method
102     *   The SKGError
103     */
104     explicit SKGTraces(int iLevel, const char* iName, SKGError* iRC);
105 
106     /**
107     * Constructor
108     * @param iName The message to display
109     * @param iLevel The level to display this error.
110     * The error will be display if the level of traces asked is greater or equal than
111     * the level of this trace (iLevel)
112     * @param iRC A pointer of the error object of the calling method
113     *   The SKGError
114     */
115     SKGTraces(int iLevel, const QString& iName, SKGError* iRC);
116 
117     /**
118     * Destructor
119     */
120     ~SKGTraces();
121 
122     /**
123      * Clean profiling statistics
124      */
125     static void cleanProfilingStatistics();
126 
127     /**
128     * Get profiling statistics
129     */
130     static QStringList getProfilingStatistics();
131 
132     /**
133      * Dump profiling statistics
134      */
135     static void dumpProfilingStatistics();
136 
137     /**
138     * Standard output stream for traces
139     */
140     static QTextStream SKGCout;
141 
142     /**
143      * The current level of indentation
144      */
145     static QString SKGIndentTrace;
146 
147     /**
148      * The current level of taces
149      */
150     static int SKGLevelTrace;
151 
152     /**
153      * To enable, disable profiling
154      */
155     static bool SKGPerfo;
156 
157 private:
158     Q_DISABLE_COPY(SKGTraces)
159     void init(int iLevel, const QString& iName, SKGError* iRC);
160 
161     QString                            m_mame;
162     bool                               m_output = false;
163     bool                               m_profiling = false;
164     SKGError*                          m_rc = nullptr;
165     double                             m_elapse = 0.0;
166     SKGPerfoMapIterator                m_it;
167 
168     static SKGPerfoMap          m_SKGPerfoMethode;
169     static SKGQStringStack      m_SKGPerfoPathMethode;
170 };
171 
172 /**
173  * Macro for traces
174  */
175 #define TOKENPASTE(x, y) x ## y
176 
177 /**
178  * Macro for traces
179  */
180 #define TOKENPASTE2(x, y) TOKENPASTE(x, y)
181 
182 #ifdef SKGNOTRACES
183 /**
184 * Macro for traces
185 */
186 #define SKGTRACEINRC(Level, Name, RC)
187 
188 /**
189 * Macro for traces
190 */
191 #define SKGTRACEIN(Level, Name)
192 #else
193 /**
194 * Macro for traces
195 */
196 #define SKGTRACEINRC(Level, Name, RC) \
197     SKGTraces TOKENPASTE2(trace1_, __LINE__)(Level, Name, &(RC));
198 
199 /**
200 * Macro for traces
201 */
202 #define SKGTRACEIN(Level, Name) \
203     SKGTraces TOKENPASTE2(trace2_, __LINE__)(Level, Name, nullptr);
204 #endif
205 
206 #ifdef SKGFULLTRACES
207 /**
208 * Macro for traces
209 */
210 #define _SKGTRACEINRC(Level, Name, RC) SKGTRACEINRC(Level, Name, RC)
211 /**
212 * Macro for traces
213 */
214 #define _SKGTRACEIN(Level, Name)    SKGTRACEIN(Level, Name)
215 #else
216 /**
217 * Macro for traces
218 */
219 #define _SKGTRACEINRC(Level, Name, RC)
220 /**
221 * Macro for traces
222 */
223 #define _SKGTRACEIN(Level, Name)
224 #endif
225 
226 /**
227  * Macro for traces
228  */
229 #define SKGTRACEINFUNCRC(Level, RC) \
230     SKGTRACEINRC(Level, Q_FUNC_INFO, RC)
231 
232 /**
233  * Macro for traces
234  */
235 #define SKGTRACEINFUNC(Level) \
236     SKGTRACEIN(Level, Q_FUNC_INFO)
237 
238 /**
239  * Macro for traces
240  */
241 #define _SKGTRACEINFUNCRC(Level, RC) \
242     _SKGTRACEINRC(Level, Q_FUNC_INFO, RC)
243 
244 /**
245  * Macro for traces
246  */
247 #define _SKGTRACEINFUNC(Level) \
248     _SKGTRACEIN(Level, Q_FUNC_INFO)
249 
250 #endif
251 
252