<commit_before>#pragma once
#include <config.h>
#include <core/Object.h>
#include <core/NamedObject.h>
#include <core/Reflection.h>
#include <core/Time.h>

#include <iostream>
#include <sstream>
#include <string>


// these macros work within any class that contains a function to a reference called log (Log & log();}
#define logInfo(x) {std::stringstream ss; ss << x ; log().info(ss.str(),__FUNCSIG__,__FILE__,__LINE__);}
#define logWarning(x) {std::stringstream ss; ss << x ; log().warn(ss.str(),__FUNCSIG__,__FILE__,__LINE__);}
#define logError(x) {std::stringstream ss; ss << x ; log().error(ss.str(),__FUNCSIG__,__FILE__,__LINE__);}
#define logMessage(level, x) {std::stringstream ss; ss << x ; log().log(level, ss.str(),__FUNCSIG__,__FILE__,__LINE__);}
//TODO move to cmake
#define DEBUG
#ifdef  DEBUG
#define logDebug(x) logMessage(5,x) 
#else 
#define logDebug(x)
#endif //  DEBUG

namespace nspace{
  
  class Log;
  class LogEntry : public virtual PropertyChangingObject{
    REFLECTABLE_OBJECT(LogEntry);    
    PROPERTY(std::string, Message){}
    PROPERTY(int, SourceLineNumber){}
    PROPERTY(std::string, SourceFileName){}
    PROPERTY(std::string, FunctionSignature){}
    PROPERTY(int, LogLevel){}
    PROPERTY(Log*, Owner){}
    PROPERTY(std::string, ClassName){}
    PROPERTY(Time, SystemTimeStamp){}
    PROPERTY(std::string, ObjectName){}
  public:


  public:
    LogEntry():_LogLevel(100),_Owner(0){
      setSystemTimeStamp(systemTime());
    }
    void toString(std::ostream & out)const{
      switch(getLogLevel()){
      case 3:out<< "Info    : ";
        break;
      case 2:out << "Warning : ";
        break;
      case 1:out << "Error   : ";
        break;
      default: out << "Message(lvl "<<getLogLevel()<<"): ";
      }
      out << getSystemTimeStamp()<<"s : ";
      out << getMessage();
      out << " (in "<<getObjectName()<<")";
      //out <<" "<<getFunctionSignature();
    }
  };
  class Log : public virtual PropertyChangingObject{
    REFLECTABLE_OBJECT(Log);

    PROPERTY(bool,LoggingEnabled){};
    DEFAULTVALUE(LoggingEnabled, true);

    PROPERTY(int, LoggingLevel){};
    DEFAULTVALUE(LoggingLevel, int(3));

    PROPERTY(std::ostream *, LogInfoStream){}
    PROPERTY(std::ostream *, LogWarningStream){}
    PROPERTY(std::ostream *, LogErrorStream){}    
    PROPERTYSET(LogEntry*,LogEntries,{
      
      std::ostream * out=0;
      switch(item->getLogLevel()){
      case 1:
        out = getLogErrorStream();
        break;
case 2:
        out = getLogWarningStream();
        break;
default:
        out = getLogInfoStream();
        break;

      }
      if(!out)return;
      *out << *item << std::endl;

    
    },{})
  protected:
    
    Log & log()const{return *const_cast<Log*>(this);}
  public:

    Log():_LogInfoStream(0),_LogWarningStream(0),_LogErrorStream(0){
      setLogInfoStream(&std::cout);
      setLogErrorStream(&std::cerr);
      setLogWarningStream(&std::cout);
      setLoggingLevelToDefault();
      setLoggingEnabledToDefault();

    }
    void log(
      int level,
      const std::string & message,
      const std::string & functionsignature="",
      const std::string & sourcefile ="",
      int sourcelinenumber=-1){
        auto entry = new LogEntry();
        entry->setLogLevel(level);
        entry->setMessage(message);
        entry->setFunctionSignature(functionsignature);
        entry->setSourceFileName(sourcefile);
        entry->setSourceLineNumber(sourcelinenumber);
        addEntry(entry);

    }
    void info(
      const std::string & message,
      const std::string & functionsignature="",
      const std::string & sourcefile ="",
      int sourcelinenumber=-1){
        auto entry = new LogEntry();
        entry->setLogLevel(3);
        entry->setMessage(message);
        entry->setFunctionSignature(functionsignature);
        entry->setSourceFileName(sourcefile);
        entry->setSourceLineNumber(sourcelinenumber);
        addEntry(entry);
      }
    
