libsir 2.2.5
Standard Incident Reporter
Loading...
Searching...
No Matches
sir.hh
Go to the documentation of this file.
1
34#ifndef _SIR_HH_INCLUDED
35# define _SIR_HH_INCLUDED
36
37# include "sir.h"
38# include "sir/helpers.h"
39# include "sir/internal.h"
40# include <type_traits>
41# include <stdexcept>
42# include <algorithm>
43# include <exception>
44# include <iostream>
45# include <cstring>
46# include <memory>
47# include <tuple>
48# include <string>
49# include <array>
50
51# if HAS_INCLUDE(<format>) && !defined (SIR_NO_STD_FORMAT) && \
52 !defined(_LIBCPP_HAS_NO_INCOMPLETE_FORMAT)
53# include <format>
54# define __SIR_HAVE_STD_FORMAT__
55# endif
56# if HAS_INCLUDE(<boost/format.hpp>) && !defined(SIR_NO_BOOST_FORMAT)
57# include <boost/format.hpp>
58# define __SIR_HAVE_BOOST_FORMAT__
59# endif
60# if HAS_INCLUDE(<fmt/format.h>) && !defined(SIR_NO_FMT_FORMAT)
61# define FMT_HEADER_ONLY
62# include <fmt/format.h>
63# define __SIR_HAVE_FMT_FORMAT__
64# endif
65# if !defined(SIR_NO_STD_IOSTREAM)
66# include <iostream>
67# endif
68
78namespace sir
79{
91 struct error {
92 uint16_t code {};
93 std::string message;
95 constexpr bool is_os_error() const noexcept {
96 return code == SIR_E_PLATFORM;
97 }
98
99 static error from_last_error() {
100 std::string message(SIR_MAXERROR, '\0');
101 const auto code = sir_geterror(message.data());
102 return { code, std::move(message) };
103 }
104 };
105
116 struct error_info : public error {
117 std::string func;
118 std::string file;
119 uint32_t line {};
120 int os_code {};
121 std::string os_message;
123 static error_info from_last_error() {
124 sir_errorinfo errinfo {};
125 sir_geterrorinfo(&errinfo);
126 return { { errinfo.code, errinfo.msg }, errinfo.func, errinfo.file,
127 errinfo.line, errinfo.os_code, errinfo.os_msg };
128 }
129 };
130
144 class exception : public std::runtime_error {
145 public:
146 using std::runtime_error::runtime_error;
147
148 exception() = delete;
149 explicit exception(const error& err) : exception(err.message) { }
150 ~exception() override = default;
151 };
152
162 class policy {
163 protected:
164 policy() = default;
165 virtual ~policy() = default;
166
167 public:
188 virtual bool get_init_data(sirinit& data) const noexcept = 0;
189
205 virtual bool on_init_complete() const noexcept = 0;
206
219 static constexpr bool throw_on_error() noexcept {
220 return false;
221 }
222 };
223
225 template<typename T>
226 concept DerivedFromPolicy = std::is_base_of_v<policy, T>;
227
237 class default_policy : public policy {
238 public:
239 default_policy() = default;
240 ~default_policy() override = default;
241
242 bool get_init_data(sirinit& data) const noexcept final {
243 return sir_makeinit(&data);
244 }
245
246 constexpr bool on_init_complete() const noexcept final {
247 return true;
248 }
249
250 static constexpr bool throw_on_error() noexcept {
251 return true;
252 }
253 };
254
267 class adapter {
268 protected:
269 adapter() = default;
270 virtual ~adapter() = default;
271 };
272
288 template<DerivedFromPolicy TPolicy>
289 static inline bool throw_on_policy(bool expr) noexcept(false) {
290 if (!expr) {
291 SIR_ASSERT(expr);
292 if constexpr(TPolicy::throw_on_error()) {
293 throw exception(error::from_last_error());
294 }
295 }
296 return expr;
297 }
298
309 template<DerivedFromPolicy TPolicy>
310 class default_adapter : public adapter {
311 public:
312 default_adapter() = default;
313 ~default_adapter() override = default;
314
316 PRINTF_FORMAT_ATTR(2, 3)
317 bool debug(PRINTF_FORMAT const char* format, ...) const {
318 _SIR_L_START(format);
319 ret = _sir_logv(SIRL_DEBUG, format, args);
320 _SIR_L_END();
321 return throw_on_policy<TPolicy>(ret);
322 }
323
325 PRINTF_FORMAT_ATTR(2, 3)
326 bool info(PRINTF_FORMAT const char* format, ...) const {
327 _SIR_L_START(format);
328 ret = _sir_logv(SIRL_INFO, format, args);
329 _SIR_L_END();
330 return throw_on_policy<TPolicy>(ret);
331 }
332
334 PRINTF_FORMAT_ATTR(2, 3)
335 bool notice(PRINTF_FORMAT const char* format, ...) const {
336 _SIR_L_START(format);
337 ret = _sir_logv(SIRL_NOTICE, format, args);
338 _SIR_L_END();
339 return throw_on_policy<TPolicy>(ret);
340 }
341
343 PRINTF_FORMAT_ATTR(2, 3)
344 bool warn(PRINTF_FORMAT const char* format, ...) const {
345 _SIR_L_START(format);
346 ret = _sir_logv(SIRL_WARN, format, args);
347 _SIR_L_END();
348 return throw_on_policy<TPolicy>(ret);
349 }
350
352 PRINTF_FORMAT_ATTR(2, 3)
353 bool error(PRINTF_FORMAT const char* format, ...) const {
354 _SIR_L_START(format);
355 ret = _sir_logv(SIRL_ERROR, format, args);
356 _SIR_L_END();
357 return throw_on_policy<TPolicy>(ret);
358 }
359
361 PRINTF_FORMAT_ATTR(2, 3)
362 bool crit(PRINTF_FORMAT const char* format, ...) const {
363 _SIR_L_START(format);
364 ret = _sir_logv(SIRL_CRIT, format, args);
365 _SIR_L_END();
366 return throw_on_policy<TPolicy>(ret);
367 }
368
370 PRINTF_FORMAT_ATTR(2, 3)
371 bool alert(PRINTF_FORMAT const char* format, ...) const {
372 _SIR_L_START(format);
373 ret = _sir_logv(SIRL_ALERT, format, args);
374 _SIR_L_END();
375 return throw_on_policy<TPolicy>(ret);
376 }
377
379 PRINTF_FORMAT_ATTR(2, 3)
380 bool emerg(PRINTF_FORMAT const char* format, ...) const {
381 _SIR_L_START(format);
382 ret = _sir_logv(SIRL_EMERG, format, args);
383 _SIR_L_END();
384 return throw_on_policy<TPolicy>(ret);
385 }
386 };
387
388# if defined(__SIR_HAVE_STD_FORMAT__)
412 template<DerivedFromPolicy TPolicy>
414 public:
415 std_format_adapter() = default;
416 ~std_format_adapter() override = default;
417
418 template<typename... Args>
419 inline bool debug_std(std::format_string<Args...> fmt, Args&&... args) const {
420 const auto str = std::vformat(fmt.get(), std::make_format_args(args...));
421 const bool ret = sir_debug("%s", str.c_str());
422 return throw_on_policy<TPolicy>(ret);
423 }
424
425 template<typename... Args>
426 inline bool info_std(std::format_string<Args...> fmt, Args&&... args) const {
427 const auto str = std::vformat(fmt.get(), std::make_format_args(args...));
428 const bool ret = sir_info("%s", str.c_str());
429 return throw_on_policy<TPolicy>(ret);
430 }
431
432 template<typename... Args>
433 inline bool notice_std(std::format_string<Args...> fmt, Args&&... args) const {
434 const auto str = std::vformat(fmt.get(), std::make_format_args(args...));
435 const bool ret = sir_notice("%s", str.c_str());
436 return throw_on_policy<TPolicy>(ret);
437 }
438
439 template<typename... Args>
440 inline bool warn_std(std::format_string<Args...> fmt, Args&&... args) const {
441 const auto str = std::vformat(fmt.get(), std::make_format_args(args...));
442 const bool ret = sir_warn("%s", str.c_str());
443 return throw_on_policy<TPolicy>(ret);
444 }
445
446 template<typename... Args>
447 inline bool error_std(std::format_string<Args...> fmt, Args&&... args) const {
448 const auto str = std::vformat(fmt.get(), std::make_format_args(args...));
449 const bool ret = sir_error("%s", str.c_str());
450 return throw_on_policy<TPolicy>(ret);
451 }
452
453 template<typename... Args>
454 inline bool crit_std(std::format_string<Args...> fmt, Args&&... args) const {
455 const auto str = std::vformat(fmt.get(), std::make_format_args(args...));
456 const bool ret = sir_crit("%s", str.c_str());
457 return throw_on_policy<TPolicy>(ret);
458 }
459
460 template<typename... Args>
461 inline bool alert_std(std::format_string<Args...> fmt, Args&&... args) const {
462 const auto str = std::vformat(fmt.get(), std::make_format_args(args...));
463 const bool ret = sir_alert("%s", str.c_str());
464 return throw_on_policy<TPolicy>(ret);
465 }
466
467 template<typename... Args>
468 inline bool emerg_std(std::format_string<Args...> fmt, Args&&... args) const {
469 const auto str = std::vformat(fmt.get(), std::make_format_args(args...));
470 const bool ret = sir_emerg("%s", str.c_str());
471 return throw_on_policy<TPolicy>(ret);
472 }
473 };
474# endif // !__SIR_HAVE_STD_FORMAT__
475
476# if defined(__SIR_HAVE_BOOST_FORMAT__)
500 template<DerivedFromPolicy TPolicy>
502 public:
503 boost_format_adapter() = default;
504 ~boost_format_adapter() override = default;
505
506 bool debug_bf(const boost::format& fmt) const {
507 const bool ret = sir_debug("%s", fmt.str().c_str());
508 return throw_on_policy<TPolicy>(ret);
509 }
510
511 bool info_bf(const boost::format& fmt) const {
512 const bool ret = sir_info("%s", fmt.str().c_str());
513 return throw_on_policy<TPolicy>(ret);
514 }
515
516 bool notice_bf(const boost::format& fmt) const {
517 const bool ret = sir_notice("%s", fmt.str().c_str());
518 return throw_on_policy<TPolicy>(ret);
519 }
520
521 bool warn_bf(const boost::format& fmt) const {
522 const bool ret = sir_warn("%s", fmt.str().c_str());
523 return throw_on_policy<TPolicy>(ret);
524 }
525
526 bool error_bf(const boost::format& fmt) const {
527 const bool ret = sir_error("%s", fmt.str().c_str());
528 return throw_on_policy<TPolicy>(ret);
529 }
530
531 bool crit_bf(const boost::format& fmt) const {
532 const bool ret = sir_crit("%s", fmt.str().c_str());
533 return throw_on_policy<TPolicy>(ret);
534 }
535
536 bool alert_bf(const boost::format& fmt) const {
537 const bool ret = sir_alert("%s", fmt.str().c_str());
538 return throw_on_policy<TPolicy>(ret);
539 }
540
541 bool emerg_bf(const boost::format& fmt) const {
542 const bool ret = sir_emerg("%s", fmt.str().c_str());
543 return throw_on_policy<TPolicy>(ret);
544 }
545 };
546# endif // !__SIR_HAVE_BOOST_FORMAT__
547
548# if defined(__SIR_HAVE_FMT_FORMAT__)
572 template<DerivedFromPolicy TPolicy>
574 public:
575 fmt_format_adapter() = default;
576 ~fmt_format_adapter() override = default;
577
578 template<typename... Args>
579 inline bool debug_fmt(fmt::format_string<Args...> fmt, Args&&... args) const {
580 const auto str = fmt::vformat(fmt, fmt::make_format_args(args...));
581 const auto ret = sir_debug("%s", str.c_str());
582 return throw_on_policy<TPolicy>(ret);
583 }
584
585 template<typename... Args>
586 inline bool info_fmt(fmt::format_string<Args...> fmt, Args&&... args) const {
587 const auto str = fmt::vformat(fmt, fmt::make_format_args(args...));
588 const auto ret = sir_info("%s", str.c_str());
589 return throw_on_policy<TPolicy>(ret);
590 }
591
592 template<typename... Args>
593 inline bool notice_fmt(fmt::format_string<Args...> fmt, Args&&... args) const {
594 const auto str = fmt::vformat(fmt, fmt::make_format_args(args...));
595 const auto ret = sir_notice("%s", str.c_str());
596 return throw_on_policy<TPolicy>(ret);
597 }
598
599 template<typename... Args>
600 inline bool warn_fmt(fmt::format_string<Args...> fmt, Args&&... args) const {
601 const auto str = fmt::vformat(fmt, fmt::make_format_args(args...));
602 const auto ret = sir_warn("%s", str.c_str());
603 return throw_on_policy<TPolicy>(ret);
604 }
605
606 template<typename... Args>
607 inline bool error_fmt(fmt::format_string<Args...> fmt, Args&&... args) const {
608 const auto str = fmt::vformat(fmt, fmt::make_format_args(args...));
609 const auto ret = sir_error("%s", str.c_str());
610 return throw_on_policy<TPolicy>(ret);
611 }
612
613 template<typename... Args>
614 inline bool crit_fmt(fmt::format_string<Args...> fmt, Args&&... args) const {
615 const auto str = fmt::vformat(fmt, fmt::make_format_args(args...));
616 const auto ret = sir_crit("%s", str.c_str());
617 return throw_on_policy<TPolicy>(ret);
618 }
619
620 template<typename... Args>
621 inline bool alert_fmt(fmt::format_string<Args...> fmt, Args&&... args) const {
622 const auto str = fmt::vformat(fmt, fmt::make_format_args(args...));
623 const auto ret = sir_alert("%s", str.c_str());
624 return throw_on_policy<TPolicy>(ret);
625 }
626
627 template<typename... Args>
628 inline bool emerg_fmt(fmt::format_string<Args...> fmt, Args&&... args) const {
629 const auto str = fmt::vformat(fmt, fmt::make_format_args(args...));
630 const auto ret = sir_emerg("%s", str.c_str());
631 return throw_on_policy<TPolicy>(ret);
632 }
633 };
634# endif // !__SIR_HAVE_FMT_FORMAT__
635
636# if !defined(SIR_NO_STD_IOSTREAM)
638 template<typename T>
639 concept DerivedFromStreamBuf = std::is_base_of_v<std::streambuf, T>;
640
666 template<DerivedFromPolicy TPolicy>
668 public:
669 std_iostream_adapter() = default;
670 ~std_iostream_adapter() override = default;
671
672 template<typename TFunc>
673 class buffer : public std::streambuf {
674 public:
675 using array_type = std::array<char_type, SIR_MAXMESSAGE>;
676
677 buffer() = delete;
678
679 explicit buffer(TFunc pfn) : _pfn(pfn) {
680 [[maybe_unused]]
681 bool ok = throw_on_policy<TPolicy>(pfn != nullptr && _arr != nullptr);
682 reset();
683 }
684
685 ~buffer() override = default;
686
687 protected:
688 void reset() {
689 if (_arr) {
690 _arr->fill('\0');
691 setp(_arr->data(), _arr->data() + _arr->size() - 1);
692 }
693 }
694
695 bool write_out() {
696 for (auto it = _arr->rbegin(); it != _arr->rend(); it++) {
697 if ((*it != '\0') && (*it == '\n')) {
698 *it = '\0';
699 break;
700 }
701 }
702
703 const bool write = _pfn ? _pfn(_arr->data()) : false;
704 reset();
705 return throw_on_policy<TPolicy>(write);
706 }
707
708 int_type overflow(int_type ch) override {
709 if (ch != traits_type::eof() && write_out()) {
710 return ch;
711 }
712 return traits_type::eof();
713 }
714
715 int sync() override {
716 return write_out() ? 0 : -1;
717 }
718
719 std::streamsize xsputn(const char_type* s, std::streamsize count) override {
720 std::streamsize written = 0;
721 do {
722 ptrdiff_t left = epptr() - pptr();
723 if (!left) {
724 int_type ch = overflow(traits_type::to_int_type(*(s + written)));
725 if (ch != traits_type::eof()) {
726 continue;
727 } else {
728 break;
729 }
730 }
731
732 auto this_write = std::min(static_cast<std::streamsize>(left),
733 count - written);
734 std::memcpy(pptr(), s + written, static_cast<std::size_t>(this_write));
735 pbump(static_cast<int>(this_write));
736 written += this_write;
737 } while (written < count);
738
739 return written;
740 }
741
742 private:
743 std::shared_ptr<array_type> _arr = std::make_shared<array_type>();
744 TFunc _pfn = nullptr;
745 };
746
747 template<DerivedFromStreamBuf TBuffer>
748 class stream : public std::ostream {
749 public:
750 explicit stream(const TBuffer& buf) : std::ostream(&_buf), _buf(buf) {}
751 ~stream() override = default;
752
753 private:
754 TBuffer _buf;
755 };
756
757 using log_func = bool(*)(const char*, ...);
758 using buffer_type = buffer<log_func>;
759 using stream_type = stream<buffer_type>;
760
761 stream_type debug_stream {buffer_type {&sir_debug}};
762 stream_type info_stream {buffer_type {&sir_info}};
763 stream_type notice_stream {buffer_type {&sir_notice}};
764 stream_type warn_stream {buffer_type {&sir_warn}};
765 stream_type error_stream {buffer_type {&sir_error}};
766 stream_type crit_stream {buffer_type {&sir_crit}};
767 stream_type alert_stream {buffer_type {&sir_alert}};
768 stream_type emerg_stream {buffer_type {&sir_emerg}};
769 };
770# endif // SIR_NO_STD_IOSTREAM
771
773 template<size_t N, typename ...Ts>
774 using NthTypeOf = typename std::tuple_element<N, std::tuple<Ts...>>::type;
775
777 template<size_t N, typename TBase, typename ...Ts>
778 consteval auto all_derived_from_t() {
779 if constexpr(!std::is_base_of_v<TBase, NthTypeOf<N, Ts...>>)
780 return std::false_type::value;
781 if constexpr(N == 0)
782 return std::true_type::value;
783 else
784 return all_derived_from_t<N - 1, TBase, Ts...>();
785 }
786
788 template<class TBase, class ...Ts>
789 concept DerivedFromT = all_derived_from_t<sizeof...(Ts) - 1, TBase, Ts...>();
790
809 template<bool RAII, DerivedFromPolicy TPolicy, template<class> class ...TAdapters>
811 class logger : public TAdapters<TPolicy>... {
812 public:
813 logger() : TAdapters<TPolicy>()... {
814 if constexpr(RAII) {
815 [[maybe_unused]]
816 bool ok = throw_on_policy<TPolicy>(_init());
817 }
818 }
819
820 logger(const logger&) = delete;
821 logger(const logger&&) = delete;
822
823 ~logger() override {
824 if constexpr(RAII) {
825 if (!cleanup()) {
826 SIR_ASSERT(false);
827 }
828 }
829 }
830
831 logger& operator=(const logger&) = delete;
832 logger& operator=(const logger&&) = delete;
833
834 bool init() const noexcept {
835 return is_initialized() ? false: _init();
836 }
837
838 bool cleanup() const noexcept {
839 return is_initialized() ? sir_cleanup() : false;
840 }
841
842 bool is_initialized() const noexcept {
843 return sir_isinitialized();
844 }
845
846 error get_error() const {
847 return error::from_last_error();
848 }
849
850 error_info get_error_info() const {
851 return error_info::from_last_error();
852 }
853
854 sirfileid add_file(const std::string& path, const sir_levels& levels,
855 const sir_options& opts) const {
856 const bool add = sir_addfile(path.c_str(), levels, opts);
857 return throw_on_policy<TPolicy>(add);
858 }
859
860 bool rem_file(const sirfileid& id) const {
861 const bool rem = sir_remfile(id);
862 return throw_on_policy<TPolicy>(rem);
863 }
864
865 sirpluginid load_plugin(const std::string& path) const {
866 const bool load = sir_loadplugin(path.c_str());
867 return throw_on_policy<TPolicy>(load);
868 }
869
870 bool unload_plugin(const sirpluginid& id) const {
871 const bool unload = sir_unloadplugin(id);
872 return throw_on_policy<TPolicy>(unload);
873 }
874
875 bool set_file_levels(const sirfileid& id, const sir_levels& levels) const {
876 const bool set = sir_filelevels(id, levels);
877 return throw_on_policy<TPolicy>(set);
878 }
879
880 bool set_file_options(const sirfileid& id, const sir_options& opts) const {
881 const bool set = sir_fileopts(id, opts);
882 return throw_on_policy<TPolicy>(set);
883 }
884
885 bool set_text_style(const sir_level& level, const sir_textattr& attr,
886 const sir_textcolor& fg, const sir_textcolor& bg) const {
887 const bool set = sir_settextstyle(level, attr, fg, bg);
888 return throw_on_policy<TPolicy>(set);
889 }
890
891 bool reset_text_styles() const {
892 const bool reset = sir_resettextstyles();
893 return throw_on_policy<TPolicy>(reset);
894 }
895
896 sir_textcolor make_rgb(const sir_textcolor& r, const sir_textcolor& g,
897 const sir_textcolor& b) const {
898 const bool make = sir_makergb(r, g, b);
899 return throw_on_policy<TPolicy>(make);
900 }
901
902 bool set_color_mode(const sir_colormode& mode) const {
903 const bool set = sir_setcolormode(mode);
904 return throw_on_policy<TPolicy>(set);
905 }
906
907 bool set_stdout_levels(const sir_levels& levels) const {
908 const bool set = sir_stdoutlevels(levels);
909 return throw_on_policy<TPolicy>(set);
910 }
911
912 bool set_stdout_options(const sir_options& opts) const {
913 const bool set = sir_stdoutopts(opts);
914 return throw_on_policy<TPolicy>(set);
915 }
916
917 bool set_stderr_levels(const sir_levels& levels) const {
918 const bool set = sir_stderrlevels(levels);
919 return throw_on_policy<TPolicy>(set);
920 }
921
922 bool set_stderr_options(const sir_options& opts) const {
923 const bool set = sir_stderropts(opts);
924 return throw_on_policy<TPolicy>(set);
925 }
926
927 bool set_syslog_levels(const sir_levels& levels) const {
928 const bool set = sir_sysloglevels(levels);
929 return throw_on_policy<TPolicy>(set);
930 }
931
932 bool set_syslog_options(const sir_options& opts) const {
933 const bool set = sir_syslogopts(opts);
934 return throw_on_policy<TPolicy>(set);
935 }
936
937 bool set_syslog_id(const std::string& id) const {
938 const bool set = sir_syslogid(id.c_str());
939 return throw_on_policy<TPolicy>(set);
940 }
941
942 bool set_syslog_category(const std::string& category) const {
943 const bool set = sir_syslogcat(category.c_str());
944 return throw_on_policy<TPolicy>(set);
945 }
946
947 std::string get_version_string() const {
948 return sir_getversionstring();
949 }
950
951 uint32_t get_version_hex() const noexcept {
952 return sir_getversionhex();
953 }
954
955 bool is_prerelease() const noexcept {
956 return sir_isprerelease();
957 }
958
959 protected:
960 bool _init() const noexcept {
961 TPolicy policy {};
962 sirinit si {};
963 if (const bool init = policy.get_init_data(si) && sir_init(&si) &&
964 policy.on_init_complete(); !init) {
965 return false;
966 }
967 return true;
968 }
969 };
970
976
977# if defined(__SIR_HAVE_STD_FORMAT__)
984 <
985 true,
989 >;
990# endif
991
992# if defined(__SIR_HAVE_BOOST_FORMAT__)
999 <
1000 true,
1004 >;
1005# endif
1006
1007# if defined(__SIR_HAVE_FMT_FORMAT__)
1014 <
1015 true,
1019 >;
1020# endif
1021
1022# if !defined(SIR_NO_STD_IOSTREAM)
1029 <
1030 true,
1034 >;
1035# endif
1036
1037} // ! namespace sir
1038
1044#endif // !_SIR_HH_INCLUDED
Defines the abstract interface for an adapter, which ultimately becomes a public base class of logger...
Definition sir.hh:267
Adapter for boost::format (when available).
Definition sir.hh:501
The default adapter implementation.
Definition sir.hh:310
bool crit(PRINTF_FORMAT const char *format,...) const
Logs a critical message (see sir_crit).
Definition sir.hh:362
bool debug(PRINTF_FORMAT const char *format,...) const
Logs a debug message (see sir_debug).
Definition sir.hh:317
bool warn(PRINTF_FORMAT const char *format,...) const
Logs a warning message (see sir_warn).
Definition sir.hh:344
bool notice(PRINTF_FORMAT const char *format,...) const
Logs a notice message (see sir_notice).
Definition sir.hh:335
bool emerg(PRINTF_FORMAT const char *format,...) const
Logs an emergency message (see sir_emerg).
Definition sir.hh:380
bool info(PRINTF_FORMAT const char *format,...) const
Logs an informational message (see sir_info).
Definition sir.hh:326
bool alert(PRINTF_FORMAT const char *format,...) const
Logs an alert message (see sir_alert).
Definition sir.hh:371
In the event that no custom configuration or behavior is desired, provides defaults for everything.
Definition sir.hh:237
bool get_init_data(sirinit &data) const noexcept final
Called by logger before initializing libsir.
Definition sir.hh:242
constexpr bool on_init_complete() const noexcept final
Called by logger immediately after libsir has been initialized.
Definition sir.hh:246
The exception type thrown by libsir.
Definition sir.hh:144
Adapter for {fmt} (when available).
Definition sir.hh:573
The primary C++ interface to libsir.
Definition sir.hh:811
Defines the partially abstract interface for a policy which controls the behavior of logger at runtim...
Definition sir.hh:162
virtual bool on_init_complete() const noexcept=0
Called by logger immediately after libsir has been initialized.
static constexpr bool throw_on_error() noexcept
Determines whether or not exceptions are thrown in the event that an unercoverable error is encounter...
Definition sir.hh:219
virtual bool get_init_data(sirinit &data) const noexcept=0
Called by logger before initializing libsir.
Adapter for std::format (when available).
Definition sir.hh:413
Provides a std::iostream interface to libsir's logging functions.
Definition sir.hh:667
Ensures that T derives from policy.
Definition sir.hh:226
Ensures that T derives from std::streambuf.
Definition sir.hh:639
True if all Ts are derived classes of TBase, otherwise false.
Definition sir.hh:789
#define SIR_MAXERROR
The maximum size, in characters, of an error message.
Definition config.h:419
bool sir_stderropts(sir_options opts)
Set new formatting options for stderr.
Definition sir.c:211
bool sir_settextstyle(sir_level level, sir_textattr attr, sir_textcolor fg, sir_textcolor bg)
Set new text styling for stdio (stdout/stderr) destinations on a per-level basis.
Definition sir.c:170
sirpluginid sir_loadplugin(const char *path)
Loads a plugin module from disk.
Definition sir.c:140
bool sir_alert(PRINTF_FORMAT const char *format,...)
Dispatches a SIRL_ALERT level message.
Definition sir.c:117
bool sir_sysloglevels(sir_levels levels)
Set new level registrations for the system logger destination.
Definition sir.c:217
bool sir_setcolormode(sir_colormode mode)
Sets the ANSI color mode for stdio destinations.
Definition sir.c:189
bool sir_error(PRINTF_FORMAT const char *format,...)
Dispatches a SIRL_ERROR level message.
Definition sir.c:101
bool sir_notice(PRINTF_FORMAT const char *format,...)
Dispatches a SIRL_NOTICE level message.
Definition sir.c:85
bool sir_stderrlevels(sir_levels levels)
Set new level registrations for stderr.
Definition sir.c:205
sir_textcolor sir_makergb(sir_textcolor r, sir_textcolor g, sir_textcolor b)
Creates a sir_textcolor from red, green, and blue components.
Definition sir.c:185
bool sir_filelevels(sirfileid id, sir_levels levels)
Set new level registrations for a log file already managed by libsir.
Definition sir.c:158
bool sir_syslogopts(sir_options opts)
Set new formatting options for the system logger destination.
Definition sir.c:228
bool sir_unloadplugin(sirpluginid id)
Unloads a previously registered plugin module.
Definition sir.c:149
bool sir_stdoutlevels(sir_levels levels)
Set new level registrations for stdout.
Definition sir.c:193
uint32_t sir_getversionhex(void)
Returns the current libsir version as a number.
Definition sir.c:263
bool sir_debug(PRINTF_FORMAT const char *format,...)
Dispatches a SIRL_DEBUG level message.
Definition sir.c:69
bool sir_resettextstyles(void)
Reset text styling for stdio (stdout/stderr) destinations to their default values.
Definition sir.c:181
bool sir_info(PRINTF_FORMAT const char *format,...)
Dispatches a SIRL_INFO level message.
Definition sir.c:77
bool sir_cleanup(void)
Tears down and cleans up libsir after use.
Definition sir.c:52
sirfileid sir_addfile(const char *path, sir_levels levels, sir_options opts)
Adds a log file and registers it to receive log output.
Definition sir.c:132
bool sir_init(sirinit *si)
Initializes libsir for use.
Definition sir.c:48
bool sir_crit(PRINTF_FORMAT const char *format,...)
Dispatches a SIRL_CRIT level message.
Definition sir.c:109
bool sir_remfile(sirfileid id)
Removes a file previously added to libsir.
Definition sir.c:136
bool sir_syslogid(const char *identity)
Set new system logger identity.
Definition sir.c:239
bool sir_warn(PRINTF_FORMAT const char *format,...)
Dispatches a SIRL_WARN level message.
Definition sir.c:93
uint16_t sir_geterror(char message[SIR_MAXERROR])
Retrieves a formatted message for the last error that occurred on the calling thread and returns the ...
Definition sir.c:60
bool sir_stdoutopts(sir_options opts)
Set new formatting options for stdout.
Definition sir.c:199
bool sir_makeinit(sirinit *si)
Fills out a sirinit structure with default values.
Definition sir.c:44
bool sir_syslogcat(const char *category)
Set new system logger category.
Definition sir.c:249
bool sir_isinitialized(void)
Determines whether or not libsir is in the initialized state.
Definition sir.c:56
const char * sir_getversionstring(void)
Returns the current libsir version as a string.
Definition sir.c:259
void sir_geterrorinfo(sir_errorinfo *err)
Retrieves granular information about the last error that occurred on the calling thread.
Definition sir.c:64
bool sir_fileopts(sirfileid id, sir_options opts)
Set new formatting options for a log file already managed by libsir.
Definition sir.c:164
bool sir_isprerelease(void)
Whether or not this is a pre-release version of libsir.
Definition sir.c:267
bool sir_emerg(PRINTF_FORMAT const char *format,...)
Dispatches a SIRL_EMERG level message.
Definition sir.c:125
uint16_t sir_level
The sir_level type.
Definition types.h:71
uint32_t sirfileid
Log file identifier type.
Definition types.h:49
sir_textattr
Attributes for stdio output.
Definition types.h:107
#define SIRL_EMERG
Nuclear war, Armageddon, etc.
Definition types.h:59
sir_colormode
Color mode selection.
Definition types.h:99
#define SIRL_ERROR
Errors.
Definition types.h:62
uint16_t sir_levels
sir_level bitmask type.
Definition types.h:74
#define SIRL_ALERT
Action required ASAP.
Definition types.h:60
#define SIRL_WARN
Warnings that could likely be ignored.
Definition types.h:63
#define SIRL_INFO
Informational messages.
Definition types.h:65
#define SIRL_DEBUG
Debugging/diagnostic output.
Definition types.h:66
uint32_t sir_textcolor
stdio text color type.
Definition types.h:141
#define SIRL_CRIT
Critical errors.
Definition types.h:61
#define SIRL_NOTICE
Normal but significant.
Definition types.h:64
uint32_t sirpluginid
Plugin module identifier type.
Definition types.h:52
uint32_t sir_options
sir_option bitmask type.
Definition types.h:96
@ SIR_E_PLATFORM
Platform error code %d: %s.
Definition errors.h:67
Information about an error that occurred.
Definition types.h:150
libsir initialization and configuration data.
Definition types.h:244
libsir C++ wrapper implementation.
Definition sir.hh:79
consteval auto all_derived_from_t()
Ensures (at compile time) that all Ts are derived classes of TBase.
Definition sir.hh:778
static bool throw_on_policy(bool expr) noexcept(false)
Handles a potential error; if an error is present and the policy in place requires throwing an except...
Definition sir.hh:289
typename std::tuple_element< N, std::tuple< Ts... > >::type NthTypeOf
Utility template for obtaining the type of Nth item in a parameter pack.
Definition sir.hh:774
Public interface to libsir.
Contains all available information about an error.
Definition sir.hh:116
std::string os_message
If an OS/libc error, the associated message.
Definition sir.hh:121
std::string func
Name of the function in which the error occurred.
Definition sir.hh:117
int os_code
If an OS/libc error, the associated code.
Definition sir.hh:120
std::string file
Name of the file in which the error occurred.
Definition sir.hh:118
uint32_t line
Line number at which the error occurred.
Definition sir.hh:119
Contains basic information about an error.
Definition sir.hh:91
uint16_t code
Numeric error code (see sir_errorcode).
Definition sir.hh:92
std::string message
Formatted error message.
Definition sir.hh:93