16  struct timeval tv = { 0, 0 };
 
   18  return tv.tv_sec * 1000000ULL + tv.tv_usec;
 
 
   23static int      log_fd = -1;
 
   24static bool     log_colorize = 
true;
 
   29  if (log_flags) [[likely]] 
return;
 
   34      log_flags |= LOG_FILE;
 
   36    log_flags |= LOG_STDERR;
 
   37  const time_t now = programstart_timestamp / 1000000;
 
   40  char tbuf[128] = { 0, };
 
   41  strftime (tbuf, 
sizeof (tbuf) - 1, 
"%Y-%m-%d %H:%M:%S %z", &stm);
 
   44  bexec = bexec ? bexec+1 : exec.
c_str();
 
   45  char pidbuf[64] = { 0, };
 
   48  logmsg (msg, 
"", 0, 
"");
 
   52logmsg (
const std::string &msg, 
const char *
const filename, 
const uint64_t columnline, 
const char *
const function_name)
 
   56  ScopedPosixLocale posix_locale; 
 
   57  if (msg.
empty()) 
return;
 
   59  if (s[s.size()-1] != 
'\n')
 
   62    char tstamp[64] = { 0, };
 
   63    snprintf (tstamp, 
sizeof (tstamp) - 1, 
"%.6f: ", 0.000001 * (
timestamp_now() - programstart_timestamp));
 
   66  if ((log_flags & LOG_LOCATIONS) &&
 
   67      filename && filename[0] && function_name) {
 
   68    char linein[128] = { 0, };
 
   69    snprintf (linein, 
sizeof (linein) - 1, 
":%u:%u: logging at: ", line, column);
 
   70    s = filename + 
std::string (linein) + function_name + 
":\n" + s;
 
   72  if (log_fd == 2 || log_flags & LOG_STDERR)
 
   74  if (!log_colorize && log_flags & LOG_STDERR)
 
   75    write (2, s.data(), s.size());
 
   77    write (log_fd, s.data(), s.size());
 
   78  if (log_colorize && log_flags & LOG_STDERR) {
 
   79    using namespace AnsiColors;
 
   80    const auto C = 
color (FG_CYAN), G = 
color (BOLD, FG_GREEN), B = 
color (FG_BLUE), Y = 
color (FG_YELLOW), R = 
color (RESET);
 
   81    const std::string HEXINT = 
"0[xX][0-9abcdefABCDEF]+";
 
   82    const std::string FULLFLOAT = 
"([1-9][0-9]*|0)([.][0-9]*)?([eE][+-]?[0-9]+)?";
 
   83    const std::string FRACTFLOAT = 
"[.][0-9]+([eE][+-]?[0-9]+)?";
 
   84    const std::string NUMBER = HEXINT + 
"|" + FULLFLOAT + 
"|" + FRACTFLOAT;
 
   85    s = 
Re::sub (
"=(" + NUMBER + 
")", 
"=" + Y + 
"$1" + R, s);
 
   86    s = 
Re::sub (
"=(\"(?:[^\"\\\\]|\\\\.)*\")", 
"=" + B + 
"$1" + R, s);
 
   87    s = 
Re::sub (
" (\\w+)=", 
" " + C + 
"$1" + R + 
"=", s);
 
   88    s = 
Re::sub (
": ([a-zA-Z.0-9_:-]+): ", 
": " + G + 
"$1:" + R + 
" ", s);
 
   89    s = 
Re::sub (
"^(\\d+[.]\\d+):", Y + 
"$1:" + R, s, Re::M);
 
   90    write (2, s.data(), s.size());
 
static String sub(const String ®ex, const String &subst, const String &input, Flags=DEFAULT)
Substitute regex in input by sbref with backreferences $00…$99 or $&.
 
std::string color(Colors acolor, Colors c1, Colors c2, Colors c3, Colors c4, Colors c5, Colors c6)
Return ANSI code for the specified color if stdout & stderr should be colorized, see colorize_tty().
 
bool colorize_tty(int fd)
Check whether the tty fd should use colorization, checks ASE_COLOR if fd == -1.
 
The Anklang C++ API namespace.
 
uint64_t uint64
A 64-bit unsigned integer, use PRI*64 in format strings.
 
std::string executable_path()
Retrieve the path to the currently running executable.
 
LogFlags
Flags to configure logging behaviour.
 
std::string String
Convenience alias for std::string.
 
LogFlags log_setup(int *) __attribute__((__weak__))
Configurable handler to open log files.
 
uint64_t timestamp_now()
Current time in µseconds.