    void warn(
      const std::string & message,
      const std::string & functionsignature="",
      const std::string & sourcefile ="",
      int sourcelinenumber=-1){
        auto entry = new LogEntry();
        entry->setLogLevel(2);
        entry->setMessage(message);
        entry->setFunctionSignature(functionsignature);
        entry->setSourceFileName(sourcefile);
        entry->setSourceLineNumber(sourcelinenumber);
        addEntry(entry);
      }
      
      void error(
      const std::string & message,
      const std::string & functionsignature="",
      const std::string & sourcefile ="",
      int sourcelinenumber=-1){
        auto entry = new LogEntry();
        entry->setLogLevel(1);
        entry->setMessage(message);
        entry->setFunctionSignature(functionsignature);
        entry->setSourceFileName(sourcefile);
        entry->setSourceLineNumber(sourcelinenumber);
        addEntry(entry);
      }
    void addEntry(LogEntry * entry){
      if(!getLoggingEnabled())return;
      if(getLoggingLevel()<entry->getLogLevel())return; // TODO delete entry? or discontinue * usage or accept entry and check logging level elsewhere?
      entry->setOwner(this);
      const TypeData & td = getTypeData();
      if(entry->getClassName()=="")entry->setClassName(getTypeData().name);
      if(entry->getObjectName()=="")entry->setObjectName(name(this));
      
      LogEntries()|=entry;
    }
  };
}<commit_msg>fixed a memory leak.   added debug(Error|Message|Warn|Info) macros which are not compiled when the DEBUG flag is not compiled still needs some work<commit_after>#pragma once
#include <config.h>
#include <core/Object.h>
#include <core/NamedObject.h>
#include <core/Reflection.h>
#include <core/Time.h>
#include <core/Set.h>

#include <iostream>
#include <sstream>
#include <string>


// these macros work within any class that contains a function to a reference called log (Log & log();}


#define createLogMessage(level, x) {std::stringstream ss; ss << x ; log().log(level, ss.str(),__FUNCSIG__,__FILE__,__LINE__);}
#define logMessage_0(x) createLogMessage(0,x)
#define logMessage_1(x) createLogMessage(1,x)
#define logMessage_2(x) createLogMessage(2,x)
#define logMessage_3(x) createLogMessage(3,x)
#define logMessage_4(x) createLogMessage(4,x)
#define logMessage_5(x) createLogMessage(5,x)
#define logMessage_6(x) createLogMessage(6,x)
#define logMessage_7(x) createLogMessage(7,x)
#define logMessage_8(x) createLogMessage(8,x)
#define logMessage_9(x) createLogMessage(9,x)
// default level
#define logMessage_(x) logMessage_3(x)

// macro for logging a message 
#define logMessage(message,level) logMessage_##level(message)


#define logInfo(x) logMessage(x,3);
#define logWarning(x) logMessage(x,2)
#define logError(x) logMessage(x,1)
#define logFatal(x) logMessage(x,0)

//TODO move to cmake
#define DEBUG
#ifdef  DEBUG
#define debugInfo(x)           logInfo(x) 
#define debugWarning(x)        logWarning(x)
#define debugError(x)          logError(x)
#define debugMessage(x,level)  logMessage(x,level)
#else 
#define debugInfo(x) 
#define debugWarning(x) 
#define debugError(x) 
#define debugMessage(level,x) 
#endif //  DEBUG

namespace nspace{

  class Log;
  class LogEntry : public virtual PropertyChangingObject{
    REFLECTABLE_OBJECT(LogEntry);    
    PROPERTY(std::string, Message){}
    PROPERTY(int, SourceLineNumber){}
    PROPERTY(std::string, SourceFileName){}
    PROPERTY(std::string, FunctionSignature){}
    PROPERTY(int, LogLevel){}
    PROPERTY(Log*, Owner){}
    PROPERTY(std::string, ClassName){}
    PROPERTY(Time, SystemTimeStamp){}
    PROPERTY(std::string, ObjectName){}
  public:


