Skip to content
pantoniouPublic

About

Fully feature complete YAML parser and emitter, supporting the latest YAML spec and passing the full YAML testsuite.

Resources

Stars

347 stars

Watchers

7 watching

Forks

Latest commit

 

History

1,559 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

libfyaml 1.0-beta2

Autotools CI CMake CI License: MIT Language: C

libfyaml is a high-performance YAML 1.2 and JSON parser/emitter with zero-copy operation, full document and event APIs, and the two major 1.0 features:

  • generics: a schema-light, sum-type value model for YAML/JSON data in C
  • reflection/meta-type: typed YAML <-> C serdes driven by C type metadata

The 1.0 series adds a clear progression:

  • use the core API when you need parser, emitter, event, or document-tree control
  • use generics when your problem is "work with values"
  • use reflection when your problem is "populate native C data structures"

Why 1.0-beta2 matters

1.0.0-beta2 is a correctness and portability release. It adds no new API.

  • fixes for the fuzzing reports gh#317 to gh#409: memory leaks, double frees, use after free, unbounded recursion and size hint errors in the scanner, parser, document builder, YPath and reflection code
  • allocation failure injection in the tests, and fixes for the error paths it found
  • ASAN builds stop on undefined behaviour and check float casts
  • support for FreeBSD, NetBSD, OpenBSD, illumos, MinGW-w64, 32-bit x86 and arm, riscv64 and big-endian ppc64, with fixes for the problems found there
  • a weekly CI run of all supported platforms, and pinned runner images in the daily run
  • a CMake based Nix derivation

The linker interface version moves to 8:1:6: the interfaces are unchanged.

Generic runtime

The center of the generic API is fy_generic.

fy_generic is the sum-type value used to represent YAML and JSON data in C. It carries one runtime value of one type: null, bool, int, float, string, sequence, mapping, or YAML-specific wrappers.

It is a single pointer-sized word with inline storage for common small values, including 61-bit signed integers on 64-bit builds, short strings, and inline 32-bit floats.

The rest of the generic API is about working with fy_generic values:

  • creating fy_generic values from C literals or parsed input
  • reading typed values back out
  • transforming one fy_generic into another
  • controlling lifetime through stack-local values and builders

That gives C a Python-like data model:

  • scalars, sequences, and mappings as immutable tagged fy_generic values
  • construction via fy_value(), fy_sequence(), and fy_mapping()
  • parse/emit helpers for YAML and JSON
  • functional collection operations such as map, filter, and reduce

If you know Python dict / list workflows, serde_json::Value, tagged unions, or other sum-type/value-tree APIs, generics are the direct fit.

Reflection / meta-type

The reflection subsystem provides schema-driven typed serdes:

  • extract type metadata from annotated C headers
  • deserialize YAML directly into native C structs
  • emit native C structs back to YAML
  • inspect type and field metadata through the public reflection API
  • choose between direct libclang authoring or packed metadata blobs

Reflection is the typed layer for stable C data models.

Python binding

The Python binding in python-libfyaml/ is built on the generic runtime. It is a direct bridge into the C generics API:

  • Python FyGeneric lazy wrappers mirror C fy_generic values
  • the binding demonstrates dict/list/scalar usage over the same data model
  • users can move from Python prototypes to C without changing how they think about the data

See the binding reference at python-libfyaml/docs/API.md.

Which layer should I use?

Core API

Choose the core library when you need:

  • event-streaming parsing
  • YAML document tree access and mutation
  • path queries and document-building helpers
  • full control over emission details and original YAML structure

Generic API

Choose generics when you need:

  • Python-like data handling in C
  • a schema-less or schema-light value layer
  • transformations over YAML/JSON values
  • a common model shared with the Python binding

Reflection API

Choose reflection when you need:

  • direct YAML <-> C struct serdes
  • stable typed configuration objects
  • metadata-aware array/mapping handling
  • deployable packed schemas without runtime libclang dependency

Quick look

Generic literals in C

#include <libfyaml/libfyaml-generic.h>

fy_generic config = fy_mapping(
    "server", fy_mapping(
        "host", "localhost",
        "port", 8080,
        "tls",  true),
    "features", fy_sequence("http", "metrics", "admin"));

Generic parse and transform

fy_generic doc = fy_parse(
    "values: [1, 2, 3, 4]",
    FYOPPF_DISABLE_DIRECTORY | FYOPPF_INPUT_TYPE_STRING,
    NULL);

fy_generic values = fy_get(doc, "values", fy_invalid);
fy_generic first = fy_first(values);

Reflection-based typed parse

#include <libfyaml/libfyaml-reflection.h>

struct fy_reflection *rfl = fy_reflection_from_c_file_with_cflags(
    "schema.h", "", false, true, NULL);

struct fy_type_context_cfg cfg = {
    .rfl = rfl,
    .entry_type = "struct app_config",
};
struct fy_type_context *ctx = fy_type_context_create(&cfg);

