// license:GPL-2.0+ // copyright-holders:Couriersud /* * pfmtlog.h */ #ifndef PFMT_H_ #define PFMT_H_ //#include //#include #include "pconfig.h" #include "pstring.h" #include "ptypes.h" namespace plib { template struct ptype_treats { }; template<> struct ptype_treats { static short cast(char x) { return x; } static const bool is_signed = true; static const char *size_specifier() { return "h"; } }; template<> struct ptype_treats { static short cast(short x) { return x; } static const bool is_signed = true; static const char *size_specifier() { return "h"; } }; template<> struct ptype_treats { static int cast(int x) { return x; } static const bool is_signed = true; static const char *size_specifier() { return ""; } }; template<> struct ptype_treats { static long cast(long x) { return x; } static const bool is_signed = true; static const char *size_specifier() { return "l"; } }; template<> struct ptype_treats { static long long cast(long long x) { return x; } static const bool is_signed = true; static const char *size_specifier() { return "ll"; } }; template<> struct ptype_treats { static unsigned short cast(unsigned char x) { return x; } static const bool is_signed = false; static const char *size_specifier() { return "h"; } }; template<> struct ptype_treats { static unsigned short cast(unsigned short x) { return x; } static const bool is_signed = false; static const char *size_specifier() { return "h"; } }; template<> struct ptype_treats { static unsigned int cast(unsigned int x) { return x; } static const bool is_signed = false; static const char *size_specifier() { return ""; } }; template<> struct ptype_treats { static unsigned long cast(unsigned long x) { return x; } static const bool is_signed = false; static const char *size_specifier() { return "l"; } }; template<> struct ptype_treats { static unsigned long long cast(unsigned long long x) { return x; } static const bool is_signed = false; static const char *size_specifier() { return "ll"; } }; template class pformat_base { public: virtual ~pformat_base() { } P &operator ()(const double x, const char *f = "") { format_element(f, "", "f", x); return static_cast

(*this); } P & e(const double x, const char *f = "") { format_element(f, "", "e", x); return static_cast

(*this); } P & g(const double x, const char *f = "") { format_element(f, "", "g", x); return static_cast

(*this); } P &operator ()(const float x, const char *f = "") { format_element(f, "", "f", x); return static_cast

(*this); } P & e(const float x, const char *f = "") { format_element(f, "", "e", x); return static_cast

(*this); } P & g(const float x, const char *f = "") { format_element(f, "", "g", x); return static_cast

(*this); } P &operator ()(const char *x, const char *f = "") { format_element(f, "", "s", x); return static_cast

(*this); } P &operator ()(char *x, const char *f = "") { format_element(f, "", "s", x); return static_cast

(*this); } P &operator ()(const void *x, const char *f = "") { format_element(f, "", "p", x); return static_cast

(*this); } P &operator ()(const pstring &x, const char *f = "") { format_element(f, "", "s", x.cstr() ); return static_cast

(*this); } template P &operator ()(const T x, const char *f = "") { if (ptype_treats::is_signed) format_element(f, ptype_treats::size_specifier(), "d", ptype_treats::cast(x)); else format_element(f, ptype_treats::size_specifier(), "u", ptype_treats::cast(x)); return static_cast

(*this); } template P &x(const T x, const char *f = "") { format_element(f, ptype_treats::size_specifier(), "x", x); return static_cast

(*this); } template P &o(const T x, const char *f = "") { format_element(f, ptype_treats::size_specifier(), "o", x); return static_cast

(*this); } protected: virtual void format_element(const char *f, const char *l, const char *fmt_spec, ...) = 0; }; class pfmt : public pformat_base { public: explicit pfmt(const pstring &fmt); explicit pfmt(const char *fmt); virtual ~pfmt(); operator pstring() const { return m_str; } const char *cstr() { return m_str; } protected: void format_element(const char *f, const char *l, const char *fmt_spec, ...) override; private: char *m_str; char m_str_buf[256]; unsigned m_allocated; unsigned m_arg; }; P_ENUM(plog_level, DEBUG, INFO, VERBOSE, WARNING, ERROR, FATAL) class plog_dispatch_intf; template class pfmt_writer_t { public: pfmt_writer_t() : m_enabled(true) { } virtual ~pfmt_writer_t() { } void operator ()(const char *fmt) const { if (build_enabled && m_enabled) vdowrite(fmt); } template void operator ()(const char *fmt, const T1 &v1) const { if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)); } template void operator ()(const char *fmt, const T1 &v1, const T2 &v2) const { if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)); } template void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3) const { if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)); } template void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4) const { if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4)); } template void operator ()(const char *fmt, const T1 &v1, const T2 &v2, const T3 &v3, const T4 &v4, const T5 &v5) const { if (build_enabled && m_enabled) vdowrite(pfmt(fmt)(v1)(v2)(v3)(v4)(v5)); } void set_enabled(const bool v) { m_enabled = v; } bool is_enabled() const { return m_enabled; } protected: virtual void vdowrite(const pstring &ls) const {} private: bool m_enabled; }; template class plog_channel : public pfmt_writer_t { public: explicit plog_channel(plog_dispatch_intf *b) : pfmt_writer_t(), m_base(b) { } virtual ~plog_channel() { } protected: virtual void vdowrite(const pstring &ls) const override; private: plog_dispatch_intf *m_base; }; class plog_dispatch_intf { template friend class plog_channel; public: virtual ~plog_dispatch_intf() { } protected: virtual void vlog(const plog_level &l, const pstring &ls) const = 0; }; template class plog_base { public: explicit plog_base(plog_dispatch_intf *proxy) : debug(proxy), info(proxy), verbose(proxy), warning(proxy), error(proxy), fatal(proxy) {} virtual ~plog_base() {}; plog_channel debug; plog_channel info; plog_channel verbose; plog_channel warning; plog_channel error; plog_channel fatal; }; template void plog_channel::vdowrite(const pstring &ls) const { m_base->vlog(L, ls); } } #endif /* PSTRING_H_ */