  public:
    LogEntry():_LogLevel(100),_Owner(0){
      setSystemTimeStamp(systemTime());
    }
    void toString(std::ostream & out)const{
      switch(getLogLevel()){
      case 3:out<< "Info    : ";
        break;
      case 2:out << "Warning : ";
        break;
      case 1:out << "Error   : ";
        break;
      default: out << "Message(lvl "<<getLogLevel()<<"): ";
      }
      out << getSystemTimeStamp()<<"s : ";
      out << getMessage();
      out << " (in "<<getObjectName()<<")";
      //out <<" "<<getFunctionSignature();
    }
  };
  class Log : public virtual PropertyChangingObject{
    REFLECTABLE_OBJECT(Log);

    PROPERTY(bool,LoggingEnabled){};
    DEFAULTVALUE(LoggingEnabled, true);

    PROPERTY(int, LoggingLevel){};
    DEFAULTVALUE(LoggingLevel, int(3));

    PROPERTY(std::ostream *, LogInfoStream){}
    PROPERTY(std::ostream *, LogWarningStream){}
    PROPERTY(std::ostream *, LogErrorStream){}    
    PROPERTYSET(LogEntry*,LogEntries,{
      std::ostream * out=0;
      switch(item->getLogLevel()){
      case 1:
        out = getLogErrorStream();
        break;
      case 2:
        out = getLogWarningStream();
        break;
      default:
        out = getLogInfoStream();
        break;

      }
      if(!out)return;
      *out << *item << std::endl;


    },{})
  protected:

    Log & log()const{return *const_cast<Log*>(this);}
  public:

    Log():_LogInfoStream(0),_LogWarningStream(0),_LogErrorStream(0){
      setLogInfoStream(&std::cout);
      setLogErrorStream(&std::cerr);
      setLogWarningStream(&std::cout);
      setLoggingLevelToDefault();
      setLoggingEnabledToDefault();

    }
    void log(
      int level,
      const std::string & message,
      const std::string & functionsignature="",
      const std::string & sourcefile ="",
      int sourcelinenumber=-1){
        auto entry = new LogEntry();
        entry->setLogLevel(level);
        entry->setMessage(message);
        entry->setFunctionSignature(functionsignature);
        entry->setSourceFileName(sourcefile);
        entry->setSourceLineNumber(sourcelinenumber);
        addEntry(entry);

    }
    void info(
      const std::string & message,
      const std::string & functionsignature="",
      const std::string & sourcefile ="",
      int sourcelinenumber=-1){
        log(3,message,functionsignature,sourcefile,sourcelinenumber);
    }

    void warn(
      const std::string & message,
      const std::string & functionsignature="",
      const std::string & sourcefile ="",
      int sourcelinenumber=-1){
        log(2,message,functionsignature,sourcefile,sourcelinenumber);
    }

    void error(
      const std::string & message,
      const std::string & functionsignature="",
      const std::string & sourcefile ="",
      int sourcelinenumber=-1){
        log(1,message,functionsignature,sourcefile,sourcelinenumber);
    }


    void addEntry(LogEntry * entry){
      if(!getLoggingEnabled()){
        delete entry;
        entry = 0;
        return;
      }
      if(getLoggingLevel()<entry->getLogLevel()){
        delete entry;
        entry = 0;
        return;
      }
      entry->setOwner(this);
      const TypeData & td = getTypeData();
      if(entry->getClassName()=="")entry->setClassName(getTypeData().name);
      if(entry->getObjectName()=="")entry->setObjectName(name(this));

      LogEntries()|=entry;
    }
  };
}
{'fraction_non_alphanumeric': 0.14394626974042476, 'fraction_numerical': 0.0063532401524777635, 'mean_word_length': 3.4288585209003215, 'pattern_counts': {'":': 0, '<': 98, '<?xml version=': 0, '>': 61, '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': '7293123', 'n_tokens_mistral': 3470, 'n_tokens_neox': 3420, 'n_words': 671}