my xfce4 dotfiles
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.2 KiB

3 years ago
  1. // Copyright 2019 Roman Perepelitsa.
  2. //
  3. // This file is part of GitStatus.
  4. //
  5. // GitStatus is free software: you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation, either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // GitStatus is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with GitStatus. If not, see <https://www.gnu.org/licenses/>.
  17. #ifndef ROMKATV_GITSTATUS_LOGGING_H_
  18. #define ROMKATV_GITSTATUS_LOGGING_H_
  19. #include <cstdlib>
  20. #include <memory>
  21. #include <ostream>
  22. #include <sstream>
  23. #define LOG(severity) LOG_I(severity)
  24. #define LOG_I(severity) \
  25. (::gitstatus::severity < ::gitstatus::g_min_log_level) \
  26. ? static_cast<void>(0) \
  27. : ::gitstatus::internal_logging::Assignable() = \
  28. ::gitstatus::internal_logging::LogStream<::gitstatus::severity>(__FILE__, __LINE__, \
  29. ::gitstatus::severity) \
  30. .ref()
  31. namespace gitstatus {
  32. enum LogLevel {
  33. DEBUG,
  34. INFO,
  35. WARN,
  36. ERROR,
  37. FATAL,
  38. };
  39. const char* LogLevelStr(LogLevel lvl);
  40. bool ParseLogLevel(const char* s, LogLevel& lvl);
  41. extern LogLevel g_min_log_level;
  42. namespace internal_logging {
  43. struct Assignable {
  44. template <class T>
  45. void operator=(const T&) const {}
  46. };
  47. class LogStreamBase {
  48. public:
  49. LogStreamBase(const char* file, int line, LogLevel lvl);
  50. LogStreamBase& ref() { return *this; }
  51. std::ostream& strm() { return *strm_; }
  52. int stashed_errno() const { return errno_; }
  53. protected:
  54. void Flush();
  55. private:
  56. int errno_;
  57. const char* file_;
  58. int line_;
  59. const char* lvl_;
  60. std::unique_ptr<std::ostringstream> strm_;
  61. };
  62. template <LogLevel>
  63. class LogStream : public LogStreamBase {
  64. public:
  65. using LogStreamBase::LogStreamBase;
  66. ~LogStream() { this->Flush(); }
  67. };
  68. template <>
  69. class LogStream<FATAL> : public LogStreamBase {
  70. public:
  71. using LogStreamBase::LogStreamBase;
  72. ~LogStream() __attribute__((noreturn)) {
  73. this->Flush();
  74. std::abort();
  75. }
  76. };
  77. template <class T>
  78. LogStreamBase& operator<<(LogStreamBase& strm, const T& val) {
  79. strm.strm() << val;
  80. return strm;
  81. }
  82. inline LogStreamBase& operator<<(LogStreamBase& strm, std::ostream& (*manip)(std::ostream&)) {
  83. strm.strm() << manip;
  84. return strm;
  85. }
  86. struct Errno {
  87. int err;
  88. };
  89. std::ostream& operator<<(std::ostream& strm, Errno e);
  90. struct StashedErrno {};
  91. inline LogStreamBase& operator<<(LogStreamBase& strm, StashedErrno) {
  92. return strm << Errno{strm.stashed_errno()};
  93. }
  94. } // namespace internal_logging
  95. inline internal_logging::Errno Errno(int err) { return {err}; }
  96. inline internal_logging::StashedErrno Errno() { return {}; }
  97. } // namespace gitstatus
  98. #endif // ROMKATV_GITSTATUS_LOGGING_H_