<h1>Hacker's Guide</h1>

This page primarily contains notes for anyone who's actively hacking on libfossil internals, e.g. changing <tt>fsl_cx</tt>'s structure.

<h2>Introduction to structs...</h2>

For all (or almost all) structs in the library are accompanied by other constructs which help ensure consistency across how structs are to be initialized. The general pattern looks like this:

<nowiki><pre>
struct fsl_foo { ... };
typedef struct fsl_foo fsl_foo;
extern const fsl_foo_empty;
#define fsl_foo_empty_m { ...member initializers... }


The purpose of the macro is to have a const-initialized state for that struct. The <tt>fsl_foo_empty</tt> instance is guaranteed to be initialized using <tt>fsl_foo_empty_m</tt>, but both the "empty" and "empty_m" variants are provided because code requires different initializers in different contexts.

The "_m" suffix denotes "macro", by the way.

All non-opaque structs can and should be initialized in code like this:

<nowiki><pre>
fsl_buffer buf = fsl_buffer_empty;
fsl_deck deck = fsl_deck_empty;

The "empty_m" macros are required mainly for in-struct initialization:
struct {
  fsl_buffer buf;
  fsl_deck deck;
} foo = {
  fsl_buffer_empty_m,
  fsl_deck_empty_m
};


That ensures that all struct members get set to known default values (which need not be NULL/0), and helps harden the code against uninitialized memory access (since all members get initialized to whatever the struct developer deemed sensible, and NULL is generally the sensible default for pointer members).


<h2>When updating structs...</h2>

When changing the members of structs, it is <em>critical</em> that the accompanying "empty_m" macro (described above) also be updated. Failing to do so can lead to undefined results (best case is a compilation failure when the shared struct "empty" instance is initialized from the "empty_m" macro).

<nowiki><pre>