libacfutils
A general purpose library of utility functions designed to make it easier to develop addons for the X-Plane flight simulator.
Loading...
Searching...
No Matches
Macros | Typedefs | Functions
log.h File Reference
#include <stdarg.h>
#include <XPLMUtilities.h>
#include "sysmacros.h"
Include dependency graph for log.h:

Go to the source code of this file.

Macros

#define BUILTIN_STRRCHR   strrchr
 
#define log_basename(f)
 
#define logMsg(...)    log_impl(log_basename(__FILE__), __LINE__, __VA_ARGS__)
 
#define logMsg_v(fmt, ap)    log_impl_v(log_basename(__FILE__), __LINE__, (fmt), (ap))
 

Typedefs

typedef void(* logfunc_t) (const char *)
 

Functions

void log_init (logfunc_t func, const char *prefix)
 
void log_fini (void)
 
logfunc_t log_get_logfunc (void)
 
static void log_xplm_cb (const char *str)
 
void log_impl (const char *filename, int line, const char *fmt,...)
 
void log_impl_v (const char *filename, int line, const char *fmt, va_list ap)
 
void log_backtrace (int skip_frames)
 

Detailed Description

This subsystem provides a convenient message logging facility. You must initialize this subsystem prior to using any other part of libacfutils which may emit log messages (which is nearly all of them). Call log_init() with a suitable logging callback in the first argument. On shutdown, call log_fini() to make sure all memory resources of the logging system are freed. To log a message, use the logMsg() macro.

See also
log_init()
log_fini()
logMsg()

Definition in file log.h.

Macro Definition Documentation

◆ BUILTIN_STRRCHR

#define BUILTIN_STRRCHR   strrchr

Definition at line 72 of file log.h.

◆ log_basename

#define log_basename (   f)
Value:
(BUILTIN_STRRCHR(f, '/') ? BUILTIN_STRRCHR(f, '/') + 1 : \
(BUILTIN_STRRCHR(f, '\\') ? BUILTIN_STRRCHR(f, '\\') + 1 : (f)))

This lets us chop out the basename (last path component) from FILE at compile time. This works on GCC and Clang. The fallback mechanism below just chops it out at compile time.

This macro is used in logMsg() to only extract the source filename of the logMsg() call. You can also use it to extract the last path component in any other macros you write.

Note
This macro requires that the argument be a string literal at compile time. The underlying implementation is using compiler built-ins to make sure only the last path component of the string is stored in the final compiled binary.

Definition at line 89 of file log.h.

◆ logMsg

#define logMsg (   ...)     log_impl(log_basename(__FILE__), __LINE__, __VA_ARGS__)

This macro is the primary logging facility in libacfutils. Its arguments are a printf-like format and optional format arguments, which will be sent to the logging function specified in log_init().

Note
Before using any logging function of libacfutils, you must call log_init() with a suitable logging callback function.

The logging function automatically constructs the string as follows:

YYYY-MM-DD HH:MM:SS PREFIX[FILENAME:LINE]: <your message goes here>
  • PREFIX is the prefix you provided in the second argument of log_init().
  • FILENAME is the name of the file in which the logMsg() macro was placed.
  • LINE is the line number in the file where the logMsg() macro was placed.
  • The remainder of the string is formatted using the printf-style arguments to the logMsg() macro.
See also
log_init()

Definition at line 112 of file log.h.

◆ logMsg_v

#define logMsg_v (   fmt,
  ap 
)     log_impl_v(log_basename(__FILE__), __LINE__, (fmt), (ap))

Same as logMsg(), but allows you to provide a va_list argument list. This allows you to nest logMsg() invocations inside of your own custom variadic functions.

Definition at line 119 of file log.h.

Typedef Documentation

◆ logfunc_t

typedef void(* logfunc_t) (const char *)

Definition at line 51 of file log.h.

Function Documentation

◆ log_backtrace()

void log_backtrace ( int  skip_frames)

\func void log_backtrace(int skip_frames) Logs a backtrace of the current stack to the logging system. This is typically called from an assertion failure handler to try and gather debugging information, before the app is terminated.

This function uses OS-specific facilities to try and determine the function names and offsets of each stack frame.

  • On macOS and Linux, this facility utilizes the backtrace() and backtrace_symbols() functions from the platforms' respective C libraries. These attempt to use any embedded symbol information inside of the binary to determine function names and offsets.
  • On Windows, binaries unfortunately almost never ship with symbol information for internal symbols not exposed via dllexport. Therefore, to support getting some semblance of useful information, libacfutils utilizes a custom symbol table provided by you. This symbol table can be generated from a compiled binary containing DWARF2 debug information using the mksyms shell script contained in the tools directory of the libacfutils source repo. Please note, that MSVC doesn't generate DWARF2 debug information and therefore this utility cannot be used for binaries compiled with MSVC. The generated file data should be redirected to a file named syms.txt and placed next to the Windows XPL file for the plugin and shipped with the plugin, like this:
    $ tools/mksyms win.xpl > syms.txt
Parameters
skip_framesNumber of stack frames to skip off the top of the stack before printing the remaining frames. Sometimes a crash handler is invoked from within an exception or signal handling callback. This would place a bunch of useless stack frames near the top of the backtrace, resulting in a backtrace that's hard to read. Use this argument to skip them, if you know for sure how many there are.

Definition at line 516 of file log.c.

◆ log_fini()

void log_fini ( void  )

Deinitializes the logging system. You must call this at the end of your plugin's unload function (XPluginStop()) to properly free any memory resources used by the logging system.

Definition at line 115 of file log.c.

◆ log_get_logfunc()

logfunc_t log_get_logfunc ( void  )

Returns the currently installed log function, which was passed in log_init().

See also
log_init()

Definition at line 130 of file log.c.

◆ log_impl()

void log_impl ( const char *  filename,
int  line,
const char *  fmt,
  ... 
)

Log implementation function. Do not call directly. Use the logMsg() macro.

See also
logMsg()

Definition at line 140 of file log.c.

◆ log_impl_v()

void log_impl_v ( const char *  filename,
int  line,
const char *  fmt,
va_list  ap 
)

Log implementation function. Do not call directly. Use the logMsg_v() macro.

See also
logMsg_v()

Definition at line 153 of file log.c.

◆ log_init()

void log_init ( logfunc_t  func,
const char *  prefix 
)

Initializes the libacfutils logging subsystem. You must call this before any other subsystem of libacfutils. Typically, you would do this at the start of your plugin load callback (XPluginStart()). This is to make sure that if any of libacfutils' subsystems or your own code needs to log errors, they can. Without initialization, any logging calls will cause the app to crash with a call to abort().

At the end of your plugin's unload, deinitialize the logging subsystem using log_fini().

Parameters
funcA callback function which will be called for every log message that will be emitted. You can provide your own logging function, or use log_xplm_cb() to simply emit any log messages to the X-Plane Log.txt.
prefixA logging prefix name, which will be prepended to every log message. This is to help disambiguate which plugin is emitting a particular message. A good choice here is something that is a short name of your plugin, e.g. "my_plugin".

Definition at line 97 of file log.c.

◆ log_xplm_cb()

static void log_xplm_cb ( const char *  str)
static

A simple logging callback function suitable for passing to log_init() in its first argument. This function simply emits the input string to the X-Plane Log.txt file via XPLMDebugString().

Definition at line 63 of file log.h.