inc/cntdebug.h
branchRCL_3
changeset 19 5b6f26637ad3
equal deleted inserted replaced
18:d4f567ce2e7c 19:5b6f26637ad3
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Trace macro declarations.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #ifndef CNTDEBUG_H
       
    20 #define CNTDEBUG_H
       
    21 
       
    22 #include <QDebug>   // QDebug
       
    23 #include <QtGlobal> // qDebug()
       
    24 
       
    25 // #define TRACK_MEMORY_LEAKS
       
    26 #define TRACES
       
    27 // #define TRACE2FILE
       
    28 
       
    29 /*!
       
    30     \def CNT_UNUSED(name)
       
    31     \brief Declares a single variable as unused when tracing is disabled.
       
    32 
       
    33     CNT_UNUSED allows variables (usually method parameters) to be declared as used only if
       
    34     tracing is enabled. Without this variables that are included in trace macros, but not otherwise
       
    35     used, would cause unused variable warnings on compilation. If tracing is enabled, CNT_UNUSED
       
    36     has no effect.
       
    37 
       
    38     Consider the following class method where the parameter number is not used at all, except for
       
    39     tracing its value on entry:
       
    40 
       
    41     \code
       
    42     #include <cntdebug.h>
       
    43 
       
    44     void MyClass::myMethod(int number)
       
    45     {
       
    46         CNT_UNUSED(number)
       
    47         CNT_ENTRY("number =" << number)
       
    48 
       
    49         // ...some more code where the parameter number is not used.
       
    50 
       
    51         CNT_EXIT
       
    52     }
       
    53     \endcode
       
    54 
       
    55     Compiling this method with tracing completely disabled at compile time would cause an unused
       
    56     variable warning to be issued unless the CNT_UNUSED macro is used to declare the variable as
       
    57     trace-only.
       
    58 
       
    59     \param name The name of the variable to declare as unused if tracing is disabled. To mark
       
    60     several variables as trace-only, add a separate CNT_UNUSED statement for each.
       
    61     \sa CNT_STATIC_ENTRY_ARGS(args), CNT_ENTRY_ARGS(args).
       
    62 */
       
    63 
       
    64 /*!
       
    65     \def CNT_STATIC_ENTRY
       
    66     \brief A method entry trace macro for static class methods or global functions.
       
    67 
       
    68     Invoking CNT_STATIC_ENTRY outputs a timestamp followed by the scope in which the macro
       
    69     was invoked and the word "entry".
       
    70 
       
    71     CNT_STATIC_ENTRY is intended to be used as the first line of static class methods or
       
    72     global functions. There is a corresponding exit macro, CNT_EXIT.
       
    73 
       
    74     The following example shows proper usage of the CNT_STATIC_ENTRY macro. Assuming a class
       
    75     has been declared with a static method that is implemented like this:
       
    76 
       
    77     \code
       
    78     #include <cntdebug.h>
       
    79 
       
    80     void MyClass::myStaticMethod()
       
    81     {
       
    82         CNT_STATIC_ENTRY
       
    83 
       
    84         int i = 1;
       
    85         i++;
       
    86 
       
    87         CNT_EXIT
       
    88     }
       
    89     \endcode
       
    90 
       
    91     calling MyClass::myStaticMethod() generates output lines of the following format:
       
    92 
       
    93     \code
       
    94     2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod() entry
       
    95     2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod() exit
       
    96     \endcode
       
    97 
       
    98     \sa CNT_STATIC_ENTRY_ARGS(args), CNT_EXIT.
       
    99 */
       
   100 
       
   101 /*!
       
   102     \def CNT_STATIC_ENTRY_ARGS(args)
       
   103     \brief A method entry trace macro with arguments for static class methods or global functions.
       
   104 
       
   105     CNT_STATIC_ENTRY_ARGS(args) is similar to CNT_STATIC_ENTRY but it allows arguments to be
       
   106     output on the same line without needing to resort to a separate CNT_LOG_ARGS call. This is
       
   107     especially handy for outputting the parameters of the method call.
       
   108 
       
   109     The following example shows proper usage of the CNT_STATIC_ENTRY_ARGS(args) macro. Assuming
       
   110     a class has been declared with a static method that is implemented like this:
       
   111 
       
   112     \code
       
   113     #include <QString>
       
   114     #include <cntdebug.h>
       
   115 
       
   116     void MyClass::myStaticMethod(const QString &text, int number)
       
   117     {
       
   118         CNT_STATIC_ENTRY_ARGS("text =" << text << "number =" << number);
       
   119 
       
   120         int i = 1;
       
   121         i++;
       
   122 
       
   123         CNT_EXIT
       
   124     }
       
   125     \endcode
       
   126 
       
   127     calling MyClass::myStaticMethod(QString("foo"), 74) generates output lines of the following
       
   128     format:
       
   129 
       
   130     \code
       
   131     2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod(const QString&, int) entry, text = "foo" number = 74
       
   132     2009-03-25 11:00:50.171 : static void MyClass::myStaticMethod(const QString&, int) exit
       
   133     \endcode
       
   134 
       
   135     \param args Any number of arguments that can be streamed into a QTextStream, joined together
       
   136     by the streaming operator <<.
       
   137     \sa CNT_STATIC_ENTRY.
       
   138 */
       
   139 
       
   140 /*!
       
   141     \def CNT_ENTRY
       
   142     \brief A method entry trace macro for class methods.
       
   143 
       
   144     Invoking CNT_ENTRY outputs a timestamp followed by the scope in which the macro
       
   145     was invoked, the word "entry" and the this pointer value of the instance invoking the
       
   146     macro.
       
   147 
       
   148     The this pointer value included in the debug output can help make the output more readable, as
       
   149     it allows different instances of the same class to be distinguished from each other.
       
   150 
       
   151     CNT_ENTRY is intended to be used as the first line of class methods. There is a corresponding
       
   152     exit macro, CNT_EXIT.
       
   153 
       
   154     The following example shows proper usage of the CNT_ENTRY macro. Assuming a class has been
       
   155     declared with a non-static method that is implemented like this:
       
   156 
       
   157     \code
       
   158     #include <cntdebug.h>
       
   159 
       
   160     void MyClass::myMethod()
       
   161     {
       
   162         CNT_ENTRY
       
   163 
       
   164         int i = 1;
       
   165         i++;
       
   166 
       
   167         CNT_EXIT
       
   168     }
       
   169     \endcode
       
   170 
       
   171     calling myMethod() on an instance of MyClass generates output lines of the following format:
       
   172 
       
   173     \code
       
   174     2009-03-25 11:00:50.171 : void MyClass::myMethod() this 0x6cdab90 entry
       
   175     2009-03-25 11:00:50.171 : void MyClass::myMethod() exit
       
   176     \endcode
       
   177 
       
   178     \sa CNT_ENTRY_ARGS(args), CNT_EXIT.
       
   179 */
       
   180 
       
   181 /*!
       
   182     \def CNT_ENTRY_ARGS(args)
       
   183     \brief A method entry trace macro with arguments for class methods.
       
   184 
       
   185     CNT_ENTRY_ARGS(args) is similar to CNT_ENTRY but it allows arguments to be output on the
       
   186     same line without needing to resort to a separate CNT_LOG_ARGS call. This is especially
       
   187     handy for outputting the parameters of the method call.
       
   188 
       
   189     The following example shows proper usage of the CNT_ENTRY_ARGS(args)) macro. Assuming a
       
   190     class has been declared with a non-static method that is implemented like this:
       
   191 
       
   192     \code
       
   193     #include <QString>
       
   194     #include <cntdebug.h>
       
   195 
       
   196     void MyClass::myMethod(const QString &text, int number)
       
   197     {
       
   198         CNT_ENTRY_ARGS("text =" << text << "number =" << number);
       
   199 
       
   200         int i = 1;
       
   201         i++;
       
   202 
       
   203         CNT_EXIT
       
   204     }
       
   205     \endcode
       
   206 
       
   207     calling myMethod(QString("foo"), 74) on an instance of MyClass generates output lines of the
       
   208     following format:
       
   209 
       
   210     \code
       
   211     2009-03-25 11:00:50.171 : void MyClass::myMethod(const QString&, int) this 0x6cdab90 entry, text = "foo" number = 74
       
   212     2009-03-25 11:00:50.171 : void MyClass::myMethod(const QString&, int) exit
       
   213     \endcode
       
   214 
       
   215     \param args Any number of arguments that can be streamed into a QTextStream, joined together
       
   216     by the streaming operator <<.
       
   217     \sa CNT_ENTRY, CNT_EXIT.
       
   218 */
       
   219 
       
   220 /*!
       
   221     \def CNT_EXIT
       
   222     \brief A method exit trace macro for class methods or global functions.
       
   223 
       
   224     Invoking CNT_EXIT outputs a timestamp followed by the scope in which the macro
       
   225     was invoked and the word "exit".
       
   226 
       
   227     CNT_EXIT is intended to be used as the last line of class methods and global functions,
       
   228     just before the return statement, if any. There are two corresponding entry macros,
       
   229     CNT_ENTRY and CNT_STATIC_ENTRY, depending on whether the method being traced is a
       
   230     non-static or a static class method. CNT_EXIT makes no distinction between these two types
       
   231     of methods and is to be used for both.
       
   232 
       
   233     See CNT_ENTRY or CNT_STATIC_ENTRY for an example of how to use CNT_EXIT.
       
   234 
       
   235     \sa CNT_EXIT_ARGS(args), CNT_ENTRY, CNT_STATIC_ENTRY.
       
   236 */
       
   237 
       
   238 /*!
       
   239     \def CNT_EXIT_ARGS(args)
       
   240     \brief A method exit trace macro with arguments for class methods or global functions.
       
   241 
       
   242     CNT_EXIT_ARGS(args) is similar to CNT_EXIT but it allows arguments to be output on the
       
   243     same line without needing to resort to a separate CNT_LOG_ARGS call. This is especially
       
   244     handy for outputting the return value of the method call.
       
   245 
       
   246     The following example shows proper usage of the CNT_EXIT_ARGS(args) macro. Assuming a
       
   247     class has been declared with a static method that is implemented like this:
       
   248 
       
   249     \code
       
   250     #include <QString>
       
   251     #include <cntdebug.h>
       
   252 
       
   253     int MyClass::myStaticMethod(const QString &text)
       
   254     {
       
   255         CNT_STATIC_ENTRY_ARGS("text =" << text);
       
   256 
       
   257         int length = text.length();
       
   258 
       
   259         CNT_EXIT_ARGS("length" << length);
       
   260 
       
   261         return length;
       
   262     }
       
   263     \endcode
       
   264 
       
   265     calling MyClass::myStaticMethod(QString("foo")) generates output lines of the following format:
       
   266 
       
   267     \code
       
   268     2009-03-25 13:20:36.448 : static int MyClass::myStaticMethod(const QString&) entry, text = "foo"
       
   269     2009-03-25 13:20:36.448 : static int MyClass::myStaticMethod(const QString&) exit, length 3
       
   270     \endcode
       
   271 
       
   272     Although the example above is a static method, CNT_EXIT_ARGS(args) works identically for
       
   273     non-static class methods and global functions.
       
   274 
       
   275     \param args Any number of arguments that can be streamed into a QTextStream, joined together
       
   276     by the streaming operator <<.
       
   277     \sa CNT_EXIT
       
   278 */
       
   279 
       
   280 /*!
       
   281     \def CNT_LOG
       
   282     \brief A trace macro for class methods or global functions.
       
   283 
       
   284     Invoking CNT_LOG outputs a timestamp followed by the scope in which the macro
       
   285     was invoked and the this pointer value of the instance invoking the
       
   286     macro.
       
   287 
       
   288     CNT_LOG is similar to CNT_ENTRY but it is especially handy for marking calls to methods that
       
   289     cannot fail, such as an empty constructor, without needing to resort to a separate CNT_EXIT call.
       
   290 
       
   291     The following example shows proper usage of the CNT_LOG(args) macro. Assuming a
       
   292     class has been declared with a static method that is implemented like this:
       
   293 
       
   294     \code
       
   295     #include <QString>
       
   296     #include <cntdebug.h>
       
   297 
       
   298     MyClass::MyClass()
       
   299     {
       
   300         CNT_LOG
       
   301     }
       
   302     \endcode
       
   303 
       
   304     calling new MyClass() generates output lines of the following format:
       
   305 
       
   306     \code
       
   307     2009-03-25 13:20:36.448 : MyClass::MyClass() this 0x6cdab90
       
   308     \endcode
       
   309 
       
   310     \sa CNT_LOG_ARGS
       
   311 */
       
   312 
       
   313 /*!
       
   314     \def CNT_LOG_ARGS(args)
       
   315     \brief A generic trace macro with arguments for class methods or global functions.
       
   316 
       
   317     The following example shows how to produce arbitrary debug output:
       
   318 
       
   319     \code
       
   320     #include <QString>
       
   321     #include <cntdebug.h>
       
   322 
       
   323     void MyClass::myMethod()
       
   324     {
       
   325         CNT_ENTRY
       
   326 
       
   327         QString myString("This is a string.");
       
   328         int myValue = 109;
       
   329 
       
   330         CNT_LOG_ARGS("this is a debug message, myString =" << myString << "myValue =" << myValue)
       
   331 
       
   332         CNT_EXIT
       
   333     }
       
   334     \endcode
       
   335 
       
   336     calling myMethod() on an instance of MyClass generates output lines of the following format:
       
   337 
       
   338     \code
       
   339     2009-03-25 13:45:22.083 : void MyClass::myMethod() this 0x6cdab90 entry
       
   340     2009-03-25 13:45:22.083 : void MyClass::myMethod() this is a debug message, myString = "This is a string." myValue = 109
       
   341     2009-03-25 13:45:22.083 : void MyClass::myMethod() exit
       
   342     \endcode
       
   343 
       
   344     Any number of arguments may be printed by chaining them together with the streaming operator
       
   345     <<. Notice that a single space character is automatically added between each streamed
       
   346     argument, hence the hardcoded strings in the example above, such as "myValue =", do not have
       
   347     a space at the beginning and end of the string. This automatic space addition is a feature
       
   348     of qDebug() streaming and cannot be disabled.
       
   349 
       
   350     \param args Any number of arguments that can be streamed into a QTextStream, joined together
       
   351     by the streaming operator <<.
       
   352 */
       
   353 
       
   354 // traces for debug builds by default, or if
       
   355 // TRACES macro is defined
       
   356 #if defined (_DEBUG) && !defined (TRACES)
       
   357 #define TRACES
       
   358 #endif
       
   359 
       
   360 #if defined (TRACES) || defined (TRACE2FILE)
       
   361     #define CNT_UNUSED(name)
       
   362     #define CNT_STATIC_ENTRY qDebug() << __PRETTY_FUNCTION__ << "entry";
       
   363     #define CNT_STATIC_ENTRY_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << "entry," << args;
       
   364     #define CNT_ENTRY qDebug() << __PRETTY_FUNCTION__ << "this" << (void *)this << "entry";
       
   365     #define CNT_ENTRY_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << "this" << (void *)this << "entry," << args;
       
   366     #define CNT_EXIT qDebug() << __PRETTY_FUNCTION__ << "exit";
       
   367     #define CNT_EXIT_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << "exit," << args;
       
   368     #define CNT_LOG qDebug() << __PRETTY_FUNCTION__ << "this" << (void *)this;
       
   369     #define CNT_LOG_ARGS(args) qDebug() << __PRETTY_FUNCTION__ << args;
       
   370     #define CNT_WARNING(args) qWarning() << __PRETTY_FUNCTION__ << args;
       
   371     #define CNT_CRITICAL(args) qCritical() << __PRETTY_FUNCTION__ << args;
       
   372     #define CNT_FATAL(args) qFatal() << __PRETTY_FUNCTION__ << args;
       
   373 #else
       
   374     #define CNT_UNUSED(name) Q_UNUSED(name)
       
   375     #define CNT_STATIC_ENTRY
       
   376     #define CNT_STATIC_ENTRY_ARGS(args)
       
   377     #define CNT_ENTRY
       
   378     #define CNT_ENTRY_ARGS(args)
       
   379     #define CNT_EXIT
       
   380     #define CNT_EXIT_ARGS(args)
       
   381     #define CNT_LOG
       
   382     #define CNT_LOG_ARGS(args)
       
   383     #define CNT_WARNING(args)
       
   384     #define CNT_CRITICAL(args)
       
   385     #define CNT_FATAL(args)
       
   386 #endif // TRACES || TRACE2FILE
       
   387     
       
   388 // for tracing memory leaks
       
   389 #ifdef TRACK_MEMORY_LEAKS
       
   390     #include <hbapplication.h>
       
   391 
       
   392     #define CNT_TRACK_QOBJECTLIFE(obj) { new CntQObjectTracker(obj, __FILE__, __LINE__); }
       
   393     #define CNT_TRACK_QOBJECTLIVES(objects) { foreach (QObject* object, objects) new CntQObjectTracker(object, __FILE__, __LINE__); }
       
   394 
       
   395     class CntQObjectTracker : public QObject
       
   396     {
       
   397         Q_OBJECT
       
   398         public:
       
   399             CntQObjectTracker(QObject *obj, QString fileName, int fileLine) {
       
   400                 objectName = obj->metaObject()->className();
       
   401                 createdInFile = fileName;
       
   402                 createdAtLine = fileLine;
       
   403                 connect(obj, SIGNAL(destroyed()), this, SLOT(objectDestroyed()));
       
   404                 connect(HbApplication::instance(), SIGNAL(aboutToQuit()), this, SLOT(reportMemoryLeak()));
       
   405             }
       
   406         public slots:
       
   407             void objectDestroyed() { delete this; }
       
   408         private slots:
       
   409             void reportMemoryLeak() { qDebug() << "MEMORY LEAK: The" << objectName << "object in" << createdInFile << "at line" << createdAtLine << "was never destroyed."; delete this; }
       
   410         private: // functions
       
   411             ~CntQObjectTracker() {}
       
   412         private: // data
       
   413             QString  objectName;
       
   414             QString  createdInFile;
       
   415             int      createdAtLine;
       
   416     };
       
   417 #else
       
   418     #define CNT_TRACK_QOBJECTLIFE(obj)
       
   419     #define CNT_TRACK_QOBJECTLIVES(obj)
       
   420 #endif
       
   421 
       
   422 // filter phonebook app traces
       
   423 #ifdef TRACE2FILE
       
   424     #include <QFile>
       
   425     #include <QTextStream>
       
   426     static void cntCustomLog2File(QtMsgType type, const char *msg)
       
   427     {   
       
   428         QFile logFile("c:/cnt_logs.log");
       
   429         if (!logFile.open(QIODevice::Append | QIODevice::Text))
       
   430         {
       
   431             qFatal("error opening c:/cnt_logs.log file");
       
   432             return;
       
   433         }
       
   434 
       
   435         QTextStream out(&logFile);
       
   436         switch (type)
       
   437         {
       
   438             case QtDebugMsg:
       
   439                 out << "[CNT] Debug: " << msg;
       
   440                 break;
       
   441             case QtWarningMsg:
       
   442                 out << "[CNT] Warning: " << msg;
       
   443                 break;
       
   444             case QtCriticalMsg:
       
   445                 out << "[CNT] Critical: " << msg;
       
   446                 break;
       
   447             case QtFatalMsg:
       
   448                 out << "[CNT] Fatal: " << msg;
       
   449                 abort();
       
   450                 break;
       
   451             default:
       
   452                 out << "[CNT] No Log Selection Type: " << msg;
       
   453                 break;
       
   454         }
       
   455     }
       
   456     #define MSG_HANDLER cntCustomLog2File
       
   457 #else
       
   458     #ifdef Q_OS_SYMBIAN
       
   459         #include <e32debug.h>
       
   460         static void cntCustomLog(QtMsgType type, const char *msg)
       
   461         {
       
   462             switch (type) {
       
   463                 case QtDebugMsg:
       
   464                     RDebug::Printf("[CNT] Debug: %s\n", msg);
       
   465                     break;
       
   466                 case QtWarningMsg:
       
   467                     RDebug::Printf("[CNT] Warning: %s\n", msg);
       
   468                     break;
       
   469                 case QtCriticalMsg:
       
   470                     RDebug::Printf("[CNT] Critical: %s\n", msg);
       
   471                     break;
       
   472                 case QtFatalMsg:
       
   473                     RDebug::Printf("[CNT] Fatal: %s\n", msg);
       
   474                     abort();
       
   475                     break;
       
   476                 default:
       
   477                     break;
       
   478             }
       
   479         }
       
   480         #define MSG_HANDLER cntCustomLog
       
   481     #else
       
   482         #define MSG_HANDLER 0
       
   483     #endif  // Q_OS_SYMBIAN
       
   484 #endif  // TRACE2FILE
       
   485 
       
   486 #endif // CNTDEBUG_H