diff --git a/include/Human.hpp b/include/Human.hpp index ed88e21c19cfd781ddcc4b90255fa4693af2d954..2231bdf5827f0a802230f281248c53cab0437362 100644 --- a/include/Human.hpp +++ b/include/Human.hpp @@ -9,6 +9,6 @@ private: public: explicit Human(int age, const std::string name = "") : name_(name), age_(age) {}; virtual ~Human(); - virtual void print() const; + virtual char* print() const; }; diff --git a/include/Student.hpp b/include/Student.hpp index 84d0e7555e7eb30f696be816edf87109505bae62..05ac91edb59025ba527d1a149f7008faadf04860 100644 --- a/include/Student.hpp +++ b/include/Student.hpp @@ -11,5 +11,5 @@ public: Student() = delete; explicit Student(int age, const std::string name = "", const std::string school = "") : Human(age, name), school_(school) {}; virtual ~Student() override; - virtual void print() const override; + virtual char* print() const override; }; \ No newline at end of file diff --git a/include/logging.hpp b/include/logging.hpp new file mode 100644 index 0000000000000000000000000000000000000000..032e8d465291742ed90af66975989d2baf4811e5 --- /dev/null +++ b/include/logging.hpp @@ -0,0 +1,82 @@ +#ifndef LOGGING_HPP +#define LOGGING_HPP + +#include +#include +#include + +enum LogLevel +{ + DEBUG = 0, + INFO, + WARNING, + ERROR +}; +struct LocationInfo +{ + LocationInfo(std::string file, int line, const char *func) : file_(file), line_(line), func_(func) {} + ~LocationInfo() = default; + + std::string file_; + int line_; + const char *func_; +}; +class LogStream; +class LogWriter; + +class LogWriter +{ +public: + LogWriter(LocationInfo location, LogLevel loglevel) + : location_(location), log_level_(loglevel) + { + char *logv = std::getenv("LOGV"); + if (logv) + { + std::string string_logv = logv; + env_log_level = std::stoi(logv); + } + else + { + env_log_level = 4; + } + }; + + void operator<(const LogStream &stream); + +private: + void output_log(const std::ostringstream &g); + LocationInfo location_; + LogLevel log_level_; + int env_log_level; +}; + +class LogStream +{ +public: + template + LogStream &operator<<(const T &val) noexcept + { + sstream_ << val; + return *this; + } + + friend class LogWriter; + +private: + std::stringstream sstream_{}; +}; + +std::string level2string(LogLevel level); +std::string get_short_name(const char *file_path); + +#define __FILESHORTNAME__ get_short_name(__FILE__) +#define LOG_IF(level) \ + LogWriter(LocationInfo(__FILESHORTNAME__, __LINE__, __FUNCTION__), level) < LogStream() +#define LOG(level) LOG_##level +#define LOG_DEBUG LOG_IF(DEBUG) +#define LOG_INFO LOG_IF(INFO) +#define LOG_WARNING LOG_IF(WARNING) +#define LOG_ERROR LOG_IF(ERROR) + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 743d1a2f0e228d3a799f1c9541002c1d3cbee4b0..802fad6ca111135e508c1daf2e15e660d9483cae 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,3 @@ add_executable( - stl_test main.cpp Human.cpp Student.cpp + stl_test main.cpp Human.cpp Student.cpp logging.cpp ) \ No newline at end of file diff --git a/src/Human.cpp b/src/Human.cpp index 7fde3fd6934721f2b565c99a99bc084038e79b6f..7e03ad3e0aa92fbb5224de4d67d380a301aa16f3 100644 --- a/src/Human.cpp +++ b/src/Human.cpp @@ -4,6 +4,8 @@ Human::~Human() { printf("Human destructor called\n"); } -void Human::print() const { - printf("My name is %s and I am %d years old\n", name_.c_str(), age_); +char* Human::print() const { + char* res = new char[100]; + sprintf(res, "My name is %s and I am %d years old\n", name_.c_str(), age_); + return res; } \ No newline at end of file diff --git a/src/Student.cpp b/src/Student.cpp index f838d600e32b9d5f5bce2856ee3bb150e0e9dd34..df0eedc6302749a6c8449f4ad1eea2eac63c693c 100644 --- a/src/Student.cpp +++ b/src/Student.cpp @@ -1,10 +1,12 @@ #include "Student.hpp" +#include "cstring" Student::~Student() { printf("Student destructor called\n"); } -void Student::print() const { - Human::print(); - printf("I'm from %s\n", school_.c_str()); +char* Student::print() const { + char *res = Human::print(); + sprintf(res + strlen(res), "I'm from %s\n", school_.c_str()); + return res; } \ No newline at end of file diff --git a/src/logging.cpp b/src/logging.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9d508956a1b2b051adfa19da833bb6ad9a3dec13 --- /dev/null +++ b/src/logging.cpp @@ -0,0 +1,42 @@ +#include "logging.hpp" + +void LogWriter::operator<(const LogStream &stream) { + std::ostringstream msg; + msg << stream.sstream_.rdbuf(); + output_log(msg); +} + +void LogWriter::output_log(const std::ostringstream &msg) { + if (log_level_ >= env_log_level) + std::cout << "[" << level2string(log_level_) << "] " + << "(" << location_.file_ + << ":" << location_.line_ + << "L "<< location_.func_<<")" + << msg.str() << std::endl; + +} +std::string level2string(LogLevel level) { + switch (level) + { + case DEBUG: + return "DEBUG"; + + case INFO: + return "INFO"; + + case WARNING: + return "WARNING"; + + case ERROR: + return "ERROR"; + + default: + return ""; + } +} +std::string get_short_name(const char * file_path) { + std::string short_file_path = file_path; + int index = short_file_path.find_last_of('/'); + + return short_file_path.substr(index+1); +} diff --git a/src/main.cpp b/src/main.cpp index fdba3bddd713ed7913f64c4a1ab6a1fcce12893e..898c43825320b3c5267cccc32e5027a2bdd7df0a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,6 +1,7 @@ #include #include "Human.hpp" #include "Student.hpp" +#include "logging.hpp" #include class check{ @@ -18,8 +19,11 @@ int main(int, char**){ vec.push_back(&human); vec.push_back(&student); for (const auto& h : vec) { - h->print(); + std::cout << h->print(); } auto student1 = static_cast(vec.back()); + // check check1 = check(student); check check1 = check(student1); + LOG(DEBUG) << student1->print(); + LOG(WARNING) << human.print(); }