Types
cyaml_type_t
Node types
CYAML_NONE = 0 | Invalid/uninitialized |
CYAML_NULL | Null value (~, null) |
CYAML_SCALAR | Scalar value |
CYAML_SEQ | Sequence (array) |
CYAML_MAP | Mapping (object) |
CYAML_ALIAS | Alias (*anchor) |
cyaml_style_t
Scalar styles
CYAML_PLAIN = 0 | Plain (unquoted) |
CYAML_SINGLE | Single-quoted |
CYAML_DOUBLE | Double-quoted |
CYAML_LITERAL | Literal block (|) |
CYAML_FOLDED | Folded block (>) |
cyaml_coll_t
Collection styles
CYAML_BLOCK = 0 | Block style (indented) |
CYAML_FLOW | Flow style ({}, []) |
cyaml_chomp_t
Chomping for block scalars
CYAML_CLIP = 0 | Default: single trailing newline |
CYAML_STRIP | Strip all trailing newlines (-) |
CYAML_KEEP | Keep all trailing newlines (+) |
cyaml_spec_t
YAML specification version
CYAML_SPEC_AUTO = 0 | Auto-detect from %YAML directive (default: 1.2) |
CYAML_SPEC_1_1 | YAML 1.1 |
CYAML_SPEC_1_2 | YAML 1.2 |
CYAML_SPEC_1_3 | YAML 1.3 |
cyaml_scalar_flags_t
Scalar flags (bitmask)
CYAML_SCALAR_NONE = 0 | |
CYAML_SCALAR_EXPLICIT_EMPTY = 1 << 0 | Empty value that should NOT become null |
Span (Atom)
cyaml_span_t
Span - a reference into source data with location info This is the core building block: no string copying during parse
uint32_t off | Byte offset into source |
uint32_t len | Length in bytes |
uint32_t start_line | 1-based start line |
uint32_t start_col | 1-based start column |
uint32_t end_line | 1-based end line |
uint32_t end_col | 1-based end column |
Node
cyaml_pair_t
Key-value pair for mappings
cyaml_node_t* key | |
cyaml_node_t* val |
Document
cyaml_pool_t
cyaml_node_t** chunks | Array of chunk pointers (never moved once allocated) |
uint32_t chunk_count | Number of allocated chunks |
uint32_t chunk_cap | Capacity of chunks array |
uint32_t count | Total nodes allocated |
cyaml_tag_directive_t
cyaml_span_t handle | Tag handle (e.g., "!" or "!!" or "!yaml!") |
cyaml_span_t prefix | Tag prefix (e.g., "tag:yaml.org,2002:") |
cyaml_doc_flags_t
Document flags
CYAML_DOC_START = 1 << 0 | Had explicit '---' marker |
CYAML_DOC_END = 1 << 1 | Had explicit '...' marker |
CYAML_HAS_DIRECTIVE = 1 << 2 | Had any directive (%YAML, %TAG, or reserved) |
CYAML_DOC_TAB_SEP = 1 << 3 | Tab separator after '---' marker |
cyaml_mode_t
Document mode
CYAML_PARSING | Parsed document (source borrowed) |
CYAML_BUILDING | Built document (source owned) |
Stream
cyaml_stream_t
[9.2] Stream - contains one or more documents l-yaml-stream ::= l-document-prefix* l-any-document? ... Source is always borrowed - caller manages lifetime
const char* src | Source buffer (borrowed, must outlive stream) |
uint32_t src_len | Source length |
cyaml_doc_t** docs | Array of documents |
uint32_t count | Number of documents |
uint32_t cap | Capacity |
Error
cyaml_error_t
cyaml_err_t code | |
cyaml_span_t span | Error location |
cyaml_err_t
CYAML_OK = 0 | |
CYAML_ERR_NOMEM | |
CYAML_ERR_SYNTAX | |
CYAML_ERR_EOF | |
CYAML_ERR_INDENT | |
CYAML_ERR_ESCAPE | |
CYAML_ERR_ANCHOR | |
CYAML_ERR_ALIAS | |
CYAML_ERR_TAG | |
CYAML_ERR_DUP_KEY | |
CYAML_ERR_IO |
Parse Options
cyaml_opts_t
bool dup_keys | Allow duplicate keys (default: false) |
bool comments | Preserve comments (default: false) |
uint32_t max_depth | Max nesting depth (0 = unlimited) |
uint32_t max_size | Max source size (0 = unlimited) |
cyaml_spec_t spec | YAML spec version (default: auto-detect) |
Emit Options
cyaml_emit_opts_t
uint8_t indent | Indentation (default: 2) |
uint8_t width | Line width, 0 = no wrap (default: 80) |
bool doc_start | Emit --- (default: false) |
bool doc_end | Emit ... (default: false) |
bool comments | Emit comments if available (default: false) |
cyaml_style_t style | Default scalar style |
cyaml_coll_t coll | Default collection style |
Parsing
cyaml_doc_t * cyaml_parse(const char* src, size_t len, const cyaml_opts_t* opts, cyaml_error_t* err)
Parse first document from YAML string
Parameters
src- Source buffer (must outlive returned doc)
len- Source length
opts- Parse options (NULL for defaults)
err- Error output (NULL to ignore)
Returns
Document or NULL on error
void cyaml_free(cyaml_doc_t* doc)
Free document and all nodes (does not free source buffer)
Parameters
doc- Document to free (NULL safe)
Stream Parsing
cyaml_stream_t * cyaml_parse_stream(const char* src, size_t len, const cyaml_opts_t* opts, cyaml_error_t* err)
Parse YAML stream containing multiple documents
Parameters
src- Source buffer (must outlive returned stream)
len- Source length
opts- Parse options (NULL for defaults)
err- Error output (NULL to ignore)
Returns
Stream or NULL on error
void cyaml_stream_free(cyaml_stream_t* stream)
Free stream and all documents (does not free source buffer)
Parameters
stream- Stream to free (NULL safe)
Span Utilities
char * cyaml_span_dup(const cyaml_doc_t* doc, cyaml_span_t s)
Duplicate span as null-terminated string
Parameters
doc- Document containing the span
s- Span to duplicate
Returns
Allocated string (caller must free) or NULL
char * cyaml_scalar_str(const cyaml_doc_t* doc, const cyaml_node_t* n)
Get scalar value as string with all YAML processing applied Handles escape sequences, line folding, and block scalar indent stripping.
Parameters
doc- Document containing the node
n- Scalar node
Returns
Allocated string (caller must free) or NULL
bool cyaml_span_eq(const cyaml_doc_t* doc, cyaml_span_t s, const char* str)
Compare span to string (case-sensitive)
Parameters
doc- Document containing the span
s- Span to compare
str- String to compare against
Returns
true if equal
bool cyaml_span_ieq(const cyaml_doc_t* doc, cyaml_span_t s, const char* str)
Compare span to string (case-insensitive)
Parameters
doc- Document containing the span
s- Span to compare
str- String to compare against
Returns
true if equal (ignoring case)
bool cyaml_span_cmp(const cyaml_doc_t* doc, cyaml_span_t a, cyaml_span_t b)
Compare two spans for equality
Parameters
doc- Document containing the spans
a- First span
b- Second span
Returns
true if equal
Scalar Value Extraction
bool cyaml_as_int(const cyaml_doc_t* doc, const cyaml_node_t* n, int64_t* out)
Parse scalar as signed integer Supports decimal, hex (0x), and octal (0o) formats.
Parameters
doc- Document containing the node
n- Scalar node to parse
out- Output value
Returns
true on success
bool cyaml_as_uint(const cyaml_doc_t* doc, const cyaml_node_t* n, uint64_t* out)
Parse scalar as unsigned integer Supports decimal, hex (0x), and octal (0o) formats.
Parameters
doc- Document containing the node
n- Scalar node to parse
out- Output value
Returns
true on success
bool cyaml_as_float(const cyaml_doc_t* doc, const cyaml_node_t* n, double* out)
Parse scalar as floating point Supports .inf, -.inf, and .nan special values.
Parameters
doc- Document containing the node
n- Scalar node to parse
out- Output value
Returns
true on success
bool cyaml_as_bool(const cyaml_doc_t* doc, const cyaml_node_t* n, bool* out)
Parse scalar as boolean Recognizes true/false (case-insensitive).
Parameters
doc- Document containing the node
n- Scalar node to parse
out- Output value
Returns
true on success
bool cyaml_is_null_val(const cyaml_doc_t* doc, const cyaml_node_t* n)
Check if scalar represents null Recognizes ~, null, Null, NULL, or empty value.
Parameters
doc- Document containing the node
n- Node to check
Returns
true if null
Mapping Access
cyaml_node_t * cyaml_get(const cyaml_doc_t* doc, const cyaml_node_t* n, const char* key)
Get mapping value by string key
Parameters
doc- Document containing the node
n- Mapping node
key- Key to look up
Returns
Value node or NULL if not found
bool cyaml_has(const cyaml_doc_t* doc, const cyaml_node_t* n, const char* key)
Check if mapping contains key
Parameters
doc- Document containing the node
n- Mapping node
key- Key to check
Returns
true if key exists
Path Access
cyaml_node_t * cyaml_path(const cyaml_doc_t* doc, const char* path)
Navigate to node at YPATH Uses YPATH syntax: /store/books[0]/title, /users/*/name, etc. Absolute paths (starting with /) evaluate from document root.
Parameters
doc- Document to query
path- YPATH expression (e.g., "/users[0]/name", "/config/db/host")
Returns
First matching node or NULL if not found
Building
cyaml_doc_t * cyaml_doc_new(void)
Create empty document for building YAML programmatically
Returns
New document or NULL on allocation failure
cyaml_node_t * cyaml_node_new(cyaml_doc_t* doc, cyaml_type_t type)
Allocate node of specified type from document pool
Parameters
doc- Document to allocate from
type- Node type
Returns
New node or NULL on failure
cyaml_node_t * cyaml_new_null(cyaml_doc_t* doc)
Create null node
Parameters
doc- Document to allocate from
Returns
New null node or NULL on failure
cyaml_node_t * cyaml_new_str(cyaml_doc_t* doc, const char* str, size_t len)
Create scalar node from string with explicit length
Parameters
doc- Document to allocate from
str- String data (copied)
len- String length
Returns
New scalar node or NULL on failure
cyaml_node_t * cyaml_new_cstr(cyaml_doc_t* doc, const char* str)
Create scalar node from null-terminated string
Parameters
doc- Document to allocate from
str- Null-terminated string (copied)
Returns
New scalar node or NULL on failure
cyaml_node_t * cyaml_new_int(cyaml_doc_t* doc, int64_t val)
Create scalar node from signed integer
Parameters
doc- Document to allocate from
val- Integer value
Returns
New scalar node or NULL on failure
cyaml_node_t * cyaml_new_uint(cyaml_doc_t* doc, uint64_t val)
Create scalar node from unsigned integer
Parameters
doc- Document to allocate from
val- Unsigned value
Returns
New scalar node or NULL on failure
cyaml_node_t * cyaml_new_float(cyaml_doc_t* doc, double val)
Create scalar node from floating point
Parameters
doc- Document to allocate from
val- Float value
Returns
New scalar node or NULL on failure
cyaml_node_t * cyaml_new_bool(cyaml_doc_t* doc, bool val)
Create scalar node from boolean
Parameters
doc- Document to allocate from
val- Boolean value
Returns
New scalar node or NULL on failure
cyaml_node_t * cyaml_new_seq(cyaml_doc_t* doc)
Create empty sequence node
Parameters
doc- Document to allocate from
Returns
New sequence node or NULL on failure
cyaml_node_t * cyaml_new_map(cyaml_doc_t* doc)
Create empty mapping node
Parameters
doc- Document to allocate from
Returns
New mapping node or NULL on failure
bool cyaml_seq_push(cyaml_node_t* seq, cyaml_node_t* item)
Append item to sequence
Parameters
seq- Sequence node
item- Item to append
Returns
true on success
bool cyaml_map_set(cyaml_doc_t* doc, cyaml_node_t* map, const char* key, cyaml_node_t* val)
Set or update mapping key-value pair
Parameters
doc- Document containing the map
map- Mapping node
key- Key string (creates new scalar key)
val- Value node
Returns
true on success
Emitting
char * cyaml_emit(const cyaml_doc_t* doc, const cyaml_emit_opts_t* opts, size_t* len)
Emit document to newly allocated YAML string
Parameters
doc- Document to emit
opts- Emit options (NULL for defaults: 2-space indent, 80 char width)
len- Output length (NULL to ignore)
Returns
Allocated string (caller must free) or NULL on error
char * cyaml_emit_node(const cyaml_doc_t* doc, const cyaml_node_t* node, const cyaml_emit_opts_t* opts, size_t* len)
Emit single node to newly allocated YAML string
Parameters
doc- Document containing the node
node- Node to emit
opts- Emit options (NULL for defaults)
len- Output length (NULL to ignore)
Returns
Allocated string (caller must free) or NULL on error
char * cyaml_stream_emit(const cyaml_stream_t* stream, size_t* len)
Emit stream to YAML preserving original formatting
Parameters
stream- Stream to emit
len- Output length (NULL to ignore)
Returns
Allocated string (caller must free) or NULL on error
Dump (Canonical Output)
char * cyaml_dump(const cyaml_doc_t* doc, size_t* len)
Dump document to canonical YAML format Uses yaml-test-suite out.yaml format conventions.
Parameters
doc- Document to dump
len- Output length (NULL to ignore)
Returns
Allocated string (caller must free) or NULL on error
char * cyaml_stream_dump(const cyaml_stream_t* stream, size_t* len)
Dump stream to canonical YAML format (all documents)
Parameters
stream- Stream to dump
len- Output length (NULL to ignore)
Returns
Allocated string (caller must free) or NULL on error
Event Stream
char * cyaml_events(const cyaml_doc_t* doc, bool indent, size_t* len)
Emit event stream for single document
Parameters
doc- Document to emit events for
indent- Add visual indentation (false for yaml-test-suite format)
len- Output length (NULL to ignore)
Returns
Allocated string (caller must free) or NULL on error
char * cyaml_stream_events(const cyaml_stream_t* stream, bool indent, size_t* len)
Emit event stream for full stream (all documents)
Parameters
stream- Stream to emit events for
indent- Add visual indentation
len- Output length (NULL to ignore)
Returns
Allocated string (caller must free) or NULL on error
JSON Output
char * cyaml_json(const cyaml_doc_t* doc, int indent, size_t* len)
Convert document to JSON
Parameters
doc- Document to convert
indent- Spaces per indent level (0 = compact)
len- Output length (NULL to ignore)
Returns
Allocated string (caller must free) or NULL on error
char * cyaml_stream_json(const cyaml_stream_t* stream, int indent, size_t* len)
Convert stream to JSON Single document streams output the JSON value directly. Multi-document streams output as a JSON array.
Parameters
stream- Stream to convert
indent- Spaces per indent level (0 = compact)
len- Output length (NULL to ignore)
Returns
Allocated string (caller must free) or NULL on error
Anchor and Alias Management
bool cyaml_set_anchor(cyaml_doc_t* doc, cyaml_node_t* node, const char* anchor)
Set anchor name on a node
Parameters
doc- Document containing the node (must be in BUILDING mode)
node- Node to anchor
anchor- Anchor name (without &), NULL to clear
Returns
true on success
cyaml_node_t * cyaml_new_alias(cyaml_doc_t* doc, cyaml_node_t* target)
Create alias node pointing to an anchored node
Parameters
doc- Document to allocate in
target- Target node (must have anchor set)
Returns
New alias node or NULL on failure
cyaml_node_t * cyaml_find_anchor(const cyaml_doc_t* doc, const char* anchor)
Find node by anchor name (searches from root)
Parameters
doc- Document to search
anchor- Anchor name to find
Returns
Node with anchor or NULL if not found
bool cyaml_resolve_aliases(cyaml_doc_t* doc)
Resolve all aliases in document (replace with deep copies of targets)
Parameters
doc- Document to resolve
Returns
true on success, false if unresolved aliases remain
Node Copy and Merge
cyaml_node_t * cyaml_node_copy(cyaml_doc_t* doc, const cyaml_doc_t* src, const cyaml_node_t* node)
Deep copy a node into a document Copies node and all children. Scalar content is copied into target doc.
Parameters
doc- Target document to allocate into
src- Source document containing the node
node- Source node to copy
Returns
New node or NULL on failure
bool cyaml_map_merge(cyaml_doc_t* doc, cyaml_node_t* dst, const cyaml_node_t* src)
Deep merge src map into dst map For conflicting keys: scalars replaced, maps merged recursively, seqs replaced.
Parameters
doc- Document containing both nodes
dst- Destination map (modified in place)
src- Source map to merge from
Returns
true on success
Key Sorting
bool cyaml_map_sort(const cyaml_doc_t* doc, cyaml_node_t* map, cyaml_key_cmp_t cmp)
Sort mapping keys
Parameters
doc- Document containing the map
map- Mapping node to sort
cmp- Comparison function (NULL for default alphabetical)
Returns
true on success
bool cyaml_map_sort_recursive(const cyaml_doc_t* doc, cyaml_node_t* node, cyaml_key_cmp_t cmp)
Sort mapping keys recursively (all nested maps)
Parameters
doc- Document containing the node
node- Starting node (will recurse into children)
cmp- Comparison function (NULL for default alphabetical)
Returns
true on success
Path-based Scanf/Printf API
int cyaml_scanf(const cyaml_doc_t* doc, const char* format, ...)
Extract values using path-based scanf
Parameters
doc- Document to query
format- Path+format string (space-separated)
Returns
Number of successfully extracted values, -1 on format error
Examples
unsigned int port;
char host[256];
cyaml_scanf(doc, "/server/port %u /server/host %255s", &port, host);
int cyaml_vscanf(const cyaml_doc_t* doc, const char* format, va_list ap)
Extract values using path-based scanf (va_list version)
Parameters
doc- Document to query
format- Path+format string (space-separated)
ap- Variable argument list
Returns
Number of successfully extracted values, -1 on format error
int cyaml_node_scanf(const cyaml_doc_t* doc, const cyaml_node_t* node, const char* format, ...)
Extract values starting from a specific node Relative paths start from node, absolute paths (/) still use root.
Parameters
doc- Document containing the node
node- Starting node for relative paths (NULL = root)
format- Path+format string
Returns
Number of successfully extracted values
int cyaml_node_vscanf(const cyaml_doc_t* doc, const cyaml_node_t* node, const char* format, va_list ap)
Extract values starting from a specific node (va_list version)
Parameters
doc- Document containing the node
node- Starting node for relative paths (NULL = root)
format- Path+format string
ap- Variable argument list
Returns
Number of successfully extracted values
cyaml_node_t * cyaml_buildf(cyaml_doc_t* doc, const char* format, ...)
Build node from printf-style format string Creates nodes by substituting values into a YAML template. Formats: %d, %u, %ld, %lu, %lld, %llu, %f, %lf, %s, %b
Parameters
doc- Document to allocate in
format- YAML with format specifiers
Returns
New node or NULL on error
Examples
cyaml_buildf(doc, "port: %d", 8080) // -> {port: 8080}
cyaml_buildf(doc, "- %s\n- %s", "a", "b") // -> [a, b]
cyaml_buildf(doc, "%s", "hello") // -> "hello"
cyaml_node_t * cyaml_vbuildf(cyaml_doc_t* doc, const char* format, va_list ap)
Build node from printf-style format string (va_list version)
Parameters
doc- Document to allocate in
format- YAML with format specifiers
ap- Variable argument list
Returns
New node or NULL on error
Path-based Modification
bool cyaml_insert_at(cyaml_doc_t* doc, const char* path, cyaml_node_t* val)
Insert or update node at path Creates intermediate maps as needed. For existing keys, replaces value. Path must resolve to a valid insertion point.
Parameters
doc- Document to modify (must be CYAML_BUILDING mode or parsed)
path- Target path (e.g., "/server/port", "/users/0/name")
val- Value node to insert (must be from same doc)
Returns
true on success
Examples
cyaml_insert_at(doc, "/server/timeout", cyaml_new_int(doc, 30));
bool cyaml_insertf(cyaml_doc_t* doc, const char* path, const char* format, ...)
Insert printf-built node at path (convenience) Equivalent to: cyaml_insert_at(doc, path, cyaml_buildf(doc, format, ...))
Parameters
doc- Document to modify
path- Target path
format- YAML format string
Returns
true on success
Examples
cyaml_insertf(doc, "/server", "timeout: %d", 30);
bool cyaml_delete_at(cyaml_doc_t* doc, const char* path)
Delete node at path Removes the node from its parent container.
Parameters
doc- Document to modify
path- Path to node to delete
Returns
true if deleted, false if not found
bool cyaml_append_at(cyaml_doc_t* doc, const char* path, cyaml_node_t* val)
Append to sequence at path Path must resolve to a sequence node.
Parameters
doc- Document to modify
path- Path to sequence
val- Value to append
Returns
true on success
bool cyaml_appendf(cyaml_doc_t* doc, const char* path, const char* format, ...)
Append printf-built node to sequence at path Path must resolve to a sequence node.
Parameters
doc- Document to modify
path- Path to sequence
format- YAML format string for new item
Returns
true on success
Node Comparison
int cyaml_node_cmp_str(const cyaml_doc_t* doc, const cyaml_node_t* node, const char* str, size_t len)
Compare scalar node value to string (like strcmp)
Parameters
doc- Document containing node
node- Node to compare (must be scalar)
str- String to compare against
len- String length (0 = use strlen)
Returns
0 if equal, <0 if node < str, >0 if node > str
bool cyaml_node_eq_str(const cyaml_doc_t* doc, const cyaml_node_t* node, const char* str)
Check if scalar node equals string
Parameters
doc- Document containing node
node- Node to compare
str- String to compare (null-terminated)
Returns
true if node value equals str
Utility
const char * cyaml_strerror(cyaml_err_t err)
Get human-readable error message
Parameters
err- Error code
Returns
Static error string
const char * cyaml_version(void)
Get library version string
Returns
Static version string (e.g., "0.1.0")
YPATH Query API
cyaml_path_result_t
Query result containing matched nodes or error info
cyaml_node_t** nodes | Array of pointers to matched nodes (owned by doc) |
uint32_t count | Number of matched nodes |
const char* error | Error message (NULL on success) |
uint32_t error_pos | Position in path where error occurred |
cyaml_path_result_t cyaml_path_query(const cyaml_doc_t* doc, const cyaml_node_t* context, const char* path)
Execute a YPATH query and return all matching nodes Nodes returned are pointers into the document - no data is copied.
Parameters
doc- Document to query
context- Context node for relative paths (NULL = use root)
path- YPATH expression (e.g., "/users[0]/name", "/items[[email protected]]")
Returns
Result with matched nodes or error info
void cyaml_path_result_free(cyaml_path_result_t* result)
Free query result
Parameters
result- Result to free (NULL safe)
cyaml_node_t * cyaml_path_first(const cyaml_doc_t* doc, const cyaml_node_t* context, const char* path)
Get first matching node (convenience wrapper) Equivalent to cyaml_path_query + taking first result + free.
Parameters
doc- Document to query
context- Context node for relative paths (NULL = use root)
path- YPATH expression
Returns
First matching node or NULL on error/no match
void cyaml_path_debug(const char* path)
Debug: dump tokens and parsed AST to stdout
Parameters
path- YPATH expression to analyze