Documentation roadmap

Start with these pages:

Reference pages:

Examples

The refreshed examples directory now covers the new alpha workflows:

  • generic literals and Python-like object construction
  • generic parse/transform/reduce flows
  • generic lambda examples with captured local variables
  • generic serial and parallel lambda-based filter/map/reduce flows with an explicit thread pool and configurable workload size
  • schema-sensitive generic round-trips
  • a Python-binding-to-C adoption bridge
  • reflection from libclang-processed headers
  • reflection export to packed blobs and runtime load from packed metadata

See examples/README.md for the full list.

Existing strengths still apply

libfyaml also remains:

  • a full YAML 1.2 and JSON parser/emitter
  • zero-copy in core parsing paths
  • free of artificial key/document size limits
  • strong on diagnostics and document manipulation
  • fully MIT licensed

Supported platforms

libfyaml is built and tested on these platforms:

Platform Versions Architectures Compilers
Linux (Ubuntu) 22.04, 24.04, 26.04 x86-64, arm64 gcc, clang
Linux (other distributions) Debian stable and testing, Fedora, Arch, Rocky Linux 9, Alpine (musl), Nix x86-64 gcc
Linux (other architectures) Ubuntu / Debian i386, armv7, riscv64, ppc64 (big-endian) gcc
macOS 15, 26 arm64 Apple clang, gcc
Windows Server 2022, Server 2025, 11 x64, arm64, x86 (Win32) MSVC, clang, MinGW-w64 gcc
FreeBSD 15.1 x86-64 clang
NetBSD 11.0 x86-64 gcc
OpenBSD 7.9 x86-64 clang
illumos (OmniOS) r151058 x86-64 gcc

Pushes and pull requests build a subset of these. The full CMake matrix, including ASAN builds on Linux and macOS, runs daily, and every platform above runs weekly.

Some features depend on the platform:

  • The generic subsystem (and so the Python bindings) needs GCC or Clang statement expressions and a little-endian target: it is not available with MSVC or on big-endian targets.
  • Durable arena garbage collection needs an atomic directory exchange, which only Linux and macOS provide; fy_durable_arena_gc() fails with ENOSYS elsewhere.
  • Durable arenas have a default fixed base address on Linux and macOS (x86-64 and arm64) and on the BSDs and illumos (x86-64); on other targets pass an explicit region_base.

Installation

Using CMake

find_package(libfyaml 1.0 REQUIRED)
target_link_libraries(your_app PRIVATE libfyaml::libfyaml)

If the installed package was built with libclang support, the CMake package also exports libfyaml_HAS_LIBCLANG.

Using pkg-config

pkg-config --cflags libfyaml
pkg-config --libs libfyaml

Building from source

Using CMake:

mkdir build && cd build
cmake ..
cmake --build .
ctest --progress -j"$(nproc)"

Using Autotools:

./bootstrap.sh
./configure
make
make check

Optional dependencies

  • llvm-dev libclang-dev: author reflection metadata directly from C headers
  • no runtime libclang is required when using packed reflection blobs

Documentation builds

Sphinx documentation targets require the Python documentation toolchain:

  • sphinx
  • sphinx_rtd_theme
  • sphinx-markdown-builder
  • linuxdoc

PDF documentation also requires a LaTeX toolchain with:

  • latexmk
  • pdflatex
  • xcolor.sty
  • wrapfig.sty

On Debian/Ubuntu, the practical package set is:

python3 -m pip install sphinx sphinx_rtd_theme sphinx-markdown-builder linuxdoc
sudo apt-get install latexmk tex-gyre texlive-fonts-recommended texlive-latex-base texlive-latex-recommended texlive-latex-extra

Then build the docs with:

cmake --build build --target doc-html
cmake --build build --target doc-latexpdf

Python binding

The binding lives in python-libfyaml/. Run its tests with:

cd python-libfyaml
python3 -m pytest tests/

The binding is part of the 1.0 release story and shows the generic runtime's data model in regular use. v1.0.0-alpha3 improved the Windows story for the binding, v1.0.0-alpha4 repaired the wheel and sdist packaging flow, v1.0.0-alpha5 broadened build and CI coverage, and v1.0.0-alpha6 expands generic formatting/document handling. v1.0.0-alpha7 adds transparent parse caching, optimized generic emission, and Stable ABI Python wheels. v1.0.0-alpha8 adds durable storage, auto-anchor emission, stronger comment round-tripping, and more complete generic helper APIs. v1.0.0-beta1 starts the beta cycle with additional conversion, predicate, iteration, formatting, and correctness fixes on top of that alpha surface. v1.0.0-beta2 fixes the fuzzing reports and extends the supported platforms.

License

libfyaml is fully MIT licensed.

About

Fully feature complete YAML parser and emitter, supporting the latest YAML spec and passing the full YAML testsuite.

Resources

Stars

347 stars

Watchers

7 watching

Forks

Releases

Packages

Used by

Contributors

Languages