1 /***************************************************************************
2     Copyright (C) 2003-2009 Robby Stephenson <robby@periapsis.org>
3  ***************************************************************************/
4 
5 /***************************************************************************
6  *                                                                         *
7  *   This program is free software; you can redistribute it and/or         *
8  *   modify it under the terms of the GNU General Public License as        *
9  *   published by the Free Software Foundation; either version 2 of        *
10  *   the License or (at your option) version 3 or any later version        *
11  *   accepted by the membership of KDE e.V. (or its successor approved     *
12  *   by the membership of KDE e.V.), which shall act as a proxy            *
13  *   defined in Section 14 of version 3 of the license.                    *
14  *                                                                         *
15  *   This program is distributed in the hope that it will be useful,       *
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
18  *   GNU General Public License for more details.                          *
19  *                                                                         *
20  *   You should have received a copy of the GNU General Public License     *
21  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
22  *                                                                         *
23  ***************************************************************************/
24 
25 #ifndef TELLICO_DEBUG_H
26 #define TELLICO_DEBUG_H
27 
28 // some of this was borrowed from amarok/src/debug.h
29 // which is copyright Max Howell <max.howell@methylblue.com>
30 // amarok is licensed under the GPL
31 
32 #include <QDebug>
33 // std::clock_t
34 #include <ctime>
35 
36 // linux has __GNUC_PREREQ, NetBSD has __GNUC_PREREQ__
37 #if defined(__GNUC_PREREQ) && !defined(__GNUC_PREREQ__)
38 #  define __GNUC_PREREQ__ __GNUC_PREREQ
39 #endif
40 
41 #if !defined(__GNUC_PREREQ__)
42 #  if defined __GNUC__
43 #    define __GNUC_PREREQ__(x, y) \
44             ((__GNUC__ == (x) && __GNUC_MINOR__ >= (y)) || \
45              (__GNUC__ > (x)))
46 #  else
47 #    define __GNUC_PREREQ__(x, y)   0
48 #  endif
49 #endif
50 
51 # if defined __cplusplus ? __GNUC_PREREQ__ (2, 6) : __GNUC_PREREQ__ (2, 4)
52 #   define MY_FUNCTION  __PRETTY_FUNCTION__
53 # else
54 #  if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
55 #   define MY_FUNCTION  __func__
56 #  else
57 #   define MY_FUNCTION  __FILE__ ":" __LINE__
58 #  endif
59 # endif
60 
61 // some logging
62 #if !defined(KDE_NO_DEBUG_OUTPUT)
63 #define TELLICO_LOG
64 #endif
65 
66 #ifndef DEBUG_PREFIX
67   #define FUNC_PREFIX ""
68 #else
69   #define FUNC_PREFIX "[" DEBUG_PREFIX "] "
70 #endif
71 
72 #define myDebug()   qDebug()
73 #define myWarning() qWarning()
74 #ifdef TELLICO_LOG
75 #define myLog()     qDebug()
76 #else
77 #define myLog()     //qDebug()
78 #endif
79 
80 namespace Debug {
81 
82 class Block {
83 
84 public:
Block(const char * label)85   Block(const char* label) : m_start(std::clock()), m_label(label) {
86     QDebug(QtDebugMsg) << "BEGIN:" << label;
87   }
88 
~Block()89   ~Block() {
90     std::clock_t finish = std::clock();
91     const double duration = (double) (finish - m_start) / CLOCKS_PER_SEC;
92     QDebug(QtDebugMsg) << "  END:" << m_label << "- duration =" << duration;
93   }
94 
95 private :
96   std::clock_t m_start;
97   const char* m_label;
98 };
99 
100 }
101 
102 /// Standard function announcer
103 #define DEBUG_FUNC myDebug() << Q_FUNC_INFO;
104 
105 /// Announce a line
106 #define DEBUG_LINE myDebug() << "[" << __FILE__ << ":" << __LINE__ << "]";
107 
108 /// Convenience macro for making a standard Debug::Block
109 #ifndef WIN32
110 #define DEBUG_BLOCK Debug::Block uniquelyNamedStackAllocatedStandardBlock( MY_FUNCTION );
111 #else
112 #define DEBUG_BLOCK
113 #endif
114 
115 #if defined(TELLICO_LOG) && !defined(WIN32) && (defined(__unix__) || defined(__unix))
116 #include <unistd.h>
117 // see https://www.gnome.org/~federico/news-2006-03.html#timeline-tools
118 // strace -ttt -f -o /tmp/logfile.strace src/tellico
119 // plot-timeline.py -o prettygraph.png /tmp/logfile.strace
120 #define MARK do { \
121     char str[128]; \
122     ::snprintf(str, 128, "MARK: %s: %s (%d)", metaObject()->className(), MY_FUNCTION, __LINE__); \
123     ::access (str, F_OK); \
124   } while(false)
125 #define MARK_MSG(s) do { \
126     char str[128]; \
127     ::snprintf(str, 128, "MARK: %s: %s (%d)", metaObject()->className(), s, __LINE__); \
128     ::access (str, F_OK); \
129   } while(false)
130 #define MARK_LINE do { \
131     char str[128]; \
132     ::snprintf(str, 128, "MARK: tellico: %s (%d)", __FILE__, __LINE__); \
133     ::access (str, F_OK); \
134   } while(false)
135 #else
136 #define MARK
137 #define MARK_MSG(s)
138 #define MARK_LINE
139 #endif
140 
141 #endif
142