<commit_before>// Copyright (c) 2012, <NAME> <<EMAIL>>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the
//    distribution.
//  * Neither the name of the author nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include    <iostream>

#include    <QMapIterator>
#include    <QStringList>

#include    "libqtlogger_common.h"
#include    "libqtlogger.h"

/** logger object constructor.
 *
 * initializes internal QtLogger#currentLevel,
 * initializes #ll_string array with string represenattion of #LOG_LEVEL,
 * enqueues startup log message with current date and time,
 * launches logger thread QtLogger#run
 */
QtLogger::QtLogger()
    : currentLevel( LL_DEBUG ),
      mmMutex(QMutex::Recursive),    // allow loadModuleLevels to lock
      configFileName(""),
      configFile( configFileName ),
      configStream( &configFile )
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME << std::endl;
#endif

    ll_string[ LL_ERROR         ].sprintf( "ERROR " );
    ll_string[ LL_WARNING       ].sprintf( "WARN  " );
    ll_string[ LL_WARNING_FINE  ].sprintf( "WARN+ " );
    ll_string[ LL_LOG           ].sprintf( "log   " );
    ll_string[ LL_LOG_FINE      ].sprintf( "log+  " );
    ll_string[ LL_DEBUG         ].sprintf( "debug " );
    ll_string[ LL_DEBUG_FINE    ].sprintf( "debug+" );

    ll_string[ LL_STUB          ].sprintf( "      " );

    messageQueue.enqueue(
            QString("logger startup: %1").arg(
                QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz")
                )
            );

    this->start();
}

/** logger object destructor.
 *
 * currently does nothing.
 */
QtLogger::~QtLogger()
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME << std::endl;
#endif
}

/** singleton logger object constructor.
 *
 * constructs static QtLogger object and returns
 * its reference
 *
 * @return reference to static QtLogger object
 */
QtLogger& QtLogger::getInstance()
{
    static QtLogger _instance;

    return _instance;
}

/** dummy function.
 *
 * does nothing.
 */
void QtLogger::foo( void* bar )
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME << std::endl;
#endif
}

/** decide whether to use file name or class/function as module name.
 *
 * uses filename or
 * namespace or
 * namespace + class
 * as module name.
 *
 * if called from top-level (i.e. outside #main) --
 * uses file name as module name.
 *
 * if called from #main -- module name = "main".
 *
 * if called from fooNameSpace::main() --
 * module name = "fooNameSpace".
 *
 * if called from fooNameSpace::FooClass::fooMethod() --
 * module name = "fooNameSpace::FooClass".
 *
 * @param funcname  should be #FUNCTION_NAME
 * @param filename  should be __FILE__
 *
 * @return module name
 */
QString QtLogger::determineModule( const char* funcname, const char* filename )
{
// TODO: nullpointer check?
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " funcname: \""
            << funcname << "\""
            << " filename: \""
            << filename << "\""
            << std::endl;
#endif

    QString ret( funcname );
    if ( ret.contains("(") )
    {
        // function

        int delim = ret.indexOf("(");
        int space = ret.lastIndexOf( " ", delim );

        ret = ret.mid( space, delim - space );

        if ( ret.contains( "::" ) )
        {
            // class || namespace

            delim = ret.lastIndexOf( "::" );
            ret = ret.left( delim );
        }
    }
    else
    {
        // file

        ret = QString( FILENAME_FROM_PATH( filename ) );
    }

    ret = ret.trimmed();

#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " module: \""
            << ret.toStdString() << "\""
            << std::endl;
#endif

    return ret;
}

/** converts #LOG_LEVEL value to string representation.
 *
 * uses initialized in QtLogger#QtLogger #ll_string array.
 *
 * @param level log level to convert
 *
 * @return string representation of passed level<br>
 *         or stub if passed level is out of bounds<commit_msg>nullpointer fix @ determinemodule<commit_after>// Copyright (c) 2012, <NAME> <<EMAIL>>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the
//    distribution.
//  * Neither the name of the author nor the names of its
//    contributors may be used to endorse or promote products derived
//    from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include    <iostream>

#include    <QMapIterator>
#include    <QStringList>

#include    "libqtlogger_common.h"
#include    "libqtlogger.h"

/** logger object constructor.
 *
 * initializes internal QtLogger#currentLevel,
 * initializes #ll_string array with string represenattion of #LOG_LEVEL,
 * enqueues startup log message with current date and time,
 * launches logger thread QtLogger#run
 */
QtLogger::QtLogger()
    : currentLevel( LL_DEBUG ),
      mmMutex(QMutex::Recursive),    // allow loadModuleLevels to lock
      configFileName(""),
      configFile( configFileName ),
      configStream( &configFile )
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME << std::endl;
#endif

    ll_string[ LL_ERROR         ].sprintf( "ERROR " );
    ll_string[ LL_WARNING       ].sprintf( "WARN  " );
    ll_string[ LL_WARNING_FINE  ].sprintf( "WARN+ " );
    ll_string[ LL_LOG           ].sprintf( "log   " );
    ll_string[ LL_LOG_FINE      ].sprintf( "log+  " );
    ll_string[ LL_DEBUG         ].sprintf( "debug " );
    ll_string[ LL_DEBUG_FINE    ].sprintf( "debug+" );

    ll_string[ LL_STUB          ].sprintf( "      " );

    messageQueue.enqueue(
            QString("logger startup: %1").arg(
                QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz")
                )
            );

    this->start();
}

/** logger object destructor.
 *
 * currently does nothing.
 */
QtLogger::~QtLogger()
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME << std::endl;
#endif
}

/** singleton logger object constructor.
 *
 * constructs static QtLogger object and returns
 * its reference
 *
 * @return reference to static QtLogger object
 */
QtLogger& QtLogger::getInstance()
{
    static QtLogger _instance;

    return _instance;
}

/** dummy function.
 *
 * does nothing.
 */
void QtLogger::foo( void* bar )
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME << std::endl;
#endif
}

/** decide whether to use file name or class/function as module name.
 *
 * uses filename or
 * namespace or
 * namespace + class
 * as module name.
 *
 * if called from top-level (i.e. outside #main) --
 * uses file name as module name.
 *
 * if called from #main -- module name = "main".
 *
 * if called from fooNameSpace::main() --
 * module name = "fooNameSpace".
 *
 * if called from fooNameSpace::FooClass::fooMethod() --
 * module name = "fooNameSpace::FooClass".
 *
 * @param funcname  should be #FUNCTION_NAME
 * @param filename  should be __FILE__
 *
 * @return module name
 */
QString QtLogger::determineModule( const char* funcname, const char* filename )
{
#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " funcname: \""
            << ( funcname?funcname:"(null)" ) << "\""
            << " filename: \""
            << ( filename?filename:"(null)" ) << "\""
            << std::endl;
#endif

    // TODO: optimize
    static char defaultModule[] = "default";

    QString ret( funcname ? funcname : defaultModule );
    if ( ret.contains("(") )
    {
        // function

        int delim = ret.indexOf("(");
        int space = ret.lastIndexOf( " ", delim );

        ret = ret.mid( space, delim - space );

        if ( ret.contains( "::" ) )
        {
            // class || namespace

            delim = ret.lastIndexOf( "::" );
            ret = ret.left( delim );
        }
    }
    else
    {
        // file

        ret = QString( filename ? FILENAME_FROM_PATH( filename ) : defaultModule );
    }

    ret = ret.trimmed();

#if ENABLE_LOGGER_LOGGING
    std::clog << FUNCTION_NAME
            << " module: \""
            << ret.toStdString() << "\""
            << std::endl;
#endif

    return ret;
}

/** converts #LOG_LEVEL value to string representation.
 *
 * uses initialized in QtLogger#QtLogger #ll_string array.
 *
 * @param level log level to convert
 *
 * @return string representation of passed level<br>
 *         or stub if passed level is out of bounds
{'fraction_non_alphanumeric': 0.11363636363636363, 'fraction_numerical': 0.0009090909090909091, 'mean_word_length': 2.802627030763913, 'pattern_counts': {'":': 4, '<': 93, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2599277', 'n_tokens_mistral': 3247, 'n_tokens_neox': 3128, 'n_words': 1076}