Last active
August 29, 2015 14:14
-
-
Save flaviut/71548888e37ccd0219a0 to your computer and use it in GitHub Desktop.
Nim libyaml wrapper. Here be dragons.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type | |
yaml_version_directive_t* = object | |
major*: cint | |
minor*: cint | |
type | |
yaml_tag_directive_t* = object | |
handle*: cstring | |
prefix*: cstring | |
type | |
yaml_encoding_t* {.size: sizeof(cint).} = enum | |
YAML_ANY_ENCODING, | |
YAML_UTF8_ENCODING, | |
YAML_UTF16LE_ENCODING, | |
YAML_UTF16BE_ENCODING | |
type | |
yaml_break_t* {.size: sizeof(cint).} = enum | |
YAML_ANY_BREAK, | |
YAML_CR_BREAK, | |
YAML_LN_BREAK, | |
YAML_CRLN_BREAK | |
type | |
yaml_error_type_t* {.size: sizeof(cint).} = enum | |
YAML_NO_ERROR, | |
YAML_MEMORY_ERROR, | |
YAML_READER_ERROR, | |
YAML_SCANNER_ERROR, | |
YAML_PARSER_ERROR, | |
YAML_COMPOSER_ERROR, | |
YAML_WRITER_ERROR, | |
YAML_EMITTER_ERROR | |
type | |
yaml_mark_t* = object | |
index*: csize | |
line*: csize | |
column*: csize | |
type | |
yaml_scalar_style_t* {.size: sizeof(cint).} = enum | |
YAML_ANY_SCALAR_STYLE, | |
YAML_PLAIN_SCALAR_STYLE, | |
YAML_SINGLE_QUOTED_SCALAR_STYLE, | |
YAML_DOUBLE_QUOTED_SCALAR_STYLE, | |
YAML_LITERAL_SCALAR_STYLE, | |
YAML_FOLDED_SCALAR_STYLE | |
type | |
yaml_sequence_style_t* {.size: sizeof(cint).} = enum | |
YAML_ANY_SEQUENCE_STYLE, | |
YAML_BLOCK_SEQUENCE_STYLE, | |
YAML_FLOW_SEQUENCE_STYLE | |
type | |
yaml_mapping_style_t* {.size: sizeof(cint).} = enum | |
YAML_ANY_MAPPING_STYLE, | |
YAML_BLOCK_MAPPING_STYLE, | |
YAML_FLOW_MAPPING_STYLE | |
type | |
yaml_token_type_t* {.size: sizeof(cint).} = enum | |
YAML_NO_TOKEN, | |
YAML_STREAM_START_TOKEN, | |
YAML_STREAM_END_TOKEN, | |
YAML_VERSION_DIRECTIVE_TOKEN, | |
YAML_TAG_DIRECTIVE_TOKEN, | |
YAML_DOCUMENT_START_TOKEN, | |
YAML_DOCUMENT_END_TOKEN, | |
YAML_BLOCK_SEQUENCE_START_TOKEN, | |
YAML_BLOCK_MAPPING_START_TOKEN, | |
YAML_BLOCK_END_TOKEN, | |
YAML_FLOW_SEQUENCE_START_TOKEN, | |
YAML_FLOW_SEQUENCE_END_TOKEN, | |
YAML_FLOW_MAPPING_START_TOKEN, | |
YAML_FLOW_MAPPING_END_TOKEN, | |
YAML_BLOCK_ENTRY_TOKEN, | |
YAML_FLOW_ENTRY_TOKEN, | |
YAML_KEY_TOKEN, | |
YAML_VALUE_TOKEN, | |
YAML_ALIAS_TOKEN, | |
YAML_ANCHOR_TOKEN, | |
YAML_TAG_TOKEN, | |
YAML_SCALAR_TOKEN | |
type | |
INNER_C_STRUCT_9581966235636552858* = object | |
encoding*: yaml_encoding_t | |
INNER_C_STRUCT_1221667129857401972* = object | |
value*: cstring | |
INNER_C_STRUCT_3317256698323717696* = object | |
value*: cstring | |
INNER_C_STRUCT_5441002398333014240* = object | |
handle*: cstring | |
suffix*: cstring | |
INNER_C_STRUCT_7453632048426669727* = object | |
value*: cstring | |
length*: csize | |
style*: yaml_scalar_style_t | |
INNER_C_STRUCT_9783180209656813162* = object | |
major*: cint | |
minor*: cint | |
INNER_C_STRUCT_13940099295483927389* = object | |
handle*: cstring | |
prefix*: cstring | |
INNER_C_UNION_9404448031707501477* = object {.union.} | |
stream_start*: INNER_C_STRUCT_9581966235636552858 | |
alias*: INNER_C_STRUCT_1221667129857401972 | |
anchor*: INNER_C_STRUCT_3317256698323717696 | |
tag*: INNER_C_STRUCT_5441002398333014240 | |
scalar*: INNER_C_STRUCT_7453632048426669727 | |
version_directive*: INNER_C_STRUCT_9783180209656813162 | |
tag_directive*: INNER_C_STRUCT_13940099295483927389 | |
yaml_token_t* = object | |
typ*: yaml_token_type_t | |
data*: INNER_C_UNION_9404448031707501477 | |
start_mark*: yaml_mark_t | |
end_mark*: yaml_mark_t | |
type | |
yaml_event_type_t* {.size: sizeof(cint).} = enum | |
YAML_NO_EVENT, | |
YAML_STREAM_START_EVENT, | |
YAML_STREAM_END_EVENT, | |
YAML_DOCUMENT_START_EVENT, | |
YAML_DOCUMENT_END_EVENT, | |
YAML_ALIAS_EVENT, | |
YAML_SCALAR_EVENT, | |
YAML_SEQUENCE_START_EVENT, | |
YAML_SEQUENCE_END_EVENT, | |
YAML_MAPPING_START_EVENT, | |
YAML_MAPPING_END_EVENT | |
type | |
INNER_C_STRUCT_12590518896704616971* = object | |
encoding*: yaml_encoding_t | |
INNER_C_STRUCT_2667561393214118032* = object | |
start*: ptr yaml_tag_directive_t | |
endd*: ptr yaml_tag_directive_t | |
INNER_C_STRUCT_8611624117794791642* = object | |
version_directive*: ptr yaml_version_directive_t | |
tag_directives*: INNER_C_STRUCT_2667561393214118032 | |
implicit*: cint | |
INNER_C_STRUCT_6989068223488568623* = object | |
implicit*: cint | |
INNER_C_STRUCT_12004643997943399240* = object | |
anchor*: cstring | |
INNER_C_STRUCT_14974408632587267100* = object | |
anchor*: cstring | |
tag*: cstring | |
value*: cstring | |
length*: csize | |
plain_implicit*: cint | |
quoted_implicit*: cint | |
style*: yaml_scalar_style_t | |
INNER_C_STRUCT_17970865806594553108* = object | |
anchor*: cstring | |
tag*: cstring | |
implicit*: cint | |
style*: yaml_sequence_style_t | |
INNER_C_STRUCT_1674767092908407322* = object | |
anchor*: cstring | |
tag*: cstring | |
implicit*: cint | |
style*: yaml_mapping_style_t | |
INNER_C_UNION_14299011587659785980* = object {.union.} | |
stream_start*: INNER_C_STRUCT_12590518896704616971 | |
document_start*: INNER_C_STRUCT_8611624117794791642 | |
document_endd*: INNER_C_STRUCT_6989068223488568623 | |
alias*: INNER_C_STRUCT_12004643997943399240 | |
scalar*: INNER_C_STRUCT_14974408632587267100 | |
sequence_start*: INNER_C_STRUCT_17970865806594553108 | |
mapping_start*: INNER_C_STRUCT_1674767092908407322 | |
yaml_event_t* = object | |
typ*: yaml_event_type_t | |
data*: INNER_C_UNION_14299011587659785980 | |
start_mark*: yaml_mark_t | |
end_mark*: yaml_mark_t | |
const YAML_NULL_TAG* = "tag:yaml.org,2002:null" | |
const YAML_BOOL_TAG* = "tag:yaml.org,2002:bool" | |
const YAML_STR_TAG* = "tag:yaml.org,2002:str" | |
const YAML_INT_TAG* = "tag:yaml.org,2002:int" | |
const YAML_FLOAT_TAG* = "tag:yaml.org,2002:float" | |
const YAML_TIMESTAMP_TAG* = "tag:yaml.org,2002:timestamp" | |
const YAML_SEQ_TAG* = "tag:yaml.org,2002:seq" | |
const YAML_MAP_TAG* = "tag:yaml.org,2002:map" | |
const YAML_DEFAULT_SCALAR_TAG* = YAML_STR_TAG | |
const YAML_DEFAULT_SEQUENCE_TAG* = YAML_SEQ_TAG | |
const YAML_DEFAULT_MAPPING_TAG* = YAML_MAP_TAG | |
var YAML_VNULL_TAG* = "tag:yaml.org,2002:null" | |
var YAML_VBOOL_TAG* = "tag:yaml.org,2002:bool" | |
var YAML_VSTR_TAG* = "tag:yaml.org,2002:str" | |
var YAML_VINT_TAG* = "tag:yaml.org,2002:int" | |
var YAML_VFLOAT_TAG* = "tag:yaml.org,2002:float" | |
var YAML_VTIMESTAMP_TAG* = "tag:yaml.org,2002:timestamp" | |
var YAML_VSEQ_TAG* = "tag:yaml.org,2002:seq" | |
var YAML_VMAP_TAG* = "tag:yaml.org,2002:map" | |
var YAML_VDEFAULT_SCALAR_TAG* = YAML_STR_TAG | |
var YAML_VDEFAULT_SEQUENCE_TAG* = YAML_SEQ_TAG | |
var YAML_VDEFAULT_MAPPING_TAG* = YAML_MAP_TAG | |
type | |
yaml_node_type_t* {.size: sizeof(cint).} = enum | |
YAML_NO_NODE, | |
YAML_SCALAR_NODE, | |
YAML_SEQUENCE_NODE, | |
YAML_MAPPING_NODE | |
yaml_node_t* = yaml_node_s | |
yaml_node_item_t* = cint | |
yaml_node_pair_t* = object | |
key*: cint | |
value*: cint | |
INNER_C_STRUCT_2771607800107246221* = object | |
value*: cstring | |
length*: csize | |
style*: yaml_scalar_style_t | |
INNER_C_STRUCT_16176656515014249903* = object | |
start*: ptr yaml_node_item_t | |
endd*: ptr yaml_node_item_t | |
top*: ptr yaml_node_item_t | |
INNER_C_STRUCT_17512274596170441087* = object | |
items*: INNER_C_STRUCT_16176656515014249903 | |
style*: yaml_sequence_style_t | |
INNER_C_STRUCT_6534273983681155882* = object | |
start*: ptr yaml_node_pair_t | |
endd*: ptr yaml_node_pair_t | |
top*: ptr yaml_node_pair_t | |
INNER_C_STRUCT_11518003446976276318* = object | |
pairs*: INNER_C_STRUCT_6534273983681155882 | |
style*: yaml_mapping_style_t | |
INNER_C_UNION_9402779093446787060* = object {.union.} | |
scalar*: INNER_C_STRUCT_2771607800107246221 | |
sequence*: INNER_C_STRUCT_17512274596170441087 | |
mapping*: INNER_C_STRUCT_11518003446976276318 | |
yaml_node_s* = object | |
typ*: yaml_node_type_t | |
tag*: cstring | |
data*: INNER_C_UNION_9402779093446787060 | |
start_mark*: yaml_mark_t | |
end_mark*: yaml_mark_t | |
type | |
INNER_C_STRUCT_2411546260517137131* = object | |
start*: ptr yaml_node_t | |
endd*: ptr yaml_node_t | |
top*: ptr yaml_node_t | |
INNER_C_STRUCT_4991458144178661981* = object | |
start*: ptr yaml_tag_directive_t | |
endd*: ptr yaml_tag_directive_t | |
yaml_document_t* = object | |
nodes*: INNER_C_STRUCT_2411546260517137131 | |
version_directive*: ptr yaml_version_directive_t | |
tag_directives*: INNER_C_STRUCT_4991458144178661981 | |
start_implicit*: cint | |
end_implicit*: cint | |
start_mark*: yaml_mark_t | |
end_mark*: yaml_mark_t | |
type | |
yaml_read_handler_t* = proc (data: pointer; buffer: cstring; size: csize; | |
size_read: ptr csize): cint | |
type | |
yaml_simple_key_t* = object | |
possible*: cint | |
required*: cint | |
token_number*: csize | |
mark*: yaml_mark_t | |
type | |
yaml_parser_state_t* {.size: sizeof(cint).} = enum | |
YAML_PARSE_STREAM_START_STATE, | |
YAML_PARSE_IMPLICIT_DOCUMENT_START_STATE, | |
YAML_PARSE_DOCUMENT_START_STATE, | |
YAML_PARSE_DOCUMENT_CONTENT_STATE, | |
YAML_PARSE_DOCUMENT_END_STATE, | |
YAML_PARSE_BLOCK_NODE_STATE, | |
YAML_PARSE_BLOCK_NODE_OR_INDENTLESS_SEQUENCE_STATE, | |
YAML_PARSE_FLOW_NODE_STATE, | |
YAML_PARSE_BLOCK_SEQUENCE_FIRST_ENTRY_STATE, | |
YAML_PARSE_BLOCK_SEQUENCE_ENTRY_STATE, | |
YAML_PARSE_INDENTLESS_SEQUENCE_ENTRY_STATE, | |
YAML_PARSE_BLOCK_MAPPING_FIRST_KEY_STATE, | |
YAML_PARSE_BLOCK_MAPPING_KEY_STATE, | |
YAML_PARSE_BLOCK_MAPPING_VALUE_STATE, | |
YAML_PARSE_FLOW_SEQUENCE_FIRST_ENTRY_STATE, | |
YAML_PARSE_FLOW_SEQUENCE_ENTRY_STATE, | |
YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_KEY_STATE, | |
YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_VALUE_STATE, | |
YAML_PARSE_FLOW_SEQUENCE_ENTRY_MAPPING_END_STATE, | |
YAML_PARSE_FLOW_MAPPING_FIRST_KEY_STATE, | |
YAML_PARSE_FLOW_MAPPING_KEY_STATE, | |
YAML_PARSE_FLOW_MAPPING_VALUE_STATE, | |
YAML_PARSE_FLOW_MAPPING_EMPTY_VALUE_STATE, | |
YAML_PARSE_END_STATE | |
type | |
yaml_alias_data_t* = object | |
anchor*: cstring | |
index*: cint | |
mark*: yaml_mark_t | |
type | |
INNER_C_STRUCT_16371464751651700497* = object | |
start*: cstring | |
endd*: cstring | |
current*: cstring | |
INNER_C_UNION_14844535658673536178* = object {.union.} | |
string*: INNER_C_STRUCT_16371464751651700497 | |
file*: ptr FILE | |
INNER_C_STRUCT_5449995434778144246* = object | |
start*: cstring | |
endd*: cstring | |
pointer*: cstring | |
last*: cstring | |
INNER_C_STRUCT_1533468219873624615* = object | |
start*: cstring | |
endd*: cstring | |
pointer*: cstring | |
last*: cstring | |
INNER_C_STRUCT_12302340786945222376* = object | |
start*: ptr yaml_token_t | |
endd*: ptr yaml_token_t | |
head*: ptr yaml_token_t | |
tail*: ptr yaml_token_t | |
INNER_C_STRUCT_6311148685867902540* = object | |
start*: ptr cint | |
endd*: ptr cint | |
top*: ptr cint | |
INNER_C_STRUCT_6741121270717550011* = object | |
start*: ptr yaml_simple_key_t | |
endd*: ptr yaml_simple_key_t | |
top*: ptr yaml_simple_key_t | |
INNER_C_STRUCT_14987939425048783309* = object | |
start*: ptr yaml_parser_state_t | |
endd*: ptr yaml_parser_state_t | |
top*: ptr yaml_parser_state_t | |
INNER_C_STRUCT_11595967245106118857* = object | |
start*: ptr yaml_mark_t | |
endd*: ptr yaml_mark_t | |
top*: ptr yaml_mark_t | |
INNER_C_STRUCT_426684507395569091* = object | |
start*: ptr yaml_tag_directive_t | |
endd*: ptr yaml_tag_directive_t | |
top*: ptr yaml_tag_directive_t | |
INNER_C_STRUCT_7828170433486051057* = object | |
start*: ptr yaml_alias_data_t | |
endd*: ptr yaml_alias_data_t | |
top*: ptr yaml_alias_data_t | |
yaml_parser_t* = object | |
error*: yaml_error_type_t | |
problem*: cstring | |
problem_offset*: csize | |
problem_value*: cint | |
problem_mark*: yaml_mark_t | |
context*: cstring | |
context_mark*: yaml_mark_t | |
read_handler*: ptr yaml_read_handler_t | |
read_handler_data*: pointer | |
input*: INNER_C_UNION_14844535658673536178 | |
eof*: cint | |
buffer*: INNER_C_STRUCT_5449995434778144246 | |
unread*: csize | |
raw_buffer*: INNER_C_STRUCT_1533468219873624615 | |
encoding*: yaml_encoding_t | |
offset*: csize | |
mark*: yaml_mark_t | |
stream_start_produced*: cint | |
stream_end_produced*: cint | |
flow_level*: cint | |
tokens*: INNER_C_STRUCT_12302340786945222376 | |
tokens_parsed*: csize | |
token_available*: cint | |
indents*: INNER_C_STRUCT_6311148685867902540 | |
indent*: cint | |
simple_key_allowed*: cint | |
simple_keys*: INNER_C_STRUCT_6741121270717550011 | |
states*: INNER_C_STRUCT_14987939425048783309 | |
state*: yaml_parser_state_t | |
marks*: INNER_C_STRUCT_11595967245106118857 | |
tag_directives*: INNER_C_STRUCT_426684507395569091 | |
aliases*: INNER_C_STRUCT_7828170433486051057 | |
document*: ptr yaml_document_t | |
type | |
yaml_write_handler_t* = proc (data: pointer; buffer: cstring; size: csize): cint | |
type | |
yaml_emitter_state_t* {.size: sizeof(cint).} = enum | |
YAML_EMIT_STREAM_START_STATE, | |
YAML_EMIT_FIRST_DOCUMENT_START_STATE, | |
YAML_EMIT_DOCUMENT_START_STATE, | |
YAML_EMIT_DOCUMENT_CONTENT_STATE, | |
YAML_EMIT_DOCUMENT_END_STATE, | |
YAML_EMIT_FLOW_SEQUENCE_FIRST_ITEM_STATE, | |
YAML_EMIT_FLOW_SEQUENCE_ITEM_STATE, | |
YAML_EMIT_FLOW_MAPPING_FIRST_KEY_STATE, | |
YAML_EMIT_FLOW_MAPPING_KEY_STATE, | |
YAML_EMIT_FLOW_MAPPING_SIMPLE_VALUE_STATE, | |
YAML_EMIT_FLOW_MAPPING_VALUE_STATE, | |
YAML_EMIT_BLOCK_SEQUENCE_FIRST_ITEM_STATE, | |
YAML_EMIT_BLOCK_SEQUENCE_ITEM_STATE, | |
YAML_EMIT_BLOCK_MAPPING_FIRST_KEY_STATE, | |
YAML_EMIT_BLOCK_MAPPING_KEY_STATE, | |
YAML_EMIT_BLOCK_MAPPING_SIMPLE_VALUE_STATE, | |
YAML_EMIT_BLOCK_MAPPING_VALUE_STATE, | |
YAML_EMIT_END_STATE | |
type | |
INNER_C_STRUCT_12749614999235445465* = object | |
buffer*: cstring | |
size*: csize | |
size_written*: ptr csize | |
INNER_C_UNION_12199099344959672631* = object {.union.} | |
string*: INNER_C_STRUCT_12749614999235445465 | |
file*: ptr FILE | |
INNER_C_STRUCT_12563198298657885016* = object | |
start*: cstring | |
endd*: cstring | |
pointer*: cstring | |
last*: cstring | |
INNER_C_STRUCT_2333930655588273530* = object | |
start*: cstring | |
endd*: cstring | |
pointer*: cstring | |
last*: cstring | |
INNER_C_STRUCT_3757196451896818589* = object | |
start*: ptr yaml_emitter_state_t | |
endd*: ptr yaml_emitter_state_t | |
top*: ptr yaml_emitter_state_t | |
INNER_C_STRUCT_394143963162845597* = object | |
start*: ptr yaml_event_t | |
endd*: ptr yaml_event_t | |
head*: ptr yaml_event_t | |
tail*: ptr yaml_event_t | |
INNER_C_STRUCT_16850922517203281724* = object | |
start*: ptr cint | |
endd*: ptr cint | |
top*: ptr cint | |
INNER_C_STRUCT_12260090914027529514* = object | |
start*: ptr yaml_tag_directive_t | |
endd*: ptr yaml_tag_directive_t | |
top*: ptr yaml_tag_directive_t | |
INNER_C_STRUCT_1556210231363541236* = object | |
anchor*: cstring | |
anchor_length*: csize | |
alias*: cint | |
INNER_C_STRUCT_17739845129940504956* = object | |
handle*: cstring | |
handle_length*: csize | |
suffix*: cstring | |
suffix_length*: csize | |
INNER_C_STRUCT_2932767511639488752* = object | |
value*: cstring | |
length*: csize | |
multiline*: cint | |
flow_plain_allowed*: cint | |
block_plain_allowed*: cint | |
single_quoted_allowed*: cint | |
block_allowed*: cint | |
style*: yaml_scalar_style_t | |
INNER_C_STRUCT_11864533033166503222* = object | |
references*: cint | |
anchor*: cint | |
serialized*: cint | |
yaml_emitter_t* = object | |
error*: yaml_error_type_t | |
problem*: cstring | |
write_handler*: ptr yaml_write_handler_t | |
write_handler_data*: pointer | |
output*: INNER_C_UNION_12199099344959672631 | |
buffer*: INNER_C_STRUCT_12563198298657885016 | |
raw_buffer*: INNER_C_STRUCT_2333930655588273530 | |
encoding*: yaml_encoding_t | |
canonical*: cint | |
best_indent*: cint | |
best_width*: cint | |
unicode*: cint | |
line_break*: yaml_break_t | |
states*: INNER_C_STRUCT_3757196451896818589 | |
state*: yaml_emitter_state_t | |
events*: INNER_C_STRUCT_394143963162845597 | |
indents*: INNER_C_STRUCT_16850922517203281724 | |
tag_directives*: INNER_C_STRUCT_12260090914027529514 | |
indent*: cint | |
flow_level*: cint | |
root_context*: cint | |
sequence_context*: cint | |
mapping_context*: cint | |
simple_key_context*: cint | |
line*: cint | |
column*: cint | |
whitespace*: cint | |
indention*: cint | |
open_ended*: cint | |
anchor_data*: INNER_C_STRUCT_1556210231363541236 | |
tag_data*: INNER_C_STRUCT_17739845129940504956 | |
scalar_data*: INNER_C_STRUCT_2932767511639488752 | |
opened*: cint | |
closed*: cint | |
anchors*: ptr INNER_C_STRUCT_11864533033166503222 | |
last_anchor_id*: cint | |
document*: ptr yaml_document_t | |
{.push importc, cdecl.} | |
proc yaml_get_version_string*(): cstring | |
proc yaml_get_version*(major: ptr cint; minor: ptr cint; patch: ptr cint) | |
proc yaml_token_delete*(token: ptr yaml_token_t) | |
proc yaml_stream_start_event_initialize*(event: ptr yaml_event_t; | |
encoding: yaml_encoding_t): cint | |
proc yaml_stream_end_event_initialize*(event: ptr yaml_event_t): cint | |
proc yaml_document_start_event_initialize*(event: ptr yaml_event_t; | |
version_directive: ptr yaml_version_directive_t; | |
tag_directives_start: ptr yaml_tag_directive_t; | |
tag_directives_end: ptr yaml_tag_directive_t; implicit: cint): cint | |
proc yaml_document_end_event_initialize*(event: ptr yaml_event_t; implicit: cint): cint | |
proc yaml_alias_event_initialize*(event: ptr yaml_event_t; | |
anchor: cstring): cint | |
proc yaml_scalar_event_initialize*(event: ptr yaml_event_t; | |
anchor: cstring; | |
tag: cstring; value: cstring; | |
length: cint; plain_implicit: cint; | |
quoted_implicit: cint; | |
style: yaml_scalar_style_t): cint | |
proc yaml_sequence_start_event_initialize*(event: ptr yaml_event_t; | |
anchor: cstring; tag: cstring; implicit: cint; | |
style: yaml_sequence_style_t): cint | |
proc yaml_sequence_end_event_initialize*(event: ptr yaml_event_t): cint | |
proc yaml_mapping_start_event_initialize*(event: ptr yaml_event_t; | |
anchor: cstring; tag: cstring; implicit: cint; | |
style: yaml_mapping_style_t): cint | |
proc yaml_mapping_end_event_initialize*(event: ptr yaml_event_t): cint | |
proc yaml_event_delete*(event: ptr yaml_event_t) | |
proc yaml_document_initialize*(document: ptr yaml_document_t; | |
version_directive: ptr yaml_version_directive_t; | |
tag_directives_start: ptr yaml_tag_directive_t; | |
tag_directives_end: ptr yaml_tag_directive_t; | |
start_implicit: cint; end_implicit: cint): cint | |
proc yaml_document_delete*(document: ptr yaml_document_t) | |
proc yaml_document_get_node*(document: ptr yaml_document_t; index: cint): ptr yaml_node_t | |
proc yaml_document_get_root_node*(document: ptr yaml_document_t): ptr yaml_node_t | |
proc yaml_document_add_scalar*(document: ptr yaml_document_t; | |
tag: cstring; value: cstring; | |
length: cint; style: yaml_scalar_style_t): cint | |
proc yaml_document_add_sequence*(document: ptr yaml_document_t; | |
tag: cstring; | |
style: yaml_sequence_style_t): cint | |
proc yaml_document_add_mapping*(document: ptr yaml_document_t; | |
tag: cstring; | |
style: yaml_mapping_style_t): cint | |
proc yaml_document_append_sequence_item*(document: ptr yaml_document_t; | |
sequence: cint; item: cint): cint | |
proc yaml_document_append_mapping_pair*(document: ptr yaml_document_t; | |
mapping: cint; key: cint; value: cint): cint | |
proc yaml_parser_initialize*(parser: ptr yaml_parser_t): cint | |
proc yaml_parser_delete*(parser: ptr yaml_parser_t) | |
proc yaml_parser_set_input_string*(parser: ptr yaml_parser_t; input: cstring; | |
size: csize) | |
proc yaml_parser_set_input_file*(parser: ptr yaml_parser_t; file: ptr FILE) | |
proc yaml_parser_set_input*(parser: ptr yaml_parser_t; | |
handler: ptr yaml_read_handler_t; data: pointer) | |
proc yaml_parser_set_encoding*(parser: ptr yaml_parser_t; | |
encoding: yaml_encoding_t) | |
proc yaml_parser_scan*(parser: ptr yaml_parser_t; token: ptr yaml_token_t): cint | |
proc yaml_parser_parse*(parser: ptr yaml_parser_t; event: ptr yaml_event_t): cint | |
proc yaml_parser_load*(parser: ptr yaml_parser_t; document: ptr yaml_document_t): cint | |
proc yaml_emitter_initialize*(emitter: ptr yaml_emitter_t): cint | |
proc yaml_emitter_delete*(emitter: ptr yaml_emitter_t) | |
proc yaml_emitter_set_output_string*(emitter: ptr yaml_emitter_t; | |
output: cstring; size: csize; | |
size_written: ptr csize) | |
proc yaml_emitter_set_output_file*(emitter: ptr yaml_emitter_t; file: ptr FILE) | |
proc yaml_emitter_set_output*(emitter: ptr yaml_emitter_t; | |
handler: ptr yaml_write_handler_t; data: pointer) | |
proc yaml_emitter_set_encoding*(emitter: ptr yaml_emitter_t; | |
encoding: yaml_encoding_t) | |
proc yaml_emitter_set_canonical*(emitter: ptr yaml_emitter_t; canonical: cint) | |
proc yaml_emitter_set_indent*(emitter: ptr yaml_emitter_t; indent: cint) | |
proc yaml_emitter_set_width*(emitter: ptr yaml_emitter_t; width: cint) | |
proc yaml_emitter_set_unicode*(emitter: ptr yaml_emitter_t; unicode: cint) | |
proc yaml_emitter_set_break*(emitter: ptr yaml_emitter_t; | |
line_break: yaml_break_t) | |
proc yaml_emitter_emit*(emitter: ptr yaml_emitter_t; event: ptr yaml_event_t): cint | |
proc yaml_emitter_open*(emitter: ptr yaml_emitter_t): cint | |
proc yaml_emitter_close*(emitter: ptr yaml_emitter_t): cint | |
proc yaml_emitter_dump*(emitter: ptr yaml_emitter_t; | |
document: ptr yaml_document_t): cint | |
proc yaml_emitter_flush*(emitter: ptr yaml_emitter_t): cint | |
{.pop.} | |
{.link: "lib/libyaml/libyaml.a".} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import lib.libyaml | |
from tables import Table, initTable, `[]`, `[]=`, pairs, `==` | |
from strutils import parseInt, parseFloat, `%` | |
from hashes import hash, THash, `!&`, `!$` | |
from typetraits import name | |
import unsigned | |
type | |
YamlObjKind* {.pure.} = enum | |
Seq | |
Map | |
String | |
Null | |
Bool | |
Int | |
Float | |
Document | |
YamlObj* = ref object | |
case kind: YamlObjKind | |
of YamlObjKind.Map: | |
mapVal: Table[YamlObj, YamlObj] | |
of YamlObjKind.Seq: | |
seqVal: seq[YamlObj] | |
of YamlObjKind.String: | |
strVal: string | |
of YamlObjKind.Bool: | |
boolVal: bool | |
of YamlObjKind.Int: | |
intVal: int | |
of YamlObjKind.Float: | |
floatVal: float64 | |
of YamlObjKind.Null: | |
nil | |
of YamlObjKind.Document: | |
nil | |
YamlDoc* = YamlObj | |
# hash & == {{{ | |
proc hash*(self: YamlObj): THash = | |
result = 0 | |
result = result !& ord(self.kind) | |
case self.kind | |
of YamlObjKind.Map: | |
for k, v in self.mapVal: | |
result = result !& hash(k) | |
result = result !& hash(v) | |
of YamlObjKind.Seq: | |
for v in self.seqVal: | |
result = result !& hash(v) | |
of YamlObjKind.String: | |
result = result !& hash(self.strVal) | |
of YamlObjKind.Bool: | |
result = result !& ord(self.boolVal) | |
of YamlObjKind.Int: | |
result = result !& hash(self.intVal) | |
of YamlObjKind.Float: | |
result = result !& hash(self.floatVal) | |
of YamlObjKind.Null, YamlObjKind.Document: | |
discard | |
proc `==`*(a, b: YamlObj): bool = | |
if a.kind != b.kind: return false | |
case a.kind | |
of YamlObjKind.Map: | |
if a.mapVal != b.mapVal: return false | |
of YamlObjKind.Seq: | |
if a.seqVal != b.seqVal: return false | |
of YamlObjKind.String: | |
if a.strVal != b.strVal: return false | |
of YamlObjKind.Bool: | |
if a.boolVal != b.boolVal: return false | |
of YamlObjKind.Int: | |
if a.intVal != b.intVal: return false | |
of YamlObjKind.Float: | |
if a.floatVal != b.floatVal: return false | |
of YamlObjKind.Null, YamlObjKind.Document: | |
discard | |
return true | |
# }}} | |
template success(test: expr): stmt = | |
if test != 1: raise newException(Exception, "failed to execute") | |
# `load()` Internals {{{ | |
type | |
LoadContext = ref object | |
parser: yaml_parser_t | |
anchors: Table[string, YamlObj] | |
gen: iterator(): yaml_event_t {.closure.} | |
proc copyEvent(self: yaml_event_t): tuple[typ: yaml_event_type_t, anchor: string] = | |
# not for general-purpose use | |
if self.data.scalar.anchor == nil: | |
return | |
return (self.typ, $self.data.scalar.anchor) | |
proc handleAnchors(self: LoadContext, | |
event: tuple[typ: yaml_event_type_t, anchor: string], | |
result: YamlObj) = | |
if event.typ in { YAML_SCALAR_EVENT, | |
YAML_SEQUENCE_START_EVENT, | |
YAML_MAPPING_START_EVENT }: | |
# first element in each branch, so is equvilent for all three | |
let anchor = event.anchor | |
if anchor != nil: | |
self.anchors[anchor] = result | |
proc events(self: LoadContext): iterator(): yaml_event_t = | |
# returned events must be copied before this run again | |
return iterator(): yaml_event_t = | |
var event: yaml_event_t | |
while true: | |
if yaml_parser_parse(addr self.parser, addr event) != 1: | |
raise newException(Exception, "Malformed input: " & $self.parser.error) | |
if event.typ == YAML_NO_EVENT: | |
break | |
yield event | |
yaml_event_delete(addr event) | |
var recognize: array[yaml_event_type_t, proc(self: LoadContext, event: yaml_event_t): YamlObj {.nimcall.}] | |
recognize[YAML_DOCUMENT_START_EVENT] = proc(self: LoadContext, event: yaml_event_t): YamlObj = | |
let next = self.gen() | |
result = recognize[next.typ](self, next) | |
let endDoc = self.gen() | |
assert(endDoc.typ == YAML_DOCUMENT_END_EVENT, "Document must only have one thing inside") | |
recognize[YAML_ALIAS_EVENT] = proc(self: LoadContext, event: yaml_event_t): YamlObj = | |
return self.anchors[$event.data.alias.anchor] | |
recognize[YAML_SCALAR_EVENT] = proc(self: LoadContext, event: yaml_event_t): YamlObj = | |
var tag: string | |
if event.data.scalar.tag != nil: | |
tag = $event.data.scalar.tag | |
case tag | |
of YAML_NULL_TAG: return YamlObj(kind : YamlObjKind.Null) | |
of YAML_BOOL_TAG: | |
result = YamlObj(kind : YamlObjKind.Bool) | |
if event.data.scalar.value == "true": | |
result.boolVal = true | |
elif event.data.scalar.value == "false": | |
result.boolVal = false | |
else: | |
assert(false, "Unknown boolean value " & $event.data.scalar.value) | |
of YAML_INT_TAG: | |
return YamlObj(kind : YamlObjKind.Int, intVal : parseInt($event.data.scalar.value)) | |
of YAML_FLOAT_TAG: | |
return YamlObj(kind : YamlObjKind.Float, floatVal : parseFloat($event.data.scalar.value)) | |
else: # unknown or string, treat as string | |
return YamlObj(kind : YamlObjKind.String, strVal : $event.data.scalar.value) | |
recognize[YAML_SEQUENCE_START_EVENT] = proc(self: LoadContext, event: yaml_event_t): YamlObj = | |
let initialEvent = copyEvent event | |
result = YamlObj(kind : YamlObjKind.Seq, seqVal : @[]) | |
var event = event | |
while true: | |
event = self.gen() | |
if event.typ == YAML_SEQUENCE_END_EVENT: break | |
result.seqVal.add(recognize[event.typ](self, event)) | |
self.handleAnchors(initialEvent, result) | |
recognize[YAML_MAPPING_START_EVENT] = proc(self: LoadContext, event: yaml_event_t): YamlObj = | |
let initialEvent = copyEvent event | |
result = YamlObj(kind : YamlObjKind.Map, mapVal : initTable[YamlObj, YamlObj]()) | |
while true: | |
let keyEvent = self.gen() | |
if keyEvent.typ == YAML_MAPPING_END_EVENT: break | |
let key = recognize[keyEvent.typ](self, keyEvent) | |
let valEvent = self.gen() | |
let val = recognize[valEvent.typ](self, valEvent) | |
result.mapVal[key] = val | |
self.handleAnchors(initialEvent, result) | |
recognize[YAML_SEQUENCE_END_EVENT] = proc(self: LoadContext, event: yaml_event_t): YamlObj = | |
assert(false, "Sequence end event should never be triggered") | |
recognize[YAML_MAPPING_END_EVENT] = proc(self: LoadContext, event: yaml_event_t): YamlObj = | |
assert(false, "Mapping end event should never be triggered") | |
recognize[YAML_DOCUMENT_END_EVENT] = proc(self: LoadContext, event: yaml_event_t): YamlObj = | |
assert(false, "Document end event should never be triggered") | |
recognize[YAML_STREAM_END_EVENT] = proc(self: LoadContext, event: yaml_event_t): YamlObj = | |
assert(false, "Stream end event should never be triggered") | |
recognize[YAML_NO_EVENT] = proc(self: LoadContext, event: yaml_event_t): YamlObj = | |
discard | |
# }}} | |
proc load*(text: string): seq[YamlDoc] = | |
## Parses the sequence of YAML documents in `text` | |
## | |
## Note: while the YAML specification allows non-scalar | |
## mapping keys, this does not. | |
var parser: yaml_parser_t | |
success yaml_parser_initialize(addr parser) | |
var loadCtx = LoadContext(parser : parser, | |
anchors : initTable[string, YamlObj]() ) | |
yaml_parser_set_input_string(addr loadCtx.parser, text, csize(text.len)) | |
yaml_parser_set_encoding(addr loadCtx.parser, YAML_UTF8_ENCODING) | |
loadCtx.gen = loadCtx.events() | |
result = @[] | |
var event = loadCtx.gen() | |
assert(event.typ == YAML_STREAM_START_EVENT, "first event must be a YAML_STREAM_START_EVENT") | |
while true: | |
event = loadCtx.gen() | |
if event.typ == YAML_STREAM_END_EVENT: break | |
result.add(recognize[event.typ](loadCtx, event)) | |
yaml_parser_delete(addr loadCtx.parser) | |
# `$`() Internals {{{ | |
type | |
StringifyContext = ref object | |
emitter: yaml_emitter_t | |
result: string | |
proc emit(ctx: StringifyContext, event: ptr yaml_event_t) = | |
if yaml_emitter_emit(addr ctx.emitter, event) != 1: | |
raise newException(Exception, "Failed to emit event: " & | |
$ctx.emitter.problem) | |
var renderers: array[YamlObjKind, proc(self: YamlObj, ctx: StringifyContext) {.nimcall.}] | |
renderers[YamlObjKind.Seq] = proc(self: YamlObj, ctx: StringifyContext) = | |
var event = create(yaml_event_t) | |
success yaml_sequence_start_event_initialize(event, nil, nil, 1, YAML_ANY_SEQUENCE_STYLE) | |
ctx.emit(event) | |
for elem in self.seqVal: | |
renderers[elem.kind](elem, ctx) | |
success yaml_sequence_end_event_initialize(event) | |
ctx.emit(event) | |
free event | |
renderers[YamlObjKind.Map] = proc(self: YamlObj, ctx: StringifyContext) = | |
var event = create(yaml_event_t) | |
success yaml_mapping_start_event_initialize(event, nil, nil, 1, YAML_ANY_MAPPING_STYLE) | |
ctx.emit(event) | |
for k, v in self.mapVal: | |
renderers[k.kind](k, ctx) | |
renderers[v.kind](v, ctx) | |
success yaml_mapping_end_event_initialize(event) | |
ctx.emit(event) | |
free event | |
renderers[YamlObjKind.String] = proc(self: YamlObj, ctx: StringifyContext) = | |
var event = create(yaml_event_t) | |
success yaml_scalar_event_initialize(event, nil, | |
YAML_STR_TAG, | |
self.strVal, | |
self.strVal.len.cint, | |
1, 1, YAML_ANY_SCALAR_STYLE) | |
ctx.emit(event) | |
free event | |
renderers[YamlObjKind.Null] = proc(self: YamlObj, ctx: StringifyContext) = | |
var event = create(yaml_event_t) | |
success yaml_scalar_event_initialize(event, nil, | |
YAML_NULL_TAG, | |
"null", | |
"null".len, | |
1, 1, YAML_ANY_SCALAR_STYLE) | |
ctx.emit(event) | |
free event | |
renderers[YamlObjKind.Bool] = proc(self: YamlObj, ctx: StringifyContext) = | |
var event = create(yaml_event_t) | |
success yaml_scalar_event_initialize(event, nil, | |
YAML_BOOL_TAG, | |
$self.boolVal, | |
($self.boolVal).len.cint, | |
1, 1, YAML_ANY_SCALAR_STYLE) | |
ctx.emit(event) | |
free event | |
renderers[YamlObjKind.Int] = proc(self: YamlObj, ctx: StringifyContext) = | |
var event = create(yaml_event_t) | |
success yaml_scalar_event_initialize(event, nil, | |
YAML_INT_TAG, | |
$self.intVal, | |
($self.intVal).len.cint, | |
1, 1, YAML_ANY_SCALAR_STYLE) | |
ctx.emit(event) | |
free event | |
renderers[YamlObjKind.Float] = proc(self: YamlObj, ctx: StringifyContext) = | |
var event = create(yaml_event_t) | |
success yaml_scalar_event_initialize(event, nil, | |
YAML_FLOAT_TAG, | |
$self.floatVal, | |
($self.floatVal).len.cint, | |
1, 1, YAML_ANY_SCALAR_STYLE) | |
ctx.emit(event) | |
free event | |
renderers[YamlObjKind.Document] = proc(self: YamlObj, ctx: StringifyContext) = | |
assert(false, "Document should never be used as a Yaml object") | |
# }}} | |
proc `$`*(input: seq[YamlDoc], | |
indent: int = 2, | |
maxWidth: int = 80): string = | |
## Stringifies the sequence of YAML documents | |
## | |
## `indent` - the size of the indentation | |
## `maxWidth` - the level at which it should be | |
## wrapped, -1 means no wrapping | |
var ctx = StringifyContext( result : "" ) | |
success yaml_emitter_initialize(addr ctx.emitter) | |
yaml_emitter_set_output( | |
addr ctx.emitter, | |
cast[ptr yaml_write_handler_t]( | |
proc(ctx: ptr StringifyContext, buffer: pointer, size: csize): cint {.nimcall.}= | |
var bufferString = newString(size) | |
moveMem(cstring(bufferString), buffer, size) | |
ctx.result.add(bufferString) | |
return 1 | |
), | |
addr ctx) | |
yaml_emitter_set_encoding(addr ctx.emitter, YAML_UTF8_ENCODING) | |
yaml_emitter_set_canonical(addr ctx.emitter, 0) | |
yaml_emitter_set_indent(addr ctx.emitter, indent.cint) | |
yaml_emitter_set_unicode(addr ctx.emitter, 1) | |
var event = create(yaml_event_t) | |
success yaml_stream_start_event_initialize(event, YAML_UTF8_ENCODING) | |
ctx.emit(event) | |
for doc in input: | |
success yaml_document_start_event_initialize(event, nil, nil, nil, 1) | |
ctx.emit(event) | |
renderers[doc.kind](doc, ctx) | |
success yaml_document_end_event_initialize(event, 1) | |
ctx.emit(event) | |
success yaml_stream_end_event_initialize(event) | |
ctx.emit(event) | |
free event | |
yaml_emitter_delete(addr ctx.emitter) | |
return ctx.result | |
proc `$`*(val: YamlObj, | |
maxWidth: int = 80, | |
indent: int = 2): string = | |
let docSeq = @[val] | |
return `$`(docSeq, maxWidth = maxWidth, indent = indent) | |
# Navigation {{{ | |
const # errors | |
eKeyInScalar = "Cannot look up key in a scalar" | |
eKeyInScalarSeq = "Cannot look up key in scalar or sequence" | |
eScalarType = "Type $2 is incompatible with scalar type $1" | |
eCollectionNotScalar = "Cannot retrieve values from collections, only scalars" | |
eMalformedCollection = "Cannot create $1, field mismatch" | |
eNotIterable = "Cannot iterate over $1" | |
proc yamlize*(val: YamlObj): YamlObj = | |
return val | |
proc yamlize*(val: int): YamlObj = | |
return YamlObj(kind : YamlObjKind.Int, intVal : int(val)) | |
proc yamlize*(val: uint): YamlObj = | |
doAssert(val shr 63 != 1) # prevent overflow | |
return YamlObj(kind : YamlObjKind.Int, intVal : int(val)) | |
proc yamlize*(val: string): YamlObj = | |
if val == nil: | |
return YamlObj(kind : YamlObjKind.Null) | |
else: | |
return YamlObj(kind : YamlObjKind.String, strVal : val) | |
proc yamlize*(val: bool): YamlObj = | |
return YamlObj(kind : YamlObjKind.Bool, boolVal : val) | |
proc yamlize*(val: float): YamlObj = | |
return YamlObj(kind : YamlObjKind.Float, floatVal : float64(val)) | |
proc yamlize*[T](val: T): YamlObj = | |
result = YamlObj(kind : YamlObjKind.Map, mapVal : initTable[YamlObj, YamlObj]()) | |
for name, val in fieldPairs(val): | |
result[yamlize(name)] = yamlize(val) | |
proc yamlize*[T](val: ref T): YamlObj = | |
if val == nil: | |
return YamlObj(kind : YamlObjKind.Null) | |
else: | |
return yamlize(val[]) | |
proc yamlize*[I, K, V](val: array[I, tuple[k: K, v: V]]): YamlObj = | |
## Yamizes a map literal: | |
## | |
## yamlize({ "foo" : "bar", "obj1" : "obj2}) | |
result = YamlObj(kind : YamlObjKind.Map, mapVal : initTable()) | |
for pair in val: | |
let (k, v) = pair | |
result.mapVal[yamlize(k)] = yamlize(v) | |
proc yamlize*[V](val: openarray[V]): YamlObj = | |
result = YamlObj(kind : YamlObjKind.Seq, seqVal : @[]) | |
for v in val: | |
result.seqVal.add(yamlize(val)) | |
proc `[]`*(self: YamlObj, key: int): YamlObj = | |
case self.kind | |
of YamlObjKind.Seq: | |
return self.seqVal[key] | |
of YamlObjKind.Map: | |
return self.mapVal[yamlize(key)] | |
else: | |
raise newException(ValueError, eKeyInScalar) | |
proc `[]`*[T](self: YamlObj, key: T): YamlObj = | |
case self.kind | |
of YamlObjKind.Map: | |
return self.mapVal[yamlize(key)] | |
else: | |
raise newException(ValueError, eKeyInScalarSeq) | |
proc `[]=`*[V](self: YamlObj, key: int, val: V) = | |
case self.kind | |
of YamlObjKind.Seq: | |
self.seqVal[key] = yamlize(val) | |
of YamlObjKind.Map: | |
self.mapVal[yamlize(key)] = yamlize(val) | |
else: | |
raise newException(ValueError, eKeyInScalar) | |
proc `[]=`*[T, V](self: YamlObj, key: T, val: V) = | |
case self.kind | |
of YamlObjKind.Map: | |
self.mapVal[yamlize(key)] = yamlize(val) | |
else: | |
raise newException(ValueError, eKeyInScalarSeq) | |
iterator items*(self: YamlObj): YamlObj = | |
case self.kind | |
of YamlObjKind.Seq: | |
for v in self.seqVal: | |
yield v | |
else: | |
raise newException(ValueError, eNotIterable % [$self.kind]) | |
iterator pairs*(self: YamlObj): tuple[idx: int, val: YamlObj] = | |
case self.kind | |
of YamlObjKind.Seq: | |
for i, v in self.seqVal: | |
yield (i, v) | |
else: | |
raise newException(ValueError, eNotIterable % [$self.kind]) | |
iterator pairs*(self: YamlObj): tuple[key, val: YamlObj] = | |
case self.kind | |
of YamlObjKind.Map: | |
for k, v in self.mapVal: | |
yield (k, v) | |
else: | |
raise newException(ValueError, eNotIterable % [$self.kind]) | |
proc `.`*(self: YamlObj, key: string): YamlObj = | |
return self[key] | |
proc `.=`*[T](self: YamlObj, key: string, val: T): YamlObj = | |
self[key] = val | |
proc get*(self: YamlObj, T: typedesc): T = | |
if self.kind == YamlObjKind.Int: | |
when not compiles(int(result)): | |
raise newException(ValueError, eScalarType % [$self.kind, name T]) | |
else: | |
return self.intVal | |
if self.kind == YamlObjKind.Float: | |
when not compiles(float(result)): | |
raise newException(ValueError, eScalarType % [$self.kind, name T]) | |
else: | |
return self.floatVal | |
if self.kind == YamlObjKind.Bool: | |
when not compiles(bool(result)): | |
raise newException(ValueError, eScalarType % [$self.kind, name T]) | |
else: | |
return self.boolVal | |
if self.kind == YamlObjKind.String: | |
when not compiles(string(result)): | |
raise newException(ValueError, eScalarType % [$self.kind, name T]) | |
else: | |
return self.strVal | |
if self.kind == YamlObjKind.Null: | |
when not compiles(result[]): | |
raise newException(ValueError, eScalarType % [$self.kind, name T]) | |
else: | |
return nil | |
raise newException(ValueError, eCollectionNotScalar) | |
# }}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment