farm-ng-core
format.h
Go to the documentation of this file.
1 // Copyright 2022, farm-ng inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
18 #include <farm_pp/preprocessor/comparison/equal.hpp>
19 #include <farm_pp/preprocessor/control/if.hpp>
20 #include <farm_pp/preprocessor/variadic/size.hpp>
21 #include <fmt/core.h>
22 #include <fmt/format.h>
23 #include <fmt/ostream.h>
24 
25 #include <functional>
26 #include <iostream>
27 
28 #ifdef FARM_COMPILE_TIME_FMT
29 #define FARM_STRING(x) FMT_STRING(x)
30 #else
31 #define FARM_STRING(x) x
32 #endif
33 
34 namespace farm_ng {
35 std::function<void(std::string const &)> &getLogLineFunction();
36 
37 void setLogLineFunction(std::function<void(std::string const &)> f);
38 
39 void logLine(std::string const &line);
40 } // namespace farm_ng
41 
42 // Begin (Impl details)
43 #define FARM_IMPL_LOG_PRINTLN_ZERO()
44 
45 #define FARM_IMPL_LOG_PRINTLN_ONE(cstr) farm_ng::logLine(FARM_STRING(cstr))
46 
47 #define FARM_IMPL_LOG_PRINTLN_ARGS(cstr, ...) \
48  farm_ng::logLine(::fmt::format(FMT_STRING(cstr), __VA_ARGS__))
49 
50 #define FARM_IMPL_LOG_PRINTLN_VARG(cstr, ...) \
51  FARM_PP_IF( \
52  FARM_PP_EQUAL(FARM_PP_VARIADIC_SIZE(cstr, ##__VA_ARGS__), 1), \
53  FARM_IMPL_LOG_PRINTLN_ONE(cstr), \
54  FARM_IMPL_LOG_PRINTLN_ARGS(cstr, ##__VA_ARGS__))
55 
56 #define FARM_IMPL_LOG_PRINTLN(...) \
57  FARM_PP_IF( \
58  FARM_PP_EQUAL(FARM_PP_VARIADIC_SIZE(dummy, ##__VA_ARGS__), 1), \
59  FARM_IMPL_LOG_PRINTLN_ZERO(), \
60  FARM_IMPL_LOG_PRINTLN_VARG(__VA_ARGS__))
61 
62 #define FARM_IMPL_ABORT() \
63  do { \
64  farm_ng::printBacktrace(); \
65  ::std::abort(); \
66  } while (false)
67 
68 // End (Impl details)
69 
70 namespace farm_ng {
71 namespace details {
72 
73 template <class... TArgs>
74 std::string runtimeFormatImpl(
75  std::string const &file,
76  int line,
77  std::string const &str,
78  TArgs &&...args) {
79  try {
80  return ::fmt::format(fmt::runtime(str), std::forward<TArgs>(args)...);
81  } catch (::fmt::format_error &e) {
82  FARM_IMPL_LOG_PRINTLN("[FARM_RUNTIME_FORMAT in {}:{}]", file, line);
84  "Runtime format error thrown for {}.\nError string: {}", str, e.what());
85  }
87 }
88 
89 } // namespace details
90 } // namespace farm_ng
91 
92 /// Formats the `cstr` using the libfmt library.
93 ///
94 /// See here for details: https://fmt.dev/latest/syntax.html
95 ///
96 /// If `str` is cstring literal, call FARM_FORMAT instead, and the format
97 /// will be checked at compile time.
98 #define FARM_RUNTIME_FORMAT(str, ...) \
99  ::farm_ng::details::runtimeFormatImpl(__FILE__, __LINE__, str, __VA_ARGS__)
100 
101 #ifdef FARM_COMPILE_TIME_FMT
102 #define FARM_IMPL_FORMAT_ARGS(cstr, ...) \
103  ::fmt::format(FMT_STRING(cstr), __VA_ARGS__)
104 #else
105 #define FARM_IMPL_FORMAT_ARGS(cstr, ...) FARM_RUNTIME_FORMAT(cstr, __VA_ARGS__)
106 #endif
107 
108 #define FARM_IMPL_FORMAT_VARG(cstr, ...) \
109  FARM_PP_IF( \
110  FARM_PP_EQUAL(FARM_PP_VARIADIC_SIZE(cstr, ##__VA_ARGS__), 1), \
111  std::string(cstr), \
112  FARM_IMPL_FORMAT_ARGS(cstr, ##__VA_ARGS__))
113 
114 /// Formats the `cstr` using the libfmt library.
115 ///
116 /// See here for details: https://fmt.dev/latest/syntax.html
117 ///
118 /// Note that compile-time format check is performed, and hence cstr needs to be
119 /// a string literal. If no compile-time check is required, and/or the string is
120 /// a variable, call ``FARM_RUNTIME_FORMAT(fmt, ...)`` instead.
121 ///
122 /// FARM_COMPILE_TIME_FMT is not defined, the runtime version will be used,
123 /// to speed up compile times.
124 ///
125 #define FARM_FORMAT(...) \
126  FARM_PP_IF( \
127  FARM_PP_EQUAL(FARM_PP_VARIADIC_SIZE(dummy, ##__VA_ARGS__), 1), \
128  std::string(), \
129  FARM_IMPL_FORMAT_VARG(__VA_ARGS__))
farm_ng
Definition: backtrace.cpp:102
farm_ng::logLine
void logLine(std::string const &line)
Definition: format.cpp:28
FARM_IMPL_LOG_PRINTLN
#define FARM_IMPL_LOG_PRINTLN(...)
Definition: format.h:56
core.event_service.str
str
Definition: event_service.py:547
backtrace.h
core.event_service.args
args
Definition: event_service.py:549
farm_ng::setLogLineFunction
void setLogLineFunction(std::function< void(std::string const &)> f)
Definition: format.cpp:24
farm_ng::getLogLineFunction
std::function< void(std::string const &)> & getLogLineFunction()
Definition: format.h:35
FARM_IMPL_ABORT
#define FARM_IMPL_ABORT()
Definition: format.h:62
farm_ng::details::runtimeFormatImpl
std::string runtimeFormatImpl(std::string const &file, int line, std::string const &str, TArgs &&...args)
Definition: format.